Changeset 7
- Timestamp:
- 11/15/06 10:43:56 (2 years ago)
- Files:
-
- trunk/luigi/adaptor/base.d (modified) (1 diff)
- trunk/luigi/adaptor/glfw.d (modified) (4 diffs)
- trunk/luigi/arranger.d (modified) (33 diffs)
- trunk/luigi/base.d (modified) (3 diffs)
- trunk/luigi/bitmaps.d (added)
- trunk/luigi/event.d (added)
- trunk/luigi/example1.d (modified) (4 diffs)
- trunk/luigi/font.d (modified) (4 diffs)
- trunk/luigi/gldraw.d (modified) (5 diffs)
- trunk/luigi/gui.d (modified) (35 diffs)
- trunk/luigi/signalobj.d (added)
- trunk/luigi/theme.d (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/luigi/adaptor/base.d
r6 r7 30 30 import sslot.signal; 31 31 import luigi.base; 32 33 /** WindowHandle is just an opaque piece of data used to identify 34 windows on the underlying windowing system. It could be an int for 35 GLUT, or an HWND for Win32, etc. 36 */ 37 typedef void* WindowHandle; 38 39 enum KeyMods { 40 None = 0, 41 Ctrl = 0x1, CtrlBit = 1, 42 Shift = 0x2, ShiftBit = 2, 43 Alt = 0x4, AltBit = 3 44 }; 45 46 char[] toString(KeyMods k) { 47 alias KeyMods e; 48 char [] ret; 49 if (k & e.Shift) { ret ~= "Shift"; } 50 if (k & e.Ctrl) { if (ret) ret~="|"; ret ~= "Ctrl"; } 51 if (k & e.Alt) { if (ret) ret~="|"; ret ~= "Alt"; } 52 if (!ret) ret = "None"; 53 return ret; 54 } 55 56 enum MouseButtons { 57 None = 0, 58 Left = 0x1, LeftBit = 1, 59 Right = 0x2, RightBit = 2, 60 Middle = 0x4, MiddleBit = 3, 61 Button0 = Left, Button0Bit = 1, 62 Button1 = Right, Button1Bit = 2, 63 Button2 = Middle, Button2Bit = 3, 64 Button3 = 0x8, Button3Bit = 4, 65 Button4 = 0x10, Button4Bit = 5, 66 Button5 = 0x20, Button5Bit = 6 67 }; 68 69 char[] toString(MouseButtons b) { 70 alias MouseButtons e; 71 char[] ret; 72 if (b & e.Left) { ret ~= "Left"; } 73 if (b & e.Middle) { if (ret) ret~="|"; ret ~= "Middle"; } 74 if (b & e.Right) { if (ret) ret~="|"; ret ~= "Right"; } 75 if (b & e.Button3){ if (ret) ret~="|"; ret ~= "Button3"; } 76 if (b & e.Button4) { if (ret) ret~="|"; ret ~= "Button4"; } 77 if (b & e.Button5) { if (ret) ret~="|"; ret ~= "Button5"; } 78 if (!ret) ret = "None"; 79 return ret; 80 } 81 82 enum Key { 83 Unknown = -1, 84 Space = 32, 85 Special = 256, 86 Escape, 87 F1, 88 F2, 89 F3, 90 F4, 91 F5, 92 F6, 93 F7, 94 F8, 95 F9, 96 F10, 97 F11, 98 F12, 99 F13, 100 F14, 101 F15, 102 F16, 103 F17, 104 F18, 105 F19, 106 F20, 107 F21, 108 F22, 109 F23, 110 F24, 111 F25, 112 Up, 113 Down, 114 Left, 115 Right, 116 LShift, Shift = LShift, 117 RShift, 118 LCtrl, Ctrl = LCtrl, 119 RCtrl, 120 LAlt, Alt = LAlt, 121 RAlt, 122 Tab, 123 Enter, 124 Backspace, 125 Insert, 126 Del, 127 PageUp, 128 PageDown, 129 Home, 130 End, 131 KP_0, 132 KP_1, 133 KP_2, 134 KP_3, 135 KP_4, 136 KP_5, 137 KP_6, 138 KP_7, 139 KP_8, 140 KP_9, 141 KP_Divide, 142 KP_Multiply, 143 KP_Subtract, 144 KP_Add, 145 KP_Decimal, 146 KP_Equal, 147 KP_Enter, 148 } 149 150 151 152 enum EventStatus { 153 Alive = 0, 154 Dead = 1, 155 156 OK = 0, 157 Abort = 1, 158 } 159 160 struct KeyEvent 161 { 162 union { 163 Point p; 164 struct { float x,y; } 165 } 166 union { 167 Point winp; 168 struct { float winx,winy; } 169 } 170 bool is_press; 171 bool is_release() { return !is_press; } 172 int key; // an ascii char (uppercase) or enum Key 173 dchar ch; 174 KeyMods mods; 175 } 176 177 struct MouseButtonEvent 178 { 179 union { 180 Point p; 181 struct { float x,y; } 182 } 183 union { 184 Point winp; 185 struct { float winx,winy; } 186 } 187 bool is_press; // otherwise release 188 bool is_release() { return !is_press; } 189 MouseButtons button; 190 MouseButtons pressed; 191 KeyMods mods; 192 } 193 194 struct MouseMoveEvent 195 { 196 union { 197 Point p; 198 struct { float x,y; } 199 } 200 union { 201 Point winp; 202 struct { float winx,winy; } 203 } 204 MouseButtons pressed; 205 KeyMods mods; 206 } 207 208 struct MouseWheelEvent 209 { 210 union { 211 Point p; 212 struct { float x,y; } 213 } 214 union { 215 Point winp; 216 struct { float winx,winy; } 217 } 218 int delta; 219 MouseButtons pressed; 220 KeyMods mods; 221 } 222 223 struct WindowSizeEvent 224 { 225 WindowHandle id; 226 float width,height; 227 alias width w; 228 alias height h; 229 } 230 231 struct WindowCloseEvent 232 { 233 WindowHandle id; 234 } 235 236 // how do I do this??? 237 /// extern luigi.gui.Widget; 238 239 struct FocusEvent 240 { 241 Object previous; 242 } 243 244 245 alias int function(KeyEvent) KeyEventFn; 246 alias int function(MouseButtonEvent) MouseButtonEventFn; 247 alias int function(MouseMoveEvent) MouseMoveEventFn; 248 alias int function(MouseWheelEvent) MouseWheelEventFn; 249 alias int function(WindowSizeEvent) WindowSizeEventFn; 250 alias int function(WindowCloseEvent) WindowCloseEventFn; 251 252 alias int delegate(KeyEvent) KeyEventDg; 253 alias int delegate(MouseButtonEvent) MouseButtonEventDg; 254 alias int delegate(MouseMoveEvent) MouseMoveEventDg; 255 alias int delegate(MouseWheelEvent) MouseWheelEventDg; 256 alias int delegate(WindowSizeEvent) WindowSizeEventDg; 257 alias int delegate(WindowCloseEvent) WindowCloseEventDg; 258 259 alias Signal!(int, KeyEvent) KeyEventSignal; 260 alias Signal!(int, MouseButtonEvent) MouseButtonEventSignal; 261 alias Signal!(int, MouseMoveEvent) MouseMoveEventSignal; 262 alias Signal!(int, MouseWheelEvent) MouseWheelEventSignal; 263 alias Signal!(int, WindowSizeEvent) WindowSizeEventSignal; 264 alias Signal!(int, WindowCloseEvent) WindowCloseEventSignal; 32 import luigi.event; 265 33 266 34 trunk/luigi/adaptor/glfw.d
r6 r7 29 29 30 30 import luigi.base; 31 import luigi.event; 31 32 import luigi.adaptor.base; 32 33 import derelict.glfw.glfw; … … 80 81 case GLFW_KEY_BACKSPACE: return Key.Backspace; 81 82 case GLFW_KEY_INSERT: return Key.Insert; 82 case GLFW_KEY_DEL: return Key.Del ;83 case GLFW_KEY_DEL: return Key.Delete; 83 84 case GLFW_KEY_PAGEUP: return Key.PageUp; 84 85 case GLFW_KEY_PAGEDOWN: return Key.PageDown; … … 162 163 ev.is_press = (action==GLFW_PRESS); 163 164 ev.mods = inst._getMods(); 165 ev.is_key = true; 166 ev.is_char = false; 164 167 inst.emit.key(ev); 165 168 } … … 168 171 KeyEvent ev; 169 172 // In practice it seems that char callbacks always come _after_ 170 // key callbacks. And you only get one char for one key. This isn't 173 // key callbacks. (That's probably the case for any sane operating system). 174 // Also, you only get one char for one key. This isn't 171 175 // necessarily the case in general with fancy input methods 172 176 // (e.g. european and asian) but it seems to be the case with GLFW. 173 // Not every key has a char, but every char has a key .177 // Not every key has a char, but every char has a key in GLFW 174 178 ev.key = m_lastKey; 175 179 ev.ch = ch; 176 180 ev.is_press = (action==GLFW_PRESS); 177 181 ev.mods = inst._getMods(); 182 ev.is_key = false; 183 ev.is_char = true; 178 184 inst.emit.key(ev); 179 185 } trunk/luigi/arranger.d
r6 r7 6 6 items to support the Arrangeable interface. The Arrangeable 7 7 interface just provides information about an item's preferred, 8 minimum and maximum sizes.8 and minimum sizes. 9 9 10 10 Note in many toolkits "arranging" is referred to as "layout". … … 62 62 interface Arrangeable 63 63 { 64 // TODO: make size methods be **width_for_height and **height_for_width? 65 // In general, for something like a flow layout, given a width I can 66 // tell you how tall I want to be, but absent that I can't say much. 67 Size minimum_size(); 68 Size maximum_size(); 69 Size preferred_size(); 64 Size minimum_size(Size bounds); 65 Size preferred_size(Size bounds); 70 66 71 67 void set_rect(Rect s); … … 96 92 } 97 93 94 struct Gaps 95 { 96 float x=0,y=0; 97 bool standard=true; 98 99 static Gaps opCall(float xgap, float ygap) { 100 Gaps g; 101 g.standard = false; 102 g.x = xgap; 103 g.y = ygap; 104 return g; 105 } 106 107 static Gaps opCall(float gap) { 108 Gaps g; 109 g.standard = false; 110 g.x = g.y = gap; 111 return g; 112 } 113 114 static Gaps opCall() { 115 Gaps g; 116 g.standard = true; 117 g.x = g.y = 0; 118 return g; 119 } 120 } 121 122 typedef Gaps Pads; 123 98 124 99 125 //-------------------------------------------------------------------------- … … 106 132 void set_rect(Rect p); 107 133 108 Size minimum_size(); 109 Size preferred_size(); 110 Size maximum_size(); 134 Size minimum_size(Size bounds); 135 Size preferred_size(Size bounds); 111 136 112 137 void arrange(); 138 139 /// Return the natural order (tab order) of the item. 140 /// The item should be contained by the given arranger. 141 int orderof(Arrangeable item); 113 142 114 143 // ArrangeableIterator child_iterator(); … … 135 164 abstract override void arrange(); 136 165 137 abstract override Size minimum_size(); 138 abstract override Size preferred_size(); 139 140 Size maximum_size() 141 { 142 return Size(float.max, float.max); 143 } 166 abstract override Size minimum_size(Size bounds); 167 abstract override Size preferred_size(Size bounds); 168 169 abstract override int orderof(Arrangeable a); 170 144 171 bool auto_add() { return m_auto_add; } 145 172 bool auto_add(bool v) { return m_auto_add=v; } … … 167 194 this() 168 195 { 169 this(Alignment.Left|Alignment.Top, DEFAULT_GAP, DEFAULT_GAP);196 this(Alignment.Left|Alignment.Top, Gaps()); 170 197 } 171 198 172 199 this(Alignment align_) 173 200 { 174 this(align_, DEFAULT_GAP, DEFAULT_GAP);175 } 176 177 this(Alignment align_, float horz_gap, float vert_gap)201 this(align_, Gaps()); 202 } 203 204 this(Alignment align_, Gaps gaps_) 178 205 { 179 206 this.rect = Rect(0,0,0,0); 180 207 this.alignment = align_; 181 this.xgap = horz_gap; 182 this.ygap = vert_gap; 208 if (gaps_.standard) { 209 gaps_.x = DEFAULT_GAP; 210 gaps_.y = DEFAULT_GAP; 211 } 212 m_gaps = gaps_; 213 } 214 215 override int orderof(Arrangeable item) { 216 assert(item !is null); 217 int idx = m_items.find_item(item); 218 assert(idx != NOT_FOUND); 219 return idx; 183 220 } 184 221 … … 201 238 } 202 239 203 Size minimum_size( )240 Size minimum_size(Size bounds) 204 241 { 205 242 return Size(_max_item_width(), _max_item_height()); … … 211 248 foreach(Arrangeable item; m_items) 212 249 { 213 maxWidth = math.fmax(maxWidth, item.preferred_size .width);250 maxWidth = math.fmax(maxWidth, item.preferred_size(rect.size).width); 214 251 } 215 252 return maxWidth; … … 221 258 foreach(Arrangeable item ; m_items) 222 259 { 223 maxHeight = math.fmax(maxHeight, item.preferred_size .height);260 maxHeight = math.fmax(maxHeight, item.preferred_size(rect.size).height); 224 261 } 225 262 return maxHeight; 226 263 } 227 264 228 override Size preferred_size() 229 { 230 float height = 0; 231 float width = 0; 265 override Size preferred_size(Size bounds) 266 { 267 float htotal=0, height = 0; 268 float wtotal = 0, width = 0; 269 int rows = 0; 270 232 271 foreach(Arrangeable c; m_items) 233 272 { 234 Size s = c.preferred_size(); 235 width += s.width; 236 height = math.fmax(height, s.height); 273 Size s = c.preferred_size(bounds); 274 width += s.width + xgap; 275 height = max(height, s.height); 276 if (width>bounds.width) { 277 wtotal = max(wtotal, width-xgap); 278 width = 0; 279 htotal += height + ygap; 280 rows++; 281 } 237 282 } 238 width += (m_items.length + 1)*xgap;239 height += 2*ygap;240 return Size(w idth, height);283 htotal += height; 284 wtotal = max(wtotal,width-xgap); 285 return Size(wtotal, htotal); 241 286 } 242 287 … … 248 293 foreach(Arrangeable c ; m_items) 249 294 { 250 Size s = c.preferred_size( );295 Size s = c.preferred_size(rect.size); 251 296 currentWidth += s.width + xgap; 252 297 if(currentWidth > rect.width) … … 288 333 foreach(FlowRow r; rows) 289 334 { 290 r.position = Point( rect.x,y);335 r.position = Point(0, y-rect.y); 291 336 r.arrange(); 292 337 y += r.size.height + ygap; … … 297 342 { 298 343 float x = rect.x2 - r.size.width; 299 r.position = Point(x ,y);344 r.position = Point(x-rect.x, y-rect.y); 300 345 r.arrange(); 301 346 y += r.size.height + ygap; … … 308 353 { 309 354 float x = rect.x + (rect.width - r.size.width)/2; 310 r.position = Point(x ,y);355 r.position = Point(x-rect.x, y-rect.y); 311 356 r.arrange(); 312 357 y += r.size.height + ygap; … … 321 366 322 367 323 float xgap() { return m_ xgap; }324 float xgap(float v) { m_ xgap = v; return m_xgap; }325 float ygap() { return m_ ygap; }326 float ygap(float v) { m_ ygap = v; return m_ygap; }368 float xgap() { return m_gaps.x; } 369 float xgap(float v) { m_gaps.x = v; return m_gaps.x; } 370 float ygap() { return m_gaps.y; } 371 float ygap(float v) { m_gaps.y = v; return m_gaps.y; } 327 372 328 373 Alignment alignment() { return m_alignment; } … … 334 379 Arrangeable[] m_items; 335 380 Alignment m_alignment; 336 float m_xgap; 337 float m_ygap; 338 381 Gaps m_gaps; 339 382 } 340 383 … … 366 409 { 367 410 _recalc(); 368 float x = rect.x; 369 float y = rect.y + (rect.height / 2); 411 float x0 = rect.x; 412 float y0 = rect.y; 413 float x = x0; 414 float y = y0 + (rect.height / 2); 370 415 foreach(Arrangeable item ; m_items) 371 416 { 372 Size s = item.preferred_size( );417 Size s = item.preferred_size(rect.size); 373 418 item.set_rect(Rect(x, y-(s.height/2), s.width, s.height)); 374 419 x += s.width + xgap; … … 382 427 foreach(Arrangeable item ; m_items) 383 428 { 384 Size s = item.preferred_size( );429 Size s = item.preferred_size(rect.size); 385 430 width += s.width; 386 431 } … … 395 440 foreach(Arrangeable item ; m_items) 396 441 { 397 maxHeight = math.fmax(maxHeight, item.preferred_size( ).height);442 maxHeight = math.fmax(maxHeight, item.preferred_size(rect.size).height); 398 443 } 399 444 return maxHeight; … … 439 484 this() 440 485 { 441 this(1, 0, 0, 0);486 this(1, 0, Gaps()); 442 487 } 443 488 444 489 this(int Columns, int Rows = 0) 445 490 { 446 this(Columns, Rows, 0, 0);447 } 448 449 this(int Columns, int Rows, float Xgap, float Ygap)491 this(Columns, Rows, Gaps()); 492 } 493 494 this(int Columns, int Rows, Gaps gaps_) 450 495 { 451 496 super(); 497 this.columns = Columns; 452 498 this.rows = Rows; 453 this.columns = Columns; 454 this.xgap = Xgap; 455 this.ygap = Ygap; 456 } 457 458 override Size preferred_size() { 459 writefln("calc Preferred"); 460 return _calc_size( (Arrangeable item){ return item.preferred_size(); } ); 461 } 462 463 override Size minimum_size() { 464 writefln("calc minimum"); 465 return _calc_size( (Arrangeable item){ return item.minimum_size(); } ); 466 } 467 499 if (gaps_.standard) { 500 gaps_.x = 0; 501 gaps_.y = 0; 502 } 503 this.m_gaps = gaps_; 504 } 505 506 override int orderof(Arrangeable item) { 507 assert(item !is null); 508 int idx = m_items.find_item(item); 509 assert(idx != NOT_FOUND); 510 return idx; 511 } 512 513 override Size preferred_size(Size bounds) { 514 float[] widths, heights; 515 return _calc_size( 516 widths,heights, 517 (Arrangeable item){ return item.preferred_size(bounds); } ); 518 } 519 520 override Size minimum_size(Size bounds) { 521 float[] widths, heights; 522 return _calc_size( 523 widths, heights, 524 (Arrangeable item){ return item.minimum_size(bounds); } ); 525 } 468 526 469 527 override void arrange() 470 528 { 471 GridSize grid = _calc_grid(); 472 473 float width = rect.width; 474 float height = rect.height; 475 476 width = (width - (grid.cols - 1) * xgap) / grid.cols; 477 height = (height - (grid.rows - 1) * ygap) / grid.rows; 478 529 if (m_items.length == 0) return; 530 531 float[] widths, heights; 532 GridCells grid = _update_cell_widths( 533 widths,heights, 534 (Arrangeable i){ return i.preferred_size(rect.size); }); 535 536 537 float x0 = rect.x; 538 float y0 = rect.y; 479 539 float x,y; 480 540 int c,r; 481 for(c = 0, x = rect.x; c < grid.cols; c++, x += width + xgap) 541 542 for(c = 0, x = x0; c < grid.cols; x += widths[c] + xgap, c++) 482 543 { 483 for(r = 0, y = rect.y; r < grid.rows; r++, y += height + ygap)544 for(r = 0, y = y0; r < grid.rows; y += heights[r] + ygap, r++) 484 545 { 485 546 int i = r * grid.cols + c; … … 487 548 { 488 549 Arrangeable item = m_items[i]; 489 item.set_rect(Rect(x , y, width, height));550 item.set_rect(Rect(x-x0, y-y0, widths[c], heights[r])); 490 551 item.arrange(); 491 552 } … … 512 573 } 513 574 514 float xgap() { return m_ xgap; }515 float xgap(float x) { return m_xgap =x; }516 517 float ygap( ) { return m_ygap; }518 float ygap(float y) { return m_ygap = y; } 575 float xgap() { return m_gaps.x; } 576 float xgap(float v) { m_gaps.x = v; return m_gaps.x; } 577 float ygap() { return m_gaps.y; } 578 float ygap(float v) { m_gaps.y = v; return m_gaps.y; } 579 519 580 520 581 int rows() { return m_rows; } … … 524 585 int columns(int v) { return m_cols = v; } 525 586 526 private struct GridSize { 527 static GridSize opCall(int r, int c) { GridSize g; g.rows = r; g.cols = c; return g; } 587 private struct GridCells { 588 static GridCells opCall(int c, int r) 589 { GridCells g; g.rows = r; g.cols = c; return g; } 528 590 int cols=0; 529 591 int rows=0; 530 592 } 531 593 532 private Grid Size_calc_grid()594 private GridCells _calc_grid() 533 595 { 534 596 int newRows = rows; 535 597 int newCols = columns; 536 int components = m_items.length;598 int nItems = m_items.length; 537 599 if(newRows > 0) 538 600 { 539 newCols = ( components + newRows - 1)/newRows;601 newCols = (nItems + newRows - 1)/newRows; 540 602 } 541 603 else 542 604 { 543 newRows = (components + newCols - 1)/newCols; 544 } 545 return GridSize(newRows, newCols); 546 } 547 548 private Size _calc_size(Size delegate(Arrangeable i) size_getter) 549 { 550 GridSize grid = _calc_grid(); 551 float[] widths; widths.length = grid.cols; 552 float[] heights; heights.length = grid.rows; 605 newRows = (nItems + newCols - 1)/newCols; 606 } 607 return GridCells(newCols, newRows); 608 } 609 610 private GridCells _update_cell_widths( 611 inout float[] widths, inout float[] heights, Size delegate(Arrangeable i)size_getter 612 ) 613 { 614 GridCells grid = _calc_grid(); 615 widths.length = grid.cols; 616 heights.length = grid.rows; 553 617 554 618 widths[] = 0; 555 619 heights[] = 0; 556 620 557 int c,r; 558 foreach(inout w; widths) { 559 foreach(inout h; heights) { 621 foreach(c, inout w; widths) { 622 foreach(r, inout h; heights) { 560 623 int i = r * grid.cols + c; 561 624 if(i < m_items.length) … … 567 630 } 568 631 } 632 return grid; 633 } 634 635 private Size _calc_size(float[] widths, float[]heights, 636 Size delegate(Arrangeable i) size_getter) 637 { 638 GridCells grid = _update_cell_widths(widths,heights,size_getter); 569 639 570 640 float width = 0; … … 575 645 return Size(width + xgap * (grid.cols - 1), 576 646 height + ygap * (grid.rows - 1)); 577 578 647 } 579 648 … … 581 650 private: 582 651 Arrangeable[] m_items; 583 int m_rows; 584 int m_cols; 585 float m_xgap; 586 float m_ygap; 652 int m_cols,m_rows; 653 Gaps m_gaps; 587 654 } 588 655 … … 608 675 this() 609 676 { 610 this(0, 0); 611 } 612 613 this(float Xgap, float Ygap) 614 { 615 this.xgap = Xgap; 616 this.ygap = Ygap; 677 this(Gaps()); 678 } 679 680 this(Gaps gap_) 681 { 682 if (gap_.standard) { 683 gap_.x = gap_.y = 0; 684 } 685 m_gaps = gap_; 617 686 auto_add = false; 618 687 } 619 688 620 override Size minimum_size() 689 override int orderof(Arrangeable item) { 690 assert(item !is null); 691 if (item==m_north) { return 0; } 692 if (item==m_west) { return 1; } 693 if (item==m_center) { return 2; } 694 if (item==m_east) { return 3; } 695 if (item==m_south) { return 4; } 696 697 assert(0, "Item is not contained in this Arranger."); 698 return 0; 699 } 700 701 702 override Size minimum_size(Size bounds) 621 703 { 622 704 float width = 0; 623 705 float height = 0; 624 706 if(m_north != null){ 625 Size s = m_north.minimum_size( );707 Size s = m_north.minimum_size(bounds); 626 708 width = math.fmax(width, s.width); 627 709 height += s.height + ygap; 628 710 } 629 711 if(m_south != null){ 630 Size s = m_south.minimum_size( );712 Size s = m_south.minimum_size(bounds); 631 713 width = math.fmax(width, s.width); 632 714 height += s.height + ygap; 633 715 } 634 716 if(m_center != null){ 635 Size s = m_center.minimum_size( );717 Size s = m_center.minimum_size(bounds); 636 718 height = math.fmax(height, s.height); 637 719 width += s.width; 638 720 } 639 721 if(m_east != null){ 640 Size s = m_east.minimum_size( );722 Size s = m_east.minimum_size(bounds); 641 723 width += s.width; 642 724 height = math.fmax(height, s.height); 643 725 } 644 726 if(m_west != null){ 645 Size s = m_west.minimum_size( );727 Size s = m_west.minimum_size(bounds); 646 728 width += s.width; 647 729 height = math.fmax(height, s.height); … … 650 732 } 651 733 652 override Size preferred_size( )734 override Size preferred_size(Size bounds) 653 735 { 654 736 float width = 0; 655 737 float height = 0; 656 738 if(m_north != null){ 657 Size s = m_north.preferred_size( );739 Size s = m_north.preferred_size(bounds); 658 740 width = math.fmax(width, s.width); 659 741 height += s.height + ygap; 660 742 } 661 743 if(m_south != null){ 662 Size s = m_south.preferred_size( );744 Size s = m_south.preferred_size(bounds); 663 745 width = math.fmax(width, s.width); 664 746 height += s.height + ygap; 665 747 } 666 748 if(m_center != null){ 667 Size s = m_center.preferred_size( );749 Size s = m_center.preferred_size(bounds); 668 750 height = math.fmax(height, s.height); 669 751 width += s.width; 670 752 } 671 753 if(m_east != null){ 672 Size s = m_east.preferred_size( );754 Size s = m_east.preferred_size(bounds); 673 755 width += s.width; 674 756 height = math.fmax(height, s.height); 675 757 } 676 758 if(m_west != null){ 677 Size s = m_west.preferred_size( );759 Size s = m_west.preferred_size(bounds); 678 760 width += s.width; 679 761 height = math.fmax(height, s.height); … … 690 772 691 773 if (m_north != null) { 692 Size s = m_north.preferred_size( );774 Size s = m_north.preferred_size(rect.size); 693 775 m_north.set_rect(Rect(left, top, right-left, s.height)); 694 776 top += s.height + ygap; … … 696 778 } 697 779 if(m_south != null){ 698 Size s = m_south.preferred_size( );780 Size s = m_south.preferred_size(rect.size); 699 781 bottom -= s.height; 700 782 m_south.set_rect(Rect(left, bottom, right-left, s.height)); … … 703 785 } 704 786 if(m_west != null){ 705 Size s = m_west.preferred_size( );787 Size s = m_west.preferred_size(rect.size); 706 788 m_west.set_rect(Rect(left, top, s.width, bottom - top)); 707 789 left += s.width + xgap; … … 709 791 } 710 792 if(m_east != null){ 711 Size s = m_east.preferred_size( );793 Size s = m_east.preferred_size(rect.size); 712 794 right -= s.width; 713 795 m_east.set_rect(Rect(right, top, s.width, bottom - top)); … … 809 891 } 810 892 811 float xgap() { return m_xgap; } 812 float xgap(float x) { return m_xgap = x; } 813 814 float ygap() { return m_ygap; } 815 float ygap(float y) { return m_ygap = y; } 893 float xgap() { return m_gaps.x; } 894 float xgap(float v) { m_gaps.x = v; return m_gaps.x; } 895 float ygap() { return m_gaps.y; } 896 float ygap(float v) { m_gaps.y = v; return m_gaps.y; } 816 897 817 898 private: … … 822 903 Arrangeable m_center; 823 904 824 float m_xgap; 825 float m_ygap; 905 Gaps m_gaps; 826 906 } trunk/luigi/base.d
r6 r7 48 48 { 49 49 // This layout lets you use rect either like 50 // (r.x, r.y, r.w , r.h) // primary50 // (r.x, r.y, r.width, r.height) // primary 51 51 // or like 52 52 // (r.x1, r.y1, r.x2, r.y2) // also allowed with restrictions 53 // or like 54 // (r.pos, r.size); 53 55 union { 54 struct { float x = 0,y = 0; } 55 struct { float x1, y1; } 56 } 57 float width=0 ,height=0; 58 56 struct { float x,y; } 57 Point pos; 58 } 59 union { 60 struct { float width ,height; } 61 Size size; 62 } 63 64 alias x x1; 65 alias y y1; 59 66 alias width w; 60 67 alias height h; … … 112 119 Size s; s.width = _w; s.height = _h; return s; 113 120 } 121 122 void opAddAssign(Size o) { w+=o.w; h+=o.h; } 123 void opSubAssign(Size o) { w-=o.w; h-=o.h; } 114 124 115 125 char[] toString() { … … 282 292 } 283 293 294 // Remove a range of elements from an array in place. 295 // It is not an error for the range to be empty or for start to be greater than end. 296 // If so, the array is not modified. 297 // Out of bounds checks performed only in debug mode. 298 // Returns: the array, which (is modified in-place). 299 // Note: This is an O(n) operation. 300 template drop_range(T) 301 { 302 T[] drop_range( inout T[] arr, int start, int end ) 303 { 304 debug if ( start>=arr.length || end > arr.length || start<0 || end<0) 305 throw new Exception(string.format("Attempt to drop range %s,%s from size %s",start,end,arr.length)); 306 if (start>=end) return arr; 307 size_t len = end-start; 308 size_t max = arr.length-len; 309 for (; start < max; start++ ) arr[start]=arr[start+len]; 310 arr.length= max; 311 return arr; 312 } 313 } 314 284 315 /*********************************************************************************** 285 316 * Lookup the index of the first element of an array that satisfies a delegate. trunk/luigi/example1.d
r6 r7 27 27 */ 28 28 import luigui = luigi.gui; 29 import luigi.adaptor.glfw; 29 30 30 31 import derelict.glfw.glfw; … … 56 57 57 58 59 // doesn't work .. ICE if you try to use this 60 class CoolTarget(T...) 61 { 62 this( void delegate(T...) dg) { fn = dg; } 63 void slot(T args) { 64 fn(args); 65 } 66 void delegate(T...) fn; 67 } 68 class BDelegate 69 { 70 alias void delegate(luigui.Widget, bool) func_t; 71 this(func_t dg) { fn = dg; } 72 void slot(luigui.Widget w, bool b) { 73 fn(w,b); 74 } 75 func_t fn; 76 } 77 class VDelegate 78 { 79 alias void delegate(luigui.Widget) func_t; 80 this(func_t dg) { fn = dg; } 81 void slot(luigui.Widget w) { 82 fn(w); 83 } 84 func_t fn; 85 } 86 58 87 void main(char[][] argv) 59 88 { … … 82 111 83 112 //---------------- CREATE GUI ---------------------- 113 84 114 luigui.Overlay gui; 85 115 with(luigui) { 116 Luigi().adaptor = GLFWAdaptor(); 117 StdTheme theme = cast(StdTheme)Luigi().theme; 86 118 gui = new Overlay; 87 119 … … 89 121 //gui.arranger = new GridArranger(2,2); 90 122 //BorderArranger layout = new BorderArranger(5,5); 91 gui.arranger = new BorderArranger( 5,5);123 gui.arranger = new BorderArranger(Gaps(5)); 92 124 93 125 alias BorderArranger.Region Region; 94 126 alias Alignment A; 95 127 96 Panel northGroup = arranger_add(new FlowPanel(gui), Region.North); 97 98 Button b10 = arranger_add(new Button(northGroup, "File")); 99 Button b11 = arranger_add(new Button(northGroup, "Edit")); 100 Button b12 = arranger_add(new Button(northGroup, "View")); 101 Button b13 = arranger_add(new Button(northGroup, "Favorites")); 102 Button b14 = arranger_add(new Button(northGroup, "Tools")); 103 Button b15 = arranger_add(new Button(northGroup, "Options")); 104 Button b16 = arranger_add(new Button(northGroup, "Help")); 105 106 Panel westGroup = arranger_add(new GridPanel(gui,2), Region.West); 107 Button b20 = arranger_add(new Button(westGroup, "Tool0")); 108 Button b21 = arranger_add(new Button(westGroup, "Tool1")); 109 Button b22 = arranger_add(new Button(westGroup, "Tool2")); 110 Button b23 = arranger_add(new Button(westGroup, "Tool3")); 111 Button b24 = arranger_add(new Button(westGroup, "Tool4")); 112 Button b25 = arranger_add(new Button(westGroup, "Tool5")); 113 Button b26 = arranger_add(new Button(westGroup, "Tool6")); 114 Button b27 = arranger_add(new Button(westGroup, "Tool7")); 115 Button b28 = arranger_add(new Button(westGroup, "Tool8")); 116 Button b29 = arranger_add(new Button(westGroup, "Tool9")); 117 118 119 Button b3 = arranger_add(new Button(gui, "Mate!"), Region.East); 120 Button b4 = arranger_add(new Button(gui, "How do you do?"), Region.South); 121 122 b4.clicked.connect( (Widget w){ writefln("ouch!"); } ); 128 Panel eastGroup = gui.add_widget(new GridPanel(1,0, Gaps(2))); 129 gui.arranger.add(eastGroup, Region.East); 130 with(eastGroup) { 131 &n
