| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |  *    list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  *    this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  *    and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 11:53:16 +02:00
										 |  |  | #include <AK/Function.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-06 20:33:02 +01:00
										 |  |  | #include <LibGUI/ModelSelection.h>
 | 
					
						
							|  |  |  | #include <LibGUI/ScrollableWidget.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  | namespace GUI { | 
					
						
							| 
									
										
										
										
											2019-04-18 22:27:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  | class AbstractView : public ScrollableWidget { | 
					
						
							| 
									
										
										
										
											2020-08-27 17:47:19 +02:00
										 |  |  |     C_OBJECT_ABSTRACT(AbstractView); | 
					
						
							| 
									
										
										
										
											2019-09-07 19:14:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2020-08-27 17:47:19 +02:00
										 |  |  |     enum class CursorMovement { | 
					
						
							|  |  |  |         Up, | 
					
						
							|  |  |  |         Down, | 
					
						
							|  |  |  |         Left, | 
					
						
							|  |  |  |         Right, | 
					
						
							|  |  |  |         Home, | 
					
						
							|  |  |  |         End, | 
					
						
							|  |  |  |         PageUp, | 
					
						
							|  |  |  |         PageDown, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-27 18:36:31 +02:00
										 |  |  |     enum class SelectionUpdate { | 
					
						
							|  |  |  |         None, | 
					
						
							|  |  |  |         Set, | 
					
						
							|  |  |  |         Shift, | 
					
						
							|  |  |  |         Ctrl, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void move_cursor(CursorMovement, SelectionUpdate) { } | 
					
						
							| 
									
										
										
										
											2020-08-27 17:47:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 20:47:16 +01:00
										 |  |  |     void set_model(RefPtr<Model>); | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     Model* model() { return m_model.ptr(); } | 
					
						
							|  |  |  |     const Model* model() const { return m_model.ptr(); } | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     ModelSelection& selection() { return m_selection; } | 
					
						
							|  |  |  |     const ModelSelection& selection() const { return m_selection; } | 
					
						
							| 
									
										
										
										
											2020-08-25 11:25:39 +02:00
										 |  |  |     virtual void select_all() { } | 
					
						
							| 
									
										
										
										
											2019-09-07 19:14:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 22:27:14 +02:00
										 |  |  |     bool is_editable() const { return m_editable; } | 
					
						
							|  |  |  |     void set_editable(bool editable) { m_editable = editable; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 20:27:51 +02:00
										 |  |  |     enum EditTrigger { | 
					
						
							|  |  |  |         None = 0, | 
					
						
							|  |  |  |         DoubleClicked = 1 << 0, | 
					
						
							|  |  |  |         EditKeyPressed = 1 << 1, | 
					
						
							|  |  |  |         AnyKeyPressed = 1 << 2, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned edit_triggers() const { return m_edit_triggers; } | 
					
						
							|  |  |  |     void set_edit_triggers(unsigned); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-11 23:11:53 -06:00
										 |  |  |     bool is_multi_select() const { return m_multi_select; } | 
					
						
							|  |  |  |     void set_multi_select(bool); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  |     virtual bool accepts_focus() const override { return true; } | 
					
						
							| 
									
										
										
										
											2020-04-12 12:03:33 +02:00
										 |  |  |     virtual void did_update_model(unsigned flags); | 
					
						
							| 
									
										
										
										
											2019-03-30 03:27:25 +01:00
										 |  |  |     virtual void did_update_selection(); | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     virtual Gfx::IntRect content_rect(const ModelIndex&) const { return {}; } | 
					
						
							| 
									
										
										
										
											2020-08-25 11:25:39 +02:00
										 |  |  |     virtual ModelIndex index_at_event_position(const Gfx::IntPoint&) const { return {}; } | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     void begin_editing(const ModelIndex&); | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |     void stop_editing(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 04:56:52 +02:00
										 |  |  |     void set_activates_on_selection(bool b) { m_activates_on_selection = b; } | 
					
						
							|  |  |  |     bool activates_on_selection() const { return m_activates_on_selection; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-07 21:34:26 +02:00
										 |  |  |     Function<void()> on_selection_change; | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     Function<void(const ModelIndex&)> on_activation; | 
					
						
							|  |  |  |     Function<void(const ModelIndex&)> on_selection; | 
					
						
							|  |  |  |     Function<void(const ModelIndex&, const ContextMenuEvent&)> on_context_menu_request; | 
					
						
							| 
									
										
										
										
											2020-02-13 21:49:14 +01:00
										 |  |  |     Function<void(const ModelIndex&, const DropEvent&)> on_drop; | 
					
						
							| 
									
										
										
										
											2019-03-23 03:53:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     Function<OwnPtr<ModelEditingDelegate>(const ModelIndex&)> aid_create_editing_delegate; | 
					
						
							| 
									
										
										
										
											2019-06-23 08:18:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     void notify_selection_changed(Badge<ModelSelection>); | 
					
						
							| 
									
										
										
										
											2019-09-07 19:14:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  |     NonnullRefPtr<Gfx::Font> font_for_index(const ModelIndex&) const; | 
					
						
							| 
									
										
										
										
											2019-10-22 21:38:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 10:44:10 +02:00
										 |  |  |     void set_key_column_and_sort_order(int column, SortOrder); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 11:25:39 +02:00
										 |  |  |     int key_column() const { return m_key_column; } | 
					
						
							|  |  |  |     SortOrder sort_order() const { return m_sort_order; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-27 18:36:31 +02:00
										 |  |  |     virtual void scroll_into_view(const ModelIndex&, [[maybe_unused]] bool scroll_horizontally = true, [[maybe_unused]] bool scroll_vertically = true) { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const ModelIndex& cursor_index() const { return m_cursor_index; } | 
					
						
							| 
									
										
										
										
											2020-08-29 00:17:42 +02:00
										 |  |  |     void set_cursor(ModelIndex, SelectionUpdate, bool scroll_cursor_into_view = true); | 
					
						
							| 
									
										
										
										
											2020-08-27 18:36:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 21:09:38 +02:00
										 |  |  |     bool is_tab_key_navigation_enabled() const { return m_tab_key_navigation_enabled; } | 
					
						
							|  |  |  |     void set_tab_key_navigation_enabled(bool enabled) { m_tab_key_navigation_enabled = enabled; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2020-02-23 12:07:13 +01:00
										 |  |  |     AbstractView(); | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     virtual ~AbstractView() override; | 
					
						
							| 
									
										
										
										
											2019-12-13 20:54:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     virtual void mousedown_event(MouseEvent&) override; | 
					
						
							|  |  |  |     virtual void mousemove_event(MouseEvent&) override; | 
					
						
							|  |  |  |     virtual void mouseup_event(MouseEvent&) override; | 
					
						
							|  |  |  |     virtual void doubleclick_event(MouseEvent&) override; | 
					
						
							|  |  |  |     virtual void context_menu_event(ContextMenuEvent&) override; | 
					
						
							| 
									
										
										
										
											2020-02-13 21:49:14 +01:00
										 |  |  |     virtual void drop_event(DropEvent&) override; | 
					
						
							| 
									
										
										
										
											2020-04-03 21:14:34 +02:00
										 |  |  |     virtual void leave_event(Core::Event&) override; | 
					
						
							| 
									
										
										
										
											2020-01-22 21:12:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-11 07:02:03 -06:00
										 |  |  |     virtual void clear_selection(); | 
					
						
							|  |  |  |     virtual void set_selection(const ModelIndex&); | 
					
						
							|  |  |  |     virtual void add_selection(const ModelIndex&); | 
					
						
							|  |  |  |     virtual void remove_selection(const ModelIndex&); | 
					
						
							|  |  |  |     virtual void toggle_selection(const ModelIndex&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 23:57:07 +02:00
										 |  |  |     virtual void did_scroll() override; | 
					
						
							| 
									
										
										
										
											2020-04-03 21:14:34 +02:00
										 |  |  |     void set_hovered_index(const ModelIndex&); | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     void activate(const ModelIndex&); | 
					
						
							| 
									
										
										
										
											2020-01-10 18:50:26 +03:00
										 |  |  |     void activate_selected(); | 
					
						
							| 
									
										
										
										
											2019-04-18 23:57:07 +02:00
										 |  |  |     void update_edit_widget_position(); | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 22:27:14 +02:00
										 |  |  |     bool m_editable { false }; | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     ModelIndex m_edit_index; | 
					
						
							|  |  |  |     RefPtr<Widget> m_edit_widget; | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     Gfx::IntRect m_edit_widget_content_rect; | 
					
						
							| 
									
										
										
										
											2020-08-28 20:47:02 +02:00
										 |  |  |     OwnPtr<ModelEditingDelegate> m_editing_delegate; | 
					
						
							| 
									
										
										
										
											2019-04-18 22:27:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     Gfx::IntPoint m_left_mousedown_position; | 
					
						
							| 
									
										
										
										
											2020-01-22 21:12:05 +03:00
										 |  |  |     bool m_might_drag { false }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-30 19:57:44 +02:00
										 |  |  |     ModelIndex m_hovered_index; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-27 10:37:31 +02:00
										 |  |  |     int m_key_column { -1 }; | 
					
						
							| 
									
										
										
										
											2020-08-16 10:44:10 +02:00
										 |  |  |     SortOrder m_sort_order; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  |     RefPtr<Model> m_model; | 
					
						
							|  |  |  |     ModelSelection m_selection; | 
					
						
							| 
									
										
										
										
											2020-08-27 18:36:31 +02:00
										 |  |  |     ModelIndex m_cursor_index; | 
					
						
							| 
									
										
										
										
											2020-08-28 20:27:51 +02:00
										 |  |  |     unsigned m_edit_triggers { EditTrigger::DoubleClicked | EditTrigger::EditKeyPressed }; | 
					
						
							| 
									
										
										
										
											2019-05-09 04:56:52 +02:00
										 |  |  |     bool m_activates_on_selection { false }; | 
					
						
							| 
									
										
										
										
											2020-07-11 23:11:53 -06:00
										 |  |  |     bool m_multi_select { true }; | 
					
						
							| 
									
										
										
										
											2020-08-28 21:09:38 +02:00
										 |  |  |     bool m_tab_key_navigation_enabled { false }; | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-02-02 15:07:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |