64
list.ScrollEvent += HandleListScrollEvent;
65
list.SizeAllocated += delegate {
68
list.PageChanged += HandleListPageChanged;
69
hBox.PackStart (list, true, true, 0);
71
vScrollbar = new VScrollbar (null);
72
vScrollbar.ValueChanged += delegate {
73
list.ForcePage ((int)vScrollbar.Value);
76
hBox.PackStart (vScrollbar, false, false, 0);
81
void HandleListScrollEvent (object o, ScrollEventArgs args)
83
if (!vScrollbar.Visible)
86
var adj = vScrollbar.Adjustment;
87
var alloc = Allocation;
89
//This widget is a special case because it's always aligned to items as it scrolls.
90
//Although this means we can't use the pixel deltas for true smooth scrolling, we
91
//can still make use of the effective scrolling velocity by basing the calculation
92
//on pixels and rounding to the nearest item.
95
args.Event.GetPageScrollPixelDeltas (0, alloc.Height, out dx, out dy);
99
var itemDelta = dy / (alloc.Height / adj.PageSize);
100
double discreteItemDelta = System.Math.Round (itemDelta);
101
if (discreteItemDelta == 0.0 && dy != 0.0)
102
discreteItemDelta = dy > 0? 1.0 : -1.0;
104
adj.AddValueClamped (discreteItemDelta);
108
void HandleListPageChanged (object sender, EventArgs e)
110
vScrollbar.Value = list.Page;
62
SetSizeRequest (list.WidthRequest, list.HeightRequest);
63
vScrollbar = new ScrolledWindow ();
64
vScrollbar.VScrollbar.SizeAllocated += (object o, SizeAllocatedArgs args) => {
65
var minWidth = list.WidthRequest + args.Allocation.Width;
66
if (this.Allocation.Width < minWidth)
67
SetSizeRequest (minWidth, list.HeightRequest);
69
vScrollbar.Child = list;
70
var vbox = new VBox ();
71
vbox.PackStart (vScrollbar, true, true, 0);
113
75
public void SelectItem (object item)
115
77
for (int i = 0; i < DataProvider.IconCount; i++) {
116
78
if (DataProvider.GetTag (i) == item) {
117
79
list.Selection = i;
118
list.Page = Math.Max (0, i - list.VisibleRows / 2);
119
vScrollbar.Value = list.Page;
80
vScrollbar.Vadjustment.Value = Math.Max (0, i * list.RowHeight - vScrollbar.Vadjustment.PageSize / 2);
136
96
Gdk.Pointer.Ungrab (Gtk.Global.CurrentEventTime);
137
97
base.OnUnmapped ();
100
void SwitchToSeletedWord ()
102
string selection = list.WordSelection.ToString ();
103
for (int i = 0; i < DataProvider.IconCount; i++) {
104
if (DataProvider.GetMarkup (i).StartsWith (selection, StringComparison.OrdinalIgnoreCase)) {
106
list.WordSelection.Append (selection);
140
111
public bool ProcessKey (Gdk.Key key, Gdk.ModifierType modifier)
144
if (list.SelectionDisabled)
145
list.SelectionDisabled = false;
148
vScrollbar.Value = list.Page;
152
if (list.SelectionDisabled)
153
list.SelectionDisabled = false;
156
vScrollbar.Value = list.Page;
159
case Gdk.Key.Page_Up:
160
list.Selection -= list.VisibleRows - 1;
161
vScrollbar.Value = list.Page;
164
case Gdk.Key.Page_Down:
165
list.Selection += list.VisibleRows - 1;
166
vScrollbar.Value = list.Page;
170
vScrollbar.Value = list.Selection = (int)vScrollbar.Adjustment.Lower;
174
vScrollbar.Value = (int)vScrollbar.Adjustment.Upper;
175
list.Selection = DataProvider.IconCount;
179
case Gdk.Key.ISO_Enter:
180
case Gdk.Key.Key_3270_Enter:
181
case Gdk.Key.KP_Enter:
182
list.OnSelectItem (EventArgs.Empty);
115
if (list.SelectionDisabled)
116
list.SelectionDisabled = false;
122
if (list.SelectionDisabled)
123
list.SelectionDisabled = false;
128
case Gdk.Key.Page_Up:
129
list.Selection -= list.VisibleRows - 1;
132
case Gdk.Key.Page_Down:
133
list.Selection += list.VisibleRows - 1;
137
list.Selection = (int)0;
141
list.Selection = DataProvider.IconCount;
149
case Gdk.Key.ISO_Enter:
150
case Gdk.Key.Key_3270_Enter:
151
case Gdk.Key.KP_Enter:
152
list.OnSelectItem (EventArgs.Empty);
156
if (char.IsLetterOrDigit (ch)) {
157
list.WordSelection.Append (ch);
158
SwitchToSeletedWord ();
189
protected override void OnSizeRequested (ref Requisition requisition)
191
base.OnSizeRequested (ref requisition);
192
var upper = Math.Max (0, DataProvider.IconCount);
193
var pageStep = list.VisibleRows;
194
vScrollbar.Adjustment.SetBounds (0, upper, 1, pageStep, pageStep);
196
if (list.VisibleRows >= DataProvider.IconCount && vScrollbar.Parent == hBox)
197
hBox.Remove (vScrollbar);
199
requisition.Height = this.list.HeightRequest + 2;
201
if (WidthRequest >= 0) {
202
width = WidthRequest;
204
width = this.list.CalcWidth ();
205
if (list.VisibleRows < DataProvider.IconCount)
206
width += vScrollbar.Allocation.Width;
208
requisition.Width = width;
211
protected override bool OnExposeEvent (Gdk.EventExpose args)
213
bool result = base.OnExposeEvent (args);
214
args.Window.DrawRectangle (Style.MidGC (Gtk.StateType.Normal), false, 0, 0, this.Allocation.Width - 1, this.Allocation.Height - 1);
218
166
protected override bool OnFocusOutEvent (Gdk.EventFocus evnt)
224
172
protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
227
176
return base.OnButtonPressEvent (evnt);
181
protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing evnt)
184
return base.OnLeaveNotifyEvent (evnt);
187
protected override bool OnEnterNotifyEvent (Gdk.EventCrossing evnt)
189
if (evnt.Window == this.GdkWindow)
191
return base.OnEnterNotifyEvent (evnt);
230
194
protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
232
196
ProcessKey (evnt.Key, evnt.State);
331
310
void UpdatePage ()
312
var area = GetRowArea (selection);
313
if (area.Y < vadj.Value) {
338
if (selection < page || selection >= page + VisibleRows) {
339
page = selection - (VisibleRows / 2);
317
if (vadj.Value + Allocation.Height < area.Bottom) {
318
vadj.Value = System.Math.Max (0, area.Bottom - vadj.PageSize + 1);
343
Page = System.Math.Max (0, System.Math.Min (page, win.DataProvider.IconCount - VisibleRows));
346
322
public bool SelectionDisabled {
350
326
this.QueueDraw ();
363
OnPageChanged (EventArgs.Empty);
368
internal void ForcePage (int page)
370
this.page = System.Math.Max (0, System.Math.Min (page, win.DataProvider.IconCount - VisibleRows));
371
OnPageChanged (EventArgs.Empty);
375
protected virtual void OnPageChanged (EventArgs e)
377
EventHandler handler = this.PageChanged;
382
public event EventHandler PageChanged;
384
330
protected override bool OnButtonPressEvent (Gdk.EventButton e)
386
332
Selection = GetRowByPosition ((int) e.Y);
433
379
int lineWidth = winWidth - margin * 2;
434
380
int xpos = margin + padding;
437
while (ypos < winHeight - margin && (page + n) < win.DataProvider.IconCount) {
438
string text = win.DataProvider.GetMarkup (page + n) ?? "<null>";
382
int n = (int)(vadj.Value / rowHeight);
383
while (ypos < winHeight - margin && n < win.DataProvider.IconCount) {
384
string text = win.DataProvider.GetMarkup (n) ?? "<null>";
439
385
layout.SetMarkup (text);
441
Gdk.Pixbuf icon = win.DataProvider.GetIcon (page + n);
387
Gdk.Pixbuf icon = win.DataProvider.GetIcon (n);
442
388
int iconHeight = icon != null ? icon.Height : 24;
443
389
int iconWidth = icon != null ? icon.Width : 0;
493
439
int GetRowByPosition (int ypos)
495
return page + (ypos-margin) / rowHeight;
441
return (int)(vadj.Value + ypos) / rowHeight;
498
444
public Gdk.Rectangle GetRowArea (int row)
501
int winWidth, winHeight;
502
this.GdkWindow.GetSize (out winWidth, out winHeight);
504
return new Gdk.Rectangle (margin, margin + rowHeight * row, winWidth, rowHeight);
446
return new Gdk.Rectangle (0, row * rowHeight, Allocation.Width, rowHeight - 1);
507
449
public int VisibleRows {
509
451
return Allocation.Height / rowHeight;
455
const int maxVisibleRows = 8;
513
456
void CalcVisibleRows ()
515
Gdk.Rectangle geometry = DesktopService.GetUsableMonitorGeometry (Screen, Screen.GetMonitorAtWindow (GdkWindow));
516
int winHeight = geometry.Height / 2;
517
458
int lvWidth, lvHeight;
518
459
this.GetSizeRequest (out lvWidth, out lvHeight);
519
460
if (layout == null)
522
int visibleRows = (winHeight + padding - margin * 2) / rowHeight;
525
if (this.win.DataProvider.IconCount > visibleRows)
526
newHeight = (rowHeight * visibleRows) + margin * 2;
464
if (this.win.DataProvider.IconCount > maxVisibleRows)
465
newHeight = (rowHeight * maxVisibleRows) + margin * 2;
528
467
newHeight = (rowHeight * this.win.DataProvider.IconCount) + margin * 2;
530
if (lvWidth != listWidth || lvHeight != newHeight) {
531
this.SetSizeRequest (listWidth, newHeight);
468
listWidth = Math.Min (450, CalcWidth ());
469
this.SetSizeRequest (listWidth, newHeight);
534
471
internal int CalcWidth ()
494
void SetBounds (Gdk.Rectangle allocation)
498
var h = allocation.Height;
499
var height = Math.Max (h, rowHeight * win.DataProvider.IconCount);
500
if (this.win.DataProvider.IconCount < maxVisibleRows) {
501
vadj.SetBounds (0, h, 0, 0, h);
503
vadj.SetBounds (0, height, RowHeight, h, h);
557
507
protected override void OnSizeAllocated (Gdk.Rectangle allocation)
559
509
base.OnSizeAllocated (allocation);
511
hadj.SetBounds (0, allocation.Width, 0, 0, allocation.Width);
513
SetBounds (allocation);