StandardTableView resizable columns

This commit is contained in:
Olivier Goffart 2023-01-23 13:38:01 +01:00 committed by Olivier Goffart
parent fabebaa009
commit 66b848227b
7 changed files with 142 additions and 47 deletions

View file

@ -409,6 +409,7 @@ export struct TableColumn := {
min-width: length,
horizontal-stretch: float,
sort-order: SortOrder,
width: length,
}
export struct StateInfo := {

View file

@ -6,10 +6,13 @@ import { Palette, ScrollView } from "std-widgets-impl.slint";
component TableViewColumn inherits Rectangle {
callback clicked <=> touch-area.clicked;
callback adjust_size(length);
in property <SortOrder> sort-order: SortOrder.unsorted;
touch-area := TouchArea {}
touch-area := TouchArea {
width: parent.width - 11px;
}
HorizontalLayout {
padding-left: 16px;
@ -37,7 +40,23 @@ component TableViewColumn inherits Rectangle {
y: parent.height - self.height;
width: 100%;
height: 1px;
background: Palette.neutralPrimaryAlt;
background: Palette.neutralLight;
}
Rectangle {
width: 1px;
x: parent.width - 1px;
background: movable-ta.has-hover ? Palette.neutralTertiary : transparent;
animate background { duration: 250ms; }
movable-ta := TouchArea {
width: 10px;
moved => {
if (self.pressed) {
adjust_size(self.mouse-x - self.pressed-x);
}
}
mouse-cursor: ew-resize;
}
}
states [
@ -65,7 +84,7 @@ component TableViewCell inherits Rectangle {
y: parent.height - self.height;
width: 100%;
height: 1px;
background: Palette.neutralPrimaryAlt;
background: Palette.neutralLight;
}
}
@ -117,25 +136,35 @@ export component StandardTableView {
}
VerticalLayout {
HorizontalLayout {
padding-right: 20px;
min-height: root.min-header-height;
Rectangle {
clip: true;
vertical-stretch: 0;
for column[index] in root.columns : TableViewColumn {
sort-order: column.sort-order;
min-width: column.min-width;
horizontal-stretch: column.horizontal-stretch;
Text {
vertical-alignment: center;
min-height: header-layout.min-height;
header-layout := HorizontalLayout {
width: max(self.preferred-width, parent.width);
x: scroll-view.viewport-x;
padding-right: 20px;
min-height: root.min-header-height;
for column[index] in root.columns : TableViewColumn {
sort-order: column.sort-order;
horizontal-stretch: column.horizontal-stretch;
min-width: column.min-width;
text: column.title;
font-weight: 900;
}
min-width: max(column.min-width, column.width);
preferred-width: self.min-width;
max-width: (index < columns.length && column.width >= 1px) ? max(column.min-width, column.width) : 100000px;
clicked => {
root.sort(index);
Text {
vertical-alignment: center;
text: column.title;
font-weight: 900;
overflow: elide;
}
clicked => {
root.sort(index);
}
adjust-size(diff) => {
column.width = max(1px, self.width + diff);
}
}
}
}
@ -151,7 +180,9 @@ export component StandardTableView {
for cell[index] in row : TableViewCell {
private property <bool> has_inner_focus;
horizontal-stretch: root.columns[index].horizontal-stretch;
min-width: root.columns[index].min-width;
min-width: max(columns[index].min-width, columns[index].width);
preferred-width: self.min-width;
max-width: (index < columns.length && columns[index].width >= 1px) ? max(columns[index].min-width, columns[index].width) : 100000px;
Rectangle {
// height: 100%;

View file

@ -8,6 +8,7 @@ import { md } from "md.slint";
component TableViewColumn inherits Rectangle {
callback clicked <=> state-layer.clicked;
callback adjust_size(length);
in property <SortOrder> sort-order: SortOrder.unsorted;
@ -46,6 +47,22 @@ component TableViewColumn inherits Rectangle {
height: 1px;
background: md.sys.color.outline;
}
Rectangle {
width: 1px;
x: parent.width - 1px;
background: movable-ta.has-hover ? md.sys.color.outline : transparent;
animate background { duration: 250ms; }
movable-ta := TouchArea {
width: 10px;
moved => {
if (self.pressed) {
adjust_size(self.mouse-x - self.pressed-x);
}
}
mouse-cursor: ew-resize;
}
}
}
component TableViewCell inherits Rectangle {
@ -114,25 +131,36 @@ export component StandardTableView {
}
VerticalLayout {
HorizontalLayout {
padding-right: 20px;
min-height: root.min-header-height;
Rectangle {
clip: true;
vertical-stretch: 0;
for column[index] in root.columns : TableViewColumn {
sort-order: column.sort-order;
min-width: column.min-width;
horizontal-stretch: column.horizontal-stretch;
min-height: header-layout.min-height;
Text {
vertical-alignment: center;
header-layout := HorizontalLayout {
padding-right: 20px;
min-height: root.min-header-height;
vertical-stretch: 0;
for column[index] in root.columns : TableViewColumn {
sort-order: column.sort-order;
horizontal-stretch: column.horizontal-stretch;
min-width: column.min-width;
text: column.title;
font-weight: 900;
}
min-width: max(column.min-width, column.width);
preferred-width: self.min-width;
max-width: (index < columns.length && column.width >= 1px) ? max(column.min-width, column.width) : 100000px;
clicked => {
root.sort(index);
Text {
vertical-alignment: center;
text: column.title;
font-weight: 900;
overflow: elide;
}
clicked => {
root.sort(index);
}
adjust-size(diff) => {
column.width = max(1px, self.width + diff);
}
}
}
}
@ -148,7 +176,9 @@ export component StandardTableView {
for cell[index] in row : TableViewCell {
private property <bool> has_inner_focus;
horizontal-stretch: root.columns[index].horizontal-stretch;
min-width: root.columns[index].min-width;
min-width: max(columns[index].min-width, columns[index].width);
preferred-width: self.min-width;
max-width: (index < columns.length && columns[index].width >= 1px) ? max(columns[index].min-width, columns[index].width) : 100000px;
Rectangle {
line-edit := LineEditInner {

View file

@ -308,12 +308,14 @@ export component StandardTableView {
alignment: start;
for row[i] in rows : Rectangle {
width: max(row-layout.preferred-width, fli.width);
row-ta := TouchArea {}
HorizontalLayout {
row-layout := HorizontalLayout {
for cell[index] in row : Rectangle {
horizontal-stretch: columns[index].horizontal-stretch;
min-width: columns[index].min-width;
preferred-width: columns[index].min-width;
min-width: max(columns[index].min-width, columns[index].width);
preferred-width: self.min-width;
max-width: (index < columns.length && columns[index].width >= 1px) ? max(columns[index].min-width, columns[index].width) : 100000px;
HorizontalLayout {
if cell.editable : NativeStandardListViewItem {
index: i;
@ -354,14 +356,26 @@ export component StandardTableView {
for column[index] in columns : NativeTableHeaderSection {
item: column;
horizontal-stretch: column.horizontal-stretch;
min-width: columns[index].min-width;
preferred-width: columns[index].min-width;
min-width: max(column.min-width, column.width);
preferred-width: self.min-width;
max-width: (index < columns.length && column.width >= 1px) ? max(column.min-width, column.width) : 100000px;
TouchArea {
clicked => {
sort(index);
}
}
TouchArea {
width: 10px;
x: parent.width - self.width / 2;
moved => {
if (self.pressed) {
column.width = max(1px, parent.width + (self.mouse-x - self.pressed-x));
}
}
mouse-cursor: ew-resize;
}
}
}
}