mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-26 14:28:49 +00:00
GTableView: Make it possible to resize the columns with the mouse.
The GModel now merely provides an initial width for the columns. Once that has been queried, the table view manages width from then on.
This commit is contained in:
parent
f3aec1a0d9
commit
48e3ea9e5c
Notes:
sideshowbarker
2024-07-19 14:15:07 +09:00
Author: https://github.com/awesomekling
Commit: 48e3ea9e5c
2 changed files with 101 additions and 22 deletions
|
@ -3,6 +3,7 @@
|
|||
#include <LibGUI/GScrollBar.h>
|
||||
#include <LibGUI/GPainter.h>
|
||||
#include <LibGUI/GTextBox.h>
|
||||
#include <LibGUI/GWindow.h>
|
||||
#include <Kernel/KeyCode.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
|
||||
|
@ -26,7 +27,7 @@ void GTableView::update_content_size()
|
|||
int content_width = 0;
|
||||
int column_count = model()->column_count();
|
||||
for (int i = 0; i < column_count; ++i)
|
||||
content_width += model()->column_metadata(i).preferred_width + horizontal_padding() * 2;
|
||||
content_width += column_width(i) + horizontal_padding() * 2;
|
||||
int content_height = item_count() * item_height();
|
||||
|
||||
set_content_size({ content_width, content_height });
|
||||
|
@ -62,7 +63,12 @@ Rect GTableView::row_rect(int item_index) const
|
|||
|
||||
int GTableView::column_width(int column_index) const
|
||||
{
|
||||
return model()->column_metadata(column_index).preferred_width;
|
||||
auto& column_data = this->column_data(column_index);
|
||||
if (!column_data.has_initialized_width) {
|
||||
column_data.has_initialized_width = true;
|
||||
column_data.width = model()->column_metadata(column_index).preferred_width;
|
||||
}
|
||||
return column_data.width;
|
||||
}
|
||||
|
||||
Rect GTableView::header_rect(int column_index) const
|
||||
|
@ -75,9 +81,7 @@ Rect GTableView::header_rect(int column_index) const
|
|||
continue;
|
||||
x_offset += column_width(i) + horizontal_padding() * 2;
|
||||
}
|
||||
auto column_metadata = model()->column_metadata(column_index);
|
||||
int column_width = column_metadata.preferred_width;
|
||||
return { x_offset, 0, column_width + horizontal_padding() * 2, header_height() };
|
||||
return { x_offset, 0, column_width(column_index) + horizontal_padding() * 2, header_height() };
|
||||
}
|
||||
|
||||
Point GTableView::adjusted_position(const Point& position)
|
||||
|
@ -85,14 +89,31 @@ Point GTableView::adjusted_position(const Point& position)
|
|||
return position.translated(-frame_thickness(), vertical_scrollbar().value() - frame_thickness());
|
||||
}
|
||||
|
||||
Rect GTableView::column_resize_grabbable_rect(int column) const
|
||||
{
|
||||
auto header_rect = this->header_rect(column);
|
||||
return { header_rect.right() - 1, header_rect.top(), 4, header_rect.height() };
|
||||
}
|
||||
|
||||
void GTableView::mousedown_event(GMouseEvent& event)
|
||||
{
|
||||
if (!model())
|
||||
return;
|
||||
|
||||
auto adjusted_position = this->adjusted_position(event.position());
|
||||
|
||||
if (event.y() < header_height()) {
|
||||
auto adjusted_position = this->adjusted_position(event.position());
|
||||
for (int i = 0; i < model()->column_count(); ++i) {
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
if (column_resize_grabbable_rect(i).contains(adjusted_position)) {
|
||||
dbgprintf("now resizing column %d\n", i);
|
||||
m_resizing_column = i;
|
||||
m_in_column_resize = true;
|
||||
m_column_resize_original_width = column_width(i);
|
||||
m_column_resize_origin = event.position();
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto header_rect = this->header_rect(i);
|
||||
if (header_rect.contains(adjusted_position)) {
|
||||
auto new_sort_order = GSortOrder::Ascending;
|
||||
|
@ -108,7 +129,6 @@ void GTableView::mousedown_event(GMouseEvent& event)
|
|||
}
|
||||
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
auto adjusted_position = this->adjusted_position(event.position());
|
||||
for (int row = 0, row_count = model()->row_count(); row < row_count; ++row) {
|
||||
if (!row_rect(row).contains(adjusted_position))
|
||||
continue;
|
||||
|
@ -125,6 +145,41 @@ void GTableView::mousedown_event(GMouseEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void GTableView::mousemove_event(GMouseEvent& event)
|
||||
{
|
||||
if (m_in_column_resize) {
|
||||
auto delta = event.position() - m_column_resize_origin;
|
||||
int new_width = m_column_resize_original_width + delta.x();
|
||||
auto& column_data = this->column_data(m_resizing_column);
|
||||
if (column_data.width != new_width) {
|
||||
column_data.width = new_width;
|
||||
update();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto adjusted_position = this->adjusted_position(event.position());
|
||||
if (event.buttons() == 0) {
|
||||
for (int i = 0; i < model()->column_count(); ++i) {
|
||||
if (column_resize_grabbable_rect(i).contains(adjusted_position)) {
|
||||
window()->set_override_cursor(GStandardCursor::ResizeHorizontal);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
window()->set_override_cursor(GStandardCursor::None);
|
||||
}
|
||||
|
||||
void GTableView::mouseup_event(GMouseEvent& event)
|
||||
{
|
||||
auto adjusted_position = this->adjusted_position(event.position());
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
if (!column_resize_grabbable_rect(m_resizing_column).contains(adjusted_position))
|
||||
window()->set_override_cursor(GStandardCursor::None);
|
||||
m_in_column_resize = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GTableView::paint_event(GPaintEvent& event)
|
||||
{
|
||||
GFrame::paint_event(event);
|
||||
|
@ -167,7 +222,7 @@ void GTableView::paint_event(GPaintEvent& event)
|
|||
if (is_column_hidden(column_index))
|
||||
continue;
|
||||
auto column_metadata = model()->column_metadata(column_index);
|
||||
int column_width = column_metadata.preferred_width;
|
||||
int column_width = this->column_width(column_index);
|
||||
const Font& font = column_metadata.font ? *column_metadata.font : this->font();
|
||||
bool is_key_column = model()->key_column() == column_index;
|
||||
Rect cell_rect(horizontal_padding() + x_offset, y, column_width, item_height());
|
||||
|
@ -214,8 +269,7 @@ void GTableView::paint_headers(Painter& painter)
|
|||
for (int column_index = 0; column_index < model()->column_count(); ++column_index) {
|
||||
if (is_column_hidden(column_index))
|
||||
continue;
|
||||
auto column_metadata = model()->column_metadata(column_index);
|
||||
int column_width = column_metadata.preferred_width;
|
||||
int column_width = this->column_width(column_index);
|
||||
bool is_key_column = model()->key_column() == column_index;
|
||||
Rect cell_rect(x_offset, 0, column_width + horizontal_padding() * 2, header_height());
|
||||
StylePainter::paint_button(painter, cell_rect, ButtonStyle::Normal, false);
|
||||
|
@ -309,23 +363,27 @@ void GTableView::scroll_into_view(const GModelIndex& index, Orientation orientat
|
|||
GScrollableWidget::scroll_into_view(rect, orientation);
|
||||
}
|
||||
|
||||
GTableView::ColumnData& GTableView::column_data(int column) const
|
||||
{
|
||||
ASSERT(model());
|
||||
ASSERT(column >= 0 && column < model()->column_count());
|
||||
if (column >= m_column_data.size())
|
||||
m_column_data.resize(model()->column_count());
|
||||
return m_column_data.at(column);
|
||||
}
|
||||
|
||||
bool GTableView::is_column_hidden(int column) const
|
||||
{
|
||||
if (column >= 0 && column < m_column_visibility.size())
|
||||
return !m_column_visibility[column];
|
||||
return false;
|
||||
return !column_data(column).visibility;
|
||||
}
|
||||
|
||||
void GTableView::set_column_hidden(int column, bool hidden)
|
||||
{
|
||||
ASSERT(column >= 0);
|
||||
if (m_column_visibility.size() <= column) {
|
||||
int previous_column_count = m_column_visibility.size();
|
||||
m_column_visibility.resize(column + 1);
|
||||
for (int i = previous_column_count; i < m_column_visibility.size(); ++i)
|
||||
m_column_visibility[i] = true;
|
||||
}
|
||||
m_column_visibility[column] = !hidden;
|
||||
auto& column_data = this->column_data(column);
|
||||
if (column_data.visibility == !hidden)
|
||||
return;
|
||||
column_data.visibility = !hidden;
|
||||
update();
|
||||
}
|
||||
|
||||
void GTableView::doubleclick_event(GMouseEvent& event)
|
||||
|
@ -344,3 +402,8 @@ void GTableView::doubleclick_event(GMouseEvent& event)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GTableView::leave_event(CEvent&)
|
||||
{
|
||||
window()->set_override_cursor(GStandardCursor::None);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue