[dconf-editor] Improve popover placement in RegistryList.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf-editor] Improve popover placement in RegistryList.
- Date: Wed, 14 Nov 2018 13:47:02 +0000 (UTC)
commit 31df8203527d608d03b7dbae75902a32c6c9e4fd
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Wed Oct 10 13:43:11 2018 +0200
Improve popover placement in RegistryList.
editor/registry-list.vala | 115 ++++++++++++++++++++++++++++++++++++++++------
editor/registry-view.vala | 2 +-
2 files changed, 102 insertions(+), 15 deletions(-)
---
diff --git a/editor/registry-list.vala b/editor/registry-list.vala
index b5b50be..9b56b05 100644
--- a/editor/registry-list.vala
+++ b/editor/registry-list.vala
@@ -23,6 +23,7 @@ private abstract class RegistryList : Grid, BrowsableView
[GtkChild] protected ListBox key_list_box;
[GtkChild] protected RegistryPlaceholder placeholder;
[GtkChild] private ScrolledWindow scrolled;
+ private Adjustment adjustment;
protected bool search_mode { private get; set; }
protected string? current_path_if_search_mode = null; // TODO only used in search mode
@@ -34,6 +35,11 @@ private abstract class RegistryList : Grid, BrowsableView
internal ModificationsHandler modifications_handler { protected get; set; }
+ construct
+ {
+ adjustment = key_list_box.get_adjustment ();
+ }
+
private bool _small_keys_list_rows;
internal bool small_keys_list_rows
{
@@ -48,16 +54,59 @@ private abstract class RegistryList : Grid, BrowsableView
}
}
- protected void scroll_to_row (ListBoxRow row, bool grab_focus)
+ protected void select_row_and_if_true_grab_focus (ListBoxRow row, bool grab_focus)
{
key_list_box.select_row (row);
if (grab_focus)
row.grab_focus ();
+ }
+ private enum ScrollToRowBehaviour {
+ CENTER,
+ SCROLL_UP,
+ SCROLL_DOWN
+ }
+ private void scroll_to_row (ListBoxRow row, ScrollToRowBehaviour behaviour)
+ {
+ int adjustment_value = (int) adjustment.get_value ();
Allocation list_allocation, row_allocation;
scrolled.get_allocation (out list_allocation);
row.get_allocation (out row_allocation);
- key_list_box.get_adjustment ().set_value (row_allocation.y + (int) ((row_allocation.height -
list_allocation.height) / 2.0));
+
+ int row_bottom_limit = row_allocation.y - list_allocation.height;
+ int row_top_limit = row_allocation.y + row_allocation.height;
+
+ if ((adjustment_value < row_bottom_limit)
+ || (adjustment_value > row_top_limit))
+ {
+ adjustment.set_value (row_allocation.y + (int) ((row_allocation.height - list_allocation.height)
/ 2.0));
+ return;
+ }
+
+ row_bottom_limit += row_allocation.height + 40;
+ row_top_limit /* -= row_allocation.height + 40; */ = row_allocation.y - 40;
+
+ switch (behaviour)
+ {
+ case ScrollToRowBehaviour.CENTER:
+ if ((adjustment_value < row_bottom_limit)
+ || (adjustment_value > row_top_limit))
+ adjustment.set_value (row_allocation.y + (int) ((row_allocation.height -
list_allocation.height) / 2.0));
+ return;
+
+ case ScrollToRowBehaviour.SCROLL_DOWN:
+ if (adjustment_value < row_bottom_limit)
+ adjustment.set_value (row_bottom_limit);
+ return;
+
+ case ScrollToRowBehaviour.SCROLL_UP:
+ if (adjustment_value > row_top_limit)
+ adjustment.set_value (row_top_limit);
+ return;
+
+ default:
+ assert_not_reached ();
+ }
}
internal void invalidate_popovers ()
@@ -113,7 +162,10 @@ private abstract class RegistryList : Grid, BrowsableView
check_resize ();
ListBoxRow? row = key_list_box.get_row_at_index (get_row_position (list_model, selected,
context_id));
if (row != null)
- scroll_to_row ((!) row, grab_focus);
+ {
+ select_row_and_if_true_grab_focus ((!) row, grab_focus);
+ scroll_to_row ((!) row, ScrollToRowBehaviour.CENTER);
+ }
}
private static int get_row_position (GLib.ListStore list_model, string selected, uint16 context_id)
{
@@ -173,9 +225,12 @@ private abstract class RegistryList : Grid, BrowsableView
ClickableListBoxRow row = (ClickableListBoxRow) ((!) selected_row).get_child ();
if (row.right_click_popover_visible ())
+ {
row.hide_right_click_popover ();
- else
- show_right_click_popover (row, null);
+ return true;
+ }
+
+ show_right_click_popover (row, null);
return true;
}
@@ -264,19 +319,23 @@ private abstract class RegistryList : Grid, BrowsableView
if (row != null)
{
+ scroll_to_row ((!) row, is_down ? ScrollToRowBehaviour.SCROLL_DOWN :
ScrollToRowBehaviour.SCROLL_UP);
if (search_mode)
{
Container list_box = (Container) ((!) selected_row).get_parent ();
- scroll_to_row ((!) row, list_box.get_focus_child () != null);
+ select_row_and_if_true_grab_focus ((!) row, list_box.get_focus_child () != null);
}
else
- scroll_to_row ((!) row, true);
+ select_row_and_if_true_grab_focus ((!) row, true);
}
return true;
}
else if (n_items >= 1)
{
- key_list_box.select_row (key_list_box.get_row_at_index (is_down ? 0 : (int) n_items - 1));
+ selected_row = key_list_box.get_row_at_index (is_down ? 0 : (int) n_items - 1);
+ if (selected_row == null)
+ return false;
+ select_row_and_if_true_grab_focus ((!) selected_row, true);
return true;
}
return false;
@@ -501,10 +560,8 @@ private abstract class RegistryList : Grid, BrowsableView
{
ListBoxRow list_box_row = (ListBoxRow) widget.get_parent (); // is a ListBoxRowWrapper
// ListBox list_box = (ListBox) list_box_row.get_parent (); // instead of key_list_box
- key_list_box.select_row (list_box_row);
- if (!search_mode)
- list_box_row.grab_focus ();
+ select_row_and_if_true_grab_focus (list_box_row, !search_mode);
if (event.button == Gdk.BUTTON_SECONDARY)
{
@@ -591,11 +648,38 @@ private abstract class RegistryList : Grid, BrowsableView
private void show_right_click_popover (ClickableListBoxRow row, int? nullable_event_x)
{
+ int adjustment_value = (int) adjustment.get_value ();
+ Allocation list_allocation, row_allocation;
+ scrolled.get_allocation (out list_allocation);
+ row.get_allocation (out row_allocation);
+
+ bool position_to_top;
+ if ((row_allocation.y > adjustment_value + list_allocation.height)
+ || (row_allocation.y + row_allocation.height < adjustment_value))
+ {
+ if (nullable_event_x != null) // called from mouse, so the row should be visible...
+ assert_not_reached ();
+ adjustment.set_value (row_allocation.y + (int) ((row_allocation.height - list_allocation.height)
/ 2.0));
+ position_to_top = false;
+ }
+ else if (adjustment_value < row_allocation.y - list_allocation.height + row_allocation.height)
+ {
+ adjustment.set_value (row_allocation.y - list_allocation.height + row_allocation.height);
+ position_to_top = true;
+ }
+ else if (adjustment_value > row_allocation.y)
+ {
+ adjustment.set_value (row_allocation.y);
+ position_to_top = false;
+ }
+ else
+ position_to_top = row_allocation.y > adjustment_value + (int) (list_allocation.height / 2.0);
+
generate_popover_if_needed (row, modifications_handler);
- place_popover (row, nullable_event_x);
+ place_popover (row, nullable_event_x, position_to_top);
rows_possibly_with_popover.append (row);
}
- private static void place_popover (ClickableListBoxRow row, int? nullable_event_x)
+ private static void place_popover (ClickableListBoxRow row, int? nullable_event_x, bool position_to_top)
{
int event_x;
if (nullable_event_x == null)
@@ -603,8 +687,11 @@ private abstract class RegistryList : Grid, BrowsableView
else
event_x = (!) nullable_event_x;
- Gdk.Rectangle rect = { x:event_x, y:row.get_allocated_height (), width:0, height:0 };
+ int event_y = position_to_top ? 2 : row.get_allocated_height () - 2;
+
+ Gdk.Rectangle rect = { x:event_x, y:event_y, width:0, height:0 };
((!) row.nullable_popover).set_pointing_to (rect);
+ ((!) row.nullable_popover).set_position (position_to_top ? PositionType.TOP : PositionType.BOTTOM);
((!) row.nullable_popover).popup ();
}
diff --git a/editor/registry-view.vala b/editor/registry-view.vala
index e92597e..fa6cc50 100644
--- a/editor/registry-view.vala
+++ b/editor/registry-view.vala
@@ -110,7 +110,7 @@ private class RegistryView : RegistryList
}
if (row == null)
assert_not_reached ();
- scroll_to_row ((!) row, true);
+ select_row_and_if_true_grab_focus ((!) row, true);
}
/*\
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]