Track prelighted rows
This needs us to be a widget window, otherwise we can't track prelight when inside inferior windows.
This commit is contained in:
parent
a5dbd116bc
commit
36aefcf17c
1 changed files with 77 additions and 42 deletions
|
@ -72,33 +72,74 @@ public class Contacts.Sorted : Container {
|
||||||
NeedSeparatorFunc? need_separator_func;
|
NeedSeparatorFunc? need_separator_func;
|
||||||
CreateSeparatorFunc? create_separator_func;
|
CreateSeparatorFunc? create_separator_func;
|
||||||
UpdateSeparatorFunc? update_separator_func;
|
UpdateSeparatorFunc? update_separator_func;
|
||||||
protected Gdk.Window event_window;
|
|
||||||
unowned ChildInfo? selected_child;
|
unowned ChildInfo? selected_child;
|
||||||
|
unowned ChildInfo? prelight_child;
|
||||||
|
|
||||||
private int do_sort (ChildInfo? a, ChildInfo? b) {
|
private int do_sort (ChildInfo? a, ChildInfo? b) {
|
||||||
return sort_func (a.widget, b.widget);
|
return sort_func (a.widget, b.widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sorted () {
|
public Sorted () {
|
||||||
set_has_window (false);
|
set_has_window (true);
|
||||||
set_redraw_on_allocate (false);
|
set_redraw_on_allocate (false);
|
||||||
|
|
||||||
children = new Sequence<ChildInfo?>();
|
children = new Sequence<ChildInfo?>();
|
||||||
child_hash = new HashMap<unowned Widget, unowned ChildInfo?> ();
|
child_hash = new HashMap<unowned Widget, unowned ChildInfo?> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unowned ChildInfo? find_child_at_y (int y) {
|
||||||
|
unowned ChildInfo? child_info = null;
|
||||||
|
for (var iter = children.get_begin_iter (); !iter.is_end (); iter = iter.next ()) {
|
||||||
|
unowned ChildInfo? info = iter.get ();
|
||||||
|
if (y >= info.y && y < info.y + info.height) {
|
||||||
|
child_info = info;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return child_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update_prelight (ChildInfo? child) {
|
||||||
|
if (child != prelight_child) {
|
||||||
|
prelight_child = child;
|
||||||
|
queue_draw ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool enter_notify_event (Gdk.EventCrossing event) {
|
||||||
|
if (event.window != get_window ())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unowned ChildInfo? child = find_child_at_y ((int)event.y);
|
||||||
|
update_prelight (child);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool leave_notify_event (Gdk.EventCrossing event) {
|
||||||
|
if (event.window != get_window ())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (event.detail != Gdk.NotifyType.INFERIOR) {
|
||||||
|
update_prelight (null);
|
||||||
|
} else {
|
||||||
|
unowned ChildInfo? child = find_child_at_y ((int)event.y);
|
||||||
|
update_prelight (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool motion_notify_event (Gdk.EventMotion event) {
|
||||||
|
unowned ChildInfo? child = find_child_at_y ((int)event.y);
|
||||||
|
update_prelight (child);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public override bool button_press_event (Gdk.EventButton event) {
|
public override bool button_press_event (Gdk.EventButton event) {
|
||||||
if (event.button == 1) {
|
if (event.button == 1) {
|
||||||
var y = event.y;
|
unowned ChildInfo? child = find_child_at_y ((int)event.y);
|
||||||
unowned ChildInfo? child_info = null;
|
selected_child = child;
|
||||||
for (var iter = children.get_begin_iter (); !iter.is_end (); iter = iter.next ()) {
|
|
||||||
unowned ChildInfo? info = iter.get ();
|
|
||||||
if (y >= info.y && y < info.y + info.height) {
|
|
||||||
child_info = info;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selected_child = child_info;
|
|
||||||
|
|
||||||
child_selected (selected_child != null ? selected_child.widget : null);
|
child_selected (selected_child != null ? selected_child.widget : null);
|
||||||
queue_draw ();
|
queue_draw ();
|
||||||
|
@ -126,6 +167,13 @@ public class Contacts.Sorted : Container {
|
||||||
allocation.width, selected_child.height);
|
allocation.width, selected_child.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prelight_child != null && prelight_child != selected_child) {
|
||||||
|
context.set_state (StateFlags.PRELIGHT);
|
||||||
|
Gtk.render_background (context, cr,
|
||||||
|
0, prelight_child.y,
|
||||||
|
allocation.width, prelight_child.height);
|
||||||
|
}
|
||||||
|
|
||||||
context.restore ();
|
context.restore ();
|
||||||
|
|
||||||
base.draw (cr);
|
base.draw (cr);
|
||||||
|
@ -144,23 +192,19 @@ public class Contacts.Sorted : Container {
|
||||||
attributes.width = allocation.width;
|
attributes.width = allocation.width;
|
||||||
attributes.height = allocation.height;
|
attributes.height = allocation.height;
|
||||||
attributes.window_type = Gdk.WindowType.CHILD;
|
attributes.window_type = Gdk.WindowType.CHILD;
|
||||||
attributes.event_mask = this.get_events () | Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK;
|
attributes.event_mask = this.get_events () |
|
||||||
|
Gdk.EventMask.ENTER_NOTIFY_MASK |
|
||||||
|
Gdk.EventMask.LEAVE_NOTIFY_MASK |
|
||||||
|
Gdk.EventMask.POINTER_MOTION_MASK |
|
||||||
|
Gdk.EventMask.EXPOSURE_MASK |
|
||||||
|
Gdk.EventMask.BUTTON_PRESS_MASK;
|
||||||
|
|
||||||
var window = get_parent_window ();
|
attributes.wclass = Gdk.WindowWindowClass.INPUT_OUTPUT;
|
||||||
|
var window = new Gdk.Window (get_parent_window (), attributes,
|
||||||
|
Gdk.WindowAttributesType.X |
|
||||||
|
Gdk.WindowAttributesType.Y);
|
||||||
|
window.set_user_data (this);
|
||||||
this.set_window (window);
|
this.set_window (window);
|
||||||
|
|
||||||
attributes.wclass = Gdk.WindowWindowClass.INPUT_ONLY;
|
|
||||||
event_window = new Gdk.Window (window, attributes,
|
|
||||||
Gdk.WindowAttributesType.X |
|
|
||||||
Gdk.WindowAttributesType.Y);
|
|
||||||
event_window.set_user_data (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void unrealize () {
|
|
||||||
event_window.set_user_data (null);
|
|
||||||
event_window.destroy ();
|
|
||||||
event_window = null;
|
|
||||||
base.unrealize ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void apply_filter (Widget child) {
|
private void apply_filter (Widget child) {
|
||||||
|
@ -292,16 +336,6 @@ public class Contacts.Sorted : Container {
|
||||||
resort ();
|
resort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void map () {
|
|
||||||
event_window.show ();
|
|
||||||
base.map ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void unmap () {
|
|
||||||
event_window.hide ();
|
|
||||||
base.unmap ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private unowned ChildInfo? lookup_info (Widget widget) {
|
private unowned ChildInfo? lookup_info (Widget widget) {
|
||||||
return child_hash.get (widget);
|
return child_hash.get (widget);
|
||||||
}
|
}
|
||||||
|
@ -454,11 +488,12 @@ public class Contacts.Sorted : Container {
|
||||||
|
|
||||||
set_allocation (allocation);
|
set_allocation (allocation);
|
||||||
|
|
||||||
if (event_window != null)
|
var window = get_window();
|
||||||
event_window.move_resize (allocation.x,
|
if (window != null)
|
||||||
allocation.y,
|
window.move_resize (allocation.x,
|
||||||
allocation.width,
|
allocation.y,
|
||||||
allocation.height);
|
allocation.width,
|
||||||
|
allocation.height);
|
||||||
|
|
||||||
child_allocation.x = allocation.x;
|
child_allocation.x = allocation.x;
|
||||||
child_allocation.y = allocation.y;
|
child_allocation.y = allocation.y;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue