Changeset 46:03fa79a48c48
- Timestamp:
- 05/22/08 07:51:47 (8 months ago)
- Files:
-
- codeDoc/jobs.txt (modified) (1 diff)
- data/conf/gui.mtt (modified) (1 diff)
- mde/gui/widget/Ifaces.d (modified) (3 diffs)
- mde/gui/widget/Widget.d (modified) (2 diffs)
- mde/gui/widget/Window.d (modified) (5 diffs)
- mde/gui/widget/layout.d (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
codeDoc/jobs.txt
r45 r46 57 57 58 58 Done (for git log message): 59 Moved the implementable widgets from mde.gui.widget.Widget to miscWidgets, leaving base widgets in Widget.60 Rewrote some of GridLayoutWidget's implementation. Made many operations general to work for either columns or rows. Some optimisations were intended but ended up being removed due to problems.61 Allowed layout's to resize from either direction (only with window resizes).data/conf/gui.mtt
r45 r46 12 12 <int|x=20> 13 13 <int|y=100> 14 <int[][int]|widgetData=[1:[0x4010,50,50],2:[0xB004,3,1,3,1,3],3:[0x3001],0:[0xB004,3,1, 3,1,3]]>14 <int[][int]|widgetData=[1:[0x4010,50,50],2:[0xB004,3,1,3,1,3],3:[0x3001],0:[0xB004,3,1,2,1,2]]> mde/gui/widget/Ifaces.d
r45 r46 22 22 /** Interface for Window, allowing widgets to call some of Window's methods. 23 23 * 24 * Contains the methods in Window available for widgets to call on their root. */ 24 * Contains the methods in Window available for widgets to call on their root. 25 * 26 * Notation: 27 * Positive/negative direction: along the x/y axis in this direction. 28 * Layout widget: a widget containing multiple sub-widges (which hence controls how they are laid 29 * out). */ 25 30 interface IWindow : IWidget 26 31 { … … 120 125 /** Used to adjust the size. 121 126 * 122 * w,h is the new size. The boolean parameters describe which direction to resize from and is 123 * only really relevent to layout widgets (see GridLayoutWidget's implementation). When 124 * calling, just past true,true if it doesn't matter. 127 * Params: 128 * nw/nh = The new width/height 129 * dir = Direction to resize from. This is only really applicable to layout widgets. 130 * It must be either -1 (start resizing from highest row/col index, decreasing the 131 * index as necessary), or +1 (resize from the lowest index, i.e. 0). 132 * Most widgets can simply ignore it. 125 133 * 126 134 * Implementation: … … 131 139 * to fill a whole row/column in a layout widget. 132 140 * 133 * If the actual size is needed, call getCurrentSize afterwards. */ 134 void setSize (int w, int h, bool, bool); 141 * If the actual size is needed, call getCurrentSize afterwards. setPosition must be called 142 * afterwards if the widget might be a layout widget. */ 143 void setWidth (int nw, int dir); 144 void setHeight (int nh, int dir); /// ditto 135 145 136 146 /** Set the current position (i.e. called on init and move). */ mde/gui/widget/Widget.d
r45 r46 41 41 // still need to set their size. 42 42 int[] adjust (int[] data) { 43 setSize (0,0,true,true); 43 setWidth (0,-1); 44 setHeight (0,-1); 44 45 return data; 45 46 } … … 73 74 /* Set size: minimal size is (mw,mh). Note that both resizable and fixed widgets should allow 74 75 * enlarging, so in both cases this is a correct implementation. */ 75 void set Size (int nw, int nh, bool, bool) {76 void setWidth (int nw, int) { 76 77 w = (nw >= mw ? nw : mw); 78 } 79 void setHeight (int nh, int) { 77 80 h = (nh >= mh ? nh : mh); 78 81 } mde/gui/widget/Window.d
r45 r46 86 86 widgetY = y + border.t; // must be updated if the window is moved 87 87 widget.setPosition (widgetX, widgetY); 88 89 // Calculate mw/mh and xw/yh (cached data): 90 widget.getMinimalSize (mw, mh); 91 mw += border.l + border.r; 92 mh += border.t + border.b; 88 93 89 94 xw = x+w; … … 207 212 208 213 void getMinimalSize (out int wM, out int hM) { 209 if (mh < 0) { // calculate if necessary 210 widget.getMinimalSize (mw, mh); 211 mw += border.l + border.r; 212 mh += border.t + border.b; 213 } 214 // mw/mh are calculated by finalise(); 214 215 wM = mw; 215 216 hM = mh; … … 220 221 } 221 222 222 void set Size (int nw, int nh, bool wB, bool hB) {223 getMinimalSize (w,h);224 if (nw > w) w = nw; // expand if new size is larger, but don't go smaller225 if (nh > h) h = nh;226 227 xw = x+w;228 yh = y+h;229 230 widget.setSize (w - border.l - border.r, h - border.t - border.b, wB, hB);231 232 gui_.requestRedraw (); // obviously necessary whenever the window's size is changed223 void setWidth (int nw, int dir) { 224 if (nw < mw) w = mw; // clamp 225 else w = nw; 226 xw = x + w; 227 widget.setWidth (w - border.l - border.r, dir); 228 } 229 void setHeight (int nh, int dir) { 230 if (nh < mh) h = mh; // clamp 231 else h = nh; 232 yh = y + h; 233 widget.setHeight (h - border.t - border.b, dir); 233 234 } 234 235 … … 245 246 widget.setPosition (widgetX, widgetY); 246 247 247 gui_.requestRedraw (); // obviously necessary whenever the window is moved248 gui_.requestRedraw (); // necessary whenever the window is moved; setPosition is called after resizes and moves 248 249 } 249 250 … … 308 309 309 310 // This function is only called if some resize is going to happen. 310 // To improve efficiency, store parameters to resize to. 311 int xSize = w, ySize = h; // new size 312 int xDiff, yDiff; // difference to new position 313 bool xHigh, yHigh; // resize from positive side 311 // x,y are used as parameters to setPosition as well as being affected by it; somewhat 312 // pointless but fairly effective. 314 313 315 314 if (resizeType & RESIZE_TYPE.L) { 316 getMinimalSize (xDiff, xSize); // (only want xDiff, temporarily used as mw)317 xSize = xDrag - cx;318 if (xSize < xDiff) xSize = xDiff; // clamp319 xDiff = w - xSize; // now used as amount to move315 int xSize = xDrag - cx; 316 if (xSize < mw) xSize = mw; // clamp 317 x += w - xSize; 318 setWidth (xSize, 1); 320 319 } 321 320 else if (resizeType & RESIZE_TYPE.R) { 322 xSize = xDrag + cx; 323 xHigh = true; 321 setWidth (xDrag + cx, -1); 324 322 } 325 323 if (resizeType & RESIZE_TYPE.T) { 326 getMinimalSize (ySize, yDiff);327 ySize = yDrag - cy;328 if (ySize < yDiff) ySize = yDiff;329 yDiff = h - ySize;324 int ySize = yDrag - cy; 325 if (ySize < mh) ySize = mh; 326 y += h - ySize; 327 setHeight (ySize, 1); 330 328 } 331 329 else if (resizeType & RESIZE_TYPE.B) { 332 ySize = yDrag + cy; 333 yHigh = true; 334 } 335 336 setSize (xSize, ySize, xHigh, yHigh); 337 if (xDiff != 0 || yDiff != 0) 338 setPosition (x + xDiff, y + yDiff); 330 setHeight (yDrag + cy, -1); 331 } 332 333 // Moves lower (x,y) coordinate if necessary and repositions any sub-widgets moved by the 334 // resizing: 335 setPosition (x, y); 339 336 } 340 337 bool endCallback (ushort cx, ushort cy, ubyte b, bool state) { mde/gui/widget/layout.d
r45 r46 38 38 class GridLayoutWidget : Widget 39 39 { 40 //BEGIN Creation & saving 40 41 this (IWindow wind, int[] data) { 41 42 // Get grid size and check data … … 63 64 } 64 65 66 /* This does two things: 67 * 1. Pass adjust data on to sub-widgets 68 * 2. Set the size, from the adjust data if possible 69 */ 65 70 int[] adjust (int[] data) { 66 71 // Give all sub-widgets their data: … … 90 95 91 96 // Tell subwidgets their new sizes. Positions are given by a later call to setPosition. 92 foreach (i,widget; subWidgets) 93 // Resizing direction is arbitrarily set to "high direction": 94 widget.setSize (col.width[i % cols], row.width[i / cols], true, true); 97 foreach (i,widget; subWidgets) { 98 // Resizing direction is arbitrarily set to negative: 99 widget.setWidth (col.width[i % cols], -1); 100 widget.setHeight (row.width[i / cols], -1); 101 } 95 102 96 103 return data[lenUsed..$]; … … 116 123 return ret; 117 124 } 118 125 //END Creation & saving 126 127 //BEGIN Size & position 119 128 bool isWSizable () { 120 129 return col.firstSizable >= 0; … … 130 139 } 131 140 132 void setSize (int nw, int nh, bool wHigh, bool hHigh) { 133 debug scope (failure) { 134 char[128] tmp; 135 logger.trace ("setSize failed: hHigh = " ~ (hHigh ? "true" : "false")); 136 logger.trace (logger.format (tmp, "rows to resize: {}, {}", row.firstSizable, row.lastSizable)); 137 } 138 // Optimisation (could easily be called with same sizes if a parent layout widget is 139 // resized, since many columns/rows may not be resized). 140 if (nw == w && nh == h) return; 141 142 // calculate the row/column sizes (and new positions) 143 if (wHigh) 144 w += col.adjustCellSizes (nw - w, col.lastSizable, -1); 145 else 146 w += col.adjustCellSizes (nw - w, col.firstSizable, 1); 147 if (hHigh) 148 h += row.adjustCellSizes (nh - h, row.lastSizable, -1); 149 else 150 h += row.adjustCellSizes (nh - h, row.firstSizable, 1); 151 152 // set the sub-widget's sizes & positions 153 setSubWidgetSP (wHigh, hHigh); 141 void setWidth (int nw, int dir) { 142 if (nw == w) return; 143 144 w += col.adjustCellSizes (nw - w, (dir == -1 ? col.lastSizable : col.firstSizable), dir); 145 146 // Note: setPosition must be called after! 147 } 148 void setHeight (int nh, int dir) { 149 if (nh == h) return; 150 151 h += row.adjustCellSizes (nh - h, (dir == -1 ? row.lastSizable : row.firstSizable), dir); 152 153 // Note: setPosition must be called after! 154 154 } 155 155 … … 161 161 widget.setPosition (x + col.pos[i % cols], y + row.pos[i / cols]); 162 162 } 163 //END Size & position 163 164 164 165 … … 211 212 void genCachedConstructionData () { 212 213 col.spacing = row.spacing = window.renderer.layoutSpacing; 214 col.setColWidth = &setColWidth; 215 row.setColWidth = &setRowHeight; 213 216 214 217 // Calculate the minimal column and row sizes: … … 270 273 } 271 274 } 272 273 // set sub-widgets size & position (done after resizing widget or rows/columns)274 void setSubWidgetSP (bool wH, bool hH) {275 for (myIt i = 0; i < cols; ++i)276 for (myIt j = 0; j < rows; ++j)277 {278 IWidget widget = subWidgets[i + cols*j];279 widget.setSize (col.width[i], row.width[j], wH, hH);280 widget.setPosition (x + col.pos[i], y + row.pos[j]);281 }282 }283 275 //END Cache calculation functions 284 276 285 277 286 //BEGIN Col/row resizing 278 void setColWidth (myIt i, int w, int dir) { 279 for (myIt j = 0; j < rows; ++j) { 280 subWidgets[i + cols*j].setWidth (w, dir); 281 } 282 } 283 void setRowHeight (myIt j, int h, int dir) { 284 for (myIt i = 0; i < cols; ++i) { 285 subWidgets[i + cols*j].setHeight (h, dir); 286 } 287 } 288 289 290 //BEGIN Col/row resizing callback 287 291 void resizeCallback (ushort cx, ushort cy) { 288 292 col.resize (cx - dragX); … … 293 297 dragY = cy; 294 298 295 // NOTE: Resizing direction is set to "high direction" which isn't always going to be 296 // correct. A more accurate but more complex approach might be to get 297 // adjustCellSizes to do the work. 298 setSubWidgetSP (true, true); 299 foreach (i,widget; subWidgets) 300 widget.setPosition (x + col.pos[i % cols], 301 y + row.pos[i / cols]); 299 302 window.requestRedraw; 300 303 } … … 310 313 // Data for resizing cols/rows: 311 314 int dragX, dragY; // coords where drag starts 312 //END Col/row resizing 315 //END Col/row resizing callback 313 316 314 317 … … 335 338 resizeU; // and up from this index 336 339 int spacing; // used by genPositions (which cannot access the layout class's data) 340 /* This is a delegate to a enclosing class's function, since: 341 * a different implementation is needed for cols or rows 342 * we're unable to access enclosing class members directly */ 343 void delegate (myIt,int,int) setColWidth; // set width of a column, with resize direction 337 344 338 345 void dupMin () { … … 408 415 * Returns: 409 416 * The amount adjusted. This may be larger than diff, since cellD is clamped by cellDMin. 417 * 418 * Note: Check variable used for start is valid before calling! If a non-sizable column's 419 * index is passed, this should get increased (if diff > 0) but not decreased. 410 420 */ 411 int adjustCellSizes (int diff, myDiff start, myDiff incr) 412 in {// Could occur if adjust isn't called first, but this would be a code error: 413 char[128] tmp; 414 logger.trace (logger.format (tmp, "start is {}", start)); 421 int adjustCellSizes (int diff, myDiff start, int incr) 422 in { 423 // Could occur if adjust isn't called first, but this would be a code error: 415 424 assert (width !is null, "adjustCellSizes: width is null"); 425 // Most likely if passed negative when sizing is disabled: 416 426 assert (start >= 0 && start < minWidth.length, "adjustCellSizes: invalid start"); 417 427 assert (incr == 1 || incr == -1, "adjustCellSizes: invalid incr"); 428 assert (setColWidth !is null, "adjustCellSizes: setColWidth is null"); 418 429 } body { 419 430 debug scope(failure) … … 422 433 if (diff > 0) { // increase size of first resizable cell 423 434 width[i] += diff; 435 setColWidth (i, width[i], incr); 424 436 } 425 437 else if (diff < 0) { // decrease … … 429 441 width[i] += rd; // decrease this cell's size (but may be too much) 430 442 rd = width[i] - minWidth[i]; 431 if (rd >= 0) // OK; we're done 443 if (rd >= 0) { // OK; we're done 444 setColWidth (i, width[i], incr); // set new width 432 445 break; // we hit the mark exactly: diff is correct 446 } 433 447 434 448 // else we decreased it too much! 435 449 width[i] = minWidth[i]; 450 setColWidth (i, width[i], incr); 436 451 // rd is remainder to decrease by 452 437 453 438 454 bool it = true; // iterate (force first time) … … 469 485 470 486 // Index types. Note that in some cases they need to hold negative values. 487 // Int is used for resizing direction (although ptrdiff_t would be more appropriate), 488 // since the value must always be -1 or +1 and int is smaller on X86_64. 471 489 alias size_t myIt; 472 490 alias ptrdiff_t myDiff;
