1 /* 2 * Copyright (C) 2015-2017, by Laszlo Szeremi under the Boost license. 3 * 4 * Pixel Perfect Engine, concrete.elements module 5 */ 6 7 module PixelPerfectEngine.concrete.elements; 8 9 import PixelPerfectEngine.graphics.bitmap; 10 import PixelPerfectEngine.graphics.draw; 11 import PixelPerfectEngine.system.etc; 12 import PixelPerfectEngine.system.inputHandler; 13 import std.algorithm; 14 import std.stdio; 15 import std.conv; 16 import PixelPerfectEngine.concrete.stylesheet; 17 18 abstract class WindowElement{ 19 //public ActionListener[] al; 20 protected wstring text; 21 protected string source; 22 public Coordinate position; 23 //private int sizeX, sizeY; 24 //public int font; 25 public BitmapDrawer output; 26 //public Bitmap16Bit[int] altStyleBrush; 27 public ElementContainer elementContainer; 28 public StyleSheet customStyle; 29 protected bool state; 30 31 public static InputHandler inputHandler; 32 public static PopUpHandler popUpHandler; 33 public static StyleSheet styleSheet; 34 35 public static void delegate() onDraw; 36 37 public void delegate(Event ev) onMouseLClickRel; 38 public void delegate(Event ev) onMouseRClickRel; 39 public void delegate(Event ev) onMouseMClickRel; 40 public void delegate(Event ev) onMouseHover; 41 public void delegate(Event ev) onMouseMove; 42 public void delegate(Event ev) onMouseLClickPre; 43 public void delegate(Event ev) onMouseRClickPre; 44 public void delegate(Event ev) onMouseMClickPre; 45 46 public void onClick(int offsetX, int offsetY, int state, ubyte button){ 47 48 } 49 public void onDrag(int x, int y, int relX, int relY, ubyte button){ 50 51 } 52 public void onKey(char c, int type){ 53 54 } 55 public void onScroll(int x, int y, int wX, int wY){ 56 57 } 58 @nogc public int getX(){ 59 return position.width; 60 } 61 @nogc public int getY(){ 62 return position.height; 63 } 64 @nogc public Coordinate getPosition(){ 65 return position; 66 } 67 /** 68 * Updates the output. 69 */ 70 public abstract void draw(); 71 72 /+protected void invokeActionEvent(int type, int value, wstring message = ""){ 73 foreach(ActionListener a; al){ 74 if(a) 75 a.actionEvent(new Event(source, null, null, null, text, value, type)); 76 } 77 } 78 79 protected void invokeActionEvent(Event e) { 80 foreach(ActionListener a; al){ 81 if(a) 82 a.actionEvent(e); 83 } 84 }+/ 85 /*private Bitmap16Bit getBrush(int style){ 86 return altStyleBrush.get(style, elementContainer.getStyleBrush(style)); 87 }*/ 88 public @nogc wstring getText(){ 89 return text; 90 } 91 public void setText(wstring s){ 92 text = s; 93 draw(); 94 95 } 96 97 public StyleSheet getAvailableStyleSheet(){ 98 if(customStyle !is null){ 99 return customStyle; 100 } 101 return elementContainer.getStyleSheet(); 102 } 103 104 public void setCustomStyle(StyleSheet s){ 105 customStyle = s; 106 } 107 /** 108 * Enables (b = true) or disables (b = false) the element. All element is enabled by default. 109 */ 110 @nogc public void setState(bool b){ 111 state = !b; 112 } 113 /** 114 * Gets the state of the element. 115 */ 116 @nogc public bool getState(){ 117 return !state; 118 } 119 } 120 121 public class Button : WindowElement{ 122 private bool isPressed; 123 public bool enableRightButtonClick; 124 public bool enableMiddleButtonClick; 125 public this(wstring text, string source, Coordinate coordinates){ 126 position = coordinates; 127 //sizeX = coordinates.width(); 128 //sizeY = coordinates.height(); 129 this.text = text; 130 this.source = source; 131 output = new BitmapDrawer(coordinates.width, coordinates.height); 132 //brushPressed = 1; 133 //draw(); 134 } 135 public override void draw(){ 136 if(output.output.width != position.width || output.output.height != position.height) 137 output = new BitmapDrawer(position.width(), position.height()); 138 if(isPressed){ 139 output.drawLine(0, position.width()-1, 0, 0, getAvailableStyleSheet().getColor("windowdescent")); 140 output.drawLine(0, 0, 0, position.height()-1, getAvailableStyleSheet().getColor("windowdescent")); 141 output.drawLine(0, position.width()-1, position.height()-1, position.height()-1, getAvailableStyleSheet().getColor("windowascent")); 142 output.drawLine(position.width()-1, position.width()-1, 0, position.height()-1, getAvailableStyleSheet().getColor("windowascent")); 143 output.drawFilledRectangle(1, position.width()-1, 1,position.height()-1, getAvailableStyleSheet().getColor("windowinactive")); 144 }else{ 145 output.drawLine(0, position.width()-1, 0, 0, getAvailableStyleSheet().getColor("windowascent")); 146 output.drawLine(0, 0, 0, position.height()-1, getAvailableStyleSheet().getColor("windowascent")); 147 output.drawLine(0, position.width()-1, position.height()-1, position.height()-1, getAvailableStyleSheet().getColor("windowdescent")); 148 output.drawLine(position.width()-1, position.width()-1, 0, position.height()-1, getAvailableStyleSheet().getColor("windowdescent")); 149 output.drawFilledRectangle(1, position.width()-1, 1,position.height()-1, getAvailableStyleSheet().getColor("window")); 150 } 151 152 output.drawText(position.width/2, position.height/2, text, getAvailableStyleSheet().getFontset("default")); 153 elementContainer.drawUpdate(this); 154 if(onDraw !is null){ 155 onDraw(); 156 } 157 } 158 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 159 if(button == MouseButton.RIGHT && enableRightButtonClick){ 160 if(state == ButtonState.PRESSED){ 161 isPressed = true; 162 draw(); 163 //invokeActionEvent(EventType.CLICK, -1); 164 if(onMouseRClickPre !is null){ 165 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 166 } 167 }else{ 168 isPressed = false; 169 draw(); 170 //invokeActionEvent(EventType.CLICK, 0); 171 if(onMouseRClickRel !is null){ 172 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 173 } 174 } 175 }else if(button == MouseButton.MID && enableMiddleButtonClick){ 176 if(state == ButtonState.PRESSED){ 177 isPressed = true; 178 draw(); 179 //invokeActionEvent(EventType.CLICK, -1); 180 if(onMouseMClickPre !is null){ 181 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 182 } 183 }else{ 184 isPressed = false; 185 draw(); 186 //invokeActionEvent(EventType.CLICK, 0); 187 if(onMouseMClickRel !is null){ 188 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 189 } 190 } 191 }else{ 192 if(state == ButtonState.PRESSED){ 193 isPressed = true; 194 draw(); 195 //invokeActionEvent(EventType.CLICK, -1); 196 if(onMouseLClickPre !is null){ 197 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 198 } 199 }else{ 200 isPressed = false; 201 draw(); 202 //invokeActionEvent(EventType.CLICK, 0); 203 if(onMouseLClickRel !is null){ 204 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 205 } 206 } 207 } 208 209 } 210 } 211 212 public class SmallButton : WindowElement{ 213 private string iconPressed, iconUnpressed; 214 private bool isPressed; 215 public bool enableRightButtonClick; 216 public bool enableMiddleButtonClick; 217 public int brushPressed, brushNormal; 218 219 public this(string iconPressed, string iconUnpressed, string source, Coordinate coordinates){ 220 position = coordinates; 221 222 //this.text = text; 223 this.source = source; 224 this.iconPressed = iconPressed; 225 this.iconUnpressed = iconUnpressed; 226 output = new BitmapDrawer(coordinates.width, coordinates.height); 227 brushPressed = 1; 228 //draw(); 229 } 230 public override void draw(){ 231 output.drawFilledRectangle(0, position.width()-1, 0,position.height()-1, 0); 232 if(isPressed){ 233 output.insertBitmap(0,0,getAvailableStyleSheet().getImage(iconPressed)); 234 }else{ 235 output.insertBitmap(0,0,getAvailableStyleSheet().getImage(iconUnpressed)); 236 } 237 elementContainer.drawUpdate(this); 238 if(onDraw !is null){ 239 onDraw(); 240 } 241 } 242 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 243 if(button == MouseButton.RIGHT && enableRightButtonClick){ 244 if(state == ButtonState.PRESSED){ 245 isPressed = true; 246 draw(); 247 //invokeActionEvent(EventType.CLICK, -1); 248 if(onMouseRClickPre !is null){ 249 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 250 } 251 }else{ 252 isPressed = false; 253 draw(); 254 //invokeActionEvent(EventType.CLICK, 0); 255 if(onMouseRClickRel !is null){ 256 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 257 } 258 } 259 }else if(button == MouseButton.MID && enableMiddleButtonClick){ 260 if(state == ButtonState.PRESSED){ 261 isPressed = true; 262 draw(); 263 //invokeActionEvent(EventType.CLICK, -1); 264 if(onMouseMClickPre !is null){ 265 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 266 } 267 }else{ 268 isPressed = false; 269 draw(); 270 //invokeActionEvent(EventType.CLICK, 0); 271 if(onMouseMClickRel !is null){ 272 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 273 } 274 } 275 }else{ 276 if(state == ButtonState.PRESSED){ 277 isPressed = true; 278 draw(); 279 //invokeActionEvent(EventType.CLICK, -1); 280 if(onMouseLClickPre !is null){ 281 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 282 } 283 }else{ 284 isPressed = false; 285 draw(); 286 //invokeActionEvent(EventType.CLICK, 0); 287 if(onMouseLClickRel !is null){ 288 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 289 } 290 } 291 } 292 293 } 294 } 295 296 public class Label : WindowElement{ 297 public this(wstring text, string source, Coordinate coordinates){ 298 position = coordinates; 299 this.text = text; 300 this.source = source; 301 output = new BitmapDrawer(coordinates.width, coordinates.height); 302 //draw(); 303 } 304 public override void draw(){ 305 //writeln(elementContainer); 306 if(output.output.width != position.width || output.output.height != position.height) 307 output = new BitmapDrawer(position.width, position.height); 308 output.drawText(0, 0, text, getAvailableStyleSheet().getFontset("default"), 1); 309 elementContainer.drawUpdate(this); 310 if(onDraw !is null){ 311 onDraw(); 312 } 313 } 314 /*public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 315 if(state == ButtonState.PRESSED) 316 invokeActionEvent(EventType.CLICK, 0); 317 }*/ 318 public override void setText(wstring s) { 319 output.destroy(); 320 output = new BitmapDrawer(position.width, position.height); 321 super.setText(s); 322 } 323 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 324 if(button == MouseButton.RIGHT){ 325 if(state == ButtonState.PRESSED){ 326 if(onMouseRClickPre !is null){ 327 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 328 } 329 }else{ 330 if(onMouseRClickRel !is null){ 331 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 332 } 333 } 334 }else if(button == MouseButton.MID){ 335 if(state == ButtonState.PRESSED){ 336 if(onMouseMClickPre !is null){ 337 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 338 } 339 }else{ 340 if(onMouseMClickRel !is null){ 341 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 342 } 343 } 344 }else{ 345 if(state == ButtonState.PRESSED){ 346 if(onMouseLClickPre !is null){ 347 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 348 } 349 }else{ 350 if(onMouseLClickRel !is null){ 351 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 352 } 353 } 354 } 355 356 } 357 } 358 359 public class TextBox : WindowElement, TextInputListener{ 360 private bool enableEdit, insert; 361 private uint pos; 362 public int brush, textpos; 363 //public TextInputHandler tih; 364 public void delegate(Event ev) onTextInput; 365 366 public this(wstring text, string source, Coordinate coordinates){ 367 position = coordinates; 368 this.text = text; 369 this.source = source; 370 output = new BitmapDrawer(coordinates.width, coordinates.height); 371 //inputHandler.addTextInputListener(source, this); 372 //insert = true; 373 //draw(); 374 } 375 376 ~this(){ 377 //inputHandler.removeTextInputListener(source); 378 } 379 public deprecated void addTextInputHandler(TextInputHandler t){ /** DEPRECATED. Will be removed soon in favor of static input handlers. */ 380 /*tih = t;*/ 381 //inputHandler.addTextInputListener(source, this); 382 } 383 384 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 385 if(button == MouseButton.RIGHT){ 386 if(state == ButtonState.PRESSED){ 387 if(onMouseRClickPre !is null){ 388 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 389 } 390 }else{ 391 if(onMouseRClickRel !is null){ 392 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 393 } 394 } 395 }else if(button == MouseButton.MID){ 396 if(state == ButtonState.PRESSED){ 397 if(onMouseMClickPre !is null){ 398 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 399 } 400 }else{ 401 if(onMouseMClickRel !is null){ 402 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 403 } 404 } 405 }else{ 406 if(state == ButtonState.PRESSED){ 407 if(onMouseLClickPre !is null){ 408 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 409 } 410 }else{ 411 if(onMouseLClickRel !is null){ 412 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 413 } 414 } 415 } 416 if(!enableEdit && state == ButtonState.PRESSED && button == MouseButton.LEFT){ 417 //invokeActionEvent(EventType.READYFORTEXTINPUT, 0); 418 enableEdit = true; 419 inputHandler.startTextInput(this); 420 draw(); 421 } 422 } 423 public override void draw(){ 424 if(output.output.width != position.width || output.output.height != position.height) 425 output = new BitmapDrawer(position.width, position.height); 426 output.drawFilledRectangle(0, position.width - 1, 0, position.height - 1, getAvailableStyleSheet().getColor("window")); 427 output.drawRectangle(0, position.width - 1, 0, position.height - 1, getAvailableStyleSheet().getColor("windowascent")); 428 429 //draw cursor 430 if(enableEdit){ 431 int x = getAvailableStyleSheet().getFontset("default").letters['A'].width , y = getAvailableStyleSheet().getFontset("default").letters['A'].height; 432 if(!insert) 433 output.drawLine((x*pos) + 2, (x*pos) + 2, 2, 2 + y, getAvailableStyleSheet().getColor("selection")); 434 else 435 output.drawFilledRectangle((x*pos) + 2, (x*(pos + 1)) + 2, 2, 2 + y, getAvailableStyleSheet().getColor("selection")); 436 } 437 438 output.drawText(2, 2, text, getAvailableStyleSheet().getFontset("default"), 1); 439 elementContainer.drawUpdate(this); 440 if(onDraw !is null){ 441 onDraw(); 442 } 443 } 444 445 alias onKey = WindowElement.onKey; 446 public void onKey(wchar c, int type){ 447 448 /*if(enableEdit){ 449 if(type == 0){ 450 text ~= c; 451 pos++; 452 draw(); 453 }else if(type == 1){ 454 pos++; 455 }else if(type == 2){ 456 pos--; 457 }else if(type == 3){ 458 invokeActionEvent(EventType.TEXTINPUT, 0, text); 459 }else{ 460 deleteCharacter(pos); 461 pos--; 462 draw(); 463 } 464 }*/ 465 } 466 private void deleteCharacter(int n){ 467 //text = remove(text, i); 468 wstring newtext; 469 for(int i; i < text.length; i++){ 470 if(i != n - 1){ 471 newtext ~= text[i]; 472 } 473 } 474 text = newtext; 475 } 476 public void textInputEvent(uint timestamp, uint windowID, char[32] text){ 477 //writeln(0); 478 int j = pos; 479 wstring newtext; 480 for(int i ; i < pos ; i++){ 481 newtext ~= this.text[i]; 482 } 483 for(int i ; i < 32 ; i++){ 484 if(text[i] == 0){ 485 break; 486 } 487 else{ 488 newtext ~= text[i]; 489 pos++; 490 if(insert){ 491 j++; 492 } 493 } 494 } 495 for( ; j < this.text.length ; j++){ 496 newtext ~= this.text[j]; 497 } 498 this.text = newtext; 499 draw(); 500 } 501 502 public void dropTextInput(){ 503 enableEdit = false; 504 //inputHandler.stopTextInput(source); 505 draw(); 506 //invokeActionEvent(EventType.TEXTINPUT, 0, text); 507 if(onTextInput !is null) 508 onTextInput(new Event(source, null, null, null, text, 0, EventType.TEXTINPUT)); 509 } 510 511 512 public void textInputKeyEvent(uint timestamp, uint windowID, TextInputKey key, ushort modifier = 0){ 513 if(key == TextInputKey.ESCAPE || key == TextInputKey.ENTER){ 514 enableEdit = false; 515 inputHandler.stopTextInput(this); 516 draw(); 517 //invokeActionEvent(EventType.TEXTINPUT, 0, text); 518 if(onTextInput !is null){ 519 onTextInput(new Event(source, null, null, null, text, 0, EventType.TEXTINPUT)); 520 } 521 }else if(key == TextInputKey.BACKSPACE){ 522 if(pos > 0){ 523 deleteCharacter(pos); 524 pos--; 525 draw(); 526 } 527 /*if(pos > 0){ 528 if(pos == text.length){ 529 text.length--; 530 pos--; 531 532 } 533 }*/ 534 }else if(key == TextInputKey.DELETE){ 535 deleteCharacter(pos + 1); 536 draw(); 537 }else if(key == TextInputKey.CURSORLEFT){ 538 if(pos > 0){ 539 --pos; 540 draw(); 541 } 542 }else if(key == TextInputKey.CURSORRIGHT){ 543 if(pos < text.length){ 544 ++pos; 545 draw(); 546 } 547 }else if(key == TextInputKey.INSERT){ 548 insert = !insert; 549 draw(); 550 }else if(key == TextInputKey.HOME){ 551 pos = 0; 552 draw(); 553 }else if(key == TextInputKey.END){ 554 pos = text.length; 555 draw(); 556 } 557 } 558 } 559 560 /** 561 * Displays multiple columns of data, also provides general text input. 562 */ 563 public class ListBox : WindowElement, ElementContainer{ 564 //public ListBoxColumn[] columns; 565 public ListBoxHeader header; 566 public ListBoxItem[] items; 567 public int[] columnWidth; 568 public int selection, brushHeader, brush, fontHeader, rowHeight; 569 public ushort selectionColor; 570 private bool fullRedraw, bodyDrawn, enableTextInput, textInputMode, insert, dragMid; 571 private VSlider vSlider; 572 private HSlider hSlider; 573 private Slider dragSld; 574 private int fullX, hposition, vposition, sliderX, sliderY, startY, endY, selectedColumn, textPos, previousEvent; 575 private BitmapDrawer textArea, headerArea; 576 private Coordinate textInputArea; 577 public void delegate(Event ev) onTextInput; 578 public void delegate(Event ev) onItemSelect; 579 public void delegate(Event ev) onScrolling; 580 581 public this(string source, Coordinate coordinates, ListBoxItem[] items, ListBoxHeader header, int rowHeight, bool enableTextInput = false){ 582 position = coordinates; 583 this.source = source; 584 this.rowHeight = rowHeight; 585 this.items = items; 586 this.header = header; 587 updateColumns(); 588 589 foreach(int i; columnWidth){ 590 fullX += i; 591 } 592 if(fullX < position.width()){ 593 fullX = position.width(); 594 } 595 596 output = new BitmapDrawer(position.width, position.height); 597 598 int foo = rowHeight * this.items.length; 599 if(foo < position.height()) 600 foo = position.width(); 601 this.enableTextInput = enableTextInput; 602 //inputHandler.addTextInputListener(source, this); 603 604 } 605 /*~this(){ 606 if(!(inputHandler is null)) 607 inputHandler.removeTextInputListener(source); 608 }*/ 609 /*public void actionEvent(Event event){ 610 if(event.source == "textInput"){ 611 items[selection].setText(selectedColumn, event.text); 612 invokeActionEvent(new Event(source, null, null, null, event.text, selection,EventType.TEXTINPUT, items[selection])); 613 updateColumns(); 614 draw(); 615 }else{ 616 draw(); 617 } 618 }*/ 619 private void textInput(Event ev){ 620 items[selection].setText(selectedColumn, ev.text); 621 //invokeActionEvent(new Event(source, null, null, null, event.text, selection,EventType.TEXTINPUT, items[selection])); 622 if(onTextInput !is null){ 623 onTextInput(new Event(source, null, null, null, ev.text, selection,EventType.TEXTINPUT, items[selection])); 624 } 625 updateColumns(); 626 draw(); 627 } 628 private void scrollHoriz(Event ev){ 629 draw(); 630 if(onScrolling !is null){ 631 onScrolling(ev); 632 } 633 } 634 private void scrollVert(Event ev){ 635 draw(); 636 if(onScrolling !is null){ 637 onScrolling(ev); 638 } 639 } 640 public void drawUpdate(WindowElement sender){ 641 output.insertBitmap(sender.getPosition().left,sender.getPosition().top,sender.output.output); 642 643 if(!fullRedraw){ 644 /*output.insertBitmapSlice(0,0,headerArea.output,Coordinate(vposition,0,vposition + fullX - 1, rowHeight - 1)); 645 output.insertBitmapSlice(0, rowHeight, textArea.output, Coordinate(vposition,hposition * rowHeight,vposition + fullX - 1 , hposition * rowHeight + (sizeY - hSlider.getPosition().getYSize) - rowHeight));*/ 646 elementContainer.drawUpdate(this); 647 } 648 } 649 public Coordinate getAbsolutePosition(WindowElement sender){ 650 return sender.position; 651 } 652 /** 653 * Updates the columns with the given data. 654 */ 655 public void updateColumns(ListBoxItem[] items){ 656 this.items = items; 657 updateColumns(); 658 draw(); 659 } 660 /** 661 * Updates the columns with the given data and header. 662 */ 663 public void updateColumns(ListBoxItem[] items, ListBoxHeader header){ 664 this.items = items; 665 this.header = header; 666 updateColumns(); 667 draw(); 668 } 669 /** 670 * Clears the content of the ListBox. 671 */ 672 public void clearData(){ 673 items.length = 0; 674 updateColumns(); 675 draw(); 676 } 677 public void updateColumns(){ 678 679 fullX = header.getFullWidth(); 680 selection = 0; 681 682 if(fullX < position.width()){ 683 fullX = position.width(); 684 } 685 int foo2 = rowHeight * this.items.length; 686 if(foo2 < position.height()) 687 foo2 = position.height(); 688 689 textArea = new BitmapDrawer(fullX, foo2); 690 headerArea = new BitmapDrawer(fullX, rowHeight); 691 692 this.vSlider = new VSlider(items.length - 1, ((position.height()-17-rowHeight) / rowHeight), "vslider", Coordinate(position.width() - 16, 0, position.width(), position.height() - 16)); 693 this.hSlider = new HSlider(fullX - 16, position.width() - 16, "hslider", Coordinate(0, position.height() - 16, position.width() - 16, position.height())); 694 this.vSlider.onScrolling = &scrollVert; 695 this.vSlider.elementContainer = this; 696 sliderX = vSlider.getX(); 697 698 699 this.hSlider.onScrolling = &scrollHoriz; 700 this.hSlider.elementContainer = this; 701 sliderY = hSlider.getY(); 702 bodyDrawn = false; 703 } 704 705 public StyleSheet getStyleSheet(){ 706 return getAvailableStyleSheet; 707 } 708 709 private void drawBody(){ 710 int foo; 711 for(int i; i < header.getNumberOfColumns(); i++){ 712 int bar; 713 for(int j; j < items.length; j++){ 714 //writeln(foo + 1, bar); 715 textArea.drawText(foo + 1, bar, items[j].getText(i), getStyleSheet().getFontset("default"), 1); 716 717 bar += rowHeight; 718 } 719 foo += header.getColumnWidth(i); 720 721 textArea.drawLine(foo, foo, 0, textArea.output.height-2, getStyleSheet().getColor("windowascent")); 722 } 723 } 724 725 public override void draw(){ 726 if(output.output.width != position.width || output.output.height != position.height){ 727 output = new BitmapDrawer(position.width(), position.height()); 728 bodyDrawn = false; 729 updateColumns(); 730 } 731 fullRedraw = true; 732 int areaX, areaY; 733 734 vposition = vSlider.value; 735 areaX = position.width - vSlider.getPosition().width(); 736 737 738 hposition = hSlider.value; 739 areaY = position.height - hSlider.getPosition().height(); 740 741 output.drawFilledRectangle(0, position.width(), 0, position.height(),getStyleSheet().getColor("window")); 742 output.drawRectangle(0, position.width() - 1, 0, position.height() - 1,getStyleSheet().getColor("windowascent")); 743 744 745 // draw the header 746 // TODO: Draw the header only once!!! 747 output.drawLine(0, position.width() - 1, rowHeight, rowHeight, getStyleSheet().getColor("windowascent")); 748 int foo; 749 for(int i; i < header.getNumberOfColumns(); i++){ 750 headerArea.drawText(foo + 1, 0, header.getText(i), getStyleSheet().getFontset("default"), 1); 751 foo += header.getColumnWidth(i); 752 headerArea.drawLine(foo, foo, 0, rowHeight - 2, getStyleSheet().getColor("windowascent")); 753 } 754 755 output.insertBitmapSlice(0,0,headerArea.output,Coordinate(hposition,0,hposition + position.width() - 17, rowHeight - 1)); 756 757 //draw the selector 758 if(selection - vposition >= 0 && vposition + ((position.height()-17-rowHeight) / rowHeight) >= selection && items.length != 0) 759 output.drawFilledRectangle(1, position.width() - 2, rowHeight + (rowHeight * (selection - vposition)), (rowHeight * 2) + (rowHeight * (selection - vposition)), getStyleSheet().getColor("selection")); 760 761 // draw the body 762 if(!bodyDrawn){ 763 bodyDrawn = true; 764 drawBody(); 765 } 766 //writeln(textArea.output.getX(),textArea.output.getY()); 767 output.insertBitmapSlice(0, rowHeight, textArea.output, Coordinate(hposition,vposition * rowHeight,hposition + position.width() - 17 , vposition * rowHeight + areaY - rowHeight)); 768 769 vSlider.draw(); 770 hSlider.draw(); 771 elementContainer.drawUpdate(this); 772 773 fullRedraw = false; 774 if(onDraw !is null){ 775 onDraw(); 776 } 777 } 778 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 779 if(button == MouseButton.RIGHT){ 780 if(state == ButtonState.PRESSED){ 781 if(onMouseRClickPre !is null){ 782 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 783 } 784 }else{ 785 if(onMouseRClickRel !is null){ 786 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 787 } 788 } 789 }else if(button == MouseButton.MID){ 790 if(state == ButtonState.PRESSED){ 791 if(onMouseMClickPre !is null){ 792 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 793 } 794 }else{ 795 if(onMouseMClickRel !is null){ 796 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 797 } 798 } 799 }else{ 800 if(state == ButtonState.PRESSED){ 801 if(onMouseLClickPre !is null){ 802 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 803 } 804 }else{ 805 if(onMouseLClickRel !is null){ 806 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 807 } 808 } 809 } 810 if(state == ButtonState.PRESSED){ 811 if(button == MouseButton.LEFT){ 812 if(offsetX > (vSlider.getPosition().left) && offsetY > (vSlider.getPosition().top)){ 813 vSlider.onClick(offsetX - vSlider.getPosition().left, offsetY - vSlider.getPosition().top, state, button); 814 dragSld = vSlider; 815 return; 816 817 }else if(offsetX > (hSlider.getPosition().left) && offsetY > (hSlider.getPosition().top)){ 818 hSlider.onClick(offsetX - hSlider.getPosition().left, offsetY - hSlider.getPosition().top, state, button); 819 dragSld = hSlider; 820 return; 821 822 }else if(offsetY > rowHeight && button == MouseButton.LEFT){ 823 offsetY -= rowHeight; 824 //writeln(selection); 825 if(selection == (offsetY / rowHeight) + vposition){ 826 //invokeActionEvent(EventType.TEXTBOXSELECT, (offsetY / rowHeight) + vposition); 827 if(!enableTextInput){ 828 //invokeActionEvent(new Event(source, null, null, null, null, (offsetY / rowHeight) + vposition,EventType.TEXTBOXSELECT, items[selection])); 829 if(onItemSelect !is null){ 830 onItemSelect(new Event(source, null, null, null, null, (offsetY / rowHeight) + vposition,EventType.TEXTBOXSELECT, items[selection])); 831 } 832 }else{ 833 offsetX += hposition; 834 selectedColumn = header.getColumnNumFromX(offsetX); 835 //writeln(offsetX); 836 if(selectedColumn != -1){ 837 if(items[selection].getTextInputType(selectedColumn) != TextInputType.DISABLE){ 838 text = items[selection].getText(selectedColumn); 839 //invokeActionEvent(EventType.READYFORTEXTINPUT,selectedColumn); 840 PopUpTextInput p = new PopUpTextInput("textInput", text, Coordinate(0,0,header.getColumnWidth(selectedColumn),20)); 841 p.onTextInput = &textInput; 842 popUpHandler.addPopUpElement(p); 843 /+textInputArea = Coordinate(header.getRangeWidth(0, selectedColumn), (selection + 1) * rowHeight /*- hposition*/, 844 header.getRangeWidth(0, selectedColumn + 1), (selection + 2) * rowHeight /*- hposition*/); 845 writeln(textInputArea);+/ 846 847 }/*else{*/ 848 if(onItemSelect !is null){ 849 onItemSelect(new Event(source, null, null, null, null, (offsetY / rowHeight) + vposition,EventType.TEXTBOXSELECT, items[selection])); 850 /*}*/ 851 } 852 } 853 } 854 }else{ 855 if((offsetY / rowHeight) + vposition < items.length){ 856 selection = (offsetY / rowHeight) + vposition; 857 draw(); 858 } 859 } 860 } 861 }else if(button == MouseButton.MID){ 862 dragMid = true; 863 } 864 }else{ 865 dragMid = false; 866 dragSld = null; 867 } 868 } 869 public override void onDrag(int x, int y, int relX, int relY, ubyte button){ 870 if(dragMid){ 871 hSlider.value += x; 872 vSlider.value += y; 873 }else if(dragSld){ 874 dragSld.onDrag(x,y,relX,relY,button); 875 } 876 } 877 public override void onScroll(int x, int y, int wX, int wY){ 878 if(textInputMode) return; 879 vSlider.onScroll(x,y,0,0); 880 hSlider.onScroll(x,y,0,0); 881 } 882 /** 883 * Returns a line. 884 */ 885 public @nogc ListBoxItem readLine(int line){ 886 return items[line]; 887 } 888 /** 889 * Adds a line to the bottom of the list. 890 */ 891 public void addLine(ListBoxItem i){ 892 items ~= i; 893 } 894 /** 895 * Inserts a line to a given point of the list. 896 */ 897 public void addLine(ListBoxItem i, int n){ 898 if(n == items.length){ 899 items ~= i; 900 }else{ 901 items.length++; 902 for(int j = items.length - 1; j > n; j++){ 903 items[j] = items[j - 1]; 904 } 905 items[n] = i; 906 } 907 } 908 /** 909 * Removes a line from the list. 910 */ 911 public void removeLine(int n){ 912 items.remove(n); 913 } 914 } 915 /** 916 * A simple toggle button. 917 */ 918 public class CheckBox : WindowElement{ 919 public int iconChecked, iconUnchecked; 920 private bool checked; 921 public int[] brush; 922 public void delegate(Event ev) onToggle; 923 924 public this(wstring text, string source, Coordinate coordinates){ 925 position = coordinates; 926 this.text = text; 927 this.source = source; 928 brush ~= 2; 929 brush ~= 3; 930 output = new BitmapDrawer(position.width, position.height); 931 //draw(); 932 } 933 934 public override void draw(){ 935 if(output.output.width != position.width || output.output.height != position.height) 936 output = new BitmapDrawer(position.width, position.height); 937 output.drawText(getAvailableStyleSheet().getImage("checkBoxA").width, 0, text, getAvailableStyleSheet().getFontset("default"), 1); 938 if(checked){ 939 output.insertBitmap(0, 0, getAvailableStyleSheet().getImage("checkBoxB")); 940 }else{ 941 output.insertBitmap(0, 0, getAvailableStyleSheet().getImage("checkBoxA")); 942 } 943 elementContainer.drawUpdate(this); 944 if(onDraw !is null){ 945 onDraw(); 946 } 947 } 948 949 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 950 /*if(state == ButtonState.PRESSED && button == MouseButton.LEFT){ 951 checked = !checked; 952 draw(); 953 invokeActionEvent(EventType.CHECKBOX, checked); 954 }*/ 955 if(button == MouseButton.RIGHT){ 956 if(state == ButtonState.PRESSED){ 957 if(onMouseRClickPre !is null){ 958 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 959 } 960 }else{ 961 if(onMouseRClickRel !is null){ 962 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 963 } 964 } 965 }else if(button == MouseButton.MID){ 966 if(state == ButtonState.PRESSED){ 967 if(onMouseMClickPre !is null){ 968 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 969 } 970 }else{ 971 if(onMouseMClickRel !is null){ 972 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 973 } 974 } 975 }else{ 976 if(state == ButtonState.PRESSED){ 977 checked = !checked; 978 draw(); 979 if(onMouseLClickPre !is null){ 980 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 981 } 982 if(onToggle !is null){ 983 onToggle(new Event(source, null, null, null, null, checked ? 1 : 0, EventType.CHECKBOX)); 984 } 985 }else{ 986 if(onMouseLClickRel !is null){ 987 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 988 } 989 } 990 } 991 } 992 /** 993 * Returns the current value (whether it's checked or not) as a boolean. 994 */ 995 public @nogc @property bool value(){ 996 return checked; 997 } 998 /** 999 * Sets the new value (whether it's checked or not) as a boolean. 1000 */ 1001 public @property bool value(bool b){ 1002 checked = b; 1003 draw(); 1004 return checked; 1005 } 1006 } 1007 /** 1008 * Radio buttons, for selecting from multiple options. 1009 */ 1010 public class RadioButtonGroup : WindowElement{ 1011 public int iconChecked, iconUnchecked; 1012 private int bposition, rowHeight, buttonpos; 1013 public wstring[] options; 1014 public int[] brush; 1015 public ushort border, background; 1016 public void delegate(Event ev) onToggle; 1017 1018 public this(wstring text, string source, Coordinate coordinates, wstring[] options, int rowHeight, int buttonpos){ 1019 this.position = coordinates; 1020 this.text = text; 1021 this.source = source; 1022 this.options = options; 1023 this.rowHeight = rowHeight; 1024 brush ~= 4; 1025 brush ~= 5; 1026 output = new BitmapDrawer(position.width, position.height); 1027 //draw(); 1028 } 1029 1030 public override void draw(){ 1031 //output.drawFilledRectangle(0, sizeX-1, 0, sizeY-1, background); 1032 if(output.output.width != position.width || output.output.height != position.height) 1033 output = new BitmapDrawer(position.width, position.height); 1034 output.drawRectangle(0, position.width-1, 0, position.height-1, getAvailableStyleSheet().getColor("windowascent")); 1035 output.drawText(16,0,text, getAvailableStyleSheet().getFontset("default"),1); 1036 for(int i; i < options.length; i++){ 1037 1038 output.drawText(16, rowHeight * (i+1),options[i],getAvailableStyleSheet().getFontset("default"),1); 1039 if(bposition == i){ 1040 output.insertBitmap(1, rowHeight * (i+1),getAvailableStyleSheet.getImage("radioButtonB")); 1041 }else{ 1042 output.insertBitmap(1, rowHeight * (i+1),getAvailableStyleSheet.getImage("radioButtonA")); 1043 } 1044 } 1045 elementContainer.drawUpdate(this); 1046 if(onDraw !is null){ 1047 onDraw(); 1048 } 1049 } 1050 1051 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 1052 if(button == MouseButton.RIGHT){ 1053 if(state == ButtonState.PRESSED){ 1054 if(onMouseRClickPre !is null){ 1055 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1056 } 1057 }else{ 1058 if(onMouseRClickRel !is null){ 1059 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1060 } 1061 } 1062 }else if(button == MouseButton.MID){ 1063 if(state == ButtonState.PRESSED){ 1064 if(onMouseMClickPre !is null){ 1065 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1066 } 1067 }else{ 1068 if(onMouseMClickRel !is null){ 1069 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1070 } 1071 } 1072 }else{ 1073 if(state == ButtonState.PRESSED){ 1074 if(onMouseLClickPre !is null){ 1075 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1076 } 1077 bposition = (offsetY) / 16; 1078 bposition--; 1079 draw(); 1080 if(onToggle !is null){ 1081 onToggle(new Event(source, null, null, null, null, bposition, EventType.RADIOBUTTON)); 1082 } 1083 }else{ 1084 if(onMouseLClickRel !is null){ 1085 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1086 } 1087 } 1088 } 1089 } 1090 public @property @nogc int value(){ 1091 return bposition; 1092 } 1093 public @property int value(int newval){ 1094 bposition = newval; 1095 draw(); 1096 return bposition; 1097 } 1098 } 1099 1100 abstract class Slider : WindowElement{ 1101 public int[] brush; 1102 1103 public int value, maxValue, barLength; 1104 public void delegate(Event ev) onScrolling; 1105 1106 /** 1107 * Returns the slider position. If barLenght > 1, then it returns the lower value. 1108 */ 1109 public @nogc @property int sliderPosition(){ 1110 return value; 1111 } 1112 public @property int sliderPosition(int newval){ 1113 if(newval < maxValue){ 1114 value = newval; 1115 draw(); 1116 } 1117 return value; 1118 } 1119 } 1120 /** 1121 * Vertical slider. 1122 */ 1123 public class VSlider : Slider{ 1124 //public int[] brush; 1125 1126 //private int value, maxValue, barLength; 1127 1128 public this(int maxValue, int barLenght, string source, Coordinate coordinates){ 1129 position = coordinates; 1130 //this.text = text; 1131 this.source = source; 1132 this.maxValue = maxValue; 1133 this.barLength = barLenght; 1134 output = new BitmapDrawer(position.width, position.height); 1135 brush ~= 6; 1136 brush ~= 8; 1137 //brush ~= 10; 1138 //draw(); 1139 } 1140 public override void draw(){ 1141 //draw background 1142 //Bitmap16Bit sliderStyle = elementContainer.getStyleBrush(brush[2]); 1143 //ushort backgroundColor = sliderStyle.readPixel(0,0), sliderColor = sliderStyle.readPixel(1,0); 1144 if(output.output.width != position.width || output.output.height != position.height) 1145 output = new BitmapDrawer(position.width, position.height); 1146 output.drawFilledRectangle(0, position.width , 0, position.height , getAvailableStyleSheet.getColor("windowinactive")); 1147 //draw upper arrow 1148 output.insertBitmap(0,0,getAvailableStyleSheet.getImage("upArrowA")); 1149 //draw lower arrow 1150 output.insertBitmap(0, position.height - getAvailableStyleSheet.getImage("downArrowA").height,getAvailableStyleSheet.getImage("downArrowA")); 1151 //draw slider 1152 if(maxValue > barLength){ 1153 double sliderlength = position.height() - (getAvailableStyleSheet.getImage("upArrowA")).height*2, unitlength = sliderlength/maxValue; 1154 double sliderpos = unitlength * value, bl = unitlength * barLength; 1155 int posA = to!int(sliderpos) + getAvailableStyleSheet.getImage("upArrowA").height, posB = to!int(bl + sliderpos) + getAvailableStyleSheet.getImage("upArrowA").height; 1156 1157 output.drawFilledRectangle(0,position.width,posA, posB, getAvailableStyleSheet.getColor("windowascent")); 1158 } 1159 elementContainer.drawUpdate(this); 1160 if(onDraw !is null){ 1161 onDraw(); 1162 } 1163 } 1164 1165 1166 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 1167 if(button == MouseButton.RIGHT){ 1168 if(state == ButtonState.PRESSED){ 1169 if(onMouseRClickPre !is null){ 1170 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1171 } 1172 }else{ 1173 if(onMouseRClickRel !is null){ 1174 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1175 } 1176 } 1177 }else if(button == MouseButton.MID){ 1178 if(state == ButtonState.PRESSED){ 1179 if(onMouseMClickPre !is null){ 1180 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1181 } 1182 }else{ 1183 if(onMouseMClickRel !is null){ 1184 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1185 } 1186 } 1187 }else{ 1188 if(state == ButtonState.PRESSED){ 1189 if(onMouseLClickPre !is null){ 1190 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1191 } 1192 if(offsetY <= getAvailableStyleSheet.getImage("upArrowA").height){ 1193 if(value != 0) value--; 1194 }else if(position.height-getAvailableStyleSheet.getImage("upArrowA").height <= offsetY){ 1195 if(value < maxValue - barLength) value++; 1196 }else{ 1197 offsetY -= getAvailableStyleSheet.getImage("upArrowA").height; 1198 double sliderlength = position.height() - (getAvailableStyleSheet.getImage("upArrowA").height*2), unitlength = sliderlength/maxValue; 1199 int v = to!int(offsetY / unitlength); 1200 //value = ((sizeY - (elementContainer.getStyleBrush(brush[1]).getY() * 2)) - offsetY) * (value / maxValue); 1201 if(v < maxValue - barLength) value = v; 1202 else value = maxValue - barLength; 1203 1204 } 1205 draw(); 1206 if(onScrolling !is null){ 1207 onScrolling(new Event(source, null, null, null, null, value, EventType.SLIDER)); 1208 } 1209 }else{ 1210 if(onMouseLClickRel !is null){ 1211 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1212 } 1213 } 1214 } 1215 1216 } 1217 public override void onScroll(int x, int y, int wX, int wY){ 1218 1219 if(x == 1){ 1220 if(value != 0) value--; 1221 }else if(x == -1){ 1222 if(value < maxValue - barLength) value++; 1223 } 1224 draw(); 1225 if(onScrolling !is null){ 1226 onScrolling(new Event(source, null, null, null, null, value, EventType.SLIDER)); 1227 } 1228 } 1229 override public void onDrag(int x,int y,int relX,int relY,ubyte button) { 1230 value+=relY; 1231 if(value >= maxValue - barLength) 1232 value = maxValue; 1233 else if(value < 0) 1234 value = 0; 1235 draw(); 1236 if(onScrolling !is null){ 1237 onScrolling(new Event(source, null, null, null, null, value, EventType.SLIDER)); 1238 } 1239 1240 } 1241 } 1242 /** 1243 * Horizontal slider. 1244 */ 1245 public class HSlider : Slider{ 1246 public this(int maxValue, int barLenght, string source, Coordinate coordinates){ 1247 position = coordinates; 1248 //this.text = text; 1249 this.source = source; 1250 this.maxValue = maxValue; 1251 this.barLength = barLenght; 1252 //writeln(barLenght,',',maxValue); 1253 output = new BitmapDrawer(position.width, position.height); 1254 brush ~= 14; 1255 brush ~= 16; 1256 //brush ~= 10; 1257 //draw(); 1258 } 1259 public override void draw(){ 1260 //draw background 1261 //Bitmap16Bit sliderStyle = elementContainer.getStyleBrush(brush[2]); 1262 //ushort backgroundColor = sliderStyle.readPixel(0,0), sliderColor = sliderStyle.readPixel(1,0); 1263 if(output.output.width != position.width || output.output.height != position.height) 1264 output = new BitmapDrawer(position.width, position.height); 1265 output.drawFilledRectangle(0, position.width , 0, position.height , getAvailableStyleSheet().getColor("windowinactive")); 1266 //draw left arrow 1267 output.insertBitmap(0,0,getAvailableStyleSheet.getImage("leftArrowA")); 1268 //draw right arrow 1269 output.insertBitmap(position.width - getAvailableStyleSheet.getImage("rightArrowA").width,0,getAvailableStyleSheet.getImage("rightArrowA")); 1270 //draw slider 1271 if(maxValue > barLength){ 1272 double sliderlength = position.width() - (getAvailableStyleSheet.getImage("rightArrowA").width*2), unitlength = sliderlength/maxValue; 1273 double sliderpos = unitlength * value, bl = unitlength * barLength; 1274 1275 int posA = to!int(sliderpos) + getAvailableStyleSheet.getImage("rightArrowA").height, posB = to!int(bl + sliderpos) + getAvailableStyleSheet.getImage("rightArrowA").height; 1276 1277 output.drawFilledRectangle(posA, posB, 0, position.height(),getAvailableStyleSheet().getColor("windowascent")); 1278 } 1279 elementContainer.drawUpdate(this); 1280 if(onDraw !is null){ 1281 onDraw(); 1282 } 1283 } 1284 public override void onClick(int offsetX, int offsetY, int state, ubyte button){ 1285 if(button == MouseButton.RIGHT){ 1286 if(state == ButtonState.PRESSED){ 1287 if(onMouseRClickPre !is null){ 1288 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1289 } 1290 }else{ 1291 if(onMouseRClickRel !is null){ 1292 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1293 } 1294 } 1295 }else if(button == MouseButton.MID){ 1296 if(state == ButtonState.PRESSED){ 1297 if(onMouseMClickPre !is null){ 1298 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1299 } 1300 }else{ 1301 if(onMouseMClickRel !is null){ 1302 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1303 } 1304 } 1305 }else{ 1306 if(state == ButtonState.PRESSED){ 1307 if(onMouseLClickPre !is null){ 1308 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1309 } 1310 if(offsetX <= getAvailableStyleSheet.getImage("rightArrowA").width){ 1311 if(value != 0) value--; 1312 } 1313 else if(position.width-getAvailableStyleSheet.getImage("rightArrowA").width <= offsetX){ 1314 if(value < maxValue - barLength) value++; 1315 } 1316 else{ 1317 offsetX -= getAvailableStyleSheet.getImage("rightArrowA").width; 1318 double sliderlength = position.width() - (elementContainer.getStyleSheet.getImage("rightArrowA").width*2), unitlength = sliderlength/maxValue; 1319 int v = to!int(offsetX / unitlength); 1320 if(v < maxValue - barLength) value = v; 1321 else value = maxValue - barLength; 1322 } 1323 draw(); 1324 if(onScrolling !is null){ 1325 onScrolling(new Event(source, null, null, null, null, value, EventType.SLIDER)); 1326 } 1327 }else{ 1328 if(onMouseLClickRel !is null){ 1329 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1330 } 1331 } 1332 } 1333 } 1334 public override void onScroll(int x, int y, int wX, int wY){ 1335 if(y == -1){ 1336 if(value != 0) value--; 1337 }else if(y == 1){ 1338 if(value < maxValue - barLength) value++; 1339 } 1340 draw(); 1341 if(onScrolling.ptr){ 1342 onScrolling(new Event(source, null, null, null, null, value, EventType.SLIDER)); 1343 } 1344 } 1345 override public void onDrag(int x,int y,int relX,int relY,ubyte button) { 1346 value+=relX; 1347 if(value >= maxValue - barLength) 1348 value = maxValue; 1349 else if(value < 0) 1350 value = 0; 1351 draw(); 1352 if(onScrolling.ptr){ 1353 onScrolling(new Event(source, null, null, null, null, value, EventType.SLIDER)); 1354 } 1355 } 1356 1357 } 1358 /** 1359 * Menubar containing menus in a tree-like structure. 1360 */ 1361 public class MenuBar: WindowElement{ 1362 private PopUpMenuElement[] menus; 1363 //private wstring[] menuNames; 1364 private int[] menuWidths; 1365 //private PopUpHandler popUpHandler; 1366 private int select, usedWidth; 1367 public this(string source, Coordinate position, PopUpMenuElement[] menus){ 1368 this.source = source; 1369 this.position = position; 1370 //this.popUpHandler = popUpHandler; 1371 this.menus = menus; 1372 select = -1; 1373 } 1374 public override void draw() { 1375 StyleSheet ss = getAvailableStyleSheet(); 1376 Fontset!Bitmap16Bit f = ss.getFontset("default"); 1377 if (output is null){ 1378 usedWidth = 1; 1379 output = new BitmapDrawer(position.width(),position.height()); 1380 foreach(m ; menus){ 1381 menuWidths ~= usedWidth; 1382 usedWidth += f.getTextLength(m.text) + (ss.drawParameters["MenuBarHorizPadding"] * 2); 1383 1384 } 1385 output.drawFilledRectangle(0, position.width(), 0, position.height(), ss.getColor("window")); 1386 }else{ 1387 output.drawFilledRectangle(0, usedWidth, 0, position.height(), ss.getColor("window")); 1388 } 1389 if(select != -1){ 1390 1391 } 1392 int x = ss.drawParameters["MenuBarHorizPadding"] + 1; 1393 foreach(m ; menus){ 1394 output.drawText(x, ss.drawParameters["MenuBarVertPadding"],m.text,f,1); 1395 x += f.getTextLength(m.text) + ss.drawParameters["MenuBarHorizPadding"]; 1396 output.drawLine(x, x, 0, position.height() - 1, ss.getColor("MenuBarSeparatorColor")); 1397 x += ss.drawParameters["MenuBarHorizPadding"]; 1398 } 1399 output.drawLine(0, 0, 0, position.height()-1, ss.getColor("windowascent")); 1400 output.drawLine(0, position.width()-1, 0, 0, ss.getColor("windowascent")); 1401 output.drawLine(0, position.width()-1, position.height()-1, position.height()-1, ss.getColor("windowdescent")); 1402 output.drawLine(position.width()-1, position.width()-1, 0, position.height()-1, ss.getColor("windowdescent")); 1403 elementContainer.drawUpdate(this); 1404 if(onDraw !is null){ 1405 onDraw(); 1406 } 1407 } 1408 private void redirectIncomingEvents(Event ev){ 1409 if(onMouseLClickPre !is null){ 1410 onMouseLClickPre(ev); 1411 } 1412 } 1413 override public void onClick(int offsetX,int offsetY,int state,ubyte button){ 1414 if(button == MouseButton.RIGHT){ 1415 if(state == ButtonState.PRESSED){ 1416 if(onMouseRClickPre !is null){ 1417 onMouseRClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1418 } 1419 }else{ 1420 if(onMouseRClickRel !is null){ 1421 onMouseRClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1422 } 1423 } 1424 }else if(button == MouseButton.MID){ 1425 if(state == ButtonState.PRESSED){ 1426 if(onMouseMClickPre !is null){ 1427 onMouseMClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1428 } 1429 }else{ 1430 if(onMouseMClickRel !is null){ 1431 onMouseMClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1432 } 1433 } 1434 }else{ 1435 if(state == ButtonState.PRESSED){ 1436 if(onMouseLClickPre !is null){ 1437 onMouseLClickPre(new Event(source, null, null, null, null, button, EventType.CLICK)); 1438 } 1439 }else{ 1440 if(onMouseLClickRel !is null){ 1441 onMouseLClickRel(new Event(source, null, null, null, null, button, EventType.CLICK)); 1442 } 1443 } 1444 } 1445 //writeln(onMouseLClickPre); 1446 if(offsetX < usedWidth && button == MouseButton.LEFT && state == ButtonState.PRESSED){ 1447 for(int i = menuWidths.length - 1 ; i >= 0 ; i--){ 1448 if(menuWidths[i] < offsetX){ 1449 PopUpMenu p = new PopUpMenu(menus[i].getSubElements(), menus[i].source); 1450 //p.al = al; 1451 p.onMouseClick = onMouseLClickPre;//&redirectIncomingEvents; 1452 Coordinate c = elementContainer.getAbsolutePosition(this); 1453 popUpHandler.addPopUpElement(p, c.left + menuWidths[i], position.height()); 1454 return; 1455 } 1456 } 1457 } 1458 1459 } 1460 1461 } 1462 /** 1463 * For creating pop-up elements like menus. 1464 */ 1465 public abstract class PopUpElement{ 1466 //public ActionListener[] al; 1467 public BitmapDrawer output; 1468 public static InputHandler inputhandler; 1469 public static StyleSheet styleSheet; 1470 public Coordinate coordinates; 1471 public StyleSheet customStyle; 1472 protected PopUpHandler parent; 1473 protected string source; 1474 protected wstring text; 1475 /*public void delegate(Event ev) onMouseLClickRel; 1476 public void delegate(Event ev) onMouseRClickRel; 1477 public void delegate(Event ev) onMouseMClickRel; 1478 public void delegate(Event ev) onMouseHover; 1479 public void delegate(Event ev) onMouseMove; 1480 public void delegate(Event ev) onMouseLClickPre; 1481 public void delegate(Event ev) onMouseRClickPre; 1482 public void delegate(Event ev) onMouseMClickPre;*/ 1483 1484 public static void delegate() onDraw; 1485 public void delegate(Event ev) onMouseClick; 1486 1487 public abstract void draw(); 1488 1489 public void onClick(int offsetX, int offsetY, int type = 0){ 1490 1491 } 1492 public void onScroll(int x, int y, int wX, int wY){ 1493 1494 } 1495 public void onMouseMovement(int x, int y){ 1496 1497 } 1498 public void addParent(PopUpHandler p){ 1499 parent = p; 1500 } 1501 1502 protected StyleSheet getStyleSheet(){ 1503 if(customStyle !is null){ 1504 return customStyle; 1505 } 1506 if(styleSheet !is null){ 1507 return styleSheet; 1508 } 1509 return parent.getStyleSheet(); 1510 } 1511 /*protected void invokeActionEvent(Event e){ 1512 foreach(ActionListener a; al){ 1513 //a.actionEvent(source, type, value, message); 1514 //writeln(a); 1515 a.actionEvent(e); 1516 } 1517 }*/ 1518 } 1519 1520 /** 1521 * To create drop-down lists, menu bars, etc. 1522 */ 1523 public class PopUpMenu : PopUpElement{ 1524 //private wstring[] texts; 1525 //private string[] sources; 1526 1527 //private uint[int] hotkeyCodes; 1528 //private Bitmap16Bit[int] icons; 1529 private int minwidth, width, height, iconWidth, select; 1530 PopUpMenuElement[] elements; 1531 1532 public this(PopUpMenuElement[] elements, string source, int iconWidth = 0){ 1533 this.elements = elements; 1534 this.source = source; 1535 this. iconWidth = iconWidth; 1536 select = -1; 1537 } 1538 public override void draw(){ 1539 StyleSheet ss = getStyleSheet(); 1540 if(output is null){ 1541 1542 minwidth = (ss.drawParameters["PopUpMenuVertPadding"] * 2) + ss.drawParameters["PopUpMenuMinTextSpace"] + iconWidth; 1543 width = minwidth; 1544 foreach(e; elements){ 1545 int newwidth = ss.getFontset("default").getTextLength(e.text~e.secondaryText) + iconWidth; 1546 if(newwidth > width){ 1547 width = newwidth; 1548 } 1549 height += ss.getFontset("default").getSize() + (ss.drawParameters["PopUpMenuVertPadding"] * 2); 1550 } 1551 width += (ss.drawParameters["PopUpMenuHorizPadding"] * 2) + ss.drawParameters["PopUpMenuMinTextSpace"]; 1552 height += ss.drawParameters["PopUpMenuVertPadding"] * 2; 1553 output = new BitmapDrawer(width, height); 1554 coordinates = Coordinate(0, 0, width, height); 1555 } 1556 output.drawFilledRectangle(0,width - 1,0,height - 1,ss.getColor("window")); 1557 1558 if(select > -1){ 1559 int y0 = (height / elements.length) * select; 1560 int y1 = (height / elements.length) + y0; 1561 output.drawFilledRectangle(1, width - 1, y0 + 1, y1 + 1, ss.getColor("selection")); 1562 } 1563 1564 1565 int y = 1 + ss.drawParameters["PopUpMenuVertPadding"]; 1566 foreach(e; elements){ 1567 if(e.secondaryText !is null){ 1568 output.drawColorText(width - ss.drawParameters["PopUpMenuHorizPadding"] - 1, y, e.secondaryText, ss.getFontset("default"), ss.getColor("PopUpMenuSecondaryTextColor"), 2); 1569 } 1570 output.drawText(ss.drawParameters["PopUpMenuHorizPadding"] + iconWidth, y, e.text, ss.getFontset("default"), 1); 1571 if(e.getIcon() !is null){ 1572 output.insertBitmap(ss.drawParameters["PopUpMenuHorizPadding"], y, e.getIcon()); 1573 } 1574 y += ss.getFontset("default").getSize() + (ss.drawParameters["PopUpMenuVertPadding"] * 2); 1575 } 1576 1577 //output.drawRectangle(1,1,height-1,width-1,ss.getColor("windowascent")); 1578 output.drawLine(0,0,0,height-1,ss.getColor("windowascent")); 1579 output.drawLine(0,width-1,0,0,ss.getColor("windowascent")); 1580 output.drawLine(0,width-1,height-1,height-1,ss.getColor("windowdescent")); 1581 output.drawLine(width-1,width-1,0,height-1,ss.getColor("windowdescent")); 1582 if(onDraw !is null){ 1583 onDraw(); 1584 } 1585 } 1586 public override void onClick(int offsetX, int offsetY, int type = 0){ 1587 offsetY /= height / elements.length; 1588 if(elements[offsetY].source == "\\submenu\\"){ 1589 PopUpMenu m = new PopUpMenu(elements[offsetY].subElements, this.source, elements[offsetY].iconWidth); 1590 m.onMouseClick = onMouseClick; 1591 parent.addPopUpElement(m); 1592 //parent.closePopUp(this); 1593 }else{ 1594 //invokeActionEvent(new Event(elements[offsetY].source, source, null, null, null, offsetY, EventType.CLICK)); 1595 if(onMouseClick !is null) 1596 onMouseClick(new Event(elements[offsetY].source, source, null, null, null, offsetY, EventType.CLICK)); 1597 parent.endPopUpSession(); 1598 //parent.closePopUp(this); 1599 } 1600 1601 } 1602 public override void onMouseMovement(int x , int y) { 1603 if(x == -1){ 1604 if(select != -1){ 1605 select = -1; 1606 draw; 1607 } 1608 }else{ 1609 y /= height / elements.length; 1610 if(y < elements.length){ 1611 select = y; 1612 } 1613 draw(); 1614 } 1615 } 1616 1617 } 1618 /** 1619 * Defines a single MenuElement, also can contain multiple subelements. 1620 */ 1621 public class PopUpMenuElement{ 1622 public string source; 1623 public wstring text, secondaryText; 1624 protected Bitmap16Bit icon; 1625 private PopUpMenuElement[] subElements; 1626 private ushort keymod; 1627 private int keycode; 1628 public int iconWidth; 1629 1630 public this(string source, wstring text, wstring secondaryText = null, Bitmap16Bit icon = null, int iconWidth = 0){ 1631 this.source = source; 1632 this.text = text; 1633 this.secondaryText = secondaryText; 1634 this.icon = icon; 1635 this.iconWidth = iconWidth; 1636 } 1637 public this(string source, wstring text, wstring secondaryText, PopUpMenuElement[] subElements){ 1638 this.source = source; 1639 this.text = text; 1640 this.secondaryText = secondaryText; 1641 this.subElements = subElements; 1642 /+this.icon = icon; 1643 this.iconWidth = iconWidth;+/ 1644 } 1645 public this(string source, wstring text, wstring secondaryText, PopUpMenuElement[] subElements, Bitmap16Bit icon = null, int iconWidth = 0){ 1646 this.source = source; 1647 this.text = text; 1648 this.secondaryText = secondaryText; 1649 this.subElements = subElements; 1650 /+this.icon = icon; 1651 this.iconWidth = iconWidth;+/ 1652 } 1653 public Bitmap16Bit getIcon(){ 1654 return icon; 1655 } 1656 public void setIcon(Bitmap16Bit icon){ 1657 this.icon = icon; 1658 } 1659 public PopUpMenuElement[] getSubElements(){ 1660 return subElements; 1661 } 1662 public void loadSubElements(PopUpMenuElement[] e){ 1663 subElements = e; 1664 } 1665 public PopUpMenuElement opIndex(size_t i){ 1666 return subElements[i]; 1667 } 1668 public PopUpMenuElement opIndexAssign(PopUpMenuElement value, size_t i){ 1669 subElements[i] = value; 1670 return value; 1671 } 1672 public size_t getLength(){ 1673 return subElements.length; 1674 } 1675 public void setLength(int l){ 1676 subElements.length = l; 1677 } 1678 1679 } 1680 /** 1681 * Text input in pop-up fashion. 1682 */ 1683 public class PopUpTextInput : PopUpElement, TextInputListener{ 1684 protected bool enableEdit, insert; 1685 protected int textPos; 1686 public void delegate(Event ev) onTextInput; 1687 1688 public this(string source, wstring text, Coordinate coordinates){ 1689 this.source = source; 1690 this.text = text; 1691 this.coordinates = coordinates; 1692 enableEdit = true; 1693 output = new BitmapDrawer(coordinates.width, coordinates.height); 1694 inputhandler.startTextInput(this); 1695 } 1696 public override void draw(){ 1697 output.drawFilledRectangle(0, coordinates.width - 1, 0, coordinates.height - 1, getStyleSheet().getColor("window")); 1698 output.drawRectangle(0, coordinates.width - 1, 0, coordinates.height - 1, getStyleSheet().getColor("windowascent")); 1699 1700 //draw cursor 1701 if(enableEdit){ 1702 int x = getStyleSheet().getFontset("default").letters['A'].width , y = getStyleSheet().getFontset("default").letters['A'].height; 1703 if(!insert) 1704 output.drawLine((x*textPos) + 2, (x*textPos) + 2, 2, 2 + y, getStyleSheet().getColor("selection")); 1705 else 1706 output.drawFilledRectangle((x*textPos) + 2, (x*(textPos + 1)) + 2, 2, 2 + y, getStyleSheet().getColor("selection")); 1707 } 1708 1709 output.drawText(2, 2, text, getStyleSheet().getFontset("default"), 1); 1710 1711 if(onDraw !is null){ 1712 onDraw(); 1713 } 1714 } 1715 private void deleteCharacter(int n){ 1716 //text = remove(text, i); 1717 wstring newtext; 1718 for(int i; i < text.length; i++){ 1719 if(i != n - 1){ 1720 newtext ~= text[i]; 1721 } 1722 } 1723 text = newtext; 1724 } 1725 public void textInputEvent(uint timestamp, uint windowID, char[32] text){ 1726 int j = textPos; 1727 wstring newtext; 1728 for(int i ; i < textPos ; i++){ 1729 newtext ~= this.text[i]; 1730 } 1731 for(int i ; i < 32 ; i++){ 1732 if(text[i] == 0){ 1733 break; 1734 } 1735 else{ 1736 newtext ~= text[i]; 1737 textPos++; 1738 if(insert){ 1739 j++; 1740 } 1741 } 1742 } 1743 for( ; j < this.text.length ; j++){ 1744 newtext ~= this.text[j]; 1745 } 1746 this.text = newtext; 1747 draw(); 1748 } 1749 public void textInputKeyEvent(uint timestamp, uint windowID, TextInputKey key, ushort modifier = 0){ 1750 switch(key){ 1751 case TextInputKey.ESCAPE: 1752 inputhandler.stopTextInput(this); 1753 /*draw(); 1754 invokeActionEvent(EventType.TEXTINPUT, 0, text);*/ 1755 break; 1756 case TextInputKey.ENTER: 1757 inputhandler.stopTextInput(this); 1758 //invokeActionEvent(new Event(source, null, null, null, text, text.length, EventType.TEXTINPUT)); 1759 if(onTextInput !is null) 1760 onTextInput(new Event(source, null, null, null, text, text.length, EventType.TEXTINPUT)); 1761 break; 1762 case TextInputKey.BACKSPACE: 1763 if(textPos > 0){ 1764 deleteCharacter(textPos); 1765 textPos--; 1766 draw(); 1767 } 1768 break; 1769 case TextInputKey.DELETE: 1770 deleteCharacter(textPos + 1); 1771 draw(); 1772 break; 1773 case TextInputKey.CURSORLEFT: 1774 if(textPos > 0){ 1775 --textPos; 1776 draw(); 1777 } 1778 break; 1779 case TextInputKey.CURSORRIGHT: 1780 if(textPos < text.length){ 1781 ++textPos; 1782 draw(); 1783 } 1784 break; 1785 case TextInputKey.INSERT: 1786 insert = !insert; 1787 draw(); 1788 break; 1789 case TextInputKey.HOME: 1790 textPos = 0; 1791 draw(); 1792 break; 1793 case TextInputKey.END: 1794 textPos = text.length; 1795 draw(); 1796 break; 1797 default: 1798 break; 1799 1800 } 1801 } 1802 public void dropTextInput(){ 1803 parent.endPopUpSession(); 1804 //inputHandler.stopTextInput(source); 1805 /*draw(); 1806 invokeActionEvent(EventType.TEXTINPUT, 0, text);*/ 1807 } 1808 } 1809 1810 public interface PopUpHandler : StyleSheetContainer{ 1811 public void addPopUpElement(PopUpElement p); 1812 public void addPopUpElement(PopUpElement p, int x, int y); 1813 public void endPopUpSession(); 1814 public void closePopUp(PopUpElement p); 1815 //public void drawUpdate(PopUpElement sender); 1816 //public StyleSheet getDefaultStyleSheet(); 1817 1818 } 1819 1820 /** 1821 * Defines the header of a ListBox. 1822 */ 1823 public class ListBoxHeader{ 1824 private wstring[] text; 1825 private int[] width; 1826 private uint[] textInputType; 1827 private int iconColumn; 1828 public this(wstring[] text, int[] width, int iconColumn = 0){ 1829 this.width = width; 1830 this.text = text; 1831 this.iconColumn = iconColumn; 1832 } 1833 /// Returns the number of columns before drawing 1834 @nogc public int getNumberOfColumns(){ 1835 return this.text.length; 1836 } 1837 /// Returns the text at the given point 1838 @nogc public wstring getText(int i){ 1839 return text[i]; 1840 } 1841 /// Returns the width of the column 1842 @nogc public int getColumnWidth(int i){ 1843 return width[i]; 1844 } 1845 /// Sets the width of the column 1846 @nogc public void setRowWidth(int i, int x){ 1847 width[i] = x; 1848 } 1849 /// Returns the number of column that contains the icon 1850 @nogc public int getIconColumn(){ 1851 return iconColumn; 1852 } 1853 /// Returns the whole width of the header 1854 @nogc public int getFullWidth(){ 1855 int result; 1856 foreach(int i; width){ 1857 result += i; 1858 } 1859 return result; 1860 } 1861 /// Returns the column number from width, or -1 if x can't fit into any range 1862 @nogc public int getColumnNumFromX(int x){ 1863 int result = -1; 1864 if(width[0] > x) return 0; 1865 for(int i = 1; i < width.length; i++){ 1866 if(width[i - 1] <= x || width[i] > x){ 1867 result = i; 1868 } 1869 } 1870 return result; 1871 } 1872 /// Returns the width of the columns in a given range 1873 @nogc public int getRangeWidth(int begin, int end){ 1874 int result; 1875 for(; begin < end ; begin++){ 1876 result += width[begin]; 1877 } 1878 return result; 1879 } 1880 /// Returns the TextInputType for the column 1881 @nogc public uint getTextInputType(int column){ 1882 return textInputType[column]; 1883 } 1884 } 1885 /** 1886 * Defines an item in the row of a ListBox. Can be passed through the Event class 1887 */ 1888 public class ListBoxItem{ 1889 private wstring[] text; 1890 private uint[] textInputType; ///If value or array is null, the ListBoxHeader's textInputType is referred 1891 private Bitmap16Bit icon; /// If used, replaces the texts in the column defined by the ListBoxHeader, otherwise defaults to the text. 1892 public this(wstring[] text, Bitmap16Bit icon = null, uint[] textInputType = null){ 1893 this.text = text; 1894 this.icon = icon; 1895 this.textInputType = textInputType; 1896 } 1897 public this(wstring[] text, uint[] textInputType){ 1898 this.text = text; 1899 this.icon = null; 1900 this.textInputType = textInputType; 1901 } 1902 /// Returns the text at the given column 1903 @nogc public wstring getText(int column){ 1904 return text[column]; 1905 } 1906 /// Sets the text in the given column 1907 @nogc public void setText(int column, wstring text){ 1908 this.text[column] = text; 1909 } 1910 /// Returns the icon 1911 public Bitmap16Bit getIcon(){ 1912 return icon; 1913 } 1914 /// Returns the input type of the given column. Refer to ListBoxHeader if return value = TextInputType.NULL 1915 @nogc public uint getTextInputType(int column){ 1916 return textInputType[column]; 1917 } 1918 public override string toString(){ 1919 wstring result; 1920 foreach(ws; text) 1921 result ~= ws; 1922 return to!string(result); 1923 } 1924 } 1925 /* 1926 * For use with ListBoxes and similar types. Currently left here for legacy purposes, being replaced with the classes ListBoxHeader and ListBoxElement 1927 * 1928 public struct ListBoxColumn{ 1929 public wstring header; 1930 public wstring[] elements; 1931 1932 this(wstring header, wstring[] elements){ 1933 this.header = header; 1934 this.elements = elements; 1935 } 1936 1937 / 1938 public void removeByNumber(int i){ 1939 elements = remove(elements, i); 1940 } 1941 }*/ 1942 1943 /** 1944 * Defines an action event in the concrete GUI. 1945 */ 1946 public class Event{ 1947 public string source, subsource, path, filename; 1948 public wstring text; 1949 public int value, type; 1950 public Object aux; 1951 /** 1952 *If a field is unneeded, leave it blank by setting it to null. 1953 */ 1954 this(string source, string subsource, string path, string filename, wstring textinput, int value, int type, Object aux = null){ 1955 this.source = source; 1956 this.subsource = subsource; 1957 this.path = path; 1958 this.filename = filename; 1959 this.text = textinput; 1960 this.value = value; 1961 this.type = type; 1962 this.aux = aux; 1963 } 1964 } 1965 1966 /+public interface ActionListener{ 1967 /** 1968 * Invoked mostly by WindowElements, Dialogs, and PopUpElements. Used to run the code and pass the eventdata. 1969 */ 1970 public void actionEvent(Event event); 1971 }+/ 1972 1973 public interface ElementContainer : StyleSheetContainer{ 1974 public Coordinate getAbsolutePosition(WindowElement sender); 1975 } 1976 1977 public interface StyleSheetContainer{ 1978 public StyleSheet getStyleSheet(); 1979 1980 public void drawUpdate(WindowElement sender); 1981 1982 } 1983 1984 public interface Focusable{ 1985 public void focusGiven(); 1986 public void focusLost(); 1987 } 1988 1989 public enum EventType{ 1990 CLICK = 0, 1991 TEXTINPUT = 1, 1992 SLIDER = 2, 1993 TEXTBOXSELECT = 3, 1994 CHECKBOX = 4, 1995 RADIOBUTTON = 5, 1996 FILEDIALOGEVENT = 6, 1997 1998 }