mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-14 19:17:48 +01:00
Tables: TableSetupColumn() user id uses ImGuiID as intended (typedef ImU32). internals: added GetCurrentTable(), LeftMostEnabledColumn. Demo/docs tweaks.
This commit is contained in:
parent
9576dfd5e7
commit
b47aa46d81
@ -9,13 +9,13 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ
|
|||||||
e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc.
|
e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc.
|
||||||
|
|
||||||
- The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.<BR>
|
- The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.<BR>
|
||||||
e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp]((https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp]((https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc.
|
e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp), etc.
|
||||||
|
|
||||||
- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR>
|
- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR>
|
||||||
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)), Marmalade ([imgui_impl_marmalade.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_marmalade.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
|
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)), Marmalade ([imgui_impl_marmalade.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_marmalade.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
|
||||||
|
|
||||||
An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
|
An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
|
||||||
For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
|
For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
|
||||||
|
|
||||||
|
|
||||||
### What are backends
|
### What are backends
|
||||||
@ -36,7 +36,7 @@ Dear ImGui is highly portable and only requires a few things to run and render,
|
|||||||
- Optional: multi-viewports support.
|
- Optional: multi-viewports support.
|
||||||
etc.
|
etc.
|
||||||
|
|
||||||
This is essentially what each backends are doing + obligatory portability cruft.
|
This is essentially what each backends are doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support).
|
||||||
|
|
||||||
It is important to understand the difference between the core Dear ImGui library (files in the root folder)
|
It is important to understand the difference between the core Dear ImGui library (files in the root folder)
|
||||||
and backends which we are describing here (backends/ folder).
|
and backends which we are describing here (backends/ folder).
|
||||||
@ -46,6 +46,11 @@ and backends which we are describing here (backends/ folder).
|
|||||||
e.g. you can get creative and use software rendering or render remotely on a different machine.
|
e.g. you can get creative and use software rendering or render remotely on a different machine.
|
||||||
|
|
||||||
|
|
||||||
|
### Integrating a backend
|
||||||
|
|
||||||
|
See "Getting Started" section of [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for more details.
|
||||||
|
|
||||||
|
|
||||||
### List of backends
|
### List of backends
|
||||||
|
|
||||||
In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:
|
In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:
|
||||||
|
4
imgui.h
4
imgui.h
@ -701,7 +701,7 @@ namespace ImGui
|
|||||||
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in
|
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in
|
||||||
// some advanced use cases (e.g. adding custom widgets in header row).
|
// some advanced use cases (e.g. adding custom widgets in header row).
|
||||||
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
|
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
|
||||||
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);
|
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0);
|
||||||
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
|
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
|
||||||
IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
|
IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
|
||||||
IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
|
IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
|
||||||
@ -711,7 +711,7 @@ namespace ImGui
|
|||||||
// since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may
|
// since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may
|
||||||
// wastefully sort your data every frame!
|
// wastefully sort your data every frame!
|
||||||
// - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
|
// - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
|
||||||
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
|
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
|
||||||
// Tables: Miscellaneous functions
|
// Tables: Miscellaneous functions
|
||||||
// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.
|
// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.
|
||||||
IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
|
IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
|
||||||
|
@ -4856,6 +4856,9 @@ static void ShowDemoWindowTables()
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In this example we'll expose most table flags and settings.
|
||||||
|
// For specific flags and settings refer to the corresponding section for more detailed explanation.
|
||||||
|
// This section is mostly useful to experiment with combining certain flags or settings with each others.
|
||||||
//ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG]
|
//ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG]
|
||||||
if (open_action != -1)
|
if (open_action != -1)
|
||||||
ImGui::SetNextItemOpen(open_action != 0);
|
ImGui::SetNextItemOpen(open_action != 0);
|
||||||
@ -4994,7 +4997,7 @@ static void ShowDemoWindowTables()
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recreate/reset item list if we changed the number of items
|
// Update item list if we changed the number of items
|
||||||
static ImVector<MyItem> items;
|
static ImVector<MyItem> items;
|
||||||
static ImVector<int> selection;
|
static ImVector<int> selection;
|
||||||
static bool items_need_sort = false;
|
static bool items_need_sort = false;
|
||||||
@ -5016,6 +5019,7 @@ static void ShowDemoWindowTables()
|
|||||||
ImVec2 table_scroll_cur, table_scroll_max; // For debug display
|
ImVec2 table_scroll_cur, table_scroll_max; // For debug display
|
||||||
const ImDrawList* table_draw_list = NULL; // "
|
const ImDrawList* table_draw_list = NULL; // "
|
||||||
|
|
||||||
|
// Submit table
|
||||||
const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f;
|
const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f;
|
||||||
if (ImGui::BeginTable("table_advanced", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use))
|
if (ImGui::BeginTable("table_advanced", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use))
|
||||||
{
|
{
|
||||||
@ -5074,9 +5078,9 @@ static void ShowDemoWindowTables()
|
|||||||
const bool item_is_selected = selection.contains(item->ID);
|
const bool item_is_selected = selection.contains(item->ID);
|
||||||
ImGui::PushID(item->ID);
|
ImGui::PushID(item->ID);
|
||||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height);
|
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height);
|
||||||
ImGui::TableNextColumn();
|
|
||||||
|
|
||||||
// For the demo purpose we can select among different type of items submitted in the first column
|
// For the demo purpose we can select among different type of items submitted in the first column
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
char label[32];
|
char label[32];
|
||||||
sprintf(label, "%04d", item->ID);
|
sprintf(label, "%04d", item->ID);
|
||||||
if (contents_type == CT_Text)
|
if (contents_type == CT_Text)
|
||||||
@ -5107,14 +5111,14 @@ static void ShowDemoWindowTables()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TableNextColumn())
|
if (ImGui::TableSetColumnIndex(1))
|
||||||
ImGui::TextUnformatted(item->Name);
|
ImGui::TextUnformatted(item->Name);
|
||||||
|
|
||||||
// Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity,
|
// Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity,
|
||||||
// and we are currently sorting on the column showing the Quantity.
|
// and we are currently sorting on the column showing the Quantity.
|
||||||
// To avoid triggering a sort while holding the button, we only trigger it when the button has been released.
|
// To avoid triggering a sort while holding the button, we only trigger it when the button has been released.
|
||||||
// You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes.
|
// You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes.
|
||||||
if (ImGui::TableNextColumn())
|
if (ImGui::TableSetColumnIndex(2))
|
||||||
{
|
{
|
||||||
if (ImGui::SmallButton("Chop")) { item->Quantity += 1; }
|
if (ImGui::SmallButton("Chop")) { item->Quantity += 1; }
|
||||||
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
|
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
|
||||||
@ -5123,16 +5127,16 @@ static void ShowDemoWindowTables()
|
|||||||
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
|
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TableNextColumn())
|
if (ImGui::TableSetColumnIndex(3))
|
||||||
ImGui::Text("%d", item->Quantity);
|
ImGui::Text("%d", item->Quantity);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableSetColumnIndex(4);
|
||||||
if (show_wrapped_text)
|
if (show_wrapped_text)
|
||||||
ImGui::TextWrapped("Lorem ipsum dolor sit amet");
|
ImGui::TextWrapped("Lorem ipsum dolor sit amet");
|
||||||
else
|
else
|
||||||
ImGui::Text("Lorem ipsum dolor sit amet");
|
ImGui::Text("Lorem ipsum dolor sit amet");
|
||||||
|
|
||||||
if (ImGui::TableNextColumn())
|
if (ImGui::TableSetColumnIndex(5))
|
||||||
ImGui::Text("1234");
|
ImGui::Text("1234");
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
@ -2091,9 +2091,10 @@ struct ImGuiTable
|
|||||||
ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held.
|
ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held.
|
||||||
ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared)
|
ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared)
|
||||||
ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1
|
ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1
|
||||||
|
ImGuiTableColumnIdx LeftMostEnabledColumn; // Index of left-most non-hidden column.
|
||||||
|
ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
|
||||||
ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column.
|
ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column.
|
||||||
ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column.
|
ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column.
|
||||||
ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
|
|
||||||
ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
|
ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
|
||||||
ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count
|
ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count
|
||||||
ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
|
ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
|
||||||
@ -2349,6 +2350,7 @@ namespace ImGui
|
|||||||
IMGUI_API void TablePopBackgroundChannel();
|
IMGUI_API void TablePopBackgroundChannel();
|
||||||
|
|
||||||
// Tables: Internals
|
// Tables: Internals
|
||||||
|
inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; }
|
||||||
IMGUI_API ImGuiTable* TableFindByID(ImGuiID id);
|
IMGUI_API ImGuiTable* TableFindByID(ImGuiID id);
|
||||||
IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f);
|
IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f);
|
||||||
IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count);
|
IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count);
|
||||||
|
@ -687,13 +687,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
table->ColumnsEnabledCount = 0;
|
table->ColumnsEnabledCount = 0;
|
||||||
table->EnabledMaskByIndex = 0x00;
|
table->EnabledMaskByIndex = 0x00;
|
||||||
table->EnabledMaskByDisplayOrder = 0x00;
|
table->EnabledMaskByDisplayOrder = 0x00;
|
||||||
|
table->LeftMostEnabledColumn = -1;
|
||||||
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
|
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
|
||||||
|
|
||||||
// [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns.
|
// [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns.
|
||||||
// Process columns in their visible orders as we are building the Prev/Next indices.
|
// Process columns in their visible orders as we are building the Prev/Next indices.
|
||||||
int count_fixed = 0; // Number of columns that have fixed sizing policies
|
int count_fixed = 0; // Number of columns that have fixed sizing policies
|
||||||
int count_stretch = 0; // Number of columns that have stretch sizing policies
|
int count_stretch = 0; // Number of columns that have stretch sizing policies
|
||||||
int last_visible_column_idx = -1;
|
int prev_visible_column_idx = -1;
|
||||||
bool has_auto_fit_request = false;
|
bool has_auto_fit_request = false;
|
||||||
bool has_resizable = false;
|
bool has_resizable = false;
|
||||||
float stretch_sum_width_auto = 0.0f;
|
float stretch_sum_width_auto = 0.0f;
|
||||||
@ -741,14 +742,16 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark as enabled and link to previous/next enabled column
|
// Mark as enabled and link to previous/next enabled column
|
||||||
column->PrevEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
|
column->PrevEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx;
|
||||||
column->NextEnabledColumn = -1;
|
column->NextEnabledColumn = -1;
|
||||||
if (last_visible_column_idx != -1)
|
if (prev_visible_column_idx != -1)
|
||||||
table->Columns[last_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n;
|
table->Columns[prev_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n;
|
||||||
|
else
|
||||||
|
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
|
||||||
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
|
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
|
||||||
table->EnabledMaskByIndex |= (ImU64)1 << column_n;
|
table->EnabledMaskByIndex |= (ImU64)1 << column_n;
|
||||||
table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder;
|
table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder;
|
||||||
last_visible_column_idx = column_n;
|
prev_visible_column_idx = column_n;
|
||||||
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
||||||
|
|
||||||
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
|
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
|
||||||
@ -778,8 +781,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
}
|
}
|
||||||
if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
|
if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
|
||||||
table->IsSortSpecsDirty = true;
|
table->IsSortSpecsDirty = true;
|
||||||
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
|
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx;
|
||||||
IM_ASSERT(table->RightMostEnabledColumn >= 0);
|
IM_ASSERT(table->LeftMostEnabledColumn >= 0 && table->RightMostEnabledColumn >= 0);
|
||||||
|
|
||||||
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
|
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
|
||||||
// to avoid the column fitting having to wait until the first visible frame of the child container (may or not be a good thing).
|
// to avoid the column fitting having to wait until the first visible frame of the child container (may or not be a good thing).
|
||||||
|
Loading…
Reference in New Issue
Block a user