summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Libraries/LibGUI/GAbstractColumnView.cpp24
-rw-r--r--Libraries/LibGUI/GAbstractView.cpp150
-rw-r--r--Libraries/LibGUI/GAbstractView.h9
-rw-r--r--Libraries/LibGUI/GColumnsView.cpp40
-rw-r--r--Libraries/LibGUI/GColumnsView.h2
-rw-r--r--Libraries/LibGUI/GItemView.cpp129
-rw-r--r--Libraries/LibGUI/GItemView.h6
-rw-r--r--Libraries/LibGUI/GListView.cpp19
-rw-r--r--Libraries/LibGUI/GListView.h1
9 files changed, 196 insertions, 184 deletions
diff --git a/Libraries/LibGUI/GAbstractColumnView.cpp b/Libraries/LibGUI/GAbstractColumnView.cpp
index a2ca580311..12244a2884 100644
--- a/Libraries/LibGUI/GAbstractColumnView.cpp
+++ b/Libraries/LibGUI/GAbstractColumnView.cpp
@@ -251,7 +251,7 @@ int GAbstractColumnView::column_width(int column_index) const
void GAbstractColumnView::mousemove_event(GMouseEvent& event)
{
if (!model())
- return;
+ return GAbstractView::mousemove_event(event);
if (m_in_column_resize) {
auto delta = event.position() - m_column_resize_origin;
@@ -301,6 +301,8 @@ void GAbstractColumnView::mousemove_event(GMouseEvent& event)
set_hovered_header_index(-1);
}
window()->set_override_cursor(GStandardCursor::None);
+
+ GAbstractView::mousemove_event(event);
}
void GAbstractColumnView::mouseup_event(GMouseEvent& event)
@@ -311,6 +313,7 @@ void GAbstractColumnView::mouseup_event(GMouseEvent& event)
if (!column_resize_grabbable_rect(m_resizing_column).contains(adjusted_position))
window()->set_override_cursor(GStandardCursor::None);
m_in_column_resize = false;
+ return;
}
if (m_pressed_column_header_index != -1) {
auto header_rect = this->header_rect(m_pressed_column_header_index);
@@ -325,17 +328,20 @@ void GAbstractColumnView::mouseup_event(GMouseEvent& event)
m_pressed_column_header_index = -1;
m_pressed_column_header_is_pressed = false;
update_headers();
+ return;
}
}
+
+ GAbstractView::mouseup_event(event);
}
void GAbstractColumnView::mousedown_event(GMouseEvent& event)
{
if (!model())
- return;
+ return GAbstractView::mousedown_event(event);
if (event.button() != GMouseButton::Left)
- return;
+ return GAbstractView::mousedown_event(event);
if (event.y() < header_height()) {
int column_count = model()->column_count();
@@ -361,19 +367,13 @@ void GAbstractColumnView::mousedown_event(GMouseEvent& event)
bool is_toggle;
auto index = index_at_event_position(event.position(), is_toggle);
- if (!index.is_valid()) {
- selection().clear();
- return;
- }
- if (is_toggle && model()->row_count(index)) {
+
+ if (index.is_valid() && is_toggle && model()->row_count(index)) {
toggle_index(index);
return;
}
- if (event.modifiers() & Mod_Ctrl)
- selection().toggle(index);
- else
- selection().set(index);
+ GAbstractView::mousedown_event(event);
}
GModelIndex GAbstractColumnView::index_at_event_position(const Point& position, bool& is_toggle) const
diff --git a/Libraries/LibGUI/GAbstractView.cpp b/Libraries/LibGUI/GAbstractView.cpp
index f7179afc3e..b8dd15c0fd 100644
--- a/Libraries/LibGUI/GAbstractView.cpp
+++ b/Libraries/LibGUI/GAbstractView.cpp
@@ -24,8 +24,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <AK/StringBuilder.h>
#include <Kernel/KeyCode.h>
#include <LibGUI/GAbstractView.h>
+#include <LibGUI/GDragOperation.h>
#include <LibGUI/GModel.h>
#include <LibGUI/GModelEditingDelegate.h>
#include <LibGUI/GPainter.h>
@@ -171,3 +173,151 @@ NonnullRefPtr<Font> GAbstractView::font_for_index(const GModelIndex& index) cons
return *column_metadata.font;
return font();
}
+
+void GAbstractView::mousedown_event(GMouseEvent& event)
+{
+ GScrollableWidget::mousedown_event(event);
+
+ if (!model())
+ return;
+
+ if (event.button() == GMouseButton::Left)
+ m_left_mousedown_position = event.position();
+
+ auto index = index_at_event_position(event.position());
+ m_might_drag = false;
+
+ if (!index.is_valid()) {
+ m_selection.clear();
+ } else if (event.modifiers() & Mod_Ctrl) {
+ m_selection.toggle(index);
+ } else if (event.button() == GMouseButton::Left) {
+ // We might be starting a drag, so don't throw away other selected items yet.
+ m_might_drag = true;
+ m_selection.add(index);
+ } else {
+ m_selection.set(index);
+ }
+
+ update();
+}
+
+void GAbstractView::mousemove_event(GMouseEvent& event)
+{
+ if (!model() || !m_might_drag)
+ return GScrollableWidget::mousemove_event(event);
+
+ if (!(event.buttons() & GMouseButton::Left) || m_selection.is_empty()) {
+ m_might_drag = false;
+ return GScrollableWidget::mousemove_event(event);
+ }
+
+ auto diff = event.position() - m_left_mousedown_position;
+ auto distance_travelled_squared = diff.x() * diff.x() + diff.y() * diff.y();
+ constexpr int drag_distance_threshold = 5;
+
+ if (distance_travelled_squared <= drag_distance_threshold)
+ return GScrollableWidget::mousemove_event(event);
+
+ dbg() << "Initiate drag!";
+ auto drag_operation = GDragOperation::construct();
+
+ RefPtr<GraphicsBitmap> bitmap;
+
+ StringBuilder text_builder;
+ StringBuilder data_builder;
+ bool first = true;
+ m_selection.for_each_index([&](auto& index) {
+ auto text_data = m_model->data(index);
+ if (!first)
+ text_builder.append(", ");
+ text_builder.append(text_data.to_string());
+
+ auto drag_data = m_model->data(index, GModel::Role::DragData);
+ data_builder.append(drag_data.to_string());
+ data_builder.append('\n');
+
+ first = false;
+
+ if (!bitmap) {
+ GVariant icon_data = model()->data(index, GModel::Role::Icon);
+ if (icon_data.is_icon())
+ bitmap = icon_data.as_icon().bitmap_for_size(32);
+ }
+ });
+
+ drag_operation->set_text(text_builder.to_string());
+ drag_operation->set_bitmap(bitmap);
+ drag_operation->set_data("url-list", data_builder.to_string());
+
+ auto outcome = drag_operation->exec();
+
+ switch (outcome) {
+ case GDragOperation::Outcome::Accepted:
+ dbg() << "Drag was accepted!";
+ break;
+ case GDragOperation::Outcome::Cancelled:
+ dbg() << "Drag was cancelled!";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void GAbstractView::mouseup_event(GMouseEvent& event)
+{
+ GScrollableWidget::mouseup_event(event);
+
+ if (!model())
+ return;
+
+ if (m_might_drag) {
+ // We were unsure about unselecting items other than the current one
+ // in mousedown_event(), because we could be seeing a start of a drag.
+ // Since we're here, it was not that; so fix up the selection now.
+ auto index = index_at_event_position(event.position());
+ if (index.is_valid())
+ m_selection.set(index);
+ else
+ m_selection.clear();
+ m_might_drag = false;
+ update();
+ }
+}
+
+void GAbstractView::doubleclick_event(GMouseEvent& event)
+{
+ if (!model())
+ return;
+
+ if (event.button() != GMouseButton::Left)
+ return;
+
+ m_might_drag = false;
+
+ auto index = index_at_event_position(event.position());
+
+ if (!index.is_valid())
+ m_selection.clear();
+ else if (!m_selection.contains(index))
+ m_selection.set(index);
+
+ activate_selected();
+}
+
+void GAbstractView::context_menu_event(GContextMenuEvent& event)
+{
+ if (!model())
+ return;
+
+ auto index = index_at_event_position(event.position());
+
+ if (index.is_valid())
+ m_selection.add(index);
+ else
+ selection().clear();
+
+ if (on_context_menu_request)
+ on_context_menu_request(index, event);
+}
diff --git a/Libraries/LibGUI/GAbstractView.h b/Libraries/LibGUI/GAbstractView.h
index 59def38632..bf8fecc172 100644
--- a/Libraries/LibGUI/GAbstractView.h
+++ b/Libraries/LibGUI/GAbstractView.h
@@ -76,6 +76,12 @@ protected:
explicit GAbstractView(GWidget* parent);
virtual ~GAbstractView() override;
+ virtual void mousedown_event(GMouseEvent&) override;
+ virtual void mousemove_event(GMouseEvent&) override;
+ virtual void mouseup_event(GMouseEvent&) override;
+ virtual void doubleclick_event(GMouseEvent&) override;
+ virtual void context_menu_event(GContextMenuEvent&) override;
+
virtual void did_scroll() override;
void activate(const GModelIndex&);
void activate_selected();
@@ -86,6 +92,9 @@ protected:
RefPtr<GWidget> m_edit_widget;
Rect m_edit_widget_content_rect;
+ Point m_left_mousedown_position;
+ bool m_might_drag { false };
+
private:
RefPtr<GModel> m_model;
OwnPtr<GModelEditingDelegate> m_editing_delegate;
diff --git a/Libraries/LibGUI/GColumnsView.cpp b/Libraries/LibGUI/GColumnsView.cpp
index 8c72925b3c..882c42a3c3 100644
--- a/Libraries/LibGUI/GColumnsView.cpp
+++ b/Libraries/LibGUI/GColumnsView.cpp
@@ -216,6 +216,8 @@ GModelIndex GColumnsView::index_at_event_position(const Point& a_position) const
void GColumnsView::mousedown_event(GMouseEvent& event)
{
+ GAbstractView::mousedown_event(event);
+
if (!model())
return;
@@ -223,15 +225,7 @@ void GColumnsView::mousedown_event(GMouseEvent& event)
return;
auto index = index_at_event_position(event.position());
- if (!index.is_valid()) {
- selection().clear();
- return;
- }
-
- if (event.modifiers() & Mod_Ctrl) {
- selection().toggle(index);
- } else {
- selection().set(index);
+ if (index.is_valid() && !(event.modifiers() & Mod_Ctrl)) {
if (model()->row_count(index))
push_column(index);
}
@@ -250,34 +244,6 @@ void GColumnsView::did_update_model()
update();
}
-void GColumnsView::doubleclick_event(GMouseEvent& event)
-{
- if (!model())
- return;
-
- if (event.button() != GMouseButton::Left)
- return;
-
- mousedown_event(event);
- activate_selected();
-}
-
-void GColumnsView::context_menu_event(GContextMenuEvent& event)
-{
- if (!model())
- return;
-
- auto index = index_at_event_position(event.position());
- if (index.is_valid()) {
- if (!selection().contains(index))
- selection().set(index);
- } else {
- selection().clear();
- }
- if (on_context_menu_request)
- on_context_menu_request(index, event);
-}
-
void GColumnsView::keydown_event(GKeyEvent& event)
{
if (!model())
diff --git a/Libraries/LibGUI/GColumnsView.h b/Libraries/LibGUI/GColumnsView.h
index f34cca2101..3e98f33cfe 100644
--- a/Libraries/LibGUI/GColumnsView.h
+++ b/Libraries/LibGUI/GColumnsView.h
@@ -51,8 +51,6 @@ private:
virtual void did_update_model() override;
virtual void paint_event(GPaintEvent&) override;
virtual void mousedown_event(GMouseEvent& event) override;
- virtual void doubleclick_event(GMouseEvent& event) override;
- virtual void context_menu_event(GContextMenuEvent& event) override;
virtual void keydown_event(GKeyEvent& event) override;
struct Column {
diff --git a/Libraries/LibGUI/GItemView.cpp b/Libraries/LibGUI/GItemView.cpp
index 1fb36a7eb2..c44c82feec 100644
--- a/Libraries/LibGUI/GItemView.cpp
+++ b/Libraries/LibGUI/GItemView.cpp
@@ -138,32 +138,32 @@ GModelIndex GItemView::index_at_event_position(const Point& position) const
void GItemView::mousedown_event(GMouseEvent& event)
{
+ if (!model())
+ return GAbstractView::mousedown_event(event);
+
+ if (event.button() != GMouseButton::Left)
+ return GAbstractView::mousedown_event(event);
+
auto index = index_at_event_position(event.position());
+ if (index.is_valid()) {
+ // We might start dragging this item, but not rubber-banding.
+ return GAbstractView::mousedown_event(event);
+ }
- if (event.button() == GMouseButton::Left) {
- m_left_mousedown_position = event.position();
- if (!index.is_valid()) {
- if (event.modifiers() & Mod_Ctrl) {
- selection().for_each_index([&](auto& index) {
- m_rubber_band_remembered_selection.append(index);
- });
- } else {
- selection().clear();
- }
- m_rubber_banding = true;
- m_rubber_band_origin = event.position();
- m_rubber_band_current = event.position();
- } else {
- if (event.modifiers() & Mod_Ctrl)
- selection().toggle(index);
- else if (selection().size() > 1)
- m_might_drag = true;
- else
- selection().set(index);
- }
+ ASSERT(m_rubber_band_remembered_selection.is_empty());
+
+ if (event.modifiers() & Mod_Ctrl) {
+ selection().for_each_index([&](auto& index) {
+ m_rubber_band_remembered_selection.append(index);
+ });
+ } else {
+ selection().clear();
}
- GAbstractView::mousedown_event(event);
+ m_might_drag = false;
+ m_rubber_banding = true;
+ m_rubber_band_origin = event.position();
+ m_rubber_band_current = event.position();
}
void GItemView::mouseup_event(GMouseEvent& event)
@@ -172,14 +172,6 @@ void GItemView::mouseup_event(GMouseEvent& event)
m_rubber_banding = false;
m_rubber_band_remembered_selection.clear();
update();
- return;
- }
- auto index = index_at_event_position(event.position());
- if (index.is_valid()) {
- if ((selection().size() > 1) & m_might_drag) {
- selection().set(index);
- m_might_drag = false;
- }
}
GAbstractView::mouseup_event(event);
}
@@ -207,86 +199,9 @@ void GItemView::mousemove_event(GMouseEvent& event)
}
}
- if (event.buttons() & GMouseButton::Left && !selection().is_empty()) {
- auto diff = event.position() - m_left_mousedown_position;
- auto distance_travelled_squared = diff.x() * diff.x() + diff.y() * diff.y();
- constexpr int drag_distance_threshold = 5;
- if (distance_travelled_squared > (drag_distance_threshold)) {
- dbg() << "Initiate drag!";
- auto drag_operation = GDragOperation::construct();
-
- RefPtr<GraphicsBitmap> bitmap;
-
- StringBuilder text_builder;
- StringBuilder data_builder;
- int index_iterations = 0;
- selection().for_each_index([&](auto& index) {
- index_iterations++;
- auto text_data = model()->data(index);
- if (index_iterations == 0)
- text_builder.append(" ");
- text_builder.append(text_data.to_string());
- if (!(index_iterations == selection().size()))
- text_builder.append(", ");
-
- auto drag_data = model()->data(index, GModel::Role::DragData);
- data_builder.append(drag_data.to_string());
- data_builder.append('\n');
-
- if (!bitmap) {
- GVariant icon_data = model()->data(index, GModel::Role::Icon);
- if (icon_data.is_icon())
- bitmap = icon_data.as_icon().bitmap_for_size(32);
- }
- });
-
- drag_operation->set_text(text_builder.to_string());
- drag_operation->set_bitmap(bitmap);
- drag_operation->set_data("url-list", data_builder.to_string());
- auto outcome = drag_operation->exec();
- switch (outcome) {
- case GDragOperation::Outcome::Accepted:
- dbg() << "Drag was accepted!";
- break;
- case GDragOperation::Outcome::Cancelled:
- dbg() << "Drag was cancelled!";
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
- }
- }
-
GAbstractView::mousemove_event(event);
}
-void GItemView::context_menu_event(GContextMenuEvent& event)
-{
- if (!model())
- return;
- auto index = index_at_event_position(event.position());
- if (index.is_valid()) {
- if (!selection().contains(index))
- selection().set(index);
- } else {
- selection().clear();
- }
- if (on_context_menu_request)
- on_context_menu_request(index, event);
- GAbstractView::context_menu_event(event);
-}
-
-void GItemView::doubleclick_event(GMouseEvent& event)
-{
- if (!model())
- return;
- if (event.button() == GMouseButton::Left) {
- mousedown_event(event);
- activate_selected();
- }
-}
-
void GItemView::get_item_rects(int item_index, const Font& font, const GVariant& item_text, Rect& item_rect, Rect& icon_rect, Rect& text_rect) const
{
item_rect = this->item_rect(item_index);
diff --git a/Libraries/LibGUI/GItemView.h b/Libraries/LibGUI/GItemView.h
index dfb52d30d4..4eb21552c6 100644
--- a/Libraries/LibGUI/GItemView.h
+++ b/Libraries/LibGUI/GItemView.h
@@ -61,8 +61,6 @@ private:
virtual void mousemove_event(GMouseEvent&) override;
virtual void mouseup_event(GMouseEvent&) override;
virtual void keydown_event(GKeyEvent&) override;
- virtual void doubleclick_event(GMouseEvent&) override;
- virtual void context_menu_event(GContextMenuEvent&) override;
int item_count() const;
Rect item_rect(int item_index) const;
@@ -75,10 +73,6 @@ private:
int m_visual_column_count { 0 };
int m_visual_row_count { 0 };
- bool m_might_drag { false };
-
- Point m_left_mousedown_position;
-
Size m_effective_item_size { 80, 80 };
bool m_rubber_banding { false };
diff --git a/Libraries/LibGUI/GListView.cpp b/Libraries/LibGUI/GListView.cpp
index c6dae846c2..750a4b1a1b 100644
--- a/Libraries/LibGUI/GListView.cpp
+++ b/Libraries/LibGUI/GListView.cpp
@@ -102,25 +102,6 @@ Point GListView::adjusted_position(const Point& position) const
return position.translated(horizontal_scrollbar().value() - frame_thickness(), vertical_scrollbar().value() - frame_thickness());
}
-void GListView::mousedown_event(GMouseEvent& event)
-{
- if (!model())
- return;
-
- if (event.button() != GMouseButton::Left)
- return;
-
- auto index = index_at_event_position(event.position());
- if (index.is_valid()) {
- if (event.modifiers() & Mod_Ctrl)
- selection().toggle(index);
- else
- selection().set(index);
- } else {
- selection().clear();
- }
-}
-
void GListView::paint_event(GPaintEvent& event)
{
GFrame::paint_event(event);
diff --git a/Libraries/LibGUI/GListView.h b/Libraries/LibGUI/GListView.h
index 4fac12902e..fb237bf8f1 100644
--- a/Libraries/LibGUI/GListView.h
+++ b/Libraries/LibGUI/GListView.h
@@ -60,7 +60,6 @@ public:
private:
virtual void did_update_model() override;
virtual void paint_event(GPaintEvent&) override;
- virtual void mousedown_event(GMouseEvent&) override;
virtual void doubleclick_event(GMouseEvent&) override;
virtual void keydown_event(GKeyEvent&) override;
virtual void resize_event(GResizeEvent&) override;