| 
									
										
										
										
											2019-06-07 11:46:02 +02:00
										 |  |  | #include <Kernel/KeyCode.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | #include <LibGUI/GAbstractView.h>
 | 
					
						
							|  |  |  | #include <LibGUI/GModel.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-23 08:18:28 +02:00
										 |  |  | #include <LibGUI/GModelEditingDelegate.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-28 17:19:56 +01:00
										 |  |  | #include <LibGUI/GPainter.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-07 11:46:02 +02:00
										 |  |  | #include <LibGUI/GScrollBar.h>
 | 
					
						
							| 
									
										
										
										
											2019-04-18 22:27:14 +02:00
										 |  |  | #include <LibGUI/GTextBox.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | GAbstractView::GAbstractView(GWidget* parent) | 
					
						
							|  |  |  |     : GScrollableWidget(parent) | 
					
						
							| 
									
										
										
										
											2019-09-07 19:14:59 +02:00
										 |  |  |     , m_selection(*this) | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GAbstractView::~GAbstractView() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 18:37:47 +02:00
										 |  |  | void GAbstractView::set_model(RefPtr<GModel>&& model) | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-14 02:36:06 +02:00
										 |  |  |     if (model == m_model) | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     if (m_model) | 
					
						
							| 
									
										
										
										
											2019-05-31 15:44:04 +02:00
										 |  |  |         m_model->unregister_view({}, *this); | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  |     m_model = move(model); | 
					
						
							|  |  |  |     if (m_model) | 
					
						
							| 
									
										
										
										
											2019-05-31 15:44:04 +02:00
										 |  |  |         m_model->register_view({}, *this); | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  |     did_update_model(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::did_update_model() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-07 20:35:31 +02:00
										 |  |  |     if (!model() || selection().first() != m_edit_index) | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |         stop_editing(); | 
					
						
							| 
									
										
										
										
											2019-03-23 02:04:31 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-30 03:27:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::did_update_selection() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-07 20:35:31 +02:00
										 |  |  |     if (!model() || selection().first() != m_edit_index) | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |         stop_editing(); | 
					
						
							| 
									
										
										
										
											2019-09-07 20:35:31 +02:00
										 |  |  |     if (model() && on_selection && selection().first().is_valid()) | 
					
						
							|  |  |  |         on_selection(selection().first()); | 
					
						
							| 
									
										
										
										
											2019-03-30 03:27:25 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-18 23:57:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::did_scroll() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     update_edit_widget_position(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::update_edit_widget_position() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_edit_widget) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     m_edit_widget->set_relative_rect(m_edit_widget_content_rect.translated(-horizontal_scrollbar().value(), -vertical_scrollbar().value())); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::begin_editing(const GModelIndex& index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ASSERT(is_editable()); | 
					
						
							|  |  |  |     ASSERT(model()); | 
					
						
							|  |  |  |     if (m_edit_index == index) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     if (!model()->is_editable(index)) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2019-09-21 17:05:35 +02:00
										 |  |  |     if (m_edit_widget) { | 
					
						
							|  |  |  |         remove_child(*m_edit_widget); | 
					
						
							|  |  |  |         m_edit_widget = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |     m_edit_index = index; | 
					
						
							| 
									
										
										
										
											2019-06-23 08:18:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ASSERT(aid_create_editing_delegate); | 
					
						
							|  |  |  |     m_editing_delegate = aid_create_editing_delegate(index); | 
					
						
							|  |  |  |     m_editing_delegate->bind(*model(), index); | 
					
						
							|  |  |  |     m_editing_delegate->set_value(model()->data(index, GModel::Role::Display)); | 
					
						
							|  |  |  |     m_edit_widget = m_editing_delegate->widget(); | 
					
						
							|  |  |  |     add_child(*m_edit_widget); | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |     m_edit_widget->move_to_back(); | 
					
						
							| 
									
										
										
										
											2019-06-23 06:45:23 +02:00
										 |  |  |     m_edit_widget_content_rect = content_rect(index).translated(frame_thickness(), frame_thickness()); | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |     update_edit_widget_position(); | 
					
						
							|  |  |  |     m_edit_widget->set_focus(true); | 
					
						
							| 
									
										
										
										
											2019-06-23 08:18:28 +02:00
										 |  |  |     m_editing_delegate->will_begin_editing(); | 
					
						
							|  |  |  |     m_editing_delegate->on_commit = [this] { | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |         ASSERT(model()); | 
					
						
							| 
									
										
										
										
											2019-06-23 08:18:28 +02:00
										 |  |  |         model()->set_data(m_edit_index, m_editing_delegate->value()); | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  |         stop_editing(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::stop_editing() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-07 11:46:02 +02:00
										 |  |  |     m_edit_index = {}; | 
					
						
							| 
									
										
										
										
											2019-09-21 17:05:35 +02:00
										 |  |  |     if (m_edit_widget) { | 
					
						
							|  |  |  |         remove_child(*m_edit_widget); | 
					
						
							|  |  |  |         m_edit_widget = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-19 00:07:33 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-09 04:56:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::activate(const GModelIndex& index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (on_activation) | 
					
						
							|  |  |  |         on_activation(index); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-09-07 19:14:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void GAbstractView::notify_selection_changed(Badge<GModelSelection>) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-07 21:34:26 +02:00
										 |  |  |     did_update_selection(); | 
					
						
							|  |  |  |     if (on_selection_change) | 
					
						
							|  |  |  |         on_selection_change(); | 
					
						
							| 
									
										
										
										
											2019-09-07 19:14:59 +02:00
										 |  |  |     update(); | 
					
						
							|  |  |  | } |