mirror of
https://github.com/archr-linux/fileman.git
synced 2026-07-13 03:19:08 -07:00
Refactoring all screen sizing to be directly based on SDL screen dimensions. Allow for fallback in case of probe failure.
This commit is contained in:
+4
-4
@@ -63,13 +63,13 @@ void Dialog::render(const bool p_focus)
|
||||
l_dialogDim.w = DIALOG_BORDER + MARGIN_X + l_dialogDim.w + MARGIN_X + DIALOG_BORDER;
|
||||
if (m_iconPresent)
|
||||
l_dialogDim.w += ICON_SIZE + MARGIN_X;
|
||||
if (l_dialogDim.w > SCREEN_WIDTH)
|
||||
l_dialogDim.w = SCREEN_WIDTH;
|
||||
if (l_dialogDim.w > m_screenWidth)
|
||||
l_dialogDim.w = m_screenWidth;
|
||||
|
||||
// Render dialog background
|
||||
l_dialogDim.h = LINE_HEIGHT + (m_labels.size() + m_options.size()) * LINE_HEIGHT + DIALOG_BORDER;
|
||||
l_dialogDim.x = (SCREEN_WIDTH - l_dialogDim.w) / 2;
|
||||
l_dialogDim.y = (SCREEN_HEIGHT - l_dialogDim.h) / 2;
|
||||
l_dialogDim.x = (m_screenWidth - l_dialogDim.w) / 2;
|
||||
l_dialogDim.y = (m_screenHeight - l_dialogDim.h) / 2;
|
||||
SDL_SetRenderDrawColor(g_renderer, COLOR_TITLE_BG, 255);
|
||||
SDL_RenderFillRect(g_renderer, &l_dialogDim);
|
||||
|
||||
|
||||
+8
-8
@@ -69,36 +69,36 @@ void ImageViewer::render(const bool p_focus)
|
||||
// Display image
|
||||
if (m_image != NULL)
|
||||
{
|
||||
if (m_fitToScreen && (m_imageW > SCREEN_WIDTH || m_imageH > SCREEN_HEIGHT - LINE_HEIGHT))
|
||||
if (m_fitToScreen && (m_imageW > m_screenWidth || m_imageH > m_screenHeight - LINE_HEIGHT))
|
||||
{
|
||||
// Resize image to fit the screen
|
||||
double aspectRatioScreen = static_cast<double>(SCREEN_WIDTH) / (SCREEN_HEIGHT - LINE_HEIGHT);
|
||||
double aspectRatioScreen = static_cast<double>(m_screenWidth) / (m_screenHeight - LINE_HEIGHT);
|
||||
double aspectRatioImage = static_cast<double>(m_imageW) / m_imageH;
|
||||
double resizeFactor = 0.0;
|
||||
if (aspectRatioImage > aspectRatioScreen)
|
||||
resizeFactor = static_cast<double>(m_imageW) / SCREEN_WIDTH;
|
||||
resizeFactor = static_cast<double>(m_imageW) / m_screenWidth;
|
||||
else
|
||||
resizeFactor = static_cast<double>(m_imageH) / (SCREEN_HEIGHT - LINE_HEIGHT);
|
||||
resizeFactor = static_cast<double>(m_imageH) / (m_screenHeight - LINE_HEIGHT);
|
||||
int imageFitW = static_cast<double>(m_imageW) / resizeFactor;
|
||||
int imageFitH = static_cast<double>(m_imageH) / resizeFactor;
|
||||
SDL_Rect destRect = { (SCREEN_WIDTH - imageFitW) / 2, LINE_HEIGHT + ((SCREEN_HEIGHT - LINE_HEIGHT - imageFitH) / 2), imageFitW, imageFitH };
|
||||
SDL_Rect destRect = { (m_screenWidth - imageFitW) / 2, LINE_HEIGHT + ((m_screenHeight - LINE_HEIGHT - imageFitH) / 2), imageFitW, imageFitH };
|
||||
SDL_RenderCopy(g_renderer, m_image, NULL, &destRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display image as it is
|
||||
SDLUtils::renderTexture(m_image, (m_imageW > SCREEN_WIDTH ? m_camera.x : 0) + (SCREEN_WIDTH / 2), (m_imageH > SCREEN_HEIGHT - LINE_HEIGHT ? m_camera.y : 0) + ((SCREEN_HEIGHT + LINE_HEIGHT) / 2), SDLUtils::T_ALIGN_CENTER, SDLUtils::T_ALIGN_MIDDLE);
|
||||
SDLUtils::renderTexture(m_image, (m_imageW > m_screenWidth ? m_camera.x : 0) + (m_screenWidth / 2), (m_imageH > m_screenHeight - LINE_HEIGHT ? m_camera.y : 0) + ((m_screenHeight + LINE_HEIGHT) / 2), SDLUtils::T_ALIGN_CENTER, SDLUtils::T_ALIGN_MIDDLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error
|
||||
SDLUtils::renderText("Unable to load image", g_font, SCREEN_WIDTH / 2, (SCREEN_HEIGHT + LINE_HEIGHT) / 2, {COLOR_TEXT_NORMAL}, {COLOR_BODY_BG}, SDLUtils::T_ALIGN_CENTER, SDLUtils::T_ALIGN_MIDDLE);
|
||||
SDLUtils::renderText("Unable to load image", g_font, m_screenWidth / 2, (m_screenHeight + LINE_HEIGHT) / 2, {COLOR_TEXT_NORMAL}, {COLOR_BODY_BG}, SDLUtils::T_ALIGN_CENTER, SDLUtils::T_ALIGN_MIDDLE);
|
||||
}
|
||||
|
||||
// Render title background
|
||||
SDL_SetRenderDrawColor(g_renderer, COLOR_TITLE_BG, 255);
|
||||
SDL_Rect rect { 0, 0, SCREEN_WIDTH, LINE_HEIGHT };
|
||||
SDL_Rect rect { 0, 0, m_screenWidth, LINE_HEIGHT };
|
||||
SDL_RenderFillRect(g_renderer, &rect);
|
||||
|
||||
// Render title
|
||||
|
||||
+14
-14
@@ -188,9 +188,9 @@ void Keyboard::init(void)
|
||||
return;
|
||||
|
||||
// Size and coordinates of the first key
|
||||
m_key[0].w = getKeyW();
|
||||
m_key[0].h = getKeyH();
|
||||
m_key[0].x = round((SCREEN_WIDTH - (11*m_key[0].w + 10*KEYBOARD_KEY_SPACING)) / 2);
|
||||
m_key[0].w = getKeyW(m_screenWidth);
|
||||
m_key[0].h = getKeyH(m_screenWidth);
|
||||
m_key[0].x = round((m_screenWidth - (11*m_key[0].w + 10*KEYBOARD_KEY_SPACING)) / 2);
|
||||
m_key[0].y = KEYBOARD_MARGIN;
|
||||
|
||||
// Height of all the keys
|
||||
@@ -199,10 +199,10 @@ void Keyboard::init(void)
|
||||
m_key[indKey].h = m_key[0].h;
|
||||
|
||||
// Size and coordinates of the keyboard
|
||||
m_keyboard.w = getKeyboardW();
|
||||
m_keyboard.h = getKeyboardH();
|
||||
m_keyboard.w = getKeyboardW(m_screenWidth);
|
||||
m_keyboard.h = getKeyboardH(m_screenWidth);
|
||||
m_keyboard.x = 0;
|
||||
m_keyboard.y = SCREEN_HEIGHT - m_keyboard.h;
|
||||
m_keyboard.y = m_screenHeight - m_keyboard.h;
|
||||
|
||||
// Keys: 1st line
|
||||
for (indKey = 1; indKey <= 10; ++indKey)
|
||||
@@ -409,24 +409,24 @@ SDL_Color Keyboard::getBackgroundColor(const int p_i, const bool p_focus) const
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Key and keyboard size
|
||||
int Keyboard::getKeyW(void)
|
||||
int Keyboard::getKeyW(const int screen_width)
|
||||
{
|
||||
return round((SCREEN_WIDTH - 2*KEYBOARD_MARGIN - 10*KEYBOARD_KEY_SPACING) / 11);
|
||||
return round((screen_width - 2*KEYBOARD_MARGIN - 10*KEYBOARD_KEY_SPACING) / 11);
|
||||
}
|
||||
|
||||
int Keyboard::getKeyH(void)
|
||||
int Keyboard::getKeyH(const int screen_width)
|
||||
{
|
||||
return round(getKeyW() / 1.2);
|
||||
return round(getKeyW(screen_width) / 1.2);
|
||||
}
|
||||
|
||||
int Keyboard::getKeyboardW(void)
|
||||
int Keyboard::getKeyboardW(const int screen_width)
|
||||
{
|
||||
return SCREEN_WIDTH;
|
||||
return screen_width;
|
||||
}
|
||||
|
||||
int Keyboard::getKeyboardH(void)
|
||||
int Keyboard::getKeyboardH(const int screen_width)
|
||||
{
|
||||
return 2*KEYBOARD_MARGIN + 3*KEYBOARD_KEY_SPACING + 4*getKeyH();
|
||||
return 2*KEYBOARD_MARGIN + 3*KEYBOARD_KEY_SPACING + 4*getKeyH(screen_width);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+4
-4
@@ -20,10 +20,10 @@ class Keyboard : public IWindow
|
||||
virtual void render(const bool p_focus);
|
||||
|
||||
// Key and keyboard size
|
||||
static int getKeyW(void);
|
||||
static int getKeyH(void);
|
||||
static int getKeyboardW(void);
|
||||
static int getKeyboardH(void);
|
||||
static int getKeyW(const int screen_width);
|
||||
static int getKeyH(const int screen_width);
|
||||
static int getKeyboardW(const int screen_width);
|
||||
static int getKeyboardH(const int screen_width);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+4
-4
@@ -51,7 +51,7 @@ void MainWindow::render(const bool p_focus)
|
||||
|
||||
// Render title background
|
||||
SDL_SetRenderDrawColor(g_renderer, COLOR_TITLE_BG, 255);
|
||||
SDL_Rect rect { 0, 0, SCREEN_WIDTH, LINE_HEIGHT };
|
||||
SDL_Rect rect { 0, 0, m_screenWidth, LINE_HEIGHT };
|
||||
SDL_RenderFillRect(g_renderer, &rect);
|
||||
|
||||
// Render title
|
||||
@@ -66,7 +66,7 @@ void MainWindow::render(const bool p_focus)
|
||||
SDL_SetRenderDrawColor(g_renderer, COLOR_CURSOR_NO_FOCUS, 255);
|
||||
rect.x = 0;
|
||||
rect.y = LINE_HEIGHT + (m_cursor - m_camera.y) * LINE_HEIGHT;
|
||||
rect.w = SCREEN_WIDTH - m_scrollbar.w;
|
||||
rect.w = m_screenWidth - m_scrollbar.w;
|
||||
rect.h = LINE_HEIGHT;
|
||||
SDL_RenderFillRect(g_renderer, &rect);
|
||||
|
||||
@@ -102,10 +102,10 @@ void MainWindow::render(const bool p_focus)
|
||||
if (m_fileLister[l_i].m_size == ULLONG_MAX)
|
||||
sizeW = 0;
|
||||
else
|
||||
sizeW = SDLUtils::renderText(FileUtils::formatSize(m_fileLister[l_i].m_size), g_font, SCREEN_WIDTH - m_scrollbar.w - MARGIN_X, l_y, l_fgColor, l_bgColor, SDLUtils::T_ALIGN_RIGHT, SDLUtils::T_ALIGN_MIDDLE);
|
||||
sizeW = SDLUtils::renderText(FileUtils::formatSize(m_fileLister[l_i].m_size), g_font, m_screenWidth - m_scrollbar.w - MARGIN_X, l_y, l_fgColor, l_bgColor, SDLUtils::T_ALIGN_RIGHT, SDLUtils::T_ALIGN_MIDDLE);
|
||||
|
||||
// File name
|
||||
fileNameMaxWidth = SCREEN_WIDTH - 4 * MARGIN_X - ICON_SIZE - m_scrollbar.w - sizeW;
|
||||
fileNameMaxWidth = m_screenWidth - 4 * MARGIN_X - ICON_SIZE - m_scrollbar.w - sizeW;
|
||||
if (m_cursor == l_i)
|
||||
{
|
||||
if (m_scrollFileNameActive)
|
||||
|
||||
+12
-2
@@ -45,11 +45,21 @@ bool SDLUtils::init()
|
||||
INHIBIT(std::cout << "SDL_JoystickOpen OK" << std::endl;)
|
||||
}
|
||||
|
||||
int width = SCREEN_WIDTH;
|
||||
int height = SCREEN_HEIGHT;
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetDesktopDisplayMode(0, &DM);
|
||||
|
||||
if(DM.w)
|
||||
width = DM.w;
|
||||
if(DM.h)
|
||||
height = DM.h;
|
||||
|
||||
// Create window
|
||||
#if FULLSCREEN == 1
|
||||
g_window = SDL_CreateWindow(APP_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
|
||||
g_window = SDL_CreateWindow(APP_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
|
||||
#else
|
||||
g_window = SDL_CreateWindow(APP_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
g_window = SDL_CreateWindow(APP_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
|
||||
#endif
|
||||
if (g_window == NULL)
|
||||
{
|
||||
|
||||
+5
-5
@@ -37,7 +37,7 @@ TextEditor::TextEditor(const std::string &p_title):
|
||||
// Init scrollbar
|
||||
adjustScrollbar();
|
||||
// Number of visible chars
|
||||
m_nbVisibleChars = round(static_cast<double>(SCREEN_WIDTH - 2*MARGIN_X - m_scrollbar.w) / g_charW);
|
||||
m_nbVisibleChars = round(static_cast<double>(m_screenWidth - 2*MARGIN_X - m_scrollbar.w) / g_charW);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -58,7 +58,7 @@ void TextEditor::render(const bool p_focus)
|
||||
|
||||
// Render title background
|
||||
SDL_SetRenderDrawColor(g_renderer, COLOR_TITLE_BG, 255);
|
||||
SDL_Rect rect { 0, 0, SCREEN_WIDTH, LINE_HEIGHT };
|
||||
SDL_Rect rect { 0, 0, m_screenWidth, LINE_HEIGHT };
|
||||
SDL_RenderFillRect(g_renderer, &rect);
|
||||
|
||||
// Render title
|
||||
@@ -128,7 +128,7 @@ void TextEditor::keyPressed(const SDL_Event &event)
|
||||
// Reset timer
|
||||
resetTimer();
|
||||
// If the keyboard hides the cursor, move the camera to make it visible
|
||||
if ((m_inputTextCursor.y - m_camera.y + 2) * LINE_HEIGHT > SCREEN_HEIGHT - Keyboard::getKeyboardH())
|
||||
if ((m_inputTextCursor.y - m_camera.y + 2) * LINE_HEIGHT > m_screenHeight - Keyboard::getKeyboardH(m_screenWidth))
|
||||
{
|
||||
m_camera.y = m_inputTextCursor.y - 2;
|
||||
adjustScrollbarPosition();
|
||||
@@ -311,8 +311,8 @@ void TextEditor::adjustCamera(void)
|
||||
m_camera.y = m_inputTextCursor.y - m_nbVisibleLines + 1;
|
||||
|
||||
// Adjust camera X
|
||||
if (MARGIN_X + (m_inputTextCursor.x - m_camera.x) * g_charW > SCREEN_WIDTH - m_scrollbar.w - MARGIN_X)
|
||||
m_camera.x = m_inputTextCursor.x - ((SCREEN_WIDTH - m_scrollbar.w - 2*MARGIN_X) / g_charW);
|
||||
if (MARGIN_X + (m_inputTextCursor.x - m_camera.x) * g_charW > m_screenWidth - m_scrollbar.w - MARGIN_X)
|
||||
m_camera.x = m_inputTextCursor.x - ((m_screenWidth - m_scrollbar.w - 2*MARGIN_X) / g_charW);
|
||||
else if ((m_inputTextCursor.x - m_camera.x) * g_charW < 0)
|
||||
m_camera.x = m_inputTextCursor.x;
|
||||
}
|
||||
|
||||
+3
-3
@@ -13,10 +13,10 @@ TextInput::TextInput(const std::string &p_title, SDL_Texture *p_icon, const std:
|
||||
// Cursor at the end of the text
|
||||
m_cursor = m_inputText.size();
|
||||
// Dialog background
|
||||
m_dialogBackground.w = SCREEN_WIDTH;
|
||||
m_dialogBackground.w = m_screenWidth;
|
||||
m_dialogBackground.h = 2*LINE_HEIGHT + DIALOG_BORDER;
|
||||
m_dialogBackground.x = (SCREEN_WIDTH - m_dialogBackground.w) / 2;
|
||||
m_dialogBackground.y = SCREEN_HEIGHT - Keyboard::getKeyboardH() - m_dialogBackground.h + DIALOG_BORDER;
|
||||
m_dialogBackground.x = (m_screenWidth - m_dialogBackground.w) / 2;
|
||||
m_dialogBackground.y = m_screenHeight - Keyboard::getKeyboardH(m_screenWidth) - m_dialogBackground.h + DIALOG_BORDER;
|
||||
// Dialog body
|
||||
m_dialogBody.x = m_dialogBackground.x + DIALOG_BORDER;
|
||||
m_dialogBody.y = m_dialogBackground.y + LINE_HEIGHT;
|
||||
|
||||
+2
-2
@@ -63,7 +63,7 @@ TextViewer::TextViewer(const std::string &p_title):
|
||||
// Init scrollbar
|
||||
adjustScrollbar();
|
||||
// Number of visible chars
|
||||
m_nbVisibleChars = round(static_cast<double>(SCREEN_WIDTH - 2*MARGIN_X - m_scrollbar.w) / g_charW);
|
||||
m_nbVisibleChars = round(static_cast<double>(m_screenWidth - 2*MARGIN_X - m_scrollbar.w) / g_charW);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -84,7 +84,7 @@ void TextViewer::render(const bool p_focus)
|
||||
|
||||
// Render title background
|
||||
SDL_SetRenderDrawColor(g_renderer, COLOR_TITLE_BG, 255);
|
||||
SDL_Rect rect { 0, 0, SCREEN_WIDTH, LINE_HEIGHT };
|
||||
SDL_Rect rect { 0, 0, m_screenWidth, LINE_HEIGHT };
|
||||
SDL_RenderFillRect(g_renderer, &rect);
|
||||
|
||||
// Render title
|
||||
|
||||
+27
-5
@@ -19,6 +19,8 @@ IWindow::IWindow(const bool p_fullscreen, const std::string &p_title) :
|
||||
m_title(p_title),
|
||||
m_cursor(0),
|
||||
m_cursorLoop(false),
|
||||
m_screenWidth(SCREEN_WIDTH),
|
||||
m_screenHeight(SCREEN_HEIGHT),
|
||||
m_nbItems(0),
|
||||
m_nbVisibleLines(0),
|
||||
m_nbVisibleChars(0),
|
||||
@@ -26,19 +28,29 @@ IWindow::IWindow(const bool p_fullscreen, const std::string &p_title) :
|
||||
m_lastPressed(-1),
|
||||
m_retVal(-1)
|
||||
{
|
||||
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetDesktopDisplayMode(0, &DM);
|
||||
|
||||
if(DM.w)
|
||||
m_screenWidth = DM.w;
|
||||
if(DM.h)
|
||||
m_screenHeight = DM.h;
|
||||
|
||||
// Init camera
|
||||
m_camera.x = 0;
|
||||
m_camera.y = 0;
|
||||
// Init scrollbar
|
||||
m_scrollbar.w = 0;
|
||||
m_scrollbar.h = 0;
|
||||
m_scrollbar.x = SCREEN_WIDTH - MARGIN_X;
|
||||
m_scrollbar.x = m_screenWidth - MARGIN_X;
|
||||
m_scrollbar.y = LINE_HEIGHT;
|
||||
// Init m_nbVisibleLines
|
||||
m_nbVisibleLines = (SCREEN_HEIGHT - LINE_HEIGHT) / LINE_HEIGHT;
|
||||
m_nbVisibleLines = (m_screenHeight - LINE_HEIGHT) / LINE_HEIGHT;
|
||||
// Add window to the list
|
||||
g_windows.push_back(this);
|
||||
g_hasChanged = true;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -49,6 +61,16 @@ bool IWindow::isFullScreen(void) const
|
||||
return m_fullscreen;
|
||||
}
|
||||
|
||||
int IWindow::getScreenWidth(void) const
|
||||
{
|
||||
return m_screenWidth;
|
||||
}
|
||||
|
||||
int IWindow::getScreenHeight(void) const
|
||||
{
|
||||
return m_screenHeight;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Execute window and return result
|
||||
@@ -325,7 +347,7 @@ void IWindow::adjustScrollbar(void)
|
||||
}
|
||||
// Scrollbar size
|
||||
m_scrollbar.w = MARGIN_X;
|
||||
m_scrollbar.h = round((double)(SCREEN_HEIGHT - LINE_HEIGHT) / (m_nbItems - m_nbVisibleLines + 1));
|
||||
m_scrollbar.h = round((double)(m_screenHeight - LINE_HEIGHT) / (m_nbItems - m_nbVisibleLines + 1));
|
||||
if (m_scrollbar.h < LINE_HEIGHT / 2)
|
||||
m_scrollbar.h = LINE_HEIGHT / 2;
|
||||
// Scrollbar position
|
||||
@@ -343,9 +365,9 @@ void IWindow::adjustScrollbarPosition(void)
|
||||
// Case: last item visible => scrollbar at bottom
|
||||
if (m_camera.y >= m_nbItems - m_nbVisibleLines)
|
||||
{
|
||||
m_scrollbar.y = SCREEN_HEIGHT - m_scrollbar.h;
|
||||
m_scrollbar.y = m_screenHeight - m_scrollbar.h;
|
||||
return;
|
||||
}
|
||||
// General case
|
||||
m_scrollbar.y = LINE_HEIGHT + round(((double)(SCREEN_HEIGHT - LINE_HEIGHT - m_scrollbar.h) / (m_nbItems - m_nbVisibleLines)) * m_camera.y);
|
||||
m_scrollbar.y = LINE_HEIGHT + round(((double)(m_screenHeight - LINE_HEIGHT - m_scrollbar.h) / (m_nbItems - m_nbVisibleLines)) * m_camera.y);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,9 @@ class IWindow
|
||||
void adjustScrollbar(void);
|
||||
void adjustScrollbarPosition(void);
|
||||
|
||||
int getScreenWidth(void) const;
|
||||
int getScreenHeight(void) const;
|
||||
|
||||
// Window is fullscreen or not
|
||||
bool m_fullscreen;
|
||||
|
||||
@@ -84,6 +87,10 @@ class IWindow
|
||||
// Loop or not when moving cursor
|
||||
bool m_cursorLoop;
|
||||
|
||||
// Calculated screen resolution, based on SDL or def if not found
|
||||
int m_screenWidth;
|
||||
int m_screenHeight;
|
||||
|
||||
// Number of selectable items
|
||||
int m_nbItems;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user