Serenity Operating System
at master 216 lines 7.9 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Function.h> 10#include <LibGUI/AbstractScrollableWidget.h> 11#include <LibGUI/Model.h> 12#include <LibGUI/ModelSelection.h> 13#include <LibGfx/TextElision.h> 14 15namespace GUI { 16 17class AbstractView 18 : public AbstractScrollableWidget 19 , public ModelClient { 20 21 C_OBJECT_ABSTRACT(AbstractView); 22 23public: 24 enum class CursorMovement { 25 Up, 26 Down, 27 Left, 28 Right, 29 Home, 30 End, 31 PageUp, 32 PageDown, 33 }; 34 35 enum class SelectionUpdate { 36 None, 37 Set, 38 Shift, 39 Ctrl, 40 ClearIfNotSelected 41 }; 42 43 enum class SelectionBehavior { 44 SelectItems, 45 SelectRows, 46 }; 47 48 enum class SelectionMode { 49 SingleSelection, 50 MultiSelection, 51 NoSelection, 52 }; 53 54 virtual void move_cursor(CursorMovement, SelectionUpdate) { } 55 56 void set_model(RefPtr<Model>); 57 Model* model() { return m_model.ptr(); } 58 Model const* model() const { return m_model.ptr(); } 59 60 ModelSelection& selection() { return m_selection; } 61 ModelSelection const& selection() const { return m_selection; } 62 virtual void select_all() { } 63 64 void activate(ModelIndex const&); 65 void activate_selected(); 66 67 bool is_editable() const { return m_editable; } 68 void set_editable(bool editable) { m_editable = editable; } 69 70 bool is_searchable() const; 71 void set_searchable(bool); 72 73 enum EditTrigger { 74 None = 0, 75 DoubleClicked = 1 << 0, 76 EditKeyPressed = 1 << 1, 77 AnyKeyPressed = 1 << 2, 78 }; 79 80 unsigned edit_triggers() const { return m_edit_triggers; } 81 void set_edit_triggers(unsigned); 82 83 SelectionBehavior selection_behavior() const { return m_selection_behavior; } 84 void set_selection_behavior(SelectionBehavior behavior) { m_selection_behavior = behavior; } 85 86 SelectionMode selection_mode() const { return m_selection_mode; } 87 void set_selection_mode(SelectionMode); 88 89 virtual void model_did_update(unsigned flags) override; 90 virtual void did_update_selection(); 91 92 virtual Gfx::IntRect content_rect(ModelIndex const&) const { return {}; } 93 virtual Gfx::IntRect editing_rect(ModelIndex const& index) const { return content_rect(index); } 94 virtual Gfx::IntRect paint_invalidation_rect(ModelIndex const& index) const { return content_rect(index); } 95 96 virtual ModelIndex index_at_event_position(Gfx::IntPoint) const { return {}; } 97 void begin_editing(ModelIndex const&); 98 void stop_editing(); 99 100 void set_activates_on_selection(bool b) { m_activates_on_selection = b; } 101 bool activates_on_selection() const { return m_activates_on_selection; } 102 103 Function<void()> on_selection_change; 104 Function<void(ModelIndex const&)> on_activation; 105 Function<void(ModelIndex const&, ContextMenuEvent const&)> on_context_menu_request; 106 Function<void(ModelIndex const&, DropEvent const&)> on_drop; 107 108 Function<OwnPtr<ModelEditingDelegate>(ModelIndex const&)> aid_create_editing_delegate; 109 110 void notify_selection_changed(Badge<ModelSelection>); 111 112 NonnullRefPtr<Gfx::Font const> font_for_index(ModelIndex const&) const; 113 114 void set_key_column_and_sort_order(int column, SortOrder); 115 116 int key_column() const { return m_key_column; } 117 void set_key_column(int column) { set_key_column_and_sort_order(column, sort_order()); } 118 SortOrder sort_order() const { return m_sort_order; } 119 void set_sort_order(SortOrder order) { set_key_column_and_sort_order(key_column(), order); } 120 121 virtual void scroll_into_view(ModelIndex const&, [[maybe_unused]] bool scroll_horizontally = true, [[maybe_unused]] bool scroll_vertically = true) { } 122 123 ModelIndex const& cursor_index() const { return m_cursor_index; } 124 ModelIndex const& selection_start_index() const { return m_selection_start_index; } 125 void set_cursor(ModelIndex, SelectionUpdate, bool scroll_cursor_into_view = true); 126 127 bool is_tab_key_navigation_enabled() const { return m_tab_key_navigation_enabled; } 128 void set_tab_key_navigation_enabled(bool enabled) { m_tab_key_navigation_enabled = enabled; } 129 130 void set_draw_item_text_with_shadow(bool b) { m_draw_item_text_with_shadow = b; } 131 bool does_draw_item_text_with_shadow() const { return m_draw_item_text_with_shadow; } 132 133protected: 134 AbstractView(); 135 virtual ~AbstractView() override; 136 137 virtual void keydown_event(KeyEvent&) override; 138 virtual void mousedown_event(MouseEvent&) override; 139 virtual void mousemove_event(MouseEvent&) override; 140 virtual void mouseup_event(MouseEvent&) override; 141 virtual void doubleclick_event(MouseEvent&) override; 142 virtual void context_menu_event(ContextMenuEvent&) override; 143 virtual void drag_enter_event(DragEvent&) override; 144 virtual void drag_move_event(DragEvent&) override; 145 virtual void drag_leave_event(Event&) override; 146 virtual void drop_event(DropEvent&) override; 147 virtual void leave_event(Core::Event&) override; 148 virtual void hide_event(HideEvent&) override; 149 virtual void focusin_event(FocusEvent&) override; 150 151 virtual void automatic_scrolling_timer_did_fire() override; 152 153 virtual void clear_selection(); 154 virtual void set_selection(ModelIndex const&); 155 virtual void set_selection_start_index(ModelIndex const&); 156 virtual void add_selection(ModelIndex const&); 157 virtual void remove_selection(ModelIndex const&); 158 virtual void toggle_selection(ModelIndex const&); 159 virtual void select_range(ModelIndex const&); 160 virtual void did_change_hovered_index([[maybe_unused]] ModelIndex const& old_index, [[maybe_unused]] ModelIndex const& new_index) { } 161 virtual void did_change_cursor_index([[maybe_unused]] ModelIndex const& old_index, [[maybe_unused]] ModelIndex const& new_index) { } 162 virtual void editing_widget_did_change([[maybe_unused]] ModelIndex const& index) { } 163 164 void draw_item_text(Gfx::Painter&, ModelIndex const&, bool, Gfx::IntRect const&, StringView, Gfx::Font const&, Gfx::TextAlignment, Gfx::TextElision, size_t search_highlighting_offset = 0); 165 166 void set_suppress_update_on_selection_change(bool value) { m_suppress_update_on_selection_change = value; } 167 168 virtual void did_scroll() override; 169 void set_hovered_index(ModelIndex const&); 170 void update_edit_widget_position(); 171 172 void stop_highlighted_search_timer(); 173 void start_highlighted_search_timer(); 174 ModelIndex find_next_search_match(StringView const); 175 void highlight_search(ModelIndex const index); 176 177 ModelIndex drop_candidate_index() const { return m_drop_candidate_index; } 178 179 bool m_editable { false }; 180 bool m_searchable { true }; 181 RefPtr<Widget> m_edit_widget; 182 Gfx::IntRect m_edit_widget_content_rect; 183 OwnPtr<ModelEditingDelegate> m_editing_delegate; 184 185 Gfx::IntPoint m_left_mousedown_position; 186 bool m_might_drag { false }; 187 188 int m_key_column { -1 }; 189 SortOrder m_sort_order; 190 191 ModelIndex m_edit_index; 192 ModelIndex m_hovered_index; 193 ModelIndex m_highlighted_search_index; 194 195private: 196 ModelIndex m_selection_start_index; 197 ModelIndex m_cursor_index; 198 ModelIndex m_drop_candidate_index; 199 200 RefPtr<Model> m_model; 201 ModelSelection m_selection; 202 DeprecatedString m_highlighted_search; 203 RefPtr<Core::Timer> m_highlighted_search_timer; 204 SelectionBehavior m_selection_behavior { SelectionBehavior::SelectItems }; 205 SelectionMode m_selection_mode { SelectionMode::SingleSelection }; 206 unsigned m_edit_triggers { EditTrigger::DoubleClicked | EditTrigger::EditKeyPressed }; 207 bool m_activates_on_selection { false }; 208 bool m_tab_key_navigation_enabled { false }; 209 bool m_is_dragging { false }; 210 bool m_draw_item_text_with_shadow { false }; 211 bool m_suppress_update_on_selection_change { false }; 212 213 Gfx::IntPoint m_automatic_scroll_delta {}; 214}; 215 216}