comparison mde/gui/widget/layout.d @ 34:6b4116e6355c

Work on the Gui: some of the framework for drag & drop. Also made Window an IWidget. Implemented getWidget(x,y) to find the widget under this location for IWidgets (but not Gui). Made Window an IWidget and made it work a little more similarly to widgets. Implemented callbacks on the Gui for mouse events (enabling drag & drop, etc.). committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 02 May 2008 16:03:52 +0100
parents 316b0230a849
children 052df9b2fe07
comparison
equal deleted inserted replaced
33:6886402c1545 34:6b4116e6355c
20 import mde.gui.exception : WidgetDataException; 20 import mde.gui.exception : WidgetDataException;
21 21
22 /// Encapsulates a grid of Widgets 22 /// Encapsulates a grid of Widgets
23 class GridWidget : Widget 23 class GridWidget : Widget
24 { 24 {
25 this (IWindow wind, IParentWidget, int[] data) { 25 this (IWindow wind, IWidget, int[] data) {
26 // Get grid size 26 // Get grid size
27 if (data.length < 2) throw new WidgetDataException; 27 if (data.length < 2) throw new WidgetDataException;
28 rows = data[0]; 28 rows = data[0];
29 cols = data[1]; 29 cols = data[1];
30 30
33 // Get all sub-widgets 33 // Get all sub-widgets
34 // Check: correct data length and rows*cols >= 0 (know data.length - 2 >= 0). 34 // Check: correct data length and rows*cols >= 0 (know data.length - 2 >= 0).
35 if (data.length != 2 + rows * cols) throw new WidgetDataException; 35 if (data.length != 2 + rows * cols) throw new WidgetDataException;
36 subWidgets.length = rows*cols; 36 subWidgets.length = rows*cols;
37 foreach (i, inout subWidget; subWidgets) { 37 foreach (i, inout subWidget; subWidgets) {
38 subWidget = window.getWidget (data[i+2], this); 38 subWidget = window.makeWidget (data[i+2], this);
39 } 39 }
40 40
41 getMinimumSize (w,h); // Calculate the size (current size is not saved) 41 getMinimumSize (w,h); // Calculate the size (current size is not saved)
42 } 42 }
43 43
55 55
56 // Find row heights and column widths (non cumulative) 56 // Find row heights and column widths (non cumulative)
57 rowH.length = rows; 57 rowH.length = rows;
58 colW.length = cols; //WARNING: code reliant on these being initialised to zero 58 colW.length = cols; //WARNING: code reliant on these being initialised to zero
59 for (uint i = 0; i < subWidgets.length; ++i) { 59 for (uint i = 0; i < subWidgets.length; ++i) {
60 uint x = i / cols; // row 60 uint n = i / cols; // row
61 if (rowH[x] < widgetH[i]) rowH[x] = widgetH[i]; 61 if (rowH[n] < widgetH[i]) rowH[n] = widgetH[i];
62 x = i % cols; // column 62 n = i % cols; // column
63 if (colW[x] < widgetW[i]) colW[x] = widgetW[i]; 63 if (colW[n] < widgetW[i]) colW[n] = widgetW[i];
64 } 64 }
65 65
66 // rowY / colX 66 // rowY / colX
67 rowY.length = rows; 67 rowY.length = rows;
68 colX.length = cols; 68 colX.length = cols;
80 cum += x + spacing; 80 cum += x + spacing;
81 } 81 }
82 w = cum - spacing; // total width 82 w = cum - spacing; // total width
83 } 83 }
84 84
85 void draw (int x, int y) { 85 void setPosition (int x, int y) {
86 super.draw (x,y); 86 this.x = x;
87 this.y = y;
87 88
88 foreach (i,widget; subWidgets) { 89 foreach (i,widget; subWidgets)
89 widget.draw (x + colX[i % cols], y + rowY[i / cols]); 90 widget.setPosition (x + colX[i % cols], y + rowY[i / cols]);
90 }
91 } 91 }
92 92
93 // Pass event on to relevant widget. Simply return if not on a widget. 93 // Find the relevant widget.
94 void clickEvent (ushort cx, ushort cy, ubyte b, bool state) { 94 IWidget getWidget (int cx, int cy) {
95 if (rows*cols == 0) return; // special case 95 if (rows*cols == 0) return this; // special case
96
97 int lx = cx - x, ly = cy - y; // use coords relative to this widget
96 98
97 // Find the column 99 // Find the column
98 int i = cols - 1; // starting from right... 100 int i = cols - 1; // starting from right...
99 while (cx < colX[i]) { // decrement while left of this column 101 while (lx < colX[i]) { // decrement while left of this column
100 if (i == 0) return; // left of first column 102 if (i == 0) return this; // left of first column
101 --i; 103 --i;
102 } // now (cx >= colX[i]) 104 } // now (lx >= colX[i])
103 if (cx >= colX[i] + colW[i]) return; // between columns 105 if (lx >= colX[i] + colW[i]) return this; // between columns
104 106
105 // Find the row; 107 // Find the row;
106 int j = rows - 1; 108 int j = rows - 1;
107 while (cy < rowY[j]) { 109 while (ly < rowY[j]) {
108 if (j == 0) return; 110 if (j == 0) return this;
109 --j; 111 --j;
110 } 112 }
111 if (cy >= rowY[j] + rowH[j]) return; 113 if (ly >= rowY[j] + rowH[j]) return this;
112 114
113 // Now we know it's in widget (i,j)'s cell (but the widget may not take up the whole cell) 115 // Now we know it's in widget (i,j)'s cell (but the widget may not take up the whole cell)
114 cx -= colX[i]; 116 lx -= colX[i];
115 cy -= rowY[j]; 117 ly -= rowY[j];
116 IWidget widg = subWidgets[i + j*cols]; 118 IWidget widg = subWidgets[i + j*cols];
117 widg.getCurrentSize (i,j); 119 widg.getCurrentSize (i,j);
118 if (cx < i && cy < j) 120 if (lx < i && ly < j)
119 widg.clickEvent (cx, cy, b, state); 121 return widg.getWidget (cx, cy);
122 }
123
124 void draw () {
125 super.draw ();
126
127 foreach (widget; subWidgets)
128 widget.draw ();
120 } 129 }
121 130
122 protected: 131 protected:
123 int rows, cols; // number of cells in grid 132 int rows, cols; // number of cells in grid
124 int[] rowH; // row height (highest widget in the row) 133 int[] rowH; // row height (highest widget in the row)
125 int[] colW; // column width (widest widget) 134 int[] colW; // column width (widest widget)
126 int[] rowY; // cumulative rowH[i-1] + border and padding 135 int[] rowY; // cumulative rowH[i-1] + border and padding
127 int[] colX; // cumulative colW[i-1] + border and padding 136 int[] colX; // cumulative colW[i-1] + border and padding
128 IWidget[] subWidgets; // all widgets in the grid (by row): 137 IWidget[] subWidgets; // all widgets in the grid (by row):
129 /* SubWidget order: [ 2 3 ] 138 /* SubWidget order: [ 0 1 ]
130 * [ 0 1 ] */ 139 * [ 2 3 ] */
131 } 140 }