summaryrefslogtreecommitdiff
path: root/LibGUI
diff options
context:
space:
mode:
Diffstat (limited to 'LibGUI')
-rw-r--r--LibGUI/GItemView.cpp28
-rw-r--r--LibGUI/GModel.cpp5
-rw-r--r--LibGUI/GModel.h4
-rw-r--r--LibGUI/GModelIndex.h20
-rw-r--r--LibGUI/GSortingProxyModel.cpp8
-rw-r--r--LibGUI/GTableView.cpp16
-rw-r--r--LibGUI/GTreeView.cpp35
7 files changed, 85 insertions, 31 deletions
diff --git a/LibGUI/GItemView.cpp b/LibGUI/GItemView.cpp
index 7fe71337d7..d41ae902aa 100644
--- a/LibGUI/GItemView.cpp
+++ b/LibGUI/GItemView.cpp
@@ -74,7 +74,7 @@ void GItemView::mousedown_event(GMouseEvent& event)
auto adjusted_position = event.position().translated(0, vertical_scrollbar().value());
for (int i = 0; i < item_count(); ++i) {
if (item_rect(i).contains(adjusted_position)) {
- model()->set_selected_index({ i, 0 });
+ model()->set_selected_index(model()->index(i, 0));
update();
return;
}
@@ -117,7 +117,7 @@ void GItemView::paint_event(GPaintEvent& event)
}
Rect item_rect = this->item_rect(item_index);
- GModelIndex model_index(item_index, m_model_column);
+ auto model_index = model()->index(item_index, m_model_column);
auto icon = model()->data(model_index, GModel::Role::Icon);
auto item_text = model()->data(model_index, GModel::Role::Display);
@@ -165,7 +165,7 @@ void GItemView::keydown_event(GKeyEvent& event)
return;
}
if (event.key() == KeyCode::Key_Home) {
- GModelIndex new_index { 0, 0 };
+ auto new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -174,7 +174,7 @@ void GItemView::keydown_event(GKeyEvent& event)
return;
}
if (event.key() == KeyCode::Key_End) {
- GModelIndex new_index { model.row_count() - 1, 0 };
+ auto new_index = model.index(model.row_count() - 1, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -185,9 +185,9 @@ void GItemView::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Up) {
GModelIndex new_index;
if (model.selected_index().is_valid())
- new_index = { model.selected_index().row() - m_visual_column_count, model.selected_index().column() };
+ new_index = model.index(model.selected_index().row() - m_visual_column_count, model.selected_index().column());
else
- new_index = { 0, 0 };
+ new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -198,9 +198,9 @@ void GItemView::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Down) {
GModelIndex new_index;
if (model.selected_index().is_valid())
- new_index = { model.selected_index().row() + m_visual_column_count, model.selected_index().column() };
+ new_index = model.index(model.selected_index().row() + m_visual_column_count, model.selected_index().column());
else
- new_index = { 0, 0 };
+ new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -211,9 +211,9 @@ void GItemView::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Left) {
GModelIndex new_index;
if (model.selected_index().is_valid())
- new_index = { model.selected_index().row() - 1, model.selected_index().column() };
+ new_index = model.index(model.selected_index().row() - 1, model.selected_index().column());
else
- new_index = { 0, 0 };
+ new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -224,9 +224,9 @@ void GItemView::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Right) {
GModelIndex new_index;
if (model.selected_index().is_valid())
- new_index = { model.selected_index().row() + 1, model.selected_index().column() };
+ new_index = model.index(model.selected_index().row() + 1, model.selected_index().column());
else
- new_index = { 0, 0 };
+ new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -236,7 +236,7 @@ void GItemView::keydown_event(GKeyEvent& event)
}
if (event.key() == KeyCode::Key_PageUp) {
int items_per_page = (visible_content_rect().height() / effective_item_size().height()) * m_visual_column_count;
- GModelIndex new_index(max(0, model.selected_index().row() - items_per_page), model.selected_index().column());
+ auto new_index = model.index(max(0, model.selected_index().row() - items_per_page), model.selected_index().column());
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -246,7 +246,7 @@ void GItemView::keydown_event(GKeyEvent& event)
}
if (event.key() == KeyCode::Key_PageDown) {
int items_per_page = (visible_content_rect().height() / effective_item_size().height()) * m_visual_column_count;
- GModelIndex new_index(min(model.row_count() - 1, model.selected_index().row() + items_per_page), model.selected_index().column());
+ auto new_index = model.index(min(model.row_count() - 1, model.selected_index().row() + items_per_page), model.selected_index().column());
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
diff --git a/LibGUI/GModel.cpp b/LibGUI/GModel.cpp
index ca8b3db6d7..a06e4053c6 100644
--- a/LibGUI/GModel.cpp
+++ b/LibGUI/GModel.cpp
@@ -44,3 +44,8 @@ void GModel::set_selected_index(const GModelIndex& index)
if (m_activates_on_selection && is_valid(index))
activate(index);
}
+
+GModelIndex GModel::create_index(int row, int column, void* data) const
+{
+ return GModelIndex(*this, row, column, data);
+}
diff --git a/LibGUI/GModel.h b/LibGUI/GModel.h
index 90949a2229..03f6b2d7f5 100644
--- a/LibGUI/GModel.h
+++ b/LibGUI/GModel.h
@@ -76,12 +76,16 @@ public:
Function<void(GModel&)> on_model_update;
Function<void(const GModelIndex&)> on_selection_changed;
+ virtual GModelIndex index(int row, int column) const { return create_index(row, column); }
+
protected:
GModel();
void for_each_view(Function<void(GAbstractView&)>);
void did_update();
+ GModelIndex create_index(int row, int column, void* data = nullptr) const;
+
private:
HashTable<GAbstractView*> m_views;
GModelIndex m_selected_index;
diff --git a/LibGUI/GModelIndex.h b/LibGUI/GModelIndex.h
index a60b3c5efc..4e66d573dc 100644
--- a/LibGUI/GModelIndex.h
+++ b/LibGUI/GModelIndex.h
@@ -1,21 +1,31 @@
#pragma once
+class GModel;
+
class GModelIndex {
+ friend class GModel;
public:
GModelIndex() { }
- GModelIndex(int row, int column)
- : m_row(row)
- , m_column(column)
- {
- }
bool is_valid() const { return m_row != -1 && m_column != -1; }
int row() const { return m_row; }
int column() const { return m_column; }
+ void* internal_data() const { return m_internal_data; }
+
bool operator==(const GModelIndex& other) const { return m_row == other.m_row && m_column == other.m_column; }
private:
+ GModelIndex(const GModel& model, int row, int column, void* internal_data)
+ : m_model(&model)
+ , m_row(row)
+ , m_column(column)
+ , m_internal_data(internal_data)
+ {
+ }
+
+ const GModel* m_model { nullptr };
int m_row { -1 };
int m_column { -1 };
+ void* m_internal_data { nullptr };
};
diff --git a/LibGUI/GSortingProxyModel.cpp b/LibGUI/GSortingProxyModel.cpp
index 312358a5cf..a2fbe054c6 100644
--- a/LibGUI/GSortingProxyModel.cpp
+++ b/LibGUI/GSortingProxyModel.cpp
@@ -32,7 +32,7 @@ GModelIndex GSortingProxyModel::map_to_target(const GModelIndex& index) const
return { };
if (index.row() >= row_count() || index.column() >= column_count())
return { };
- return { m_row_mappings[index.row()], index.column() };
+ return target().index(m_row_mappings[index.row()], index.column());
}
String GSortingProxyModel::row_name(int index) const
@@ -86,8 +86,8 @@ void GSortingProxyModel::resort()
if (m_key_column == -1)
return;
quick_sort(m_row_mappings.begin(), m_row_mappings.end(), [&] (auto row1, auto row2) -> bool {
- auto data1 = target().data({ row1, m_key_column }, GModel::Role::Sort);
- auto data2 = target().data({ row2, m_key_column }, GModel::Role::Sort);
+ auto data1 = target().data(target().index(row1, m_key_column), GModel::Role::Sort);
+ auto data2 = target().data(target().index(row2, m_key_column), GModel::Role::Sort);
if (data1 == data2)
return 0;
bool is_less_than = data1 < data2;
@@ -97,7 +97,7 @@ void GSortingProxyModel::resort()
// Preserve selection.
for (int i = 0; i < row_count; ++i) {
if (m_row_mappings[i] == previously_selected_target_row) {
- set_selected_index({ i, 0 });
+ set_selected_index(index(i, 0));
break;
}
}
diff --git a/LibGUI/GTableView.cpp b/LibGUI/GTableView.cpp
index 0e2f66be59..a284dee8c3 100644
--- a/LibGUI/GTableView.cpp
+++ b/LibGUI/GTableView.cpp
@@ -86,7 +86,7 @@ void GTableView::mousedown_event(GMouseEvent& event)
auto adjusted_position = event.position().translated(0, vertical_scrollbar().value());
for (int i = 0; i < item_count(); ++i) {
if (row_rect(i).contains(adjusted_position)) {
- model()->set_selected_index({ i, 0 });
+ model()->set_selected_index(model()->index(i, 0));
update();
return;
}
@@ -143,7 +143,7 @@ void GTableView::paint_event(GPaintEvent& event)
auto cell_rect_for_fill = cell_rect.inflated(horizontal_padding() * 2, 0);
painter.fill_rect(cell_rect_for_fill, key_column_background_color);
}
- GModelIndex cell_index(row_index, column_index);
+ auto cell_index = model()->index(row_index, column_index);
auto data = model()->data(cell_index);
if (data.is_bitmap()) {
painter.blit(cell_rect.location(), data.as_bitmap(), data.as_bitmap().rect());
@@ -228,9 +228,9 @@ void GTableView::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Up) {
GModelIndex new_index;
if (model.selected_index().is_valid())
- new_index = { model.selected_index().row() - 1, model.selected_index().column() };
+ new_index = model.index(model.selected_index().row() - 1, model.selected_index().column());
else
- new_index = { 0, 0 };
+ new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -241,9 +241,9 @@ void GTableView::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Down) {
GModelIndex new_index;
if (model.selected_index().is_valid())
- new_index = { model.selected_index().row() + 1, model.selected_index().column() };
+ new_index = model.index(model.selected_index().row() + 1, model.selected_index().column());
else
- new_index = { 0, 0 };
+ new_index = model.index(0, 0);
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -253,7 +253,7 @@ void GTableView::keydown_event(GKeyEvent& event)
}
if (event.key() == KeyCode::Key_PageUp) {
int items_per_page = visible_content_rect().height() / item_height();
- GModelIndex new_index(max(0, model.selected_index().row() - items_per_page), model.selected_index().column());
+ auto new_index = model.index(max(0, model.selected_index().row() - items_per_page), model.selected_index().column());
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
@@ -263,7 +263,7 @@ void GTableView::keydown_event(GKeyEvent& event)
}
if (event.key() == KeyCode::Key_PageDown) {
int items_per_page = visible_content_rect().height() / item_height();
- GModelIndex new_index(min(model.row_count() - 1, model.selected_index().row() + items_per_page), model.selected_index().column());
+ auto new_index = model.index(min(model.row_count() - 1, model.selected_index().row() + items_per_page), model.selected_index().column());
if (model.is_valid(new_index)) {
model.set_selected_index(new_index);
scroll_into_view(new_index, Orientation::Vertical);
diff --git a/LibGUI/GTreeView.cpp b/LibGUI/GTreeView.cpp
index e2bfd53032..031efc55e5 100644
--- a/LibGUI/GTreeView.cpp
+++ b/LibGUI/GTreeView.cpp
@@ -1,9 +1,44 @@
#include <LibGUI/GTreeView.h>
#include <LibGUI/GPainter.h>
+class TestModel : public GModel {
+public:
+ static Retained<TestModel> create() { return adopt(*new TestModel); }
+
+ virtual int row_count(const GModelIndex& = GModelIndex()) const;
+ virtual int column_count(const GModelIndex& = GModelIndex()) const;
+ virtual GVariant data(const GModelIndex&, Role = Role::Display) const;
+ virtual void update();
+ virtual ColumnMetadata column_metadata(int) const { return { 100 }; }
+};
+
+int TestModel::row_count(const GModelIndex& index) const
+{
+ return 0;
+}
+
+int TestModel::column_count(const GModelIndex&) const
+{
+ return 1;
+}
+
+void TestModel::update()
+{
+}
+
+GVariant TestModel::data(const GModelIndex&, Role) const
+{
+ return { };
+}
+
GTreeView::GTreeView(GWidget* parent)
: GAbstractView(parent)
{
+ set_frame_shape(GFrame::Shape::Container);
+ set_frame_shadow(GFrame::Shadow::Sunken);
+ set_frame_thickness(2);
+
+ set_model(TestModel::create());
}
GTreeView::~GTreeView()