├── .editorconfig ├── .gitignore ├── CHANGELOG.md ├── README.md ├── bump-version.sh ├── docs ├── dguihub.html ├── dguihub │ ├── application.html │ ├── application │ │ └── Application.html │ ├── button.html │ ├── button │ │ ├── Button.html │ │ ├── CheckBox.html │ │ └── RadioButton.html │ ├── canvas.html │ ├── canvas │ │ ├── BitmapBit.html │ │ ├── BitmapCopyMode.html │ │ ├── BitmapData.html │ │ ├── Canvas.html │ │ ├── Color.html │ │ ├── EdgeMode.html │ │ ├── EdgeType.html │ │ ├── FontStyle.html │ │ ├── GradientFillRectMode.html │ │ ├── HatchStyle.html │ │ ├── ImageType.html │ │ ├── PenStyle.html │ │ ├── TextAlignment.html │ │ ├── TextFormatFlags.html │ │ └── TextTrimming.html │ ├── colordialog.html │ ├── combobox.html │ ├── contextmenu.html │ ├── core │ │ ├── charset.html │ │ ├── collection.html │ │ ├── controls │ │ │ ├── abstractbutton.html │ │ │ ├── abstractbutton │ │ │ │ ├── AbstractButton.html │ │ │ │ ├── CheckState.html │ │ │ │ └── CheckedButton.html │ │ │ ├── containercontrol.html │ │ │ ├── control.html │ │ │ ├── ownerdrawcontrol.html │ │ │ ├── reflectedcontrol.html │ │ │ ├── scrollablecontrol.html │ │ │ ├── subclassedcontrol.html │ │ │ └── textcontrol.html │ │ ├── dialogs │ │ │ ├── commondialog.html │ │ │ └── dialogresult.html │ │ ├── events │ │ │ ├── controlcodeeventargs.html │ │ │ ├── event.html │ │ │ ├── eventargs.html │ │ │ ├── keyeventargs.html │ │ │ ├── mouseeventargs.html │ │ │ ├── painteventargs.html │ │ │ └── scrolleventargs.html │ │ ├── exception.html │ │ ├── geometry.html │ │ ├── handle.html │ │ ├── interfaces │ │ │ ├── idisposable.html │ │ │ └── ilayoutcontrol.html │ │ ├── menu │ │ │ └── abstractmenu.html │ │ ├── message.html │ │ ├── tag.html │ │ ├── utils.html │ │ ├── winapi.html │ │ ├── wincomp.html │ │ └── windowclass.html │ ├── filebrowserdialog.html │ ├── folderbrowserdialog.html │ ├── fontdialog.html │ ├── form.html │ ├── imagelist.html │ ├── label.html │ ├── layout │ │ ├── gridpanel.html │ │ ├── layoutcontrol.html │ │ ├── panel.html │ │ └── splitpanel.html │ ├── listbox.html │ ├── listview.html │ ├── menubar.html │ ├── messagebox.html │ ├── messagebox │ │ ├── MsgBox.html │ │ ├── MsgBoxButtons.html │ │ └── MsgBoxIcons.html │ ├── picturebox.html │ ├── progressbar.html │ ├── registry.html │ ├── resources.html │ ├── richtextbox.html │ ├── scrollbar.html │ ├── semver.html │ ├── statusbar.html │ ├── tabcontrol.html │ ├── textbox.html │ ├── timer.html │ ├── toolbar.html │ ├── tooltip.html │ ├── trackbar.html │ └── treeview.html ├── highlight.pack.js ├── index.html ├── search.js ├── show_hide.js └── style.css ├── dub.sdl ├── examples ├── checkbox │ ├── app.d │ └── dub.sdl ├── dropdown │ ├── app.d │ └── dub.sdl ├── events │ ├── app.d │ └── dub.sdl ├── gradientr │ ├── app.d │ └── dub.sdl ├── gradientt │ ├── app.d │ └── dub.sdl ├── grid │ ├── app.d │ └── dub.sdl ├── hello │ ├── app.d │ └── dub.sdl ├── listview │ ├── app.d │ └── dub.sdl ├── menu │ ├── app.d │ └── dub.sdl ├── opendialog │ ├── app.d │ └── dub.sdl ├── picture │ ├── app.d │ ├── dub.sdl │ └── image.bmp ├── raw │ ├── app.d │ ├── dub.sdl │ └── image.bmp ├── res │ ├── app.d │ ├── bitmap.ico │ ├── dub.sdl │ ├── image.bmp │ ├── resource.rc │ └── resource.res ├── splitter │ ├── app.d │ └── dub.sdl └── toolbar │ ├── app.d │ └── dub.sdl ├── hmod.cfg ├── mlstyle.css └── src └── dguihub ├── application.d ├── button.d ├── canvas.d ├── colordialog.d ├── combobox.d ├── contextmenu.d ├── core ├── charset.d ├── collection.d ├── controls │ ├── abstractbutton.d │ ├── containercontrol.d │ ├── control.d │ ├── ownerdrawcontrol.d │ ├── reflectedcontrol.d │ ├── scrollablecontrol.d │ ├── subclassedcontrol.d │ └── textcontrol.d ├── dialogs │ ├── commondialog.d │ └── dialogresult.d ├── events │ ├── controlcodeeventargs.d │ ├── event.d │ ├── eventargs.d │ ├── keyeventargs.d │ ├── mouseeventargs.d │ ├── painteventargs.d │ └── scrolleventargs.d ├── exception.d ├── geometry.d ├── handle.d ├── interfaces │ ├── idisposable.d │ └── ilayoutcontrol.d ├── menu │ └── abstractmenu.d ├── message.d ├── tag.d ├── utils.d ├── winapi.d ├── wincomp.d └── windowclass.d ├── filebrowserdialog.d ├── folderbrowserdialog.d ├── fontdialog.d ├── form.d ├── imagelist.d ├── label.d ├── layout ├── gridpanel.d ├── layoutcontrol.d ├── panel.d └── splitpanel.d ├── listbox.d ├── listview.d ├── menubar.d ├── messagebox.d ├── package.d ├── picturebox.d ├── progressbar.d ├── registry.d ├── rename.sh ├── resources.d ├── richtextbox.d ├── scrollbar.d ├── semver.d ├── statusbar.d ├── tabcontrol.d ├── textbox.d ├── timer.d ├── toolbar.d ├── tooltip.d ├── trackbar.d └── treeview.d /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.d] 2 | dfmt_align_switch_statements = true 3 | # allman, otbs, or stroustrup 4 | dfmt_brace_style = otbs 5 | #dfmt_brace_style = stroustrup 6 | dfmt_outdent_attributes = true 7 | dfmt_outdent_labels = true 8 | dfmt_soft_max_line_length = 80 9 | dfmt_space_after_cast = false 10 | dfmt_space_after_keywords = true 11 | dfmt_split_operator_at_line_end = false 12 | 13 | trim_trailing_whitespace = true 14 | end_of_line = lf 15 | indent_size = 3 16 | indent_style = space 17 | insert_final_newline = true 18 | max_line_length = 120 19 | tab_width = 8 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .dub 2 | docs.json 3 | __dummy.html 4 | *.o 5 | *.obj 6 | __test__*__ 7 | *.exe 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change log for dguihub 2 | 3 | ## [0.1.0] - 2017-02-10 4 | - Initial version 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DGui Graphic Library 2 | [![Dub version](https://img.shields.io/dub/v/dguihub.svg)](https://code.dlang.org/packages/dguihub) 3 | [![Dub downloads](https://img.shields.io/dub/dt/dguihub.svg)](https://code.dlang.org/packages/dguihub) 4 | 5 | Yet another fork of [DGui Form Library](https://bitbucket.org/dgui/dgui) 6 | 7 | ## Compiling DGuiHub 8 | The simplest way to compile is to use [dub](http://code.dlang.org/) package. 9 | 10 | ``` 11 | $ dub build 12 | ``` 13 | ## API Reference 14 | See [api](http://o3o.github.io/dguihub/). 15 | 16 | 17 | ## Simple example 18 | ``` 19 | module hello; 20 | 21 | import dguihub; 22 | 23 | class MainForm : Form { 24 | public this() { 25 | this.text = "DGui Form"; 26 | this.size = Size(500, 400); 27 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 28 | } 29 | } 30 | 31 | int main(string[] args) { 32 | return Application.run(new MainForm()); // Start the application 33 | } 34 | 35 | ``` 36 | 37 | ## Compiling examples 38 | 39 | Directly from _examples_ directory 40 | ``` 41 | $ cd examples/hello 42 | $ dub 43 | ``` 44 | 45 | or using subpackage 46 | 47 | ``` 48 | $ dub run dguihub:hello 49 | ``` 50 | 51 | ## Related Projects 52 | 53 | | Project | Author | 54 | | ----------------------------- | ------- | 55 | | [DGui](https://bitbucket.org/dgui/dgui) | Antonio Trogu | 56 | | [DGuiT](https://github.com/FrankLIKE/DguiT) | FrankLike | 57 | 58 | ## License 59 | The project is licensed under the terms of the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). 60 | -------------------------------------------------------------------------------- /bump-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh +v 2 | NEW_VER=$@ 3 | sed -i -r "s/VERSION\s*=\s*\"[0-9]+\.[0-9]+\.[0-9]+(-[a-z]+\.[0-9]+)?\"/VERSION = \"${NEW_VER}\"/g" src/dguihub/semver.d 4 | git commit -a -m "Bumped version to ${NEW_VER}" 5 | -------------------------------------------------------------------------------- /docs/dguihub/button/CheckBox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CheckBox 8 | 9 | 10 | 11 | 12 | 13 |
14 | 19 | 125 |
126 |
public class CheckBox : CheckedButton
127 | 
128 |

129 |

Standard windows _CheckBox 130 |

131 | 132 | 133 |
134 |

135 | 136 | 137 |
138 |
139 | 140 |
141 | 144 |
145 | 146 | 147 | -------------------------------------------------------------------------------- /docs/dguihub/button/RadioButton.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | RadioButton 8 | 9 | 10 | 11 | 12 | 13 |
14 | 19 | 125 |
126 |
public class RadioButton : CheckedButton
127 | 
128 |

129 |

Standard windows _RadioButton 130 |

131 | 132 | 133 |
134 |

135 | 136 | 137 |
138 |
139 | 140 |
141 | 144 |
145 | 146 | 147 | -------------------------------------------------------------------------------- /docs/dguihub/canvas/Canvas.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Canvas 8 | 9 | 10 | 11 | 12 | 13 |
14 | 19 | 125 |
126 |
public class Canvas : Handle!(HDC), IDisposable
127 | 
128 |

129 |

The _Canvas object is the DGui's rappresentation of a Device Context (Screen DC, Memory DC and Printer DC) 130 |

131 |

Note: Printer DC is not implemented 132 |

133 | 134 | 135 |
136 |

137 | 138 | 139 |
140 |
141 | 142 |
143 | 146 |
147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/dguihub/core/controls/abstractbutton.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | dguihub.core.controls.abstractbutton 8 | 9 | 10 | 11 | 12 | 13 |
14 | 19 | 125 |
126 |
127 | 128 |
129 | 132 |
133 | 134 | 135 | -------------------------------------------------------------------------------- /docs/show_hide.js: -------------------------------------------------------------------------------- 1 | window.onload = function(e) 2 | { 3 | var elems = document.querySelectorAll( "div.toc ul ul" ); 4 | for( var i = 0; i < elems.length; ++i ) 5 | { 6 | if( elems[i].style.display != "block" ) 7 | elems[i].style.display = "none"; 8 | } 9 | } 10 | 11 | function show_hide(id) 12 | { 13 | var elem = document.getElementById( id ); 14 | if( elem.style.display == "block" ) 15 | elem.style.display = "none"; 16 | else elem.style.display = "block"; 17 | } 18 | -------------------------------------------------------------------------------- /dub.sdl: -------------------------------------------------------------------------------- 1 | name "dguihub" 2 | description "A graphic library for Windows (github version)." 3 | authors "Trogu Antonio Davide" "Denis Shelomovskii" "Orfeo Da Vià" 4 | copyright "Copyright © 2011-2013, Trogu Antonio Davide" 5 | license "Boost" 6 | 7 | subPackage "examples/events" 8 | subPackage "examples/gradientr" 9 | subPackage "examples/gradientt" 10 | subPackage "examples/grid" 11 | subPackage "examples/hello" 12 | subPackage "examples/menu" 13 | subPackage "examples/opendialog" 14 | subPackage "examples/picture" 15 | subPackage "examples/raw" 16 | subPackage "examples/res" 17 | subPackage "examples/splitter" 18 | 19 | -------------------------------------------------------------------------------- /examples/checkbox/app.d: -------------------------------------------------------------------------------- 1 | module example.checkbox; 2 | import std.string; 3 | 4 | import dguihub; 5 | 6 | class MainForm : Form { 7 | private CheckBox check; 8 | public this() { 9 | this.text = "DGui Form"; 10 | this.size = Size(500, 400); 11 | this.startPosition = FormStartPosition.centerScreen; 12 | check = new CheckBox(); 13 | // x, y, w, h 14 | check.bounds = Rect(10, 10, 80, 24); 15 | check.parent = this; 16 | check.click.attach(&this.onClick); 17 | check.checkChanged.attach(&this.onCheck); 18 | 19 | Button setOn = new Button(); 20 | setOn.text = "ON"; 21 | setOn.bounds = Rect(10, 40, 80, 30); 22 | setOn.parent = this; 23 | setOn.click.attach(&this.onClick1); 24 | 25 | Button setOff = new Button(); 26 | setOff.text = "OFF"; 27 | setOff.bounds = Rect(10, 80, 80, 30); 28 | setOff.parent = this; 29 | setOff.click.attach(&this.onClick0); 30 | 31 | } 32 | 33 | private void onClick0(Control sender, EventArgs e) { 34 | check.checked = false; 35 | } 36 | 37 | private void onClick1(Control sender, EventArgs e) { 38 | check.checked = true; 39 | } 40 | 41 | private void onClick(Control sender, EventArgs e) { 42 | bool v = (cast(CheckBox)sender).checked; 43 | MsgBox.show("OnClick", "click event: Now check is %s".format(v)); 44 | } 45 | 46 | private void onCheck(Control sender, EventArgs e) { 47 | bool v = (cast(CheckBox)sender).checked; 48 | MsgBox.show("OnCheck", "checkChanged event. Now check is %s".format(v)); 49 | } 50 | } 51 | 52 | int main(string[] args) { 53 | return Application.run(new MainForm()); 54 | } 55 | -------------------------------------------------------------------------------- /examples/checkbox/dub.sdl: -------------------------------------------------------------------------------- 1 | name "checkbox" 2 | description "Simple checkbox example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/dropdown/app.d: -------------------------------------------------------------------------------- 1 | module hello; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | private ComboBox combo; 7 | public this() { 8 | this.text = "DGui Form"; 9 | this.size = Size(500, 400); 10 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 11 | combo = new ComboBox(); 12 | combo.dropDownStyle(DropDownStyles.simple); 13 | //combo.dock = DockStyle.top; 14 | // x, y, w, h 15 | combo.bounds = Rect(10, 10, 80, 160); 16 | import std.string; 17 | for (size_t i = 0; i < 176; ++i) { 18 | combo.addItem("OUT %2d".format(i)); 19 | } 20 | combo.parent = this; 21 | combo.itemChanged.attach(&this.onBtnClick); 22 | } 23 | private void onBtnClick(Control sender, EventArgs e) { 24 | import std.conv; 25 | if (combo !is null) { 26 | MsgBox.show("Click Event", combo.selectedIndex.to!string()); 27 | //MsgBox.show("Click Event", combo.selectedItem.to!string()); 28 | } else { 29 | MsgBox.show("Click Event", "null"); 30 | } 31 | 32 | } 33 | } 34 | 35 | int main(string[] args) { 36 | return Application.run(new MainForm()); // Start the application 37 | } 38 | -------------------------------------------------------------------------------- /examples/dropdown/dub.sdl: -------------------------------------------------------------------------------- 1 | name "dropdown" 2 | description "Simple dropdown example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/events/app.d: -------------------------------------------------------------------------------- 1 | module events; 2 | 3 | import dguihub; 4 | class MainForm : Form { 5 | private Button _btnOk; 6 | 7 | public this() { 8 | this.text = "DGui Events"; 9 | this.size = Size(300, 250); 10 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 11 | 12 | this._btnOk = new Button(); 13 | this._btnOk.text = "Click Me!"; 14 | this._btnOk.dock = DockStyle.fill; // Fill the whole form area 15 | this._btnOk.parent = this; 16 | this._btnOk.click.attach(&this.onBtnOkClick); //Attach the click event with the selected procedure 17 | } 18 | 19 | private void onBtnOkClick(Control sender, EventArgs e) { 20 | // Display a message box 21 | MsgBox.show("OnClick", "Button.onClick()"); 22 | } 23 | } 24 | 25 | int main(string[] args) { 26 | return Application.run(new MainForm()); // Start the application 27 | } 28 | -------------------------------------------------------------------------------- /examples/events/dub.sdl: -------------------------------------------------------------------------------- 1 | name "events" 2 | description "Simple event example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/gradientr/app.d: -------------------------------------------------------------------------------- 1 | module gradient_rect; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | public this() { 7 | this.text = "GDI: Gradient Fill Rect"; 8 | this.size = Size(400, 200); 9 | this.startPosition = FormStartPosition.centerScreen; 10 | } 11 | 12 | protected override void onPaint(PaintEventArgs e) { 13 | Canvas c = e.canvas; 14 | 15 | c.fillRectGradient(Rect(nullPoint, this.size), SystemColors.blue, 16 | SystemColors.green, GradientFillRectMode.vertical); 17 | super.onPaint(e); 18 | } 19 | } 20 | 21 | int main(string[] args) { 22 | return Application.run(new MainForm()); // Start the application 23 | } 24 | -------------------------------------------------------------------------------- /examples/gradientr/dub.sdl: -------------------------------------------------------------------------------- 1 | name "gradientr" 2 | description "Simple gradient example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | 9 | lflags "/subsystem:windows" platform="windows" 10 | 11 | dependency "dguihub" path="../../" 12 | -------------------------------------------------------------------------------- /examples/gradientt/app.d: -------------------------------------------------------------------------------- 1 | module gradient_triangle; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | public this() { 7 | this.text = "GDI: Gradient Fill Triangle"; 8 | this.size = Size(360, 190); 9 | this.startPosition = FormStartPosition.centerScreen; 10 | this.formBorderStyle = FormBorderStyle.fixedDialog; 11 | this.maximizeBox = false; 12 | this.minimizeBox = false; 13 | } 14 | 15 | protected override void onPaint(PaintEventArgs e) { 16 | Canvas c = e.canvas; 17 | 18 | c.fillTriangleGradient(10, 180, 180, 10, 350, 180, SystemColors.blue, 19 | SystemColors.green, SystemColors.red); 20 | super.onPaint(e); 21 | } 22 | } 23 | 24 | int main(string[] args) { 25 | return Application.run(new MainForm()); // Start the application 26 | } 27 | -------------------------------------------------------------------------------- /examples/gradientt/dub.sdl: -------------------------------------------------------------------------------- 1 | name "gradientt" 2 | description "Simple gradientt example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | 9 | lflags "/subsystem:windows" platform="windows" 10 | 11 | dependency "dguihub" path="../../" 12 | -------------------------------------------------------------------------------- /examples/grid/app.d: -------------------------------------------------------------------------------- 1 | module grid; 2 | 3 | import std.string; 4 | import dguihub; 5 | import dguihub.layout.gridpanel; 6 | 7 | class MainForm : Form { 8 | private GridPanel _gridPanel; 9 | private Collection!(Label) _labels; 10 | private Collection!(TextBox) _textboxes; 11 | private Collection!(Button) _buttons; 12 | 13 | public this() { 14 | this.text = "DGui SplitPanel Example"; 15 | this.size = Size(400, 400); 16 | this.maximizeBox = false; 17 | this.minimizeBox = false; 18 | this.startPosition = FormStartPosition.centerScreen; 19 | this.formBorderStyle = FormBorderStyle.fixedDialog; 20 | 21 | this._gridPanel = new GridPanel(); 22 | this._gridPanel.dock = DockStyle.fill; 23 | this._gridPanel.parent = this; 24 | 25 | this._labels = new Collection!(Label); 26 | this._textboxes = new Collection!(TextBox); 27 | this._buttons = new Collection!(Button); 28 | 29 | // Add 10 rows 30 | for (int i = 0; i < 10; i++) { 31 | RowPart row = this._gridPanel.addRow(); 32 | row.marginTop = 4; // Set 4 pixel of empty space (top part) for this row 33 | row.height = 23; //If you don't set the row's height, it will be used the component's height (if set) 34 | 35 | string s = format("Row No. %d", i); 36 | 37 | /* COLUMN 1 */ 38 | Label lbl = new Label(); 39 | lbl.text = s; 40 | lbl.alignment = TextAlignment.middle | TextAlignment.left; 41 | 42 | ColumnPart col1 = row.addColumn(lbl); //Add the component in the column 1, this parameter can be 'null' if you want to add an empty space 43 | col1.width = 60; //If you don't set the column's width, it will be used the component's width (if set) 44 | col1.marginLeft = 4; // Set 4 pixel of empty space (left part) for column 1 45 | 46 | /* COLUMN 2 */ 47 | TextBox tbx = new TextBox(); 48 | tbx.text = s; 49 | 50 | ColumnPart col2 = row.addColumn(tbx); //Add the component in the column 2, this parameter can be 'null' if you want to add an empty space 51 | col2.width = 80; //If you don't set the column's width, it will be used the component's width (if set) 52 | col2.marginRight = 4; // Set 4 pixel of empty space (right part) for column 2 53 | 54 | /* COLUMN 3 */ 55 | Button btn = new Button(); 56 | btn.text = "Click Me!"; 57 | btn.tag = tbx; // Save the TextBox (just for this sample, is not needed for GridPanel) 58 | btn.click.attach(&this.onBtnClick); 59 | 60 | ColumnPart col3 = row.addColumn(btn); //Add the component in the column 2, this parameter can be 'null' if you want to add an empty space 61 | col3.width = 60; //If you don't set the column's width, it will be used the component's width (if set) 62 | 63 | this._labels.add(lbl); 64 | this._textboxes.add(tbx); 65 | this._buttons.add(btn); 66 | } 67 | } 68 | 69 | private void onBtnClick(Control sender, EventArgs e) { 70 | TextBox tbx = sender.tag!(TextBox); 71 | MsgBox.show("Click Event", tbx.text); 72 | } 73 | } 74 | 75 | int main(string[] args) { 76 | return Application.run(new MainForm()); 77 | } 78 | -------------------------------------------------------------------------------- /examples/grid/dub.sdl: -------------------------------------------------------------------------------- 1 | name "grid" 2 | description "Simple grid example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/hello/app.d: -------------------------------------------------------------------------------- 1 | module hello; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | public this() { 7 | this.text = "DGui Form"; 8 | this.size = Size(500, 400); 9 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 10 | } 11 | } 12 | 13 | int main(string[] args) { 14 | return Application.run(new MainForm()); // Start the application 15 | } 16 | -------------------------------------------------------------------------------- /examples/hello/dub.sdl: -------------------------------------------------------------------------------- 1 | name "hello" 2 | description "Simple hello example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/listview/app.d: -------------------------------------------------------------------------------- 1 | module example.listview; 2 | import std.string; 3 | import std.stdio; 4 | 5 | import dguihub; 6 | 7 | class MainForm : Form { 8 | private ListView list; 9 | public this() { 10 | this.text = "DGui Form"; 11 | this.size = Size(500, 400); 12 | this.startPosition = FormStartPosition.centerScreen; 13 | list = new ListView(); 14 | list.viewStyle = ViewStyle.report; 15 | list.gridLines = true; 16 | // x, y, w, h 17 | list.bounds = Rect(10, 10, 450, 350); 18 | list.addColumn("Item column", 100, ColumnTextAlign.left); 19 | list.addColumn("Column 2", 100, ColumnTextAlign.left); 20 | list.addColumn("Column 3", 100, ColumnTextAlign.left); 21 | list.addColumn("Column 4", 100, ColumnTextAlign.center); 22 | 23 | list.parent = this; 24 | 25 | ListViewItem item1 = list.addItem("item1", -1, true); 26 | item1.addSubItem("1"); 27 | item1.addSubItem("2"); 28 | item1.addSubItem("3"); 29 | 30 | ListViewItem item2 = list.addItem("item2", -1, false); 31 | // Place a check mark next to the item. 32 | item2.addSubItem("4"); 33 | item2.addSubItem("5"); 34 | item2.addSubItem("6"); 35 | 36 | 37 | } 38 | } 39 | 40 | int main(string[] args) { 41 | return Application.run(new MainForm()); 42 | } 43 | -------------------------------------------------------------------------------- /examples/listview/dub.sdl: -------------------------------------------------------------------------------- 1 | name "listview" 2 | description "Simple listview example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/menu/app.d: -------------------------------------------------------------------------------- 1 | module menu; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | private MenuBar _mainMenu; 7 | 8 | public this() { 9 | this.text = "DGui Menu Test"; 10 | this.size = Size(500, 400); 11 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 12 | 13 | this._mainMenu = new MenuBar(); 14 | MenuItem m1 = this._mainMenu.addItem("Menu 1"); //Menu 1 15 | MenuItem m2 = this._mainMenu.addItem("Menu 2"); //Menu 2 16 | MenuItem m3 = this._mainMenu.addItem("Menu 3"); //Menu 3 17 | 18 | MenuItem m1_1 = m1.addItem("Menu 1.1"); //Add new menu item in Menu 1 19 | MenuItem m1_2 = m1.addItem("Menu 1.2"); //Add new menu item in Menu 1 20 | MenuItem m1_3 = m1.addItem("Menu 1.3"); //Add new menu item in Menu 1 21 | 22 | /* Menu 2 Creation */ 23 | m2.addItem("Menu 2.1"); 24 | m2.addItem("Menu 2.2", false); // Disable this menu item 25 | m2.addSeparator(); //Add a separator 26 | m2.addItem("Menu 2.3"); 27 | 28 | /* Creazione Menu 3 */ 29 | m3.addItem("Menu 3.1"); 30 | m3.addItem("Menu 3.2"); 31 | m3.addSeparator(); //Add a separator 32 | m3.addItem("Menu 3.3", false); // Disable this menu item 33 | 34 | m1_1.click.attach(&this.onMenu1_1Click); // Link the click event 35 | m1_2.click.attach(&this.onMenu1_2Click); // Link the click event 36 | m1_3.click.attach(&this.onMenu1_3Click); // Link the click event 37 | 38 | this.menu = this._mainMenu; // Associate the menu previously created with the form 39 | } 40 | 41 | private void onMenu1_1Click(MenuItem sender, EventArgs e) { 42 | MsgBox.show("Menu 1 -> 1.1 Click", "Menu 1 -> 1"); 43 | } 44 | 45 | private void onMenu1_2Click(MenuItem sender, EventArgs e) { 46 | MsgBox.show("Menu 1 -> 1.2 Click", "Menu 1 -> 1"); 47 | } 48 | 49 | private void onMenu1_3Click(MenuItem sender, EventArgs e) { 50 | MsgBox.show("Menu 1 -> 1.3 Click", "Menu 1 -> 1"); 51 | } 52 | } 53 | 54 | int main(string[] args) { 55 | return Application.run(new MainForm()); // Start the application 56 | } 57 | -------------------------------------------------------------------------------- /examples/menu/dub.sdl: -------------------------------------------------------------------------------- 1 | name "menu" 2 | description "Simple menu example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/opendialog/app.d: -------------------------------------------------------------------------------- 1 | module opendialog; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | private Button _btnOk; 7 | 8 | public this() { 9 | this.text = "DGui Events"; 10 | this.size = Size(300, 250); 11 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 12 | 13 | this._btnOk = new Button(); 14 | this._btnOk.text = "Click Me!"; 15 | this._btnOk.dock = DockStyle.fill; // Fill the whole form area 16 | this._btnOk.parent = this; 17 | this._btnOk.click.attach(&this.onBtnOkClick); //Attach the click event with the selected procedure 18 | } 19 | 20 | private void onBtnOkClick(Control sender, EventArgs e) { 21 | FileBrowserDialog dlg = new FileBrowserDialog(); 22 | dlg.filter = "D Lang file (*.d)|*.d|All files (*.*)|*.*"; 23 | dlg.showDialog(); 24 | MsgBox.show("OnClick", dlg.result); 25 | } 26 | } 27 | 28 | int main(string[] args) { 29 | return Application.run(new MainForm()); // Start the application 30 | } 31 | -------------------------------------------------------------------------------- /examples/opendialog/dub.sdl: -------------------------------------------------------------------------------- 1 | name "opendialog" 2 | description "Simple opendialog example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/picture/app.d: -------------------------------------------------------------------------------- 1 | module picture; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | private PictureBox _pict; 7 | 8 | public this() { 9 | this.text = "DGui Picture Box Text"; 10 | this.size = Size(300, 250); 11 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 12 | 13 | this._pict = new PictureBox(); 14 | this._pict.dock = DockStyle.fill; 15 | this._pict.sizeMode = SizeMode.autoSize; // Stretch the image 16 | this._pict.image = Bitmap.fromFile("image.bmp"); //Load image from file 17 | this._pict.parent = this; 18 | } 19 | } 20 | 21 | int main(string[] args) { 22 | return Application.run(new MainForm()); // Start the application 23 | } 24 | -------------------------------------------------------------------------------- /examples/picture/dub.sdl: -------------------------------------------------------------------------------- 1 | name "picture" 2 | description "Simple opendialog example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/picture/image.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o3o/dguihub/6f3d23b04c00ca45a42d3bf7d1545bc3f0cd3c32/examples/picture/image.bmp -------------------------------------------------------------------------------- /examples/raw/app.d: -------------------------------------------------------------------------------- 1 | module rawbitmap; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | private PictureBox _pict; 7 | private Bitmap _orgBmp; 8 | private Bitmap _bmp; 9 | 10 | public this() { 11 | this._orgBmp = Bitmap.fromFile("image.bmp"); //Load the bitmap from file (this is the original) 12 | this._bmp = Bitmap.fromFile("image.bmp"); //Load the bitmap from file (this one will be modified) 13 | 14 | this.text = "DGui Events"; 15 | this.size = Size(300, 250); 16 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 17 | 18 | this._pict = new PictureBox(); 19 | this._pict.sizeMode = SizeMode.autoSize; // Stretch the image 20 | this._pict.dock = DockStyle.fill; // Fill the whole form area 21 | this._pict.image = this._bmp; 22 | this._pict.parent = this; 23 | 24 | this.menu = new MenuBar(); 25 | MenuItem mi = this.menu.addItem("Bitmap"); 26 | 27 | MenuItem mOrgColors = mi.addItem("Original Colors"); 28 | MenuItem mInvColors = mi.addItem("Invert Colors"); 29 | MenuItem mGsColors = mi.addItem("Gray Scale"); 30 | 31 | mOrgColors.click.attach(&this.onMenuOrgColorsClick); 32 | mInvColors.click.attach(&this.onMenuInvColorsClick); 33 | mGsColors.click.attach(&this.onMenuGsColorsClick); 34 | } 35 | 36 | private void onMenuOrgColorsClick(MenuItem sender, EventArgs e) { 37 | BitmapData bd; 38 | this._orgBmp.getData(bd); //Get the original data 39 | this._bmp.setData(bd); //Set the original bitmap data 40 | this._pict.invalidate(); // Tell at the PictureBox to redraw itself 41 | } 42 | 43 | private void onMenuInvColorsClick(MenuItem sender, EventArgs e) { 44 | BitmapData bd; 45 | this._bmp.getData(bd); //Get the original data 46 | 47 | for (int i = 0; i < bd.bitsCount; i++) // Invert Colors! 48 | { 49 | bd.bits[i].rgbRed = ~bd.bits[i].rgbRed; 50 | bd.bits[i].rgbGreen = ~bd.bits[i].rgbGreen; 51 | bd.bits[i].rgbBlue = ~bd.bits[i].rgbBlue; 52 | } 53 | 54 | this._bmp.setData(bd); //Set the original bitmap data 55 | this._pict.invalidate(); // Tell at the PictureBox to redraw itself 56 | } 57 | 58 | private void onMenuGsColorsClick(MenuItem sender, EventArgs e) { 59 | BitmapData bd; 60 | this._bmp.getData(bd); //Get the original data 61 | 62 | for (int i = 0; i < bd.bitsCount; i++) // Gray Scale! 63 | { 64 | ubyte mid = cast(ubyte)((bd.bits[i].rgbRed + bd.bits[i].rgbGreen + bd.bits[i].rgbBlue) / 3); 65 | 66 | bd.bits[i].rgbRed = mid; 67 | bd.bits[i].rgbGreen = mid; 68 | bd.bits[i].rgbBlue = mid; 69 | } 70 | 71 | this._bmp.setData(bd); //Set the original bitmap data 72 | this._pict.invalidate(); // Tell at the PictureBox to redraw itself 73 | } 74 | } 75 | 76 | int main(string[] args) { 77 | return Application.run(new MainForm()); // Start the application 78 | } 79 | -------------------------------------------------------------------------------- /examples/raw/dub.sdl: -------------------------------------------------------------------------------- 1 | name "raw" 2 | description "Simple raw example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/raw/image.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o3o/dguihub/6f3d23b04c00ca45a42d3bf7d1545bc3f0cd3c32/examples/raw/image.bmp -------------------------------------------------------------------------------- /examples/res/app.d: -------------------------------------------------------------------------------- 1 | module resources; 2 | 3 | import dguihub; 4 | 5 | enum { 6 | IDI_MYICON = 100, 7 | IDB_MYBITMAP = 200, 8 | } 9 | 10 | class MainForm : Form { 11 | private PictureBox _pict; 12 | 13 | public this() { 14 | this.text = "DGui Events"; 15 | this.size = Size(300, 250); 16 | this.startPosition = FormStartPosition.centerScreen; // Set Form Position 17 | this.icon = Application.resources.getIcon(IDI_MYICON); //Load the icon from resource and associate it with MainForm 18 | 19 | this._pict = new PictureBox(); 20 | this._pict.dock = DockStyle.fill; // Fill the whole form area 21 | this._pict.sizeMode = SizeMode.autoSize; // Stretch the image 22 | this._pict.image = Application.resources.getBitmap(IDB_MYBITMAP); //Load the bitmap from resources 23 | this._pict.parent = this; 24 | } 25 | } 26 | 27 | int main(string[] args) { 28 | return Application.run(new MainForm()); // Start the application 29 | } 30 | -------------------------------------------------------------------------------- /examples/res/bitmap.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o3o/dguihub/6f3d23b04c00ca45a42d3bf7d1545bc3f0cd3c32/examples/res/bitmap.ico -------------------------------------------------------------------------------- /examples/res/dub.sdl: -------------------------------------------------------------------------------- 1 | name "res" 2 | description "Simple resources example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | sourceFiles "./resource.res" platform="windows" 9 | lflags "/subsystem:windows" platform="windows" 10 | 11 | dependency "dguihub" path="../../" 12 | -------------------------------------------------------------------------------- /examples/res/image.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o3o/dguihub/6f3d23b04c00ca45a42d3bf7d1545bc3f0cd3c32/examples/res/image.bmp -------------------------------------------------------------------------------- /examples/res/resource.rc: -------------------------------------------------------------------------------- 1 | #define IDI_MYICON 100 2 | #define IDB_MYBITMAP 200 3 | 4 | IDI_MYICON ICON DISCARDABLE "bitmap.ico" 5 | IDB_MYBITMAP BITMAP DISCARDABLE "image.bmp" 6 | 7 | -------------------------------------------------------------------------------- /examples/res/resource.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o3o/dguihub/6f3d23b04c00ca45a42d3bf7d1545bc3f0cd3c32/examples/res/resource.res -------------------------------------------------------------------------------- /examples/splitter/app.d: -------------------------------------------------------------------------------- 1 | module splitter; 2 | 3 | import std.string; 4 | import dguihub; 5 | import dguihub.layout.splitpanel; 6 | 7 | class MainForm : Form { 8 | private SplitPanel _spVPanel; 9 | private SplitPanel _spHPanel; 10 | private RichTextBox _rtbText; 11 | private RichTextBox _rtbText2; 12 | private TreeView _tvwTree; 13 | 14 | public this() { 15 | this.text = "DGui SplitPanel Example"; 16 | this.size = Size(500, 500); 17 | this.startPosition = FormStartPosition.centerScreen; 18 | 19 | this._spVPanel = new SplitPanel(); 20 | this._spVPanel.dock = DockStyle.fill; 21 | this._spVPanel.splitPosition = 200; 22 | this._spVPanel.splitOrientation = SplitOrientation.vertical; // Split Window vertically (this is the default option) 23 | this._spVPanel.parent = this; 24 | 25 | // Add another Splitter Panel in Panel1 of the Vertical Splitter Panel (aka. Right Panel) 26 | this._spHPanel = new SplitPanel(); 27 | this._spHPanel.dock = DockStyle.fill; 28 | this._spHPanel.splitPosition = 300; 29 | this._spHPanel.splitOrientation = SplitOrientation.horizontal; // Split Window horizontally (this is the default option) 30 | this._spHPanel.parent = this._spVPanel.panel2; // The parent of the Horizontal Splitter Panel is the left panel of the Vertical Splitter Panel 31 | 32 | // Add a TreeView in Panel1 of the Vertical Splitter Panel (aka. Left Panel) 33 | this._tvwTree = new TreeView(); 34 | this._tvwTree.dock = DockStyle.fill; 35 | this._tvwTree.parent = this._spVPanel.panel1; 36 | 37 | for (int i = 0; i < 4; i++) { 38 | TreeNode node1 = this._tvwTree.addNode(format("Node %d", i)); 39 | 40 | for (int j = 0; j < 5; j++) { 41 | node1.addNode(format("Node %d -> %d", i, j)); 42 | } 43 | } 44 | 45 | // Add a RichTextBox in Panel1 of the Horizontal Splitter Panel (aka. Top Panel) 46 | this._rtbText = new RichTextBox(); 47 | this._rtbText.dock = DockStyle.fill; 48 | this._rtbText.readOnly = true; 49 | this._rtbText.text = "This is a RichTextBox inside a Horizontal Splitter Panel (Top Panel)!"; 50 | this._rtbText.parent = this._spHPanel.panel1; // The parent of the RichTextBox is the Top Panel of the Horizontal Splitter Panel 51 | 52 | // Add a RichTextBox in Panel2 of the Horizontal (aka. Bottom Panel) 53 | this._rtbText = new RichTextBox(); 54 | this._rtbText.dock = DockStyle.fill; 55 | this._rtbText.readOnly = true; 56 | this._rtbText.text 57 | = "This is a RichTextBox inside a Horizontal Splitter Panel (Bottom Panel)!"; 58 | this._rtbText.parent = this._spHPanel.panel2; // The parent of the RichTextBox is the Bottom Panel of the Horizontal Splitter Panel 59 | 60 | } 61 | } 62 | 63 | int main(string[] args) { 64 | return Application.run(new MainForm()); 65 | } 66 | -------------------------------------------------------------------------------- /examples/splitter/dub.sdl: -------------------------------------------------------------------------------- 1 | name "splitter" 2 | description "Simple splitter example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /examples/toolbar/app.d: -------------------------------------------------------------------------------- 1 | module toolbar_32_x_32; 2 | 3 | import dguihub; 4 | 5 | class MainForm : Form { 6 | private ImageList _imgList; 7 | private ToolBar _tbrToolbar; 8 | 9 | public this() { 10 | this.text = "ToolBar 32 x 32"; 11 | this.size = Size(400, 200); 12 | this.startPosition = FormStartPosition.centerScreen; 13 | 14 | this._imgList = new ImageList(); 15 | this._imgList.size = Size(32, 32); //The ImageList's size set the ToolBar's size. 16 | this._imgList.addImage(SystemIcons.question); 17 | this._imgList.addImage(SystemIcons.warning); 18 | 19 | this._tbrToolbar = new ToolBar(); 20 | this._tbrToolbar.imageList = this._imgList; 21 | this._tbrToolbar.parent = this; 22 | 23 | this._tbrToolbar.addButton(0); 24 | this._tbrToolbar.addButton(1); 25 | this._tbrToolbar.addButton(0); 26 | this._tbrToolbar.addButton(1); 27 | this._tbrToolbar.addSeparator(); 28 | this._tbrToolbar.addButton(0, false); 29 | this._tbrToolbar.addButton(1, false); 30 | } 31 | } 32 | 33 | int main(string[] args) { 34 | return Application.run(new MainForm()); // Start the application 35 | } 36 | -------------------------------------------------------------------------------- /examples/toolbar/dub.sdl: -------------------------------------------------------------------------------- 1 | name "tb" 2 | description "Simple toolbar example" 3 | authors "Orfeo Da Viá" 4 | copyright "Copyright © 2017, o3o" 5 | license "Boost" 6 | sourcePaths "." 7 | targetType "executable" 8 | lflags "/subsystem:windows" platform="windows" 9 | 10 | dependency "dguihub" path="../../" 11 | -------------------------------------------------------------------------------- /hmod.cfg: -------------------------------------------------------------------------------- 1 | 2 | # This file contains configuration options for harbored-mod (hmod). 3 | # 4 | # By default, hmod loads configuration from file 'hmod.cfg' in the directory from where 5 | # hmod is running, if such file exists. These configuration options can also be passed 6 | # as command-line options for hmod, overriding contents of the config file, if any, 7 | # with the exception of options that allow multiple values (such as 'exclude' or 8 | # 'macros') where the values specified as command-line options are *added* to the values 9 | # in config file. 10 | 11 | 12 | 13 | # Source code files or directories to document. Specify more than once to document more 14 | # files/directories, e.g: 15 | # 16 | # source = ./source 17 | # source = ./thirdparty 18 | # 19 | # This will document both the source code in the ./source/ and ./thirdparty/ directories. 20 | # 21 | # For DUB (http://code.dlang.org) projects, './source' is usually a good setting here. 22 | source = ./src 23 | 24 | 25 | # Directory where the generated documentation will be written. 26 | output-directory = ./docs 27 | 28 | # Modules or packages to exclude from generated documentation. Specify more than once to 29 | # exclude more modules/packages, e.g: 30 | # 31 | # exclude = tharsis.util 32 | # exclude = tharsis.entity.gamestate 33 | # 34 | # This will exclude both the package (or module) tharsis.util and module (or package) 35 | # tharsis.entity.gamestate . 36 | exclude = 37 | 38 | 39 | # DDoc+markdown source of the main page of your documentation. Currently the main page is 40 | # blank by default; this can be used to fill it with something useful. 41 | 42 | #index = ./doc/hmod/alyx.md 43 | 44 | 45 | # DDoc+markdown source of additional content to add to the table of contents sidebar. 46 | # Useful e.g. to add links to tutorials. 47 | 48 | toc-additional = 49 | 50 | 51 | # CSS file to use for styling. Can be used to replace the default style. 52 | # To create a new style, you can start by generating the default style file with 53 | # 'hmod --generate-css CSS_OUT_FILE' (CSS_OUT_FILE is name the generated file will have) 54 | # and then modifying the CSS to get the desired style. 55 | 56 | css = ./mlstyle.css 57 | 58 | 59 | # File to load DDoc macros from. Can be used to override builtin macros or add new ones. 60 | # Can be specified more than once to use multiple macro files, e.g.: 61 | # 62 | # macros = macros.ddoc 63 | # macros = moremacros.ddoc 64 | 65 | 66 | macros = 67 | 68 | # Additional config file to load, if needed. Configuration options in specified file will 69 | # override or add to any options specified before this line, and will be overridden by 70 | # any options after this line. Think of it as including the config file in this file. 71 | 72 | config = 73 | 74 | 75 | #--------------------------------------------------------------------------- 76 | # Configuration options **only** useful for harbored-mod testing 77 | #--------------------------------------------------------------------------- 78 | # Uncommenting these will result in printing help information; only useful for testing. 79 | # 80 | # # Print help message. 81 | # 82 | # help 83 | # 84 | # 85 | # # Generate default CSS file and write it to specified file. 86 | # generate-css = hmod-style.css 87 | # 88 | # 89 | # # Generate default config file and write it to 'hmod.cfg'. 90 | # 91 | # generate-cfg 92 | -------------------------------------------------------------------------------- /src/dguihub/button.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.button; 10 | 11 | import dguihub.core.controls.abstractbutton; 12 | 13 | /// Standarde windows _Button 14 | class Button : AbstractButton { 15 | /** 16 | Returns: 17 | A DialogResult enum (ok, ignore, close, yes, no, cancel, ...) 18 | 19 | See_Also: 20 | Form.showDialog() 21 | */ 22 | @property public DialogResult dialogResult() { 23 | return this._dr; 24 | } 25 | 26 | /** 27 | Sets DialogResult for a button 28 | 29 | Params: 30 | dr = DialogResult of the button. 31 | 32 | See_Also: 33 | Form.showDialog() 34 | */ 35 | @property public void dialogResult(DialogResult dr) { 36 | this._dr = dr; 37 | } 38 | 39 | protected override void createControlParams(ref CreateControlParams ccp) { 40 | switch (this._drawMode) { 41 | case OwnerDrawMode.normal: 42 | this.setStyle(BS_PUSHBUTTON, true); 43 | break; 44 | 45 | case OwnerDrawMode.fixed, OwnerDrawMode.variable: 46 | this.setStyle(BS_OWNERDRAW, true); 47 | break; 48 | 49 | default: 50 | break; 51 | } 52 | 53 | ccp.className = WC_DBUTTON; 54 | 55 | super.createControlParams(ccp); 56 | } 57 | } 58 | 59 | /// Standard windows _CheckBox 60 | class CheckBox : CheckedButton { 61 | protected override void createControlParams(ref CreateControlParams ccp) { 62 | switch (this._drawMode) { 63 | case OwnerDrawMode.normal: 64 | this.setStyle(BS_AUTOCHECKBOX, true); 65 | break; 66 | 67 | case OwnerDrawMode.fixed, OwnerDrawMode.variable: 68 | this.setStyle(BS_OWNERDRAW, true); 69 | break; 70 | 71 | default: 72 | break; 73 | } 74 | 75 | ccp.className = WC_DCHECKBOX; 76 | 77 | super.createControlParams(ccp); 78 | } 79 | } 80 | 81 | /// Standard windows _RadioButton 82 | class RadioButton : CheckedButton { 83 | protected override void createControlParams(ref CreateControlParams ccp) { 84 | switch (this._drawMode) { 85 | case OwnerDrawMode.normal: 86 | this.setStyle(BS_AUTORADIOBUTTON, true); 87 | break; 88 | 89 | case OwnerDrawMode.fixed, OwnerDrawMode.variable: 90 | this.setStyle(BS_OWNERDRAW, true); 91 | break; 92 | 93 | default: 94 | break; 95 | } 96 | 97 | ccp.className = WC_DRADIOBUTTON; 98 | 99 | super.createControlParams(ccp); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/dguihub/colordialog.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.colordialog; 10 | 11 | public import dguihub.core.dialogs.commondialog; 12 | 13 | class ColorDialog : CommonDialog!(CHOOSECOLORW, Color) { 14 | public override bool showDialog() { 15 | static COLORREF[16] custColors; 16 | custColors[] = RGB(255, 255, 255); 17 | 18 | this._dlgStruct.lStructSize = CHOOSECOLORW.sizeof; 19 | this._dlgStruct.lpCustColors = custColors.ptr; // Must be defined !!! 20 | this._dlgStruct.hwndOwner = GetActiveWindow(); 21 | 22 | if (ChooseColorW(&this._dlgStruct)) { 23 | this._dlgRes = Color.fromCOLORREF(this._dlgStruct.rgbResult); 24 | return true; 25 | } 26 | 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/dguihub/contextmenu.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.contextmenu; 10 | 11 | private import dguihub.core.geometry; 12 | public import dguihub.core.menu.abstractmenu; 13 | 14 | class ContextMenu : RootMenu { 15 | public void popupMenu(HWND hWnd, Point pt) { 16 | if (!this.created) { 17 | this.create(); 18 | } 19 | 20 | TrackPopupMenu(this._handle, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, null); 21 | } 22 | 23 | public override void create() { 24 | this._handle = CreatePopupMenu(); 25 | super.create(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/dguihub/core/charset.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | 10 | /* ANSI <-> UNICODE bridge module */ 11 | 12 | module dguihub.core.charset; 13 | 14 | import std.conv : to; 15 | public import std.utf : toUTFz; 16 | import dguihub.core.winapi; 17 | import dguihub.core.utils; 18 | 19 | /** 20 | * $(B) Unicode Wrapper of CreateWindowEx API $(B) 21 | */ 22 | public HWND createWindowEx(DWORD exStyle, string className, string windowName, 23 | DWORD style, int x, int y, int nWidth, int nHeight, HWND hWndParent, LPVOID lpParam) { 24 | return CreateWindowExW(exStyle, toUTFz!(wchar*)(className), 25 | toUTFz!(wchar*)(windowName), style, x, y, nWidth, nHeight, hWndParent, 26 | null, getHInstance(), lpParam); 27 | } 28 | 29 | public BOOL getClassInfoEx(string className, WNDCLASSEXW* pWndClassEx) { 30 | return GetClassInfoExW(getHInstance(), toUTFz!(wchar*)(className), pWndClassEx); 31 | } 32 | 33 | public string getModuleFileName(HMODULE hModule) { 34 | wchar[MAX_PATH + 1] path = void; 35 | 36 | int len = GetModuleFileNameW(hModule, path.ptr, path.length); 37 | return to!(string)(path[0 .. len]); 38 | } 39 | 40 | public HICON extractAssociatedIcon(string s, WORD* pIcon) { 41 | return ExtractAssociatedIconW(getHInstance(), toUTFz!(wchar*)(s), pIcon); 42 | } 43 | 44 | public HANDLE loadImage(HINSTANCE hInstance, string s, UINT uType, int cxDesired, 45 | int cyDesired, UINT fuLoad) { 46 | return LoadImageW(hInstance, toUTFz!(wchar*)(s), uType, cxDesired, cyDesired, fuLoad); 47 | } 48 | 49 | public HANDLE loadImage(HINSTANCE hInstance, wchar* pResID, UINT uType, 50 | int cxDesired, int cyDesired, UINT fuLoad) { 51 | return LoadImageW(hInstance, pResID, uType, cxDesired, cyDesired, fuLoad); 52 | } 53 | 54 | public int drawTextEx(HDC hdc, string s, RECT* lprc, UINT dwDTFormat, DRAWTEXTPARAMS* lpDTParams) { 55 | return DrawTextExW(hdc, toUTFz!(wchar*)(s), -1, lprc, dwDTFormat, lpDTParams); 56 | } 57 | 58 | public HMODULE loadLibrary(string s) { 59 | return LoadLibraryW(toUTFz!(wchar*)(s)); 60 | } 61 | 62 | public HMODULE getModuleHandle(string s) { 63 | return GetModuleHandleW(toUTFz!(wchar*)(s)); 64 | } 65 | 66 | public void getTempPath(ref string s) { 67 | wchar[MAX_PATH + 1] path = void; 68 | 69 | int len = GetTempPathW(MAX_PATH, path.ptr); 70 | s = to!(string)(path[0 .. len]); 71 | } 72 | 73 | public int getWindowTextLength(HWND hWnd) { 74 | return GetWindowTextLengthW(hWnd); 75 | } 76 | 77 | public string getWindowText(HWND hWnd) { 78 | int len = getWindowTextLength(hWnd); 79 | 80 | if (!len) { 81 | return null; 82 | } 83 | 84 | len++; 85 | 86 | wchar[] t = new wchar[len]; 87 | len = GetWindowTextW(hWnd, t.ptr, len); 88 | return to!(string)(t[0 .. len]); 89 | } 90 | 91 | public BOOL setWindowText(HWND hWnd, string s) { 92 | return SetWindowTextW(hWnd, toUTFz!(wchar*)(s)); 93 | } 94 | 95 | public HFONT createFontIndirect(LOGFONTW* lf) { 96 | return CreateFontIndirectW(lf); 97 | } 98 | 99 | public HFONT createFontIndirect(string s, LOGFONTW* lf) { 100 | if (s.length >= LF_FACESIZE) { 101 | s = s[0 .. LF_FACESIZE - 1]; 102 | } 103 | 104 | wstring ws = to!(wstring)(s); 105 | 106 | foreach (int i, wchar wch; ws) { 107 | lf.lfFaceName[i] = wch; 108 | } 109 | 110 | lf.lfFaceName[ws.length] = '\0'; 111 | 112 | return CreateFontIndirectW(lf); 113 | } 114 | 115 | public DWORD getClassLong(HWND hWnd, int nIndex) { 116 | return GetClassLongW(hWnd, nIndex); 117 | } 118 | 119 | public DWORD setWindowLong(HWND hWnd, int nIndex, LONG dwNewLong) { 120 | return SetWindowLongW(hWnd, nIndex, dwNewLong); 121 | } 122 | 123 | public LONG getWindowLong(HWND hWnd, int nIndex) { 124 | return GetWindowLongW(hWnd, nIndex); 125 | } 126 | 127 | public ATOM registerClassEx(string className, HCURSOR hCursor, HBRUSH hBackground, 128 | WNDPROC wndProc, uint style) { 129 | WNDCLASSEXW wc; 130 | 131 | wc.cbSize = WNDCLASSEXW.sizeof; 132 | wc.lpszClassName = toUTFz!(wchar*)(className); 133 | wc.hCursor = hCursor; 134 | wc.hInstance = getHInstance(); 135 | wc.hbrBackground = hBackground; 136 | wc.lpfnWndProc = wndProc; 137 | wc.style = style; 138 | 139 | return RegisterClassExW(&wc); 140 | } 141 | 142 | public ATOM registerClassEx(WNDCLASSEXW* wc) { 143 | return RegisterClassExW(wc); 144 | } 145 | -------------------------------------------------------------------------------- /src/dguihub/core/collection.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.collection; 10 | 11 | class Collection(T) { 12 | private T[] _t; 13 | 14 | public final int add(T t) { 15 | this._t ~= t; 16 | return this._t.length - 1; 17 | } 18 | 19 | public final void clear() { 20 | this._t.length = 0; 21 | } 22 | 23 | public final T[] get() { 24 | return this._t; 25 | } 26 | 27 | @property public final int length() { 28 | return this._t.length; 29 | } 30 | 31 | public final void remove(T t) { 32 | this.removeAt(this.find(t)); 33 | } 34 | 35 | public final void removeAt(int idx) { 36 | int x = 0; 37 | T[] newT = new T[this._t.length - 1]; 38 | 39 | foreach (int i, T t; this._t) { 40 | if (i != idx) { 41 | newT[x] = t; 42 | x++; 43 | } 44 | } 45 | 46 | this._t = newT; 47 | } 48 | 49 | public final int find(T t) { 50 | foreach (int i, T ft; this._t) { 51 | if (ft is t) { 52 | return i; 53 | } 54 | } 55 | 56 | return -1; 57 | } 58 | 59 | public T opIndex(int i) nothrow { 60 | if (i >= 0 && i < this._t.length) { 61 | return this._t[i]; 62 | } 63 | 64 | assert(false, "Index out of range"); 65 | } 66 | 67 | public int opApply(int delegate(ref T) dg) { 68 | int res = 0; 69 | 70 | if (this._t.length) { 71 | for (int i = 0; i < this._t.length; i++) { 72 | res = dg(this._t[i]); 73 | 74 | if (res) { 75 | break; 76 | } 77 | } 78 | } 79 | 80 | return res; 81 | } 82 | 83 | public int opApply(int delegate(ref int, ref T) dg) { 84 | int res = 0; 85 | 86 | if (this._t.length) { 87 | for (int i = 0; i < this._t.length; i++) { 88 | res = dg(i, this._t[i]); 89 | 90 | if (res) { 91 | break; 92 | } 93 | } 94 | } 95 | 96 | return res; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/abstractbutton.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | * 3 | * Copyright: Trogu Antonio Davide 2011-2013 4 | * 5 | * License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * 7 | * Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.abstractbutton; 10 | 11 | public import dguihub.core.dialogs.dialogresult; 12 | public import dguihub.core.controls.ownerdrawcontrol; 13 | 14 | /** 15 | * Enum that contain the check state of a *CheckBox* or similar component 16 | */ 17 | enum CheckState : uint { 18 | checked = BST_CHECKED, ///Checked State 19 | unchecked = BST_UNCHECKED, ///Unchecked State 20 | indeterminate = BST_INDETERMINATE, ///Indeterminate State 21 | } 22 | 23 | /** 24 | * Abstract class of a *Button* *CheckBox and *RadioButton* 25 | */ 26 | abstract class AbstractButton : OwnerDrawControl { 27 | protected DialogResult _dr = DialogResult.none; 28 | 29 | protected override void createControlParams(ref CreateControlParams ccp) { 30 | AbstractButton.setBit(this._cBits, ControlBits.ownClickMsg, true); // Let Button to handle Click Event itself 31 | 32 | ccp.superclassName = WC_BUTTON; 33 | this.setStyle(WS_TABSTOP, true); 34 | 35 | super.createControlParams(ccp); 36 | } 37 | 38 | protected override void onReflectedMessage(ref Message m) { 39 | switch (m.msg) { 40 | case WM_COMMAND: { 41 | switch (HIWORD(m.wParam)) { 42 | case BN_CLICKED: { 43 | MouseKeys mk = MouseKeys.none; 44 | 45 | if (GetAsyncKeyState(MK_LBUTTON)) { 46 | mk |= MouseKeys.left; 47 | } 48 | 49 | if (GetAsyncKeyState(MK_MBUTTON)) { 50 | mk |= MouseKeys.middle; 51 | } 52 | 53 | if (GetAsyncKeyState(MK_RBUTTON)) { 54 | mk |= MouseKeys.right; 55 | } 56 | 57 | Point p = Point(LOWORD(m.lParam), HIWORD(m.lParam)); 58 | scope MouseEventArgs e = new MouseEventArgs(p, mk); 59 | this.onClick(EventArgs.empty); 60 | 61 | if (this._dr !is DialogResult.none) { 62 | Control c = this.topLevelControl; 63 | 64 | if (c) { 65 | c.sendMessage(DGUI_SETDIALOGRESULT, this._dr, 0); 66 | } 67 | } 68 | } 69 | break; 70 | 71 | default: 72 | break; 73 | } 74 | } 75 | break; 76 | 77 | default: 78 | break; 79 | } 80 | 81 | super.onReflectedMessage(m); 82 | } 83 | } 84 | 85 | /** 86 | * Abstract class of a checkable button (_CheckBox, _RadioButton, ...) 87 | */ 88 | abstract class CheckedButton : AbstractButton { 89 | public Event!(Control, EventArgs) checkChanged; ///Checked Changed Event of a Checkable _Button 90 | 91 | private CheckState _checkState = CheckState.unchecked; 92 | 93 | /** 94 | * Returns: 95 | * True if the _Button is _checked otherwise False. 96 | * 97 | * See_Also: 98 | * checkState() property below. 99 | */ 100 | @property public bool checked() { 101 | return this.checkState is CheckState.checked; 102 | } 103 | 104 | /** 105 | * Sets the checked state of a checkable _button 106 | * 107 | * Params: 108 | * True checks the _button, False unchecks it. 109 | */ 110 | @property public void checked(bool b) { 111 | this.checkState = b ? CheckState.checked : CheckState.unchecked; 112 | } 113 | 114 | /** 115 | * Returns: 116 | * A CheckState enum that returns the state of the checkable button (it includes the indeterminate state too) 117 | */ 118 | @property public CheckState checkState() { 119 | if (this.created) { 120 | return cast(CheckState)this.sendMessage(BM_GETCHECK, 0, 0); 121 | } 122 | 123 | return this._checkState; 124 | } 125 | 126 | /** 127 | * Sets the check state of a checkable button 128 | */ 129 | @property public void checkState(CheckState cs) { 130 | this._checkState = cs; 131 | 132 | if (this.created) { 133 | this.sendMessage(BM_SETCHECK, cs, 0); 134 | } 135 | } 136 | 137 | protected override void onHandleCreated(EventArgs e) { 138 | this.sendMessage(BM_SETCHECK, this._checkState, 0); 139 | super.onHandleCreated(e); 140 | } 141 | 142 | protected override void onReflectedMessage(ref Message m) { 143 | switch (m.msg) { 144 | case WM_COMMAND: { 145 | switch (HIWORD(m.wParam)) { 146 | case BN_CLICKED: { 147 | if (this._checkState !is this.checkState) //Is Check State Changed? 148 | { 149 | this._checkState = this.checkState; 150 | this.onCheckChanged(EventArgs.empty); 151 | } 152 | } 153 | break; 154 | 155 | default: 156 | break; 157 | } 158 | } 159 | break; 160 | 161 | default: 162 | break; 163 | } 164 | 165 | super.onReflectedMessage(m); 166 | } 167 | 168 | protected void onCheckChanged(EventArgs e) { 169 | this.checkChanged(this, e); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/containercontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.containercontrol; 10 | 11 | public import dguihub.core.controls.reflectedcontrol; 12 | 13 | abstract class ContainerControl : ReflectedControl { 14 | protected Collection!(Control) _childControls; 15 | 16 | @property public final bool rtlLayout() { 17 | return cast(bool)(this.getExStyle() & WS_EX_LAYOUTRTL); 18 | } 19 | 20 | @property public final void rtlLayout(bool b) { 21 | this.setExStyle(WS_EX_LAYOUTRTL, b); 22 | } 23 | 24 | @property public final Control[] controls() { 25 | if (this._childControls) { 26 | return this._childControls.get(); 27 | } 28 | 29 | return null; 30 | } 31 | 32 | private void addChildControl(Control c) { 33 | if (!this._childControls) { 34 | this._childControls = new Collection!(Control); 35 | } 36 | 37 | this._childControls.add(c); 38 | 39 | if (this.created) { 40 | c.show(); 41 | } 42 | } 43 | 44 | protected void doChildControls() { 45 | if (this._childControls) { 46 | foreach (Control c; this._childControls) { 47 | if (!c.created) //Extra Check: Avoid creating duplicate components (added at runtime) 48 | { 49 | c.show(); 50 | } 51 | } 52 | } 53 | } 54 | 55 | protected override void createControlParams(ref CreateControlParams ccp) { 56 | this.setStyle(WS_CLIPCHILDREN, true); 57 | this.setExStyle(WS_EX_CONTROLPARENT, true); 58 | 59 | super.createControlParams(ccp); 60 | } 61 | 62 | protected override void onDGuiMessage(ref Message m) { 63 | switch (m.msg) { 64 | case DGUI_ADDCHILDCONTROL: 65 | this.addChildControl(winCast!(Control)(m.wParam)); 66 | break; 67 | 68 | default: 69 | break; 70 | } 71 | 72 | super.onDGuiMessage(m); 73 | } 74 | 75 | protected override void onHandleCreated(EventArgs e) { 76 | this.doChildControls(); 77 | super.onHandleCreated(e); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/ownerdrawcontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.ownerdrawcontrol; 10 | 11 | public import dguihub.core.controls.subclassedcontrol; 12 | public import dguihub.core.events.eventargs; 13 | 14 | enum OwnerDrawMode : ubyte { 15 | normal = 0, 16 | fixed = 1, 17 | variable = 2, 18 | } 19 | 20 | enum DrawItemState : uint { 21 | default_ = ODS_DEFAULT, 22 | checked = ODS_CHECKED, 23 | disabled = ODS_DISABLED, 24 | focused = ODS_FOCUS, 25 | grayed = ODS_GRAYED, 26 | selected = ODS_SELECTED, 27 | } 28 | 29 | class MeasureItemEventArgs : EventArgs { 30 | private int _width; 31 | private int _height; 32 | private int _index; 33 | private Canvas _canvas; 34 | 35 | public this(Canvas c, int width, int height, int index) { 36 | this._canvas = c; 37 | this._width = width; 38 | this._height = height; 39 | this._index = index; 40 | } 41 | 42 | @property public Canvas canvas() { 43 | return this._canvas; 44 | } 45 | 46 | @property public int width() { 47 | return this._width; 48 | } 49 | 50 | @property public void width(int w) { 51 | this._width = w; 52 | } 53 | 54 | @property public int height() { 55 | return this._height; 56 | } 57 | 58 | @property public void height(int h) { 59 | this._height = h; 60 | } 61 | 62 | @property public int index() { 63 | return this._index; 64 | } 65 | } 66 | 67 | class DrawItemEventArgs : EventArgs { 68 | private DrawItemState _state; 69 | private Color _foreColor; 70 | private Color _backColor; 71 | private Canvas _canvas; 72 | private Rect _itemRect; 73 | private int _index; 74 | 75 | public this(Canvas c, DrawItemState state, Rect itemRect, Color foreColor, 76 | Color backColor, int index) { 77 | this._canvas = c; 78 | this._state = state; 79 | this._itemRect = itemRect; 80 | this._foreColor = foreColor; 81 | this._backColor = backColor; 82 | this._index = index; 83 | } 84 | 85 | @property public Canvas canvas() { 86 | return this._canvas; 87 | } 88 | 89 | @property public DrawItemState itemState() { 90 | return this._state; 91 | } 92 | 93 | @property public Rect itemRect() { 94 | return this._itemRect; 95 | } 96 | 97 | @property public Color foreColor() { 98 | return this._foreColor; 99 | } 100 | 101 | @property public Color backColor() { 102 | return this._backColor; 103 | } 104 | 105 | public void drawBackground() { 106 | scope SolidBrush brush = new SolidBrush(this._backColor); 107 | this._canvas.fillRectangle(brush, this._itemRect); 108 | } 109 | 110 | public void drawFocusRect() { 111 | if (this._state & DrawItemState.focused) { 112 | DrawFocusRect(this._canvas.handle, &this._itemRect.rect); 113 | } 114 | } 115 | 116 | @property public int index() { 117 | return this._index; 118 | } 119 | } 120 | 121 | abstract class OwnerDrawControl : SubclassedControl { 122 | public Event!(Control, MeasureItemEventArgs) measureItem; 123 | public Event!(Control, DrawItemEventArgs) drawItem; 124 | 125 | protected OwnerDrawMode _drawMode = OwnerDrawMode.normal; 126 | 127 | @property public OwnerDrawMode drawMode() { 128 | return this._drawMode; 129 | } 130 | 131 | @property public void drawMode(OwnerDrawMode dm) { 132 | this._drawMode = dm; 133 | } 134 | 135 | protected void onMeasureItem(MeasureItemEventArgs e) { 136 | this.measureItem(this, e); 137 | } 138 | 139 | protected void onDrawItem(DrawItemEventArgs e) { 140 | this.drawItem(this, e); 141 | } 142 | 143 | protected override void onReflectedMessage(ref Message m) { 144 | switch (m.msg) { 145 | case WM_MEASUREITEM: { 146 | MEASUREITEMSTRUCT* pMeasureItem = cast(MEASUREITEMSTRUCT*)m.lParam; 147 | HDC hdc = GetDC(this._handle); 148 | SetBkColor(hdc, this.backColor.colorref); 149 | SetTextColor(hdc, this.foreColor.colorref); 150 | 151 | scope Canvas c = Canvas.fromHDC(hdc); 152 | scope MeasureItemEventArgs e = new MeasureItemEventArgs(c, 153 | pMeasureItem.itemWidth, pMeasureItem.itemHeight, pMeasureItem.itemID); 154 | 155 | this.onMeasureItem(e); 156 | 157 | if (e.width) { 158 | pMeasureItem.itemWidth = e.width; 159 | } 160 | 161 | if (e.height) { 162 | pMeasureItem.itemHeight = e.height; 163 | } 164 | 165 | ReleaseDC(this._handle, null); 166 | } 167 | break; 168 | 169 | case WM_DRAWITEM: { 170 | DRAWITEMSTRUCT* pDrawItem = cast(DRAWITEMSTRUCT*)m.lParam; 171 | Rect r = Rect.fromRECT(&pDrawItem.rcItem); 172 | 173 | Color fc, bc; 174 | 175 | if (pDrawItem.itemState & ODS_SELECTED) { 176 | fc = SystemColors.colorHighlightText; 177 | bc = SystemColors.colorHighlight; 178 | } else { 179 | fc = this.foreColor; 180 | bc = this.backColor; 181 | } 182 | 183 | scope Canvas c = Canvas.fromHDC(pDrawItem.hDC); 184 | scope DrawItemEventArgs e = new DrawItemEventArgs(c, 185 | cast(DrawItemState)pDrawItem.itemState, r, fc, bc, pDrawItem.itemID); 186 | 187 | this.onDrawItem(e); 188 | } 189 | break; 190 | 191 | default: 192 | break; 193 | } 194 | 195 | super.onReflectedMessage(m); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/reflectedcontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.reflectedcontrol; 10 | 11 | public import dguihub.core.controls.control; 12 | 13 | abstract class ReflectedControl : Control { 14 | private void reflectMessageToChild(ref Message m) { 15 | HWND hFrom = void; //Inizializzata sotto 16 | 17 | switch (m.msg) { 18 | case WM_NOTIFY: 19 | NMHDR* pNotify = cast(NMHDR*)m.lParam; 20 | hFrom = pNotify.hwndFrom; 21 | break; 22 | 23 | case WM_MEASUREITEM: { 24 | MEASUREITEMSTRUCT* pMeasureItem = cast(MEASUREITEMSTRUCT*)m.lParam; 25 | 26 | switch (pMeasureItem.CtlType) { 27 | case ODT_COMBOBOX: 28 | hFrom = GetParent(cast(HWND)pMeasureItem.CtlID); 29 | break; 30 | 31 | case ODT_MENU: 32 | hFrom = this._handle; // Set the owner of the menu (this window) 33 | break; 34 | 35 | default: 36 | hFrom = cast(HWND)pMeasureItem.CtlID; 37 | break; 38 | } 39 | } 40 | break; 41 | 42 | case WM_DRAWITEM: { 43 | DRAWITEMSTRUCT* pDrawItem = cast(DRAWITEMSTRUCT*)m.lParam; 44 | 45 | switch (pDrawItem.CtlType) { 46 | case ODT_COMBOBOX: 47 | hFrom = GetParent(pDrawItem.hwndItem); 48 | break; 49 | 50 | case ODT_MENU: 51 | hFrom = this._handle; // Set the owner of the menu (this window) 52 | break; 53 | 54 | default: 55 | hFrom = cast(HWND)pDrawItem.hwndItem; 56 | break; 57 | } 58 | } 59 | break; 60 | 61 | default: // WM_COMMAND 62 | hFrom = cast(HWND)m.lParam; 63 | break; 64 | } 65 | 66 | /* If 'hFrom' is this window, the notification is sent by menus */ 67 | Control c = winCast!(Control)(GetWindowLongW(hFrom, GWL_USERDATA)); 68 | 69 | if (c) { 70 | c.sendMessage(DGUI_REFLECTMESSAGE, cast(WPARAM)&m, 0); 71 | } 72 | } 73 | 74 | protected override void wndProc(ref Message m) { 75 | switch (m.msg) { 76 | case WM_NOTIFY, WM_COMMAND, WM_MEASUREITEM, WM_DRAWITEM, WM_CTLCOLOREDIT, WM_CTLCOLORBTN: { 77 | this.originalWndProc(m); //Components like: ComboBoxEx need this one! 78 | 79 | if (ReflectedControl.hasBit(this._cBits, ControlBits.canNotify)) //Avoid fake notification messages caused by component's properties (like text(), checked(), ...) 80 | { 81 | this.reflectMessageToChild(m); 82 | } 83 | } 84 | break; 85 | 86 | default: 87 | super.wndProc(m); 88 | break; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/scrollablecontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.scrollablecontrol; 10 | 11 | public import dguihub.core.controls.reflectedcontrol; 12 | public import dguihub.core.events.mouseeventargs; 13 | public import dguihub.core.events.scrolleventargs; 14 | 15 | abstract class ScrollableControl : ReflectedControl { 16 | public Event!(Control, ScrollEventArgs) scroll; 17 | public Event!(Control, MouseWheelEventArgs) mouseWheel; 18 | 19 | protected final void scrollWindow(ScrollWindowDirection swd, int amount) { 20 | this.scrollWindow(swd, amount, nullRect); 21 | } 22 | 23 | protected final void scrollWindow(ScrollWindowDirection swd, int amount, Rect rectScroll) { 24 | if (this.created) { 25 | switch (swd) { 26 | case ScrollWindowDirection.left: 27 | ScrollWindowEx(this._handle, amount, 0, null, 28 | rectScroll == nullRect ? null : &rectScroll.rect, null, null, SW_INVALIDATE); 29 | break; 30 | 31 | case ScrollWindowDirection.up: 32 | ScrollWindowEx(this._handle, 0, amount, null, 33 | rectScroll == nullRect ? null : &rectScroll.rect, null, null, SW_INVALIDATE); 34 | break; 35 | 36 | case ScrollWindowDirection.right: 37 | ScrollWindowEx(this._handle, -amount, 0, null, 38 | rectScroll == nullRect ? null : &rectScroll.rect, null, null, SW_INVALIDATE); 39 | break; 40 | 41 | case ScrollWindowDirection.down: 42 | ScrollWindowEx(this._handle, 0, -amount, null, 43 | rectScroll == nullRect ? null : &rectScroll.rect, null, null, SW_INVALIDATE); 44 | break; 45 | 46 | default: 47 | break; 48 | } 49 | } 50 | } 51 | 52 | protected void onMouseWheel(MouseWheelEventArgs e) { 53 | this.mouseWheel(this, e); 54 | } 55 | 56 | protected void onScroll(ScrollEventArgs e) { 57 | this.scroll(this, e); 58 | } 59 | 60 | protected override void wndProc(ref Message m) { 61 | switch (m.msg) { 62 | case WM_MOUSEWHEEL: { 63 | short delta = GetWheelDelta(m.wParam); 64 | scope MouseWheelEventArgs e = new MouseWheelEventArgs(Point(LOWORD(m.lParam), 65 | HIWORD(m.lParam)), cast(MouseKeys)m.wParam, delta > 0 66 | ? MouseWheel.up : MouseWheel.down); 67 | this.onMouseWheel(e); 68 | this.originalWndProc(m); 69 | } 70 | break; 71 | 72 | case WM_VSCROLL, WM_HSCROLL: { 73 | ScrollDirection sd = m.msg == WM_VSCROLL ? ScrollDirection.vertical 74 | : ScrollDirection.horizontal; 75 | ScrollMode sm = cast(ScrollMode)m.wParam; 76 | 77 | scope ScrollEventArgs e = new ScrollEventArgs(sd, sm); 78 | this.onScroll(e); 79 | 80 | this.originalWndProc(m); 81 | } 82 | break; 83 | 84 | default: 85 | break; 86 | } 87 | 88 | super.wndProc(m); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/subclassedcontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.subclassedcontrol; 10 | 11 | public import dguihub.core.controls.reflectedcontrol; 12 | 13 | abstract class SubclassedControl : ReflectedControl { 14 | private WNDPROC _oldWndProc; // Original Window Procedure 15 | 16 | protected override void createControlParams(ref CreateControlParams ccp) { 17 | this._oldWndProc = WindowClass.superclass(ccp.superclassName, 18 | ccp.className, cast(WNDPROC) /*FIXME may throw*/ &Control.msgRouter); 19 | } 20 | 21 | protected override uint originalWndProc(ref Message m) { 22 | if (IsWindowUnicode(this._handle)) { 23 | m.result = CallWindowProcW(this._oldWndProc, this._handle, m.msg, m.wParam, m.lParam); 24 | } else { 25 | m.result = CallWindowProcA(this._oldWndProc, this._handle, m.msg, m.wParam, m.lParam); 26 | } 27 | 28 | return m.result; 29 | } 30 | 31 | protected override void wndProc(ref Message m) { 32 | switch (m.msg) { 33 | case WM_ERASEBKGND: { 34 | if (SubclassedControl.hasBit(this._cBits, ControlBits.doubleBuffered)) { 35 | Rect r = void; 36 | GetUpdateRect(this._handle, &r.rect, false); 37 | 38 | scope Canvas orgCanvas = Canvas.fromHDC(cast(HDC)m.wParam, false); //Don't delete it, it's a DC from WM_ERASEBKGND or WM_PAINT 39 | scope Canvas memCanvas = orgCanvas.createInMemory(); // Off Screen Canvas 40 | 41 | Message rm = m; 42 | 43 | rm.msg = WM_ERASEBKGND; 44 | rm.wParam = cast(WPARAM)memCanvas.handle; 45 | this.originalWndProc(rm); 46 | 47 | rm.msg = WM_PAINT; 48 | //rm.wParam = cast(WPARAM)memCanvas.handle; 49 | this.originalWndProc(rm); 50 | 51 | scope PaintEventArgs e = new PaintEventArgs(memCanvas, r); 52 | this.onPaint(e); 53 | 54 | memCanvas.copyTo(orgCanvas, r, r.position); 55 | SubclassedControl.setBit(this._cBits, ControlBits.erased, true); 56 | m.result = 0; 57 | } else { 58 | this.originalWndProc(m); 59 | } 60 | } 61 | break; 62 | 63 | case WM_PAINT: { 64 | if (SubclassedControl.hasBit(this._cBits, ControlBits.doubleBuffered) 65 | && SubclassedControl.hasBit(this._cBits, ControlBits.erased)) { 66 | SubclassedControl.setBit(this._cBits, ControlBits.erased, false); 67 | m.result = 0; 68 | } else { 69 | /* *** Not double buffered *** */ 70 | Rect r = void; 71 | GetUpdateRect(this._handle, &r.rect, false); //Keep drawing area 72 | this.originalWndProc(m); 73 | 74 | scope Canvas c = Canvas.fromHDC(m.wParam ? cast(HDC)m.wParam 75 | : GetDC(this._handle), m.wParam ? false : true); 76 | HRGN hRgn = CreateRectRgnIndirect(&r.rect); 77 | SelectClipRgn(c.handle, hRgn); 78 | DeleteObject(hRgn); 79 | 80 | SetBkColor(c.handle, this.backColor.colorref); 81 | SetTextColor(c.handle, this.foreColor.colorref); 82 | 83 | scope PaintEventArgs e = new PaintEventArgs(c, r); 84 | this.onPaint(e); 85 | } 86 | } 87 | break; 88 | 89 | case WM_CREATE: 90 | this.originalWndProc(m); 91 | super.wndProc(m); 92 | break; 93 | 94 | default: 95 | super.wndProc(m); 96 | break; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/dguihub/core/controls/textcontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.controls.textcontrol; 10 | 11 | public import dguihub.core.controls.subclassedcontrol; 12 | 13 | abstract class TextControl : SubclassedControl { 14 | public Event!(Control, EventArgs) textChanged; 15 | 16 | public void appendText(string s) { 17 | if (this.created) { 18 | this.sendMessage(EM_REPLACESEL, true, cast(LPARAM)toUTFz!(wchar*)(s)); 19 | } else { 20 | this._text ~= s; 21 | } 22 | } 23 | 24 | @property public final bool readOnly() { 25 | return cast(bool)(this.getStyle() & ES_READONLY); 26 | } 27 | 28 | @property public final void readOnly(bool b) { 29 | this.setStyle(ES_READONLY, b); 30 | } 31 | 32 | public void undo() { 33 | this.sendMessage(EM_UNDO, 0, 0); 34 | } 35 | 36 | public void cut() { 37 | this.sendMessage(WM_CUT, 0, 0); 38 | } 39 | 40 | public void copy() { 41 | this.sendMessage(WM_COPY, 0, 0); 42 | } 43 | 44 | public void paste() { 45 | this.sendMessage(WM_PASTE, 0, 0); 46 | } 47 | 48 | public void selectAll() { 49 | this.sendMessage(EM_SETSEL, 0, -1); 50 | } 51 | 52 | public void clear() { 53 | this.sendMessage(WM_CLEAR, 0, 0); 54 | } 55 | 56 | @property public bool modified() { 57 | if (this.created) { 58 | return cast(bool)this.sendMessage(EM_GETMODIFY, 0, 0); 59 | } 60 | 61 | return false; 62 | } 63 | 64 | @property public void modified(bool b) { 65 | this.sendMessage(EM_SETMODIFY, b, 0); 66 | } 67 | 68 | @property public int textLength() { 69 | if (this.created) { 70 | return getWindowTextLength(this._handle); 71 | } 72 | 73 | return this._text.length; 74 | } 75 | 76 | @property public final string selectedText() { 77 | CHARRANGE chrg = void; //Inizializzata sotto 78 | 79 | this.sendMessage(EM_EXGETSEL, 0, cast(LPARAM)&chrg); 80 | return this.text[chrg.cpMin .. chrg.cpMax]; 81 | } 82 | 83 | @property public final int selectionStart() { 84 | CHARRANGE chrg = void; //Inizializzata sotto 85 | 86 | this.sendMessage(EM_EXGETSEL, 0, cast(LPARAM)&chrg); 87 | return chrg.cpMin; 88 | } 89 | 90 | @property public final int selectionLength() { 91 | CHARRANGE chrg = void; //Inizializzata sotto 92 | 93 | this.sendMessage(EM_EXGETSEL, 0, cast(LPARAM)&chrg); 94 | return chrg.cpMax - chrg.cpMin; 95 | } 96 | 97 | protected override void createControlParams(ref CreateControlParams ccp) { 98 | this.setStyle(WS_TABSTOP, true); 99 | ccp.defaultBackColor = SystemColors.colorWindow; 100 | 101 | super.createControlParams(ccp); 102 | } 103 | 104 | protected override void onReflectedMessage(ref Message m) { 105 | if (m.msg == WM_COMMAND && HIWORD(m.wParam) == EN_CHANGE 106 | && TextControl.hasBit(this._cBits, ControlBits.canNotify)) { 107 | this.onTextChanged(EventArgs.empty); 108 | } 109 | 110 | super.onReflectedMessage(m); 111 | } 112 | 113 | protected override void onHandleCreated(EventArgs e) { 114 | this.modified = false; // Force to 'False' 115 | 116 | super.onHandleCreated(e); 117 | } 118 | 119 | protected void onTextChanged(EventArgs e) { 120 | this.textChanged(this, e); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/dguihub/core/dialogs/commondialog.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.dialogs.commondialog; 10 | 11 | public import dguihub.core.charset; 12 | public import dguihub.core.winapi; 13 | public import dguihub.canvas; // ??? 14 | 15 | class CommonDialog(T1, T2) { 16 | protected T1 _dlgStruct; 17 | protected T2 _dlgRes; 18 | protected string _title; 19 | 20 | @property public string title() { 21 | return this._title; 22 | } 23 | 24 | @property public void title(string s) { 25 | this._title = s; 26 | } 27 | 28 | @property public T2 result() { 29 | return this._dlgRes; 30 | } 31 | 32 | public abstract bool showDialog(); 33 | } 34 | -------------------------------------------------------------------------------- /src/dguihub/core/dialogs/dialogresult.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.dialogs.dialogresult; 10 | 11 | private import dguihub.core.winapi; 12 | 13 | enum DialogResult : int { 14 | none, 15 | ok = IDOK, 16 | yes = IDYES, 17 | no = IDNO, 18 | cancel = IDCANCEL, 19 | retry = IDRETRY, 20 | abort = IDABORT, 21 | ignore = IDIGNORE, 22 | close = cancel, //Same as 'cancel' 23 | } 24 | -------------------------------------------------------------------------------- /src/dguihub/core/events/controlcodeeventargs.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.controlcodeeventargs; 10 | 11 | public import dguihub.core.events.eventargs; 12 | public import dguihub.core.winapi; 13 | 14 | enum ControlCode : uint { 15 | ignore = 0, 16 | button = DLGC_BUTTON, 17 | defaultPushButton = DLGC_DEFPUSHBUTTON, 18 | hasSetSel = DLGC_HASSETSEL, 19 | radioButton = DLGC_RADIOBUTTON, 20 | static_ = DLGC_STATIC, 21 | noDefaultPushButton = DLGC_UNDEFPUSHBUTTON, 22 | wantAllKeys = DLGC_WANTALLKEYS, 23 | wantArrows = DLGC_WANTARROWS, 24 | wantChars = DLGC_WANTCHARS, 25 | wantTab = DLGC_WANTTAB, 26 | } 27 | 28 | class ControlCodeEventArgs : EventArgs { 29 | private ControlCode _ctrlCode = ControlCode.ignore; 30 | 31 | @property public ControlCode controlCode() { 32 | return this._ctrlCode; 33 | } 34 | 35 | @property public void controlCode(ControlCode cc) { 36 | this._ctrlCode = cc; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/dguihub/core/events/event.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.event; 10 | 11 | struct Event(T1, T2) { 12 | private alias void delegate(T1, T2) SlotDelegate; 13 | private alias void function(T1, T2) SlotFunction; 14 | 15 | private SlotDelegate[] _slotDg; 16 | private SlotFunction[] _slotFn; 17 | 18 | public alias opCall call; 19 | 20 | public void opCall(T1 t1, T2 t2) { 21 | synchronized { 22 | for (int i = 0; i < this._slotDg.length; i++) { 23 | this._slotDg[i](t1, t2); 24 | } 25 | 26 | for (int i = 0; i < this._slotFn.length; i++) { 27 | this._slotFn[i](t1, t2); 28 | } 29 | } 30 | } 31 | 32 | public void attach(SlotDelegate dg) { 33 | if (dg) { 34 | this._slotDg ~= dg; 35 | } 36 | } 37 | 38 | public void attach(SlotFunction fn) { 39 | if (fn) { 40 | this._slotFn ~= fn; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/dguihub/core/events/eventargs.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.eventargs; 10 | 11 | class EventArgs { 12 | private static EventArgs _empty; 13 | 14 | protected this() { 15 | 16 | } 17 | 18 | @property public static EventArgs empty() { 19 | if (!this._empty) { 20 | _empty = new EventArgs(); 21 | } 22 | 23 | return _empty; 24 | } 25 | } 26 | 27 | class CancelEventArgs(T) : EventArgs { 28 | private bool _cancel = false; 29 | private T _t; 30 | 31 | public this(T t) { 32 | this._t = t; 33 | } 34 | 35 | @property public final bool cancel() { 36 | return this._cancel; 37 | } 38 | 39 | @property public final void cancel(bool b) { 40 | this._cancel = b; 41 | } 42 | 43 | @property public final T item() { 44 | return this._t; 45 | } 46 | } 47 | 48 | class ItemEventArgs(T) : EventArgs { 49 | private T _checkedItem; 50 | 51 | public this(T item) { 52 | this._checkedItem = item; 53 | } 54 | 55 | @property public T item() { 56 | return this._checkedItem; 57 | } 58 | } 59 | 60 | class ItemChangedEventArgs(T) : EventArgs { 61 | private T _oldItem; 62 | private T _newItem; 63 | 64 | public this(T oItem, T nItem) { 65 | this._oldItem = oItem; 66 | this._newItem = nItem; 67 | } 68 | 69 | @property public T oldItem() { 70 | return this._oldItem; 71 | } 72 | 73 | @property public T newItem() { 74 | return this._newItem; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/dguihub/core/events/keyeventargs.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.keyeventargs; 10 | 11 | public import dguihub.core.events.eventargs; 12 | 13 | enum Keys : uint // docmain 14 | { 15 | none = 0, /// No keys specified. 16 | 17 | /// 18 | shift = 0x10000, /// Modifier keys. 19 | control = 0x20000, 20 | alt = 0x40000, 21 | 22 | a = 'A', /// Letters. 23 | b = 'B', 24 | c = 'C', 25 | d = 'D', 26 | e = 'E', 27 | f = 'F', 28 | g = 'G', 29 | h = 'H', 30 | i = 'I', 31 | j = 'J', 32 | k = 'K', 33 | l = 'L', 34 | m = 'M', 35 | n = 'N', 36 | o = 'O', 37 | p = 'P', 38 | q = 'Q', 39 | r = 'R', 40 | s = 'S', 41 | t = 'T', 42 | u = 'U', 43 | v = 'V', 44 | w = 'W', 45 | x = 'X', 46 | y = 'Y', 47 | z = 'Z', 48 | 49 | d0 = '0', /// Digits. 50 | d1 = '1', 51 | d2 = '2', 52 | d3 = '3', 53 | d4 = '4', 54 | d5 = '5', 55 | d6 = '6', 56 | d7 = '7', 57 | d8 = '8', 58 | d9 = '9', 59 | 60 | f1 = 112, /// F - function keys. 61 | f2 = 113, 62 | f3 = 114, 63 | f4 = 115, 64 | f5 = 116, 65 | f6 = 117, 66 | f7 = 118, 67 | f8 = 119, 68 | f9 = 120, 69 | f10 = 121, 70 | f11 = 122, 71 | f12 = 123, 72 | f13 = 124, 73 | f14 = 125, 74 | f15 = 126, 75 | f16 = 127, 76 | f17 = 128, 77 | f18 = 129, 78 | f19 = 130, 79 | f20 = 131, 80 | f21 = 132, 81 | f22 = 133, 82 | f23 = 134, 83 | f24 = 135, 84 | 85 | numPad0 = 96, /// Numbers on keypad. 86 | numPad1 = 97, 87 | numPad2 = 98, 88 | numPad3 = 99, 89 | numPad4 = 100, 90 | numPad5 = 101, 91 | numPad6 = 102, 92 | numPad7 = 103, 93 | numPad8 = 104, 94 | numPad9 = 105, 95 | 96 | add = 107, /// 97 | apps = 93, /// Application. 98 | attn = 246, /// 99 | back = 8, /// Backspace. 100 | cancel = 3, /// 101 | capital = 20, /// 102 | capsLock = 20, 103 | clear = 12, /// 104 | controlKey = 17, /// 105 | crSel = 247, /// 106 | decimal = 110, /// 107 | del = 46, /// 108 | delete_ = del, /// 109 | period = 190, /// 110 | dot = period, 111 | divide = 111, /// 112 | down = 40, /// Down arrow. 113 | end = 35, /// 114 | enter = 13, /// 115 | eraseEOF = 249, /// 116 | escape = 27, /// 117 | execute = 43, /// 118 | exsel = 248, /// 119 | finalMode = 4, /// IME final mode. 120 | hangulMode = 21, /// IME Hangul mode. 121 | hanguelMode = 21, 122 | hanjaMode = 25, /// IME Hanja mode. 123 | help = 47, /// 124 | home = 36, /// 125 | imeAccept = 30, /// 126 | imeConvert = 28, /// 127 | imeModeChange = 31, /// 128 | imeNonConvert = 29, /// 129 | insert = 45, /// 130 | junjaMode = 23, /// 131 | kanaMode = 21, /// 132 | kanjiMode = 25, /// 133 | leftControl = 162, /// Left Ctrl. 134 | left = 37, /// Left arrow. 135 | lineFeed = 10, /// 136 | leftMenu = 164, /// Left Alt. 137 | leftShift = 160, /// 138 | leftWin = 91, /// Left Windows logo. 139 | menu = 18, /// Alt. 140 | multiply = 106, /// 141 | next = 34, /// Page down. 142 | noName = 252, // Reserved for future use. 143 | numLock = 144, /// 144 | oem8 = 223, // OEM specific. 145 | oemClear = 254, 146 | pa1 = 253, 147 | pageDown = 34, /// 148 | pageUp = 33, /// 149 | pause = 19, /// 150 | play = 250, /// 151 | print = 42, /// 152 | printScreen = 44, /// 153 | processKey = 229, /// 154 | rightControl = 163, /// Right Ctrl. 155 | return_ = 13, /// 156 | right = 39, /// Right arrow. 157 | rightMenu = 165, /// Right Alt. 158 | rightShift = 161, /// 159 | rightWin = 92, /// Right Windows logo. 160 | scroll = 145, /// Scroll lock. 161 | select = 41, /// 162 | separator = 108, /// 163 | shiftKey = 16, /// 164 | snapshot = 44, /// Print screen. 165 | space = 32, /// 166 | spacebar = space, // Extra. 167 | subtract = 109, /// 168 | tab = 9, /// 169 | up = 38, /// Up arrow. 170 | zoom = 251, /// 171 | 172 | // Windows 2000+ 173 | browserBack = 166, /// 174 | browserFavorites = 171, 175 | browserForward = 167, 176 | browserHome = 172, 177 | browserRefresh = 168, 178 | browserSearch = 170, 179 | browserStop = 169, 180 | launchApplication1 = 182, /// 181 | launchApplication2 = 183, 182 | launchMail = 180, 183 | mediaNextTrack = 176, /// 184 | mediaPlayPause = 179, 185 | mediaPreviousTrack = 177, 186 | mediaStop = 178, 187 | oemBackslash = 226, // OEM angle bracket or backslash. 188 | oemCloseBrackets = 221, 189 | oemComma = 188, 190 | oemMinus = 189, 191 | oemOpenBrackets = 219, 192 | oemPeriod = 190, 193 | oemPipe = 220, 194 | oemPlus = 187, 195 | oemQuestion = 191, 196 | oemQuotes = 222, 197 | oemSemicolon = 186, 198 | oemTilde = 192, 199 | selectMedia = 181, /// 200 | volumeDown = 174, /// 201 | volumeMute = 173, 202 | volumeUp = 175, 203 | 204 | /// Bit mask to extract key code from key value. 205 | keyCode = 0xFFFF, 206 | 207 | /// Bit mask to extract modifiers from key value. 208 | modifiers = 0xFFFF0000, 209 | } 210 | 211 | class KeyEventArgs : EventArgs { 212 | private Keys _keys; 213 | private bool _handled = true; 214 | 215 | public this(Keys keys) { 216 | this._keys = keys; 217 | } 218 | 219 | @property public Keys keyCode() { 220 | return this._keys; 221 | } 222 | 223 | @property public bool handled() { 224 | return this._handled; 225 | } 226 | 227 | @property public void handled(bool b) { 228 | this._handled = b; 229 | } 230 | } 231 | 232 | class KeyCharEventArgs : KeyEventArgs { 233 | private char _keyChar; 234 | 235 | public this(Keys keys, char keyCh) { 236 | super(keys); 237 | this._keyChar = keyCh; 238 | } 239 | 240 | @property public char keyChar() { 241 | return this._keyChar; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /src/dguihub/core/events/mouseeventargs.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.mouseeventargs; 10 | 11 | public import dguihub.core.events.eventargs; 12 | import dguihub.core.geometry; 13 | import dguihub.core.winapi; 14 | 15 | enum MouseWheel : ubyte { 16 | up, 17 | down, 18 | } 19 | 20 | enum MouseKeys : uint { 21 | none = 0, // No mouse buttons specified. 22 | 23 | // Standard mouse keys 24 | left = MK_LBUTTON, 25 | right = MK_RBUTTON, 26 | middle = MK_MBUTTON,// Windows 2000+ 27 | //XBUTTON1 = 0x0800000, 28 | //XBUTTON2 = 0x1000000, 29 | } 30 | 31 | class MouseEventArgs : EventArgs { 32 | private MouseKeys _mKeys; 33 | private Point _cursorPos; 34 | 35 | public this(Point cursorPos, MouseKeys mk) { 36 | this._cursorPos = cursorPos; 37 | this._mKeys = mk; 38 | } 39 | 40 | @property public Point location() { 41 | return this._cursorPos; 42 | } 43 | 44 | @property public MouseKeys keys() { 45 | return this._mKeys; 46 | } 47 | } 48 | 49 | class MouseWheelEventArgs : MouseEventArgs { 50 | private MouseWheel _mw; 51 | 52 | public this(Point cursorPos, MouseKeys mk, MouseWheel mw) { 53 | this._mw = mw; 54 | 55 | super(cursorPos, mk); 56 | } 57 | 58 | @property public MouseWheel wheel() { 59 | return this._mw; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/dguihub/core/events/painteventargs.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.painteventargs; 10 | 11 | public import dguihub.core.events.eventargs; 12 | import dguihub.core.geometry; 13 | import dguihub.canvas; 14 | 15 | class PaintEventArgs : EventArgs { 16 | private Canvas _canvas; 17 | private Rect _clipRectangle; 18 | 19 | public this(Canvas c, Rect r) { 20 | this._canvas = c; 21 | this._clipRectangle = r; 22 | } 23 | 24 | @property public final Canvas canvas() { 25 | return this._canvas; 26 | } 27 | 28 | @property public final Rect clipRectangle() { 29 | return this._clipRectangle; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/dguihub/core/events/scrolleventargs.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.events.scrolleventargs; 10 | 11 | public import dguihub.core.events.eventargs; 12 | import dguihub.core.winapi; 13 | 14 | enum ScrollMode : uint { 15 | bottom = SB_BOTTOM, 16 | endScroll = SB_ENDSCROLL, 17 | lineDown = SB_LINEDOWN, 18 | lineUp = SB_LINEUP, 19 | pageDown = SB_PAGEDOWN, 20 | pageUp = SB_PAGEUP, 21 | thumbPosition = SB_THUMBPOSITION, 22 | thumbTrack = SB_THUMBTRACK, 23 | top = SB_TOP, 24 | left = SB_LEFT, 25 | right = SB_RIGHT, 26 | lineLeft = SB_LINELEFT, 27 | lineRight = SB_LINERIGHT, 28 | pageLeft = SB_PAGELEFT, 29 | pageRight = SB_PAGERIGHT, 30 | } 31 | 32 | enum ScrollWindowDirection : ubyte { 33 | left = 0, 34 | up = 1, 35 | right = 2, 36 | down = 4, 37 | } 38 | 39 | enum ScrollDirection : ubyte { 40 | vertical, 41 | horizontal, 42 | } 43 | 44 | class ScrollEventArgs : EventArgs { 45 | private ScrollDirection _dir; 46 | private ScrollMode _mode; 47 | 48 | public this(ScrollDirection sd, ScrollMode sm) { 49 | this._dir = sd; 50 | this._mode = sm; 51 | } 52 | 53 | @property public ScrollDirection direction() { 54 | return this._dir; 55 | } 56 | 57 | @property public ScrollMode mode() { 58 | return this._mode; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/dguihub/core/exception.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.exception; 10 | 11 | import std.string : format; 12 | import std.windows.syserror; 13 | import dguihub.core.winapi : GetLastError; 14 | 15 | mixin template exceptionBody() { 16 | public this(string msg) { 17 | super(msg); 18 | } 19 | } 20 | 21 | final class DGuiException : Exception { 22 | mixin exceptionBody; 23 | } 24 | 25 | final class Win32Exception : Exception { 26 | mixin exceptionBody; 27 | } 28 | 29 | final class RegistryException : Exception { 30 | mixin exceptionBody; 31 | } 32 | 33 | final class GDIException : Exception { 34 | mixin exceptionBody; 35 | } 36 | 37 | final class WindowsNotSupportedException : Exception { 38 | mixin exceptionBody; 39 | } 40 | 41 | void throwException(T1, T2...)(string fmt, T2 args) { 42 | static if (is(T1 : Win32Exception)) { 43 | throw new T1(format(fmt ~ "\nWindows Message: '%s'", args, sysErrorString(GetLastError()))); 44 | } else { 45 | throw new T1(format(fmt, args)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/dguihub/core/geometry.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.geometry; 10 | 11 | import dguihub.core.winapi; 12 | 13 | struct Rect { 14 | public union { 15 | align(1) struct { 16 | uint left = 0; 17 | uint top = 0; 18 | uint right = 0; 19 | uint bottom = 0; 20 | } 21 | 22 | RECT rect; 23 | } 24 | 25 | public static Rect opCall(Point pt, Size sz) { 26 | return opCall(pt.x, pt.y, sz.width, sz.height); 27 | } 28 | 29 | public static Rect opCall(uint l, uint t, uint w, uint h) { 30 | Rect r = void; //Viene inizializzata sotto. 31 | 32 | r.left = l; 33 | r.top = t; 34 | r.right = l + w; 35 | r.bottom = t + h; 36 | 37 | return r; 38 | } 39 | 40 | public const bool opEquals(ref const Rect r) { 41 | return this.left == r.left && this.top == r.top && this.right == r.right 42 | && this.bottom == r.bottom; 43 | } 44 | 45 | @property public int x() { 46 | return this.left; 47 | } 48 | 49 | @property public void x(int newX) { 50 | int w = this.width; 51 | 52 | this.left = newX; 53 | this.right = newX + w; 54 | } 55 | 56 | @property public int y() { 57 | return this.top; 58 | } 59 | 60 | @property public void y(int newY) { 61 | int h = this.height; 62 | 63 | this.top = newY; 64 | this.bottom = newY + h; 65 | } 66 | 67 | @property public int width() { 68 | if (this.right != CW_USEDEFAULT) { 69 | return this.right - this.left; 70 | } 71 | 72 | return CW_USEDEFAULT; 73 | } 74 | 75 | @property public void width(int w) { 76 | this.right = this.left + w; 77 | } 78 | 79 | @property public int height() { 80 | if (this.bottom != CW_USEDEFAULT) { 81 | return this.bottom - this.top; 82 | } 83 | 84 | return CW_USEDEFAULT; 85 | } 86 | 87 | @property public void height(int h) { 88 | this.bottom = this.top + h; 89 | } 90 | 91 | @property public Point position() { 92 | return Point(this.left, this.top); 93 | } 94 | 95 | @property public void position(Point pt) { 96 | Size sz = this.size; //Copia dimensioni 97 | 98 | this.left = pt.x; 99 | this.top = pt.y; 100 | this.right = this.left + sz.width; 101 | this.bottom = this.top + sz.height; 102 | } 103 | 104 | @property public Size size() { 105 | return Size(this.width, this.height); 106 | } 107 | 108 | @property public void size(Size sz) { 109 | this.right = this.left + sz.width; 110 | this.bottom = this.top + sz.height; 111 | } 112 | 113 | @property public bool empty() { 114 | return this.width <= 0 && this.height <= 0; 115 | } 116 | 117 | public static Rect fromRECT(RECT* pWinRect) { 118 | Rect r = void; //Inizializzata sotto 119 | 120 | r.rect = *pWinRect; 121 | return r; 122 | } 123 | } 124 | 125 | struct Point { 126 | public union { 127 | align(1) struct { 128 | uint x = 0; 129 | uint y = 0; 130 | } 131 | 132 | POINT point; 133 | } 134 | 135 | public bool inRect(Rect r) { 136 | if (point.x < r.left || point.y < r.top || point.x > r.right || point.y > r.bottom) { 137 | return false; 138 | } 139 | 140 | return true; 141 | } 142 | 143 | public bool opEquals(ref const Point pt) const { 144 | return this.x == pt.x && this.y == pt.y; 145 | } 146 | 147 | public static Point opCall(int x, int y) { 148 | Point pt = void; //Viene inizializzata sotto. 149 | 150 | pt.x = x; 151 | pt.y = y; 152 | return pt; 153 | } 154 | } 155 | 156 | struct Size { 157 | public union { 158 | align(1) struct { 159 | uint width = 0; 160 | uint height = 0; 161 | } 162 | 163 | SIZE size; 164 | } 165 | 166 | public bool opEquals(ref const Size sz) const { 167 | return this.width == sz.width && this.height == sz.height; 168 | } 169 | 170 | public static Size opCall(int w, int h) { 171 | Size sz = void; 172 | 173 | sz.width = w; 174 | sz.height = h; 175 | return sz; 176 | } 177 | } 178 | 179 | public const Rect nullRect; // = Rect.init; 180 | public const Point nullPoint; // = Point.init; 181 | public const Size nullSize; // = Size.init; 182 | -------------------------------------------------------------------------------- /src/dguihub/core/handle.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.handle; 10 | 11 | abstract class Handle(T) { 12 | protected T _handle; 13 | 14 | @property public final bool created() const { 15 | return cast(bool)this._handle; 16 | } 17 | 18 | @property public /*final*/ T handle() { 19 | return this._handle; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/dguihub/core/interfaces/idisposable.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.interfaces.idisposable; 10 | 11 | interface IDisposable { 12 | void dispose(); 13 | } 14 | -------------------------------------------------------------------------------- /src/dguihub/core/interfaces/ilayoutcontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.interfaces.ilayoutcontrol; 10 | 11 | interface ILayoutControl { 12 | void updateLayout(); 13 | } 14 | -------------------------------------------------------------------------------- /src/dguihub/core/message.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.message; 10 | 11 | import dguihub.core.winapi; 12 | 13 | /* DGui Custom Messages in order to overcome WinAPI's limitation */ 14 | enum { 15 | DGUI_BASE = WM_APP + 1, // DGui's internal message start 16 | DGUI_ADDCHILDCONTROL = DGUI_BASE, // void DGUI_ADDCHILDCONTROL(Control childControl, NULL) 17 | DGUI_DOLAYOUT = DGUI_BASE + 1, // void DGUI_DOLAYOUT(NULL, NULL) 18 | DGUI_SETDIALOGRESULT = DGUI_BASE + 2, // void DGUI_SETDIALOGRESULT(DialogResult result, NULL) 19 | DGUI_REFLECTMESSAGE = DGUI_BASE + 3, // void DGUI_REFLECTMESSAGE(Message m, NULL) 20 | DGUI_CHILDCONTROLCREATED = DGUI_BASE + 4, // void DGUI_CHILDCONTROLCREATED(Control childControl, NULL) 21 | DGUI_CREATEONLY = DGUI_BASE + 5, // void DGUI_CREATEONLY(NULL, NULL) 22 | } 23 | 24 | struct Message { 25 | HWND hWnd; 26 | uint msg; 27 | WPARAM wParam; 28 | LPARAM lParam; 29 | LRESULT result; 30 | 31 | public static Message opCall(HWND h, uint msg, WPARAM wp, LPARAM lp) { 32 | Message m; 33 | 34 | m.hWnd = h; 35 | m.msg = msg; 36 | m.wParam = wp; 37 | m.lParam = lp; 38 | 39 | return m; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/dguihub/core/tag.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.tag; 10 | 11 | public import std.variant; 12 | 13 | mixin template tagProperty() { 14 | private Variant _tt; 15 | 16 | /* 17 | * DMD 2.052 BUG: Cannot differentiate var(T)() and var(T)(T t) 18 | * template functions, use variadic template with length check. 19 | */ 20 | @property public T[0] tag(T...)() { 21 | static assert(T.length == 1, "Multiple parameters not allowed"); 22 | return this._tt.get!(T[0]); 23 | } 24 | 25 | @property public void tag(T)(T t) { 26 | this._tt = t; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/dguihub/core/utils.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.utils; 10 | 11 | import std.path; 12 | import dguihub.core.winapi; 13 | import dguihub.core.charset; 14 | 15 | enum WindowsVersion { 16 | unknown = 0, 17 | windows2000 = 1, 18 | windowsXP = 2, 19 | windowsVista = 4, 20 | windows7 = 8, 21 | } 22 | 23 | T winCast(T)(Object o) { 24 | return cast(T)(cast(void*)o); 25 | } 26 | 27 | T winCast(T)(size_t st) { 28 | return cast(T)(cast(void*)st); 29 | } 30 | 31 | HINSTANCE getHInstance() { 32 | static HINSTANCE hInst = null; 33 | 34 | if (!hInst) { 35 | hInst = GetModuleHandleW(null); 36 | } 37 | 38 | return hInst; 39 | } 40 | 41 | string getExecutablePath() { 42 | static string exePath; 43 | 44 | if (!exePath.length) { 45 | exePath = getModuleFileName(null); 46 | } 47 | 48 | return exePath; 49 | } 50 | 51 | string getStartupPath() { 52 | static string startPath; 53 | 54 | if (!startPath.length) { 55 | startPath = std.path.dirName(getExecutablePath()); 56 | } 57 | 58 | return startPath; 59 | } 60 | 61 | string getTempPath() { 62 | static string tempPath; 63 | 64 | if (!tempPath.length) { 65 | dguihub.core.charset.getTempPath(tempPath); 66 | } 67 | 68 | return tempPath; 69 | } 70 | 71 | string makeFilter(string userFilter) { 72 | char[] newFilter; 73 | foreach (char ch; userFilter) { 74 | if (ch == '|') { 75 | newFilter ~= '\0'; 76 | } else { 77 | newFilter ~= ch; 78 | } 79 | } 80 | 81 | newFilter ~= '\0'; 82 | return newFilter.idup; 83 | } unittest { 84 | assert(makeFilter("a") == "a\0"); 85 | assert(makeFilter("a|b") == "a\0b\0"); 86 | } 87 | 88 | public WindowsVersion getWindowsVersion() { 89 | static WindowsVersion ver = WindowsVersion.unknown; 90 | static WindowsVersion[uint][uint] versions; 91 | 92 | if (ver is WindowsVersion.unknown) { 93 | if (!versions.length) { 94 | versions[5][0] = WindowsVersion.windows2000; 95 | versions[5][1] = WindowsVersion.windowsXP; 96 | versions[6][0] = WindowsVersion.windowsVista; 97 | versions[6][1] = WindowsVersion.windows7; 98 | } 99 | 100 | OSVERSIONINFOW ovi; 101 | ovi.dwOSVersionInfoSize = OSVERSIONINFOW.sizeof; 102 | 103 | GetVersionExW(&ovi); 104 | 105 | WindowsVersion[uint]* pMajVer = (ovi.dwMajorVersion in versions); 106 | 107 | if (pMajVer) { 108 | WindowsVersion* pMinVer = (ovi.dwMinorVersion in *pMajVer); 109 | 110 | if (pMinVer) { 111 | ver = versions[ovi.dwMajorVersion][ovi.dwMinorVersion]; 112 | } 113 | } 114 | } 115 | 116 | return ver; 117 | } 118 | 119 | /** 120 | * Returns a wstring from a wchar array 121 | * 122 | * see https://github.com/AndrejMitrovic/DWinProgramming/blob/bbd6cc282468add8c8dbb1de1046a40e5ecb6be0/Samples/Chap22/Drum/DrumFile.d 123 | */ 124 | wstring fromWStringz(const wchar* s) { 125 | if (s is null) return null; 126 | 127 | wchar* ptr; 128 | for (ptr = cast(wchar*)s; *ptr; ++ptr) {} 129 | 130 | return to!wstring(s[0..ptr-s]); 131 | } unittest { 132 | wchar[] buffer = new wchar[](256); 133 | buffer[] = '\0'; 134 | buffer[0] = 'é'; 135 | wstring res = fromWStringz(buffer.ptr); 136 | 137 | import std.string; 138 | assert(res.length == 1, "len is %s".format(res.length)); 139 | } 140 | -------------------------------------------------------------------------------- /src/dguihub/core/wincomp.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | 10 | /* Windows 2000/XP/Vista/7 Compatibility Module */ 11 | 12 | module dguihub.core.wincomp; 13 | 14 | import dguihub.core.utils; 15 | import dguihub.core.winapi; 16 | import dguihub.core.charset; 17 | import dguihub.core.exception; 18 | 19 | private const WIN_NOT_SUPPORTED_MSG = "This function cannot be used on Windows 2000/XP"; 20 | 21 | enum { 22 | BPPF_ERASE = 0x0001, 23 | } 24 | 25 | align(1) struct BP_PAINTPARAMS { 26 | DWORD cbSize; 27 | DWORD dwFlags; 28 | RECT* prcExclude; 29 | BLENDFUNCTION* pBlendFunction; 30 | } 31 | 32 | private alias HANDLE HPAINTBUFFER; 33 | private alias uint BP_BUFFERFORMAT; //It's a enum but we need only one value from it, make it an alias of type uint. 34 | 35 | private alias extern (Windows) HPAINTBUFFER function(HDC, RECT*, 36 | BP_BUFFERFORMAT, BP_PAINTPARAMS*, HDC*) BeginBufferedPaintProc; 37 | private alias extern (Windows) HRESULT function(HPAINTBUFFER, RGBQUAD**, int*) GetBufferedPaintBitsProc; 38 | private alias extern (Windows) HRESULT function(HPAINTBUFFER, BOOL) EndBufferedPaintProc; 39 | 40 | private BeginBufferedPaintProc beginBufferedPaint; 41 | private GetBufferedPaintBitsProc getBufferedPaintBits; 42 | private EndBufferedPaintProc endBufferedPaint; 43 | 44 | private void initBitmapInfo(ref BITMAPINFO bi, SIZE sz) { 45 | bi.bmiHeader.biSize = BITMAPINFOHEADER.sizeof; 46 | bi.bmiHeader.biPlanes = 1; 47 | bi.bmiHeader.biCompression = 0; //BI_RGB; 48 | bi.bmiHeader.biWidth = sz.cx; 49 | bi.bmiHeader.biHeight = sz.cy; 50 | bi.bmiHeader.biBitCount = 32; 51 | } 52 | 53 | private HBITMAP create32BitHBITMAP(HDC hdc, SIZE sz) { 54 | BITMAPINFO bi; 55 | initBitmapInfo(bi, sz); 56 | 57 | return CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, null, null, 0); 58 | } 59 | 60 | bool hasAlpha(ARGB* pArgb, SIZE szIco, int cxRow) { 61 | ulong cxDelta = cxRow - szIco.cx; 62 | 63 | for (ulong y = szIco.cy; y; --y) { 64 | for (ulong x = szIco.cx; x; --x) { 65 | if (*pArgb++ & 0xFF000000) { 66 | return true; 67 | } 68 | } 69 | 70 | pArgb += cxDelta; 71 | } 72 | 73 | return false; 74 | } 75 | 76 | private void convertToPARGB32(HDC hdc, ARGB* pArgb, HBITMAP hBmpMask, SIZE sz, int cxRow) { 77 | BITMAPINFO bi; 78 | initBitmapInfo(bi, sz); 79 | 80 | ubyte[] pBits = new ubyte[bi.bmiHeader.biWidth * 4 * bi.bmiHeader.biHeight]; 81 | GetDIBits(hdc, hBmpMask, 0, bi.bmiHeader.biHeight, pBits.ptr, &bi, DIB_RGB_COLORS); 82 | 83 | ulong cxDelta = cxRow - bi.bmiHeader.biWidth; 84 | ARGB* pArgbMask = cast(ARGB*)pBits.ptr; 85 | 86 | for (ulong y = bi.bmiHeader.biHeight; y; --y) { 87 | for (ulong x = bi.bmiHeader.biWidth; x; --x) { 88 | if (*pArgbMask++) { 89 | // transparent pixel 90 | *pArgb++ = 0; 91 | } else { 92 | // opaque pixel 93 | *pArgb++ |= 0xFF000000; 94 | } 95 | } 96 | 97 | pArgb += cxDelta; 98 | } 99 | } 100 | 101 | private void convertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hIcon, SIZE szIco) { 102 | int cxRow; 103 | RGBQUAD* pRgbQuad; 104 | 105 | getBufferedPaintBits(hPaintBuffer, &pRgbQuad, &cxRow); 106 | ARGB* pArgb = cast(ARGB*)pRgbQuad; 107 | 108 | if (!hasAlpha(pArgb, szIco, cxRow)) { 109 | ICONINFO ii; 110 | GetIconInfo(hIcon, &ii); 111 | 112 | if (ii.hbmMask) { 113 | convertToPARGB32(hdc, pArgb, ii.hbmMask, szIco, cxRow); 114 | } 115 | 116 | DeleteObject(ii.hbmColor); 117 | DeleteObject(ii.hbmMask); 118 | } 119 | } 120 | 121 | public HBITMAP iconToBitmapPARGB32(HICON hIcon) { 122 | static HMODULE hUxTheme; 123 | WindowsVersion ver = getWindowsVersion(); 124 | 125 | SIZE szIco; 126 | szIco.cx = GetSystemMetrics(SM_CXSMICON); 127 | szIco.cy = GetSystemMetrics(SM_CYSMICON); 128 | 129 | RECT rIco; 130 | rIco.left = 0; 131 | rIco.top = 0; 132 | rIco.right = szIco.cx; 133 | rIco.bottom = szIco.cy; 134 | 135 | if (ver > WindowsVersion.windowsXP) //Is Vista or 7 136 | { 137 | if (!hUxTheme) { 138 | hUxTheme = getModuleHandle("UxTheme.dll"); 139 | 140 | beginBufferedPaint = cast(BeginBufferedPaintProc)GetProcAddress(hUxTheme, 141 | "BeginBufferedPaint"); 142 | getBufferedPaintBits = cast(GetBufferedPaintBitsProc)GetProcAddress(hUxTheme, 143 | "GetBufferedPaintBits"); 144 | endBufferedPaint = cast(EndBufferedPaintProc)GetProcAddress(hUxTheme, "EndBufferedPaint"); 145 | } 146 | 147 | HDC hdc = CreateCompatibleDC(null); 148 | HBITMAP hBitmap = create32BitHBITMAP(hdc, szIco); 149 | HBITMAP hOldBitmap = SelectObject(hdc, hBitmap); 150 | 151 | BLENDFUNCTION bf; 152 | bf.BlendOp = 0; // AC_SRC_OVER 153 | bf.SourceConstantAlpha = 255; 154 | bf.AlphaFormat = 1; // AC_SRC_ALPHA 155 | 156 | BP_PAINTPARAMS pp; 157 | pp.cbSize = BP_PAINTPARAMS.sizeof; 158 | pp.dwFlags = BPPF_ERASE; 159 | pp.pBlendFunction = &bf; 160 | 161 | HDC hdcBuffer; 162 | HPAINTBUFFER hPaintBuffer = beginBufferedPaint(hdc, &rIco, 1 /*BPBF_DIB*/ , &pp, &hdcBuffer); 163 | DrawIconEx(hdcBuffer, 0, 0, hIcon, szIco.cx, szIco.cy, 0, null, DI_NORMAL); 164 | convertBufferToPARGB32(hPaintBuffer, hdc, hIcon, szIco); 165 | endBufferedPaint(hPaintBuffer, true); 166 | 167 | SelectObject(hdc, hOldBitmap); 168 | DeleteDC(hdc); 169 | 170 | return hBitmap; 171 | } 172 | 173 | throwException!(WindowsNotSupportedException)("Not supported in 2000/XP"); 174 | return null; 175 | } 176 | -------------------------------------------------------------------------------- /src/dguihub/core/windowclass.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.core.windowclass; 10 | 11 | import std.utf : toUTFz; 12 | import dguihub.core.charset; 13 | import dguihub.core.winapi; 14 | import dguihub.core.exception; 15 | import dguihub.core.utils; 16 | import dguihub.canvas; 17 | 18 | enum { 19 | // Windows Classes 20 | WC_BUTTON = "Button", 21 | WC_COMBOBOXEX = "ComboBoxEx32", 22 | WC_LISTBOX = "ListBox", 23 | WC_LISTVIEW = "SysListView32", 24 | WC_PROGRESSBAR = "msctls_progress32", 25 | WC_RICHEDIT = "RichEdit20W", 26 | WC_STATUSBAR = "msctls_statusbar32", 27 | WC_TABCONTROL = "SysTabControl32", 28 | WC_EDIT = "EDIT", 29 | WC_TOOLBAR = "ToolBarWindow32", 30 | WC_TRACKBAR = "msctls_trackbar32", 31 | WC_TOOLTIP = "tooltips_class32", 32 | WC_TREEVIEW = "SysTreeView32", 33 | //WC_STATIC = "STATIC", 34 | 35 | // DGui Classes 36 | WC_DPANEL = "DPanel", 37 | WC_FORM = "DForm", 38 | WC_DBUTTON = "DButton", 39 | WC_DCHECKBOX = "DCheckBox", 40 | WC_DRADIOBUTTON = "DRadioButton", 41 | WC_DCOMBOBOX = "DComboBox", 42 | WC_DLABEL = "DLabel", 43 | WC_DLISTBOX = "DListBox", 44 | WC_DPICTUREBOX = "DPicturebox", 45 | WC_DLISTVIEW = "DListView", 46 | WC_DPROGRESSBAR = "DProgressBar", 47 | WC_DRICHEDIT = "DRichTextBox", 48 | WC_DSTATUSBAR = "DStatusBar", 49 | WC_DTABCONTROL = "DTabControl", 50 | WC_DEDIT = "DTextBox", 51 | WC_DTOOLBAR = "DToolBar", 52 | WC_DTRACKBAR = "DTrackBar", 53 | WC_DTOOLTIP = "DToolTip", 54 | WC_DTREEVIEW = "DTreeView", 55 | WC_DGRIDPANEL = "DGridPanel", 56 | WC_DSPLITPANEL = "DSplitPanel", 57 | } 58 | 59 | enum ClassStyles : uint { 60 | none = 0x00000000, 61 | vRedraw = 0x00000001, 62 | hRedraw = 0x00000002, 63 | keyCVTWindow = 0x00000004, 64 | doubleClicks = 0x00000008, 65 | ownDC = 0x00000020, 66 | classDC = 0x00000040, 67 | parentDC = 0x00000080, 68 | noKeyCVT = 0x00000100, 69 | noClose = 0x00000200, 70 | saveBits = 0x00000800, 71 | byteAlignClient = 0x00001000, 72 | byteAlignWindow = 0x00002000, 73 | globalClass = 0x00004000, 74 | IME = 0x00010000, 75 | } 76 | 77 | final class WindowClass { 78 | public static void register(string className, ClassStyles classStyle, 79 | Cursor cursor, WNDPROC wndProc) { 80 | WNDCLASSEXW wc; 81 | wc.cbSize = WNDCLASSEXW.sizeof; 82 | 83 | if (!getClassInfoEx(className, &wc)) { 84 | if (!registerClassEx(className, cursor ? cursor.handle 85 | : SystemCursors.arrow.handle, null, wndProc, classStyle)) { 86 | throwException!(Win32Exception)("Windows Class '%s' not created", className); 87 | } 88 | } 89 | } 90 | 91 | public static WNDPROC superclass(string oldClassName, string newClassName, WNDPROC newWndProc) { 92 | WNDCLASSEXW oldWc = void, newWc = void; 93 | 94 | oldWc.cbSize = WNDCLASSEXW.sizeof; 95 | newWc.cbSize = WNDCLASSEXW.sizeof; 96 | 97 | const(wchar)* pNewClassName = toUTFz!(const(wchar)*)(newClassName); 98 | getClassInfoEx(oldClassName, &oldWc); 99 | 100 | if (!getClassInfoEx(newClassName, &newWc)) // IF Class Non Found THEN 101 | { 102 | newWc = oldWc; 103 | newWc.style &= ~ClassStyles.globalClass; // Remove Global Class 104 | 105 | newWc.lpfnWndProc = newWndProc; 106 | newWc.lpszClassName = pNewClassName; 107 | newWc.hInstance = getHInstance(); 108 | //newWc.hbrBackground = null; 109 | 110 | if (!registerClassEx(&newWc)) { 111 | throwException!(Win32Exception)("Windows Class '%s' not created", newClassName); 112 | } 113 | } 114 | 115 | return oldWc.lpfnWndProc; //Back to the original window procedure 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/dguihub/filebrowserdialog.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.filebrowserdialog; 10 | 11 | //private import std.utf : toUTFz, toUTF8, encode; 12 | 13 | import std.conv : to; 14 | public import dguihub.core.dialogs.commondialog; 15 | 16 | import dguihub.core.utils; 17 | 18 | enum FileBrowseMode { 19 | open = 0, 20 | save = 1, 21 | } 22 | // OPENFILENAMEW is in druntime/src/core/sys/windows/commdlg.d 23 | class FileBrowserDialog : CommonDialog!(OPENFILENAMEW, string) { 24 | private string _filter; 25 | private FileBrowseMode _fbm = FileBrowseMode.open; 26 | 27 | @property public void browseMode(FileBrowseMode fbm) { 28 | this._fbm = fbm; 29 | } 30 | 31 | @property public string filter() { 32 | return this._filter; 33 | } 34 | 35 | @property public void filter(string f) { 36 | this._filter = makeFilter(f); 37 | } 38 | 39 | public override bool showDialog() { 40 | import std.array; 41 | 42 | // dynamic array 43 | wchar[] buffer = new wchar[](MAX_PATH + 1); 44 | buffer[] = '\0'; 45 | 46 | this._dlgStruct.lStructSize = OPENFILENAMEW.sizeof; 47 | this._dlgStruct.hwndOwner = GetActiveWindow(); 48 | this._dlgStruct.lpstrFilter = toUTFz!(wchar*)(this._filter); 49 | this._dlgStruct.lpstrTitle = toUTFz!(wchar*)(this._title); 50 | this._dlgStruct.lpstrFile = buffer.ptr; 51 | this._dlgStruct.nMaxFile = MAX_PATH; 52 | this._dlgStruct.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT; 53 | 54 | bool res = false; 55 | 56 | switch (this._fbm) { 57 | case FileBrowseMode.open: 58 | res = cast(bool)GetOpenFileNameW(&this._dlgStruct); 59 | break; 60 | 61 | case FileBrowseMode.save: 62 | res = cast(bool)GetSaveFileNameW(&this._dlgStruct); 63 | break; 64 | 65 | default: 66 | assert(false, "Unknown browse mode"); 67 | } 68 | 69 | if (res) { 70 | this._dlgRes = to!string(fromWStringz(buffer.ptr)); 71 | } 72 | 73 | return res; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/dguihub/folderbrowserdialog.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.folderbrowserdialog; 10 | 11 | pragma(lib, "shell32.lib"); 12 | 13 | public import dguihub.core.dialogs.commondialog; 14 | import dguihub.core.utils; 15 | 16 | import std.conv; 17 | 18 | class FolderBrowserDialog : CommonDialog!(BROWSEINFOW, string) { 19 | public override bool showDialog() { 20 | wchar[] buffer = new wchar[MAX_PATH + 1]; 21 | //wchar[MAX_PATH + 1] buffer; 22 | buffer[] = '\0'; 23 | 24 | this._dlgStruct.hwndOwner = GetActiveWindow(); 25 | this._dlgStruct.pszDisplayName = buffer.ptr; 26 | this._dlgStruct.ulFlags = BIF_RETURNONLYFSDIRS; 27 | this._dlgStruct.lpszTitle = toUTFz!(wchar*)(this._title); 28 | 29 | ITEMIDLIST* pidl = SHBrowseForFolderW(&this._dlgStruct); 30 | 31 | if (pidl) { 32 | SHGetPathFromIDListW(pidl, buffer.ptr); //Get Full Path. 33 | this._dlgRes = to!string(fromWStringz(buffer.ptr)); 34 | return true; 35 | } 36 | 37 | return false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/dguihub/fontdialog.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.fontdialog; 10 | 11 | public import dguihub.core.dialogs.commondialog; 12 | 13 | class FontDialog : CommonDialog!(CHOOSEFONTW, Font) { 14 | public override bool showDialog() { 15 | LOGFONTW lf = void; 16 | 17 | this._dlgStruct.lStructSize = CHOOSEFONTW.sizeof; 18 | this._dlgStruct.hwndOwner = GetActiveWindow(); 19 | this._dlgStruct.Flags = CF_INITTOLOGFONTSTRUCT | CF_EFFECTS | CF_SCREENFONTS; 20 | this._dlgStruct.lpLogFont = &lf; 21 | 22 | if (ChooseFontW(&this._dlgStruct)) { 23 | this._dlgRes = Font.fromHFONT(createFontIndirect(&lf)); 24 | return true; 25 | } 26 | 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/dguihub/imagelist.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.imagelist; 10 | 11 | import dguihub.core.interfaces.idisposable; 12 | import dguihub.core.collection; 13 | import dguihub.core.charset; 14 | import dguihub.core.winapi; 15 | import dguihub.core.handle; 16 | import dguihub.canvas; 17 | 18 | enum ColorDepth : uint { 19 | depth4bit = ILC_COLOR4, 20 | depth8bit = ILC_COLOR8, 21 | depth16bit = ILC_COLOR16, 22 | depth24bit = ILC_COLOR24, 23 | depth32bit = ILC_COLOR32, 24 | } 25 | 26 | /* 27 | * Dynamic Binding (Uses The Latest Version Available) 28 | */ 29 | 30 | private alias extern (Windows) HIMAGELIST function(int, int, uint, int, int) ImageList_CreateProc; 31 | private alias extern (Windows) HIMAGELIST function(HIMAGELIST) ImageList_DestroyProc; 32 | private alias extern (Windows) BOOL function(HIMAGELIST, int) ImageList_RemoveProc; 33 | private alias extern (Windows) int function(HIMAGELIST, HICON) ImageList_AddIconProc; 34 | private alias extern (Windows) int function(HIMAGELIST, int, HDC, int, int, UINT) ImageList_DrawProc; 35 | private alias extern (Windows) int function(HIMAGELIST, COLORREF) ImageList_SetBkColorProc; 36 | 37 | class ImageList : Handle!(HIMAGELIST), IDisposable { 38 | private static ImageList_CreateProc imageList_Create; 39 | private static ImageList_RemoveProc imageList_Remove; 40 | private static ImageList_AddIconProc imageList_AddIcon; 41 | private static ImageList_DestroyProc imageList_Destroy; 42 | private static ImageList_DrawProc imageList_Draw; 43 | private static ImageList_SetBkColorProc imageList_SetBkColor; 44 | 45 | private ColorDepth _depth = ColorDepth.depth32bit; 46 | private Size _size; 47 | private Collection!(Icon) _images; 48 | 49 | public this() { 50 | if (!imageList_Create) { 51 | HMODULE hModule = getModuleHandle("comctl32.dll"); 52 | 53 | /* 54 | * Static Library Issue: Use Dynamic Binding so Visual Styles are enabled (if supported) 55 | */ 56 | 57 | imageList_Create = cast(ImageList_CreateProc)GetProcAddress(hModule, "ImageList_Create"); 58 | imageList_Remove = cast(ImageList_RemoveProc)GetProcAddress(hModule, "ImageList_Remove"); 59 | imageList_AddIcon = cast(ImageList_AddIconProc)GetProcAddress(hModule, "ImageList_AddIcon"); 60 | imageList_Destroy = cast(ImageList_DestroyProc)GetProcAddress(hModule, "ImageList_Destroy"); 61 | imageList_Draw = cast(ImageList_DrawProc)GetProcAddress(hModule, "ImageList_Draw"); 62 | imageList_SetBkColor = cast(ImageList_SetBkColorProc)GetProcAddress(hModule, 63 | "ImageList_SetBkColor"); 64 | } 65 | } 66 | 67 | public ~this() { 68 | if (this.created) { 69 | this.dispose(); 70 | } 71 | } 72 | 73 | public void dispose() { 74 | foreach (Icon i; this._images) { 75 | i.dispose(); //Dispose Icons before delete the ImageList. 76 | } 77 | 78 | imageList_Destroy(this._handle); 79 | } 80 | 81 | @property public override HIMAGELIST handle() { 82 | if (!this.created) { 83 | if (this._size == nullSize) { 84 | this._size.width = 16; 85 | this._size.height = 16; 86 | } 87 | 88 | this._handle = imageList_Create(this._size.width, this._size.height, 89 | this._depth | ILC_MASK, 0, 0); 90 | imageList_SetBkColor(this._handle, CLR_NONE); 91 | } 92 | 93 | return super.handle; 94 | } 95 | 96 | public final void drawIcon(int i, Canvas dest, Point pos) { 97 | imageList_Draw(this._handle, i, dest.handle, pos.x, pos.y, ILD_NORMAL); 98 | } 99 | 100 | public final int addImage(Icon ico) { 101 | if (!this._images) { 102 | this._images = new Collection!(Icon)(); 103 | } 104 | 105 | this._images.add(ico); 106 | 107 | if (!this.created) { 108 | if (this._size == nullSize) { 109 | this._size.width = 16; 110 | this._size.height = 16; 111 | } 112 | 113 | this._handle = imageList_Create(this._size.width, this._size.height, 114 | this._depth | ILC_MASK, 0, 0); 115 | imageList_SetBkColor(this._handle, CLR_NONE); 116 | } 117 | 118 | return imageList_AddIcon(this._handle, ico.handle); 119 | } 120 | 121 | public final void removeImage(int index) { 122 | if (this._images) { 123 | this._images.removeAt(index); 124 | } 125 | 126 | if (this.created) { 127 | imageList_Remove(this._handle, index); 128 | } 129 | } 130 | 131 | public final void clear() { 132 | imageList_Remove(this._handle, -1); 133 | } 134 | 135 | @property public final Icon[] images() { 136 | if (this._images) { 137 | return this._images.get(); 138 | } 139 | 140 | return null; 141 | } 142 | 143 | @property public final Size size() { 144 | return this._size; 145 | } 146 | 147 | @property public final void size(Size sz) { 148 | this._size = sz; 149 | } 150 | 151 | @property public final ColorDepth colorDepth() { 152 | return this._depth; 153 | } 154 | 155 | @property public final void colorDepth(ColorDepth depth) { 156 | this._depth = depth; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/dguihub/label.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.label; 10 | 11 | import std.string; 12 | import dguihub.core.controls.control; 13 | 14 | enum LabelDrawMode : ubyte { 15 | normal = 0, 16 | ownerDraw = 1, 17 | } 18 | 19 | class Label : Control { 20 | private LabelDrawMode _drawMode = LabelDrawMode.normal; 21 | private TextAlignment _textAlign = TextAlignment.middle | TextAlignment.left; 22 | 23 | alias @property Control.text text; 24 | private bool _multiLine = false; 25 | 26 | @property public override void text(string s) { 27 | super.text = s; 28 | 29 | this._multiLine = false; 30 | 31 | foreach (char ch; s) { 32 | if (ch == '\n' || ch == '\r') { 33 | this._multiLine = true; 34 | break; 35 | } 36 | } 37 | 38 | if (this.created) { 39 | this.invalidate(); 40 | } 41 | } 42 | 43 | @property public final LabelDrawMode drawMode() { 44 | return this._drawMode; 45 | } 46 | 47 | @property public final void drawMode(LabelDrawMode ldm) { 48 | this._drawMode = ldm; 49 | } 50 | 51 | @property public final TextAlignment alignment() { 52 | return this._textAlign; 53 | } 54 | 55 | @property public final void alignment(TextAlignment ta) { 56 | this._textAlign = ta; 57 | 58 | if (this.created) { 59 | this.invalidate(); 60 | } 61 | } 62 | 63 | protected override void createControlParams(ref CreateControlParams ccp) { 64 | ccp.className = WC_DLABEL; 65 | ccp.classStyle = ClassStyles.hRedraw | ClassStyles.vRedraw; 66 | 67 | super.createControlParams(ccp); 68 | } 69 | 70 | protected override void onPaint(PaintEventArgs e) { 71 | super.onPaint(e); 72 | 73 | if (this._drawMode is LabelDrawMode.normal) { 74 | Canvas c = e.canvas; 75 | Rect r = Rect(nullPoint, this.clientSize); 76 | 77 | scope TextFormat tf = new TextFormat(this._multiLine 78 | ? TextFormatFlags.wordBreak : TextFormatFlags.singleLine); 79 | tf.alignment = this._textAlign; 80 | 81 | scope SolidBrush sb = new SolidBrush(this.backColor); 82 | c.fillRectangle(sb, r); 83 | c.drawText(this.text, r, this.foreColor, this.font, tf); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/dguihub/layout/gridpanel.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.layout.gridpanel; 10 | 11 | import std.algorithm; 12 | import dguihub.core.interfaces.idisposable; 13 | import dguihub.layout.layoutcontrol; 14 | 15 | class ColumnPart : IDisposable { 16 | private Control _control; 17 | private GridPanel _gridPanel; 18 | private int _width = 0; 19 | private int _marginLeft = 0; 20 | private int _marginRight = 0; 21 | 22 | package this(GridPanel gp, Control c) { 23 | this._gridPanel = gp; 24 | this._control = c; 25 | } 26 | 27 | public ~this() { 28 | this.dispose(); 29 | } 30 | 31 | public void dispose() { 32 | if (this._control) { 33 | this._control.dispose(); 34 | this._control = null; 35 | } 36 | } 37 | 38 | @property public int marginLeft() { 39 | return this._marginLeft; 40 | } 41 | 42 | @property public void marginLeft(int m) { 43 | this._marginLeft = m; 44 | } 45 | 46 | @property public int marginRight() { 47 | return this._marginRight; 48 | } 49 | 50 | @property public void marginRight(int m) { 51 | this._marginRight = m; 52 | } 53 | 54 | @property public int width() { 55 | return this._width; 56 | } 57 | 58 | @property public void width(int w) { 59 | this._width = w; 60 | 61 | if (this._gridPanel && this._gridPanel.created) { 62 | this._gridPanel.updateLayout(); 63 | } 64 | } 65 | 66 | @property public GridPanel gridPanel() { 67 | return this._gridPanel; 68 | } 69 | 70 | @property public Control control() { 71 | return this._control; 72 | } 73 | } 74 | 75 | class RowPart : IDisposable { 76 | private Collection!(ColumnPart) _columns; 77 | private GridPanel _gridPanel; 78 | private int _height = 0; 79 | private int _marginTop = 0; 80 | private int _marginBottom = 0; 81 | 82 | package this(GridPanel gp) { 83 | this._gridPanel = gp; 84 | } 85 | 86 | public ~this() { 87 | this.dispose(); 88 | } 89 | 90 | public void dispose() { 91 | if (this._columns) { 92 | foreach (ColumnPart cp; this._columns) { 93 | cp.dispose(); 94 | } 95 | 96 | this._columns.clear(); 97 | } 98 | } 99 | 100 | @property public int marginTop() { 101 | return this._marginTop; 102 | } 103 | 104 | @property public void marginTop(int m) { 105 | this._marginTop = m; 106 | } 107 | 108 | @property public int marginBottom() { 109 | return this._marginBottom; 110 | } 111 | 112 | @property public void marginBottom(int m) { 113 | this._marginBottom = m; 114 | } 115 | 116 | @property public int height() { 117 | return this._height; 118 | } 119 | 120 | @property public void height(int h) { 121 | this._height = h; 122 | 123 | if (this._gridPanel && this._gridPanel.created) { 124 | this._gridPanel.updateLayout(); 125 | } 126 | } 127 | 128 | @property public GridPanel gridPanel() { 129 | return this._gridPanel; 130 | } 131 | 132 | public ColumnPart addColumn() { 133 | return this.addColumn(null); 134 | } 135 | 136 | public ColumnPart addColumn(Control c) { 137 | if (!this._columns) { 138 | this._columns = new Collection!(ColumnPart)(); 139 | } 140 | 141 | if (c) { 142 | this._gridPanel.canAddChild = true; // Unlock Add Child 143 | c.parent = this._gridPanel; // Set the parent 144 | this._gridPanel.canAddChild = false; // Lock Add Child 145 | } 146 | 147 | ColumnPart cp = new ColumnPart(this._gridPanel, c); 148 | this._columns.add(cp); 149 | 150 | if (c && this._gridPanel && this._gridPanel.created) { 151 | c.show(); // Layout is done by LayoutControl 152 | } 153 | 154 | return cp; 155 | } 156 | 157 | public void removeColumn(int idx) { 158 | ColumnPart c = this._columns[idx]; 159 | 160 | this._columns.removeAt(idx); 161 | c.dispose(); 162 | 163 | this._gridPanel.updateLayout(); //Recalculate layout 164 | } 165 | 166 | @property public ColumnPart[] columns() { 167 | if (this._columns) { 168 | return this._columns.get(); 169 | } 170 | 171 | return null; 172 | } 173 | } 174 | 175 | class GridPanel : LayoutControl { 176 | private Collection!(RowPart) _rows; 177 | private bool _canAddChild = false; 178 | 179 | @property package void canAddChild(bool b) { 180 | this._canAddChild = b; 181 | } 182 | 183 | public RowPart addRow() { 184 | if (!this._rows) { 185 | this._rows = new Collection!(RowPart)(); 186 | } 187 | 188 | RowPart rp = new RowPart(this); 189 | this._rows.add(rp); 190 | 191 | return rp; 192 | } 193 | 194 | public void removeRow(int idx) { 195 | if (this._rows) { 196 | RowPart c = this._rows[idx]; 197 | 198 | this._rows.removeAt(idx); 199 | c.dispose(); 200 | } 201 | } 202 | 203 | @property public RowPart[] rows() { 204 | if (this._rows) { 205 | return this._rows.get(); 206 | } 207 | 208 | return null; 209 | } 210 | 211 | protected override void createControlParams(ref CreateControlParams ccp) { 212 | ccp.className = WC_DGRIDPANEL; 213 | ccp.defaultCursor = SystemCursors.arrow; 214 | 215 | super.createControlParams(ccp); 216 | } 217 | 218 | protected override void onDGuiMessage(ref Message m) { 219 | switch (m.msg) { 220 | case DGUI_ADDCHILDCONTROL: { 221 | if (this._canAddChild) { 222 | super.onDGuiMessage(m); 223 | } else { 224 | throwException!(DGuiException)("GridPanel doesn't accept child controls"); 225 | } 226 | } 227 | break; 228 | 229 | default: 230 | super.onDGuiMessage(m); 231 | break; 232 | } 233 | } 234 | 235 | public override void updateLayout() { 236 | if (this._rows) { 237 | int x = 0, y = 0, ctrlCount = 0; 238 | 239 | foreach (RowPart rp; this._rows) { 240 | if (rp.columns) { 241 | ctrlCount += rp.columns.length; 242 | } 243 | } 244 | 245 | scope ResizeManager rm = new ResizeManager(ctrlCount); 246 | 247 | foreach (RowPart rp; this._rows) { 248 | x = 0; // This is a new Row 249 | int maxCtrlHeight = rp.height; 250 | 251 | if (rp.columns) { 252 | if (!maxCtrlHeight) { 253 | // Find the max height of Controls 254 | foreach (ColumnPart cp; rp.columns) { 255 | if (cp.control) { 256 | maxCtrlHeight = max(maxCtrlHeight, cp.control.height); 257 | } 258 | } 259 | } 260 | 261 | foreach (ColumnPart cp; rp.columns) { 262 | int w = cp.width; 263 | 264 | if (cp.control) { 265 | if (!w) { 266 | w = cp.control.width; 267 | } 268 | 269 | //cp.control.bounds = Rect(cp.marginLeft + x, rp.marginTop + y, w, maxCtrlHeight); 270 | rm.resizeControl(cp.control, cp.marginLeft + x, 271 | rp.marginTop + y, w, maxCtrlHeight); 272 | } 273 | 274 | x += cp.marginLeft + w + cp.marginRight; 275 | } 276 | } 277 | 278 | y += rp.marginTop + maxCtrlHeight + rp.marginBottom; 279 | } 280 | } 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /src/dguihub/layout/layoutcontrol.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.layout.layoutcontrol; 10 | 11 | import dguihub.core.interfaces.ilayoutcontrol; 12 | public import dguihub.core.controls.containercontrol; 13 | 14 | class ResizeManager : Handle!(HDWP), IDisposable { 15 | public this(int c) { 16 | if (c > 1) { 17 | this._handle = BeginDeferWindowPos(c); 18 | } 19 | } 20 | 21 | public ~this() { 22 | this.dispose(); 23 | } 24 | 25 | public void dispose() { 26 | if (this._handle) { 27 | EndDeferWindowPos(this._handle); 28 | } 29 | } 30 | 31 | public void setPosition(Control ctrl, Point pt) { 32 | this.setPosition(ctrl, pt.x, pt.y); 33 | } 34 | 35 | public void setPosition(Control ctrl, int x, int y) { 36 | this.resizeControl(ctrl, x, y, 0, 0, PositionSpecified.position); 37 | } 38 | 39 | public void setSize(Control ctrl, Size sz) { 40 | this.setSize(ctrl, sz.width, sz.height); 41 | } 42 | 43 | public void setSize(Control ctrl, int w, int h) { 44 | this.resizeControl(ctrl, 0, 0, w, h, PositionSpecified.size); 45 | } 46 | 47 | public void resizeControl(Control ctrl, Rect r, PositionSpecified ps = PositionSpecified.all) { 48 | this.resizeControl(ctrl, r.x, r.y, r.width, r.height, ps); 49 | } 50 | 51 | public void resizeControl(Control ctrl, int x, int y, int w, int h, 52 | PositionSpecified ps = PositionSpecified.all) { 53 | uint wpf = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE; 54 | 55 | if (ps !is PositionSpecified.all) { 56 | if (ps is PositionSpecified.position) { 57 | wpf &= ~SWP_NOMOVE; 58 | } else //if(ps is PositionSpecified.size) 59 | { 60 | wpf &= ~SWP_NOSIZE; 61 | } 62 | } else { 63 | wpf &= ~(SWP_NOMOVE | SWP_NOSIZE); 64 | } 65 | 66 | if (this._handle) { 67 | this._handle = DeferWindowPos(this._handle, ctrl.handle, null, x, y, w, h, wpf); 68 | } else { 69 | SetWindowPos(ctrl.handle, null, x, y, w, h, wpf); //Bounds updated in WM_WINDOWPOSCHANGED 70 | } 71 | } 72 | } 73 | 74 | abstract class LayoutControl : ContainerControl, ILayoutControl { 75 | public override void show() { 76 | super.show(); 77 | this.updateLayout(); 78 | } 79 | 80 | public void updateLayout() { 81 | if (this._childControls && this.created && this.visible) { 82 | scope ResizeManager rm = new ResizeManager(this._childControls.length); 83 | Rect da = Rect(nullPoint, this.clientSize); 84 | 85 | foreach (Control c; this._childControls) { 86 | if (da.empty) { 87 | rm.dispose(); 88 | break; 89 | } 90 | 91 | if (c.dock !is DockStyle.none && c.visible && c.created) { 92 | switch (c.dock) { 93 | case DockStyle.left: 94 | //c.bounds = Rect(da.left, da.top, c.width, da.height); 95 | rm.resizeControl(c, da.left, da.top, c.width, da.height); 96 | da.left += c.width; 97 | break; 98 | 99 | case DockStyle.top: 100 | //c.bounds = Rect(da.left, da.top, da.width, c.height); 101 | rm.resizeControl(c, da.left, da.top, da.width, c.height); 102 | da.top += c.height; 103 | break; 104 | 105 | case DockStyle.right: 106 | //c.bounds = Rect(da.right - c.width, da.top, c.width, da.height); 107 | rm.resizeControl(c, da.right - c.width, 108 | da.top, c.width, da.height); 109 | da.right -= c.width; 110 | break; 111 | 112 | case DockStyle.bottom: 113 | //c.bounds = Rect(c, da.left, da.bottom - c.height, da.width, c.height); 114 | rm.resizeControl(c, da.left, 115 | da.bottom - c.height, da.width, c.height); 116 | da.bottom -= c.height; 117 | break; 118 | 119 | case DockStyle.fill: 120 | //c.bounds = da; 121 | rm.resizeControl(c, da); 122 | da.size = nullSize; 123 | break; 124 | 125 | default: 126 | rm.dispose(); 127 | assert(false, "Unknown DockStyle"); 128 | //break; 129 | } 130 | } 131 | } 132 | } 133 | } 134 | 135 | protected override void onDGuiMessage(ref Message m) { 136 | switch (m.msg) { 137 | case DGUI_DOLAYOUT: 138 | this.updateLayout(); 139 | break; 140 | 141 | case DGUI_CHILDCONTROLCREATED: { 142 | Control c = winCast!(Control)(m.wParam); 143 | 144 | if (c.dock !is DockStyle.none && c.visible) { 145 | this.updateLayout(); 146 | } 147 | } 148 | break; 149 | 150 | default: 151 | break; 152 | } 153 | 154 | super.onDGuiMessage(m); 155 | } 156 | 157 | protected override void onHandleCreated(EventArgs e) { 158 | super.onHandleCreated(e); 159 | 160 | this.updateLayout(); 161 | } 162 | 163 | protected override void onResize(EventArgs e) { 164 | this.updateLayout(); 165 | 166 | InvalidateRect(this._handle, null, true); 167 | UpdateWindow(this._handle); 168 | super.onResize(e); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/dguihub/layout/panel.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.layout.panel; 10 | 11 | public import dguihub.layout.layoutcontrol; 12 | 13 | class Panel : LayoutControl { 14 | protected override void createControlParams(ref CreateControlParams ccp) { 15 | ccp.className = WC_DPANEL; 16 | ccp.defaultCursor = SystemCursors.arrow; 17 | 18 | super.createControlParams(ccp); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/dguihub/layout/splitpanel.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | 10 | module dguihub.layout.splitpanel; 11 | 12 | import dguihub.core.events.event; 13 | import dguihub.core.events.eventargs; 14 | import dguihub.layout.layoutcontrol; 15 | import dguihub.layout.panel; 16 | 17 | enum SplitOrientation { 18 | vertical = 1, 19 | horizontal = 2, 20 | } 21 | 22 | class SplitPanel : LayoutControl { 23 | private enum int splitterSize = 8; 24 | 25 | private SplitOrientation _splitOrientation = SplitOrientation.vertical; 26 | private bool _downing = false; 27 | private int _splitPos = 0; 28 | private Panel _panel1; 29 | private Panel _panel2; 30 | 31 | public this() { 32 | this._panel1 = new Panel(); 33 | this._panel1.parent = this; 34 | 35 | this._panel2 = new Panel(); 36 | this._panel2.parent = this; 37 | } 38 | 39 | @property public void splitPosition(int sp) { 40 | this._splitPos = sp; 41 | 42 | if (this.created) { 43 | this.updateLayout(); 44 | } 45 | } 46 | 47 | @property public Panel panel1() { 48 | return this._panel1; 49 | } 50 | 51 | @property public Panel panel2() { 52 | return this._panel2; 53 | } 54 | 55 | @property SplitOrientation splitOrientation() { 56 | return this._splitOrientation; 57 | } 58 | 59 | @property void splitOrientation(SplitOrientation so) { 60 | this._splitOrientation = so; 61 | } 62 | 63 | public override void updateLayout() { 64 | scope ResizeManager rm = new ResizeManager(2); //Fixed Panel 65 | 66 | bool changed = false; 67 | 68 | switch (this._splitOrientation) { 69 | case SplitOrientation.vertical: { 70 | if (this._splitPos >= 0 && (this._splitPos + splitterSize) < this.width) { 71 | rm.setSize(this._panel1, this._splitPos, this.height); 72 | rm.resizeControl(this._panel2, this._splitPos + splitterSize, 0, 73 | this.width - (this._splitPos + splitterSize), this.height); 74 | changed = true; 75 | } 76 | } 77 | break; 78 | 79 | default: // SplitOrientation.horizontal 80 | { 81 | if (this._splitPos >= 0 && (this._splitPos + splitterSize) < this.height) { 82 | rm.setSize(this._panel1, this.width, this._splitPos); 83 | rm.resizeControl(this._panel2, 0, this._splitPos + splitterSize, 84 | this.width, this.height - (this._splitPos + splitterSize)); 85 | changed = true; 86 | } 87 | } 88 | break; 89 | } 90 | 91 | if (changed) { 92 | this.invalidate(); 93 | } 94 | } 95 | 96 | protected override void onMouseKeyDown(MouseEventArgs e) { 97 | if (e.keys == MouseKeys.left) { 98 | this._downing = true; 99 | SetCapture(this._handle); 100 | } 101 | 102 | super.onMouseKeyDown(e); 103 | } 104 | 105 | protected override void onMouseKeyUp(MouseEventArgs e) { 106 | if (this._downing) { 107 | this._downing = false; 108 | ReleaseCapture(); 109 | } 110 | 111 | super.onMouseKeyUp(e); 112 | } 113 | 114 | protected override void onMouseMove(MouseEventArgs e) { 115 | if (this._downing) { 116 | Point pt = Cursor.position; 117 | convertPoint(pt, null, this); 118 | 119 | switch (this._splitOrientation) { 120 | case SplitOrientation.vertical: 121 | this._splitPos = pt.x; 122 | break; 123 | 124 | default: // SplitOrientation.horizontal 125 | this._splitPos = pt.y; 126 | break; 127 | } 128 | 129 | this.updateLayout(); 130 | } 131 | 132 | super.onMouseMove(e); 133 | } 134 | 135 | protected override void createControlParams(ref CreateControlParams ccp) { 136 | ccp.className = WC_DSPLITPANEL; 137 | 138 | switch (this._splitOrientation) { 139 | case SplitOrientation.vertical: 140 | ccp.defaultCursor = SystemCursors.sizeWE; 141 | break; 142 | 143 | default: // SplitOrientation.horizontal 144 | ccp.defaultCursor = SystemCursors.sizeNS; 145 | break; 146 | } 147 | 148 | if (!this._splitPos) { 149 | switch (this._splitOrientation) { 150 | case SplitOrientation.vertical: 151 | this._splitPos = this.width / 3; 152 | break; 153 | 154 | default: // SplitOrientation.horizontal 155 | this._splitPos = this.height - (this.height / 3); 156 | break; 157 | } 158 | } 159 | 160 | super.createControlParams(ccp); 161 | } 162 | 163 | protected override void onDGuiMessage(ref Message m) { 164 | switch (m.msg) { 165 | case DGUI_ADDCHILDCONTROL: { 166 | Control c = winCast!(Control)(m.wParam); 167 | 168 | if (c is this._panel1 || c is this._panel2) { 169 | super.onDGuiMessage(m); 170 | } else { 171 | throwException!(DGuiException)("SplitPanel doesn't accept child controls"); 172 | } 173 | } 174 | break; 175 | 176 | default: 177 | super.onDGuiMessage(m); 178 | break; 179 | } 180 | } 181 | 182 | protected override void onHandleCreated(EventArgs e) { 183 | switch (this._splitOrientation) { 184 | case SplitOrientation.vertical: 185 | this.cursor = SystemCursors.sizeWE; 186 | break; 187 | 188 | default: // SplitOrientation.horizontal 189 | this.cursor = SystemCursors.sizeNS; 190 | break; 191 | } 192 | 193 | super.onHandleCreated(e); 194 | } 195 | 196 | protected override void onPaint(PaintEventArgs e) { 197 | Canvas c = e.canvas; 198 | Rect cr = e.clipRectangle; 199 | int mid = this._splitPos + (splitterSize / 2); 200 | scope Pen dp = new Pen(SystemColors.color3DDarkShadow, 2, PenStyle.dot); 201 | scope Pen lp = new Pen(SystemColors.colorButtonFace, 2, PenStyle.dot); 202 | 203 | switch (this._splitOrientation) { 204 | case SplitOrientation.vertical: { 205 | c.drawEdge(Rect(this._splitPos, cr.top, splitterSize, cr.bottom), 206 | EdgeType.raised, EdgeMode.left | EdgeMode.right); 207 | 208 | for (int p = (this.height / 2) - 15, i = 0; i < 8; i++, p += 5) { 209 | c.drawLine(dp, mid, p, mid, p + 1); 210 | c.drawLine(lp, mid - 1, p - 1, mid - 1, p); 211 | } 212 | } 213 | break; 214 | 215 | default: // SplitOrientation.horizontal 216 | { 217 | c.drawEdge(Rect(cr.left, this._splitPos, cr.right, splitterSize), 218 | EdgeType.raised, EdgeMode.top | EdgeMode.bottom); 219 | 220 | for (int p = (this.width / 2) - 15, i = 0; i < 8; i++, p += 5) { 221 | c.drawLine(dp, p, mid, p + 1, mid); 222 | c.drawLine(lp, p - 1, mid + 1, p - 1, mid); 223 | } 224 | } 225 | break; 226 | } 227 | 228 | super.onPaint(e); 229 | } 230 | 231 | protected override void wndProc(ref Message m) { 232 | if (m.msg == WM_WINDOWPOSCHANGING) { 233 | WINDOWPOS* pWndPos = cast(WINDOWPOS*)m.lParam; 234 | 235 | if (!(pWndPos.flags & SWP_NOSIZE)) { 236 | switch (this._splitOrientation) { 237 | case SplitOrientation.vertical: { 238 | if (this.width) // Avoid division by 0 239 | this._splitPos = MulDiv(pWndPos.cx, this._splitPos, this.width); 240 | } 241 | break; 242 | 243 | default: // SplitOrientation.horizontal 244 | { 245 | if (this.height) // Avoid division by 0 246 | this._splitPos = MulDiv(pWndPos.cy, this._splitPos, this.height); 247 | } 248 | break; 249 | } 250 | } 251 | } 252 | 253 | super.wndProc(m); 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /src/dguihub/listbox.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.listbox; 10 | 11 | import std.utf : toUTFz; 12 | public import dguihub.core.controls.ownerdrawcontrol; 13 | import dguihub.core.utils; 14 | 15 | class ListBox : OwnerDrawControl { 16 | private static class StringItem { 17 | private string _str; 18 | 19 | public this(string s) { 20 | this._str = s; 21 | } 22 | 23 | public override string toString() { 24 | return this._str; 25 | } 26 | } 27 | 28 | public Event!(Control, EventArgs) itemChanged; 29 | 30 | private Collection!(Object) _items; 31 | private Object _selectedItem; 32 | private int _selectedIndex; 33 | 34 | public final int addItem(string s) { 35 | return this.addItem(new StringItem(s)); 36 | } 37 | 38 | public final int addItem(Object obj) { 39 | if (!this._items) { 40 | this._items = new Collection!(Object)(); 41 | } 42 | 43 | this._items.add(obj); 44 | 45 | if (this.created) { 46 | return this.createItem(obj); 47 | } 48 | 49 | return this._items.length - 1; 50 | } 51 | 52 | public final void removeItem(int idx) { 53 | if (this.created) { 54 | this.sendMessage(LB_DELETESTRING, idx, 0); 55 | } 56 | 57 | this._items.removeAt(idx); 58 | } 59 | 60 | @property public final int selectedIndex() { 61 | if (this.created) { 62 | return this.sendMessage(LB_GETCURSEL, 0, 0); 63 | } 64 | 65 | return this._selectedIndex; 66 | } 67 | 68 | @property public final void selectedIndex(int i) { 69 | this._selectedIndex = i; 70 | 71 | if (this.created) { 72 | this.sendMessage(LB_SETCURSEL, i, 0); 73 | } 74 | } 75 | 76 | @property public final Object selectedItem() { 77 | int idx = this.selectedIndex; 78 | 79 | if (this._items) { 80 | return this._items[idx]; 81 | } 82 | 83 | return null; 84 | } 85 | 86 | @property public final string selectedString() { 87 | Object obj = this.selectedItem; 88 | return (obj ? obj.toString() : null); 89 | } 90 | 91 | @property public final Object[] items() { 92 | if (this._items) { 93 | return this._items.get(); 94 | } 95 | 96 | return null; 97 | } 98 | 99 | private int createItem(Object obj) { 100 | return this.sendMessage(LB_ADDSTRING, 0, cast(LPARAM)toUTFz!(wchar*)(obj.toString())); 101 | } 102 | 103 | protected void onItemChanged(EventArgs e) { 104 | this.itemChanged(this, e); 105 | } 106 | 107 | protected override void createControlParams(ref CreateControlParams ccp) { 108 | /* LBN_SELCHANGE: This notification code is sent only by a list box that has the LBS_NOTIFY style (by MSDN) */ 109 | this.setStyle(LBS_NOINTEGRALHEIGHT | LBS_NOTIFY, true); 110 | this.setExStyle(WS_EX_CLIENTEDGE, true); 111 | 112 | ccp.superclassName = WC_LISTBOX; 113 | ccp.className = WC_DLISTBOX; 114 | ccp.defaultBackColor = SystemColors.colorWindow; 115 | 116 | switch (this._drawMode) { 117 | case OwnerDrawMode.fixed: 118 | this.setStyle(LBS_OWNERDRAWFIXED, true); 119 | break; 120 | 121 | case OwnerDrawMode.variable: 122 | this.setStyle(LBS_OWNERDRAWVARIABLE, true); 123 | break; 124 | 125 | default: 126 | break; 127 | } 128 | 129 | super.createControlParams(ccp); 130 | } 131 | 132 | protected override void onReflectedMessage(ref Message m) { 133 | if (m.msg == WM_COMMAND && HIWORD(m.wParam) == LBN_SELCHANGE) { 134 | this._selectedIndex = this.sendMessage(LB_GETCURSEL, 0, 0); 135 | this.onItemChanged(EventArgs.empty); 136 | } 137 | 138 | super.onReflectedMessage(m); 139 | } 140 | 141 | protected override void onHandleCreated(EventArgs e) { 142 | if (this._items) { 143 | foreach (Object obj; this._items) { 144 | this.createItem(obj); 145 | } 146 | } 147 | 148 | super.onHandleCreated(e); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/dguihub/menubar.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.menubar; 10 | 11 | public import dguihub.core.menu.abstractmenu; 12 | 13 | class MenuBar : RootMenu { 14 | public override void create() { 15 | this._handle = CreateMenu(); 16 | super.create(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/dguihub/messagebox.d: -------------------------------------------------------------------------------- 1 | /** 2 | * Implements message box facilities. 3 | */ 4 | module dguihub.messagebox; 5 | 6 | import std.utf : toUTFz; 7 | 8 | private import dguihub.core.winapi; 9 | public import dguihub.core.dialogs.dialogresult; 10 | 11 | /// 12 | enum MsgBoxButtons : uint { 13 | ok = MB_OK, 14 | yesNo = MB_YESNO, 15 | okCancel = MB_OKCANCEL, 16 | retryCancel = MB_RETRYCANCEL, 17 | yesNoCancel = MB_YESNOCANCEL, 18 | abortRetryIgnore = MB_ABORTRETRYIGNORE, 19 | } 20 | 21 | /// 22 | enum MsgBoxIcons : uint { 23 | /// 24 | none = 0, 25 | /** 26 | * Icon with an exclamation point 27 | */ 28 | warning = MB_ICONWARNING, 29 | /** 30 | * Icon with a lowercase letter i in a circle. 31 | */ 32 | information = MB_ICONINFORMATION, 33 | /** 34 | * Icon with a question mark. 35 | */ 36 | question = MB_ICONQUESTION, 37 | error = MB_ICONERROR, ///Icon with a X letter. 38 | 39 | } 40 | 41 | /** 42 | * Displays a message window which presents a message to the user. 43 | */ 44 | final class MsgBox { 45 | private this() {} 46 | 47 | /** 48 | * Shows a message box. 49 | * 50 | * Params: 51 | * title = The message title 52 | * text = The text to display in the message box 53 | * button = Specifies which buttons to display in the message box. 54 | * icon = Specifies which icon to display in the message box. 55 | */ 56 | public static DialogResult show(string title, string text, MsgBoxButtons button, MsgBoxIcons icon) { 57 | return cast(DialogResult)MessageBoxW(GetActiveWindow(), 58 | toUTFz!(wchar*)(text), toUTFz!(wchar*)(title), button | icon); 59 | } 60 | 61 | /** 62 | * Shows a message box. 63 | * 64 | * Params: 65 | * title = The message title 66 | * text = The text to display in the message box 67 | * button = Specifies which buttons to display in the message box. 68 | */ 69 | public static DialogResult show(string title, string text, MsgBoxButtons button) { 70 | return MsgBox.show(title, text, button, MsgBoxIcons.none); 71 | } 72 | 73 | /** 74 | * Shows a message box with OK button. 75 | * 76 | * Params: 77 | * title = The message title 78 | * text = The text to display in the message box 79 | * icon = Specifies which icon to display in the message box. 80 | */ 81 | public static DialogResult show(string title, string text, MsgBoxIcons icon) { 82 | return MsgBox.show(title, text, MsgBoxButtons.ok, icon); 83 | } 84 | 85 | /** 86 | * Shows a message box with OK button. 87 | * 88 | * Params: 89 | * title = The message title 90 | * text = The text to display in the message box 91 | */ 92 | public static DialogResult show(string title, string text) { 93 | return MsgBox.show(title, text, MsgBoxButtons.ok, MsgBoxIcons.none); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/dguihub/package.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | 10 | /** 11 | DGui Main Import Module. 12 | 13 | $(B $(RED DLL Versions and prerequisites:)) 14 | 15 | $(TABLE 16 | $(TR $(TD $(B Version)) $(TD $(B DLL)) $(TD $(B Distribution Platform))) 17 | $(TR $(TD 4.0) $(TD All) $(TD Windows 95 and Windows NT 4.0)) 18 | $(TR $(TD 4.7) $(TD All) $(TD Windows Internet Explorer 3.x)) 19 | $(TR $(TD 4.71) $(TD All) $(TD Internet Explorer 4.0. $(I $(LPAREN)See note 2$(RPAREN)))) 20 | $(TR $(TD 4.72) $(TD All) $(TD Internet Explorer 4.01 and Windows 98. See note 2)) 21 | $(TR $(TD 5.0) $(TD Shlwapi.dll) $(TD Internet Explorer 5 and Windows 98 SE. See note 3)) 22 | $(TR $(TD 5.5) $(TD Shlwapi.dll) $(TD Internet Explorer 5.5 and Windows Millennium Edition (Windows Me))) 23 | $(TR $(TD 6.0) $(TD Shlwapi.dll) $(TD Windows XP and Windows Vista)) 24 | $(TR $(TD 5.0) $(TD Shell32.dll) $(TD Windows 2000 and Windows Me. $(I $(LPAREN)See note 3$(RPAREN)))) 25 | $(TR $(TD 6.0) $(TD Shell32.dll) $(TD Windows XP)) 26 | $(TR $(TD 6.0.1) $(TD Shell32.dll) $(TD Windows Vista)) 27 | $(TR $(TD 6.1) $(TD Shell32.dll) $(TD Windows 7)) 28 | $(TR $(TD 5.8) $(TD Comctl32.dll) $(TD Internet Explorer 5. $(I $(LPAREN)See note 3$(RPAREN)))) 29 | $(TR $(TD 5.81) $(TD Comctl32.dll) $(TD Windows 2000 and Windows Me. $(I $(LPAREN)See note 3$(RPAREN)))) 30 | $(TR $(TD 5.82) $(TD Comctl32.dll) $(TD Windows XP and Windows Vista. $(I $(LPAREN)See note 4$(RPAREN)))) 31 | $(TR $(TD 6.0) $(TD Comctl32.dll) $(TD Windows XP, Windows Vista and Windows 7 $(LPAREN)Not redistributable$(RPAREN) )) 32 | ) 33 | 34 | $(B $(BLUE NOTE 1:)) 35 | 36 | The 4.00 versions of Shell32.dll and Comctl32.dll are found on the original 37 | versions of Windows 95 and Windows NT 4.0. New versions of Commctl.dll were shipped 38 | with _all Internet Explorer releases. Shlwapi.dll shipped with Internet Explorer 4.0, 39 | so its initial version number here is 4.71. The Shell was not updated with the Internet Explorer 3.0 release, 40 | so Shell32.dll does not have a version 4.70. 41 | While Shell32.dll versions 4.71 and 4.72 were shipped with the corresponding Internet Explorer releases, 42 | they were not necessarily installed (see note 2). 43 | For subsequent releases, the version numbers for the three DLLs are not identical. 44 | In general, you should assume that _all three DLLs may have different version numbers, 45 | and test each one separately. 46 | 47 | 48 | $(B $(BLUE NOTE 2:)) 49 | 50 | All systems with Internet Explorer 4.0 or 4.01 will have the associated version of Comctl32.dll 51 | and Shlwapi.dll (4.71 or 4.72, respectively). However, for systems prior to Windows 98, 52 | Internet Explorer 4.0 and 4.01 can be installed with or without the integrated Shell. 53 | If they are installed with the integrated Shell, the associated version of Shell32.dll will be installed. 54 | If they are installed without the integrated Shell, Shell32.dll is not updated. 55 | No other versions of Internet Explorer update Shell32.dll. In other words, the presence of 56 | version 4.71 or 4.72 of Comctl32.dll or Shlwapi.dll on a system does not guarantee that Shell32.dll 57 | has the same version number. All Windows 98 systems have version 4.72 of Shell32.dll. 58 | 59 | 60 | $(B $(BLUE NOTE 3:)) 61 | 62 | Version 5.80 of Comctl32.dll and version 5.0 of Shlwapi.dll are distributed with Internet Explorer 5. 63 | They will be found on all systems on which Internet Explorer 5 is installed, except Windows 2000. 64 | Internet Explorer 5 does not update the Shell, so version 5.0 of Shell32.dll will not be found on Windows NT, 65 | Windows 95, or Windows 98 systems. 66 | Version 5.0 of Shell32.dll will be distributed with Windows 2000 and Windows Me, 67 | along with version 5.0 of Shlwapi.dll, and version 5.81 of Comctl32.dll. 68 | 69 | 70 | $(B $(BLUE NOTE 4:)) 71 | 72 | ComCtl32.dll version 6 is not redistributable. 73 | If you want your application to use ComCtl32.dll version 6, 74 | you must add an application manifest that indicates that version 6 should be used if it is available. 75 | 76 | $(I Source:) $(LINK2 http://msdn.microsoft.com/en-us/library/bb776779%28VS.85%29.aspx, MSDN) 77 | */ 78 | 79 | module dguihub; 80 | 81 | public import dguihub.application; 82 | public import dguihub.messagebox, dguihub.imagelist; 83 | public import dguihub.toolbar, dguihub.statusbar, dguihub.progressbar, dguihub.trackbar; 84 | public import dguihub.core.geometry, dguihub.core.events.event, dguihub.core.utils; 85 | public import dguihub.colordialog, dguihub.fontdialog, dguihub.filebrowserdialog, 86 | dguihub.folderbrowserdialog; 87 | public import dguihub.form, dguihub.button, dguihub.label, dguihub.textbox, 88 | dguihub.richtextbox, dguihub.tabcontrol, dguihub.combobox, dguihub.listbox, 89 | dguihub.listview, dguihub.treeview, dguihub.picturebox, dguihub.scrollbar, dguihub.tooltip; 90 | -------------------------------------------------------------------------------- /src/dguihub/picturebox.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.picturebox; 10 | 11 | import dguihub.core.controls.control; 12 | import dguihub.canvas; 13 | 14 | enum SizeMode { 15 | normal = 0, 16 | autoSize = 1, 17 | } 18 | 19 | class PictureBox : Control { 20 | private SizeMode _sm = SizeMode.normal; 21 | private Image _img; 22 | 23 | public override void dispose() { 24 | if (this._img) { 25 | this._img.dispose(); 26 | this._img = null; 27 | } 28 | 29 | super.dispose(); 30 | } 31 | 32 | alias @property Control.bounds bounds; 33 | 34 | @property public override void bounds(Rect r) { 35 | if (this._img && this._sm is SizeMode.autoSize) { 36 | // Ignora 'r.size' e usa la dimensione dell'immagine 37 | Size sz = r.size; 38 | super.bounds = Rect(r.x, r.y, sz.width, sz.height); 39 | 40 | } else { 41 | super.bounds = r; 42 | } 43 | } 44 | 45 | @property public final SizeMode sizeMode() { 46 | return this._sm; 47 | } 48 | 49 | @property public final void sizeMode(SizeMode sm) { 50 | this._sm = sm; 51 | 52 | if (this.created) { 53 | this.redraw(); 54 | } 55 | } 56 | 57 | @property public final Image image() { 58 | return this._img; 59 | } 60 | 61 | @property public final void image(Image img) { 62 | if (this._img) { 63 | this._img.dispose(); // Destroy the previous image 64 | } 65 | 66 | this._img = img; 67 | 68 | if (this.created) { 69 | this.redraw(); 70 | } 71 | } 72 | 73 | protected override void createControlParams(ref CreateControlParams ccp) { 74 | ccp.className = WC_DPICTUREBOX; 75 | ccp.defaultCursor = SystemCursors.arrow; 76 | ccp.classStyle = ClassStyles.parentDC; 77 | 78 | super.createControlParams(ccp); 79 | } 80 | 81 | protected override void onPaint(PaintEventArgs e) { 82 | if (this._img) { 83 | Canvas c = e.canvas; 84 | 85 | switch (this._sm) { 86 | case SizeMode.autoSize: 87 | c.drawImage(this._img, Rect(nullPoint, this.size)); 88 | break; 89 | 90 | default: 91 | c.drawImage(this._img, 0, 0); 92 | break; 93 | } 94 | } 95 | 96 | super.onPaint(e); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/dguihub/progressbar.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.progressbar; 10 | 11 | import dguihub.core.controls.subclassedcontrol; 12 | 13 | class ProgressBar : SubclassedControl { 14 | private uint _minRange = 0; 15 | private uint _maxRange = 100; 16 | private uint _step = 10; 17 | private uint _value = 0; 18 | 19 | @property public uint minRange() { 20 | return this._minRange; 21 | } 22 | 23 | @property public void minRange(uint mr) { 24 | this._minRange = mr; 25 | 26 | if (this.created) { 27 | this.sendMessage(PBM_SETRANGE32, this._minRange, this._maxRange); 28 | } 29 | } 30 | 31 | @property public uint maxRange() { 32 | return this._maxRange; 33 | } 34 | 35 | @property public void maxRange(uint mr) { 36 | this._maxRange = mr; 37 | 38 | if (this.created) { 39 | this.sendMessage(PBM_SETRANGE32, this._minRange, this._maxRange); 40 | } 41 | } 42 | 43 | @property public uint step() { 44 | return this._minRange; 45 | } 46 | 47 | @property public void step(uint s) { 48 | this._step = s; 49 | 50 | if (this.created) { 51 | this.sendMessage(PBM_SETSTEP, this._step, 0); 52 | } 53 | } 54 | 55 | @property public uint value() { 56 | if (this.created) { 57 | return this.sendMessage(PBM_GETPOS, 0, 0); 58 | } 59 | 60 | return this._value; 61 | } 62 | 63 | @property public void value(uint p) { 64 | this._value = p; 65 | 66 | if (this.created) { 67 | this.sendMessage(PBM_SETPOS, p, 0); 68 | } 69 | } 70 | 71 | public void increment() { 72 | if (this.created) { 73 | this.sendMessage(PBM_STEPIT, 0, 0); 74 | } else { 75 | throwException!(DGuiException)("Cannot increment the progress bar"); 76 | } 77 | } 78 | 79 | protected override void createControlParams(ref CreateControlParams ccp) { 80 | ccp.superclassName = WC_PROGRESSBAR; 81 | ccp.className = WC_DPROGRESSBAR; 82 | 83 | assert(this._dock !is DockStyle.fill, "ProgressBar: Invalid Dock Style"); 84 | 85 | if (this._dock is DockStyle.left || this._dock is DockStyle.right) { 86 | this.setStyle(PBS_VERTICAL, true); 87 | } 88 | 89 | super.createControlParams(ccp); 90 | } 91 | 92 | protected override void onHandleCreated(EventArgs e) { 93 | this.sendMessage(PBM_SETRANGE32, this._minRange, this._maxRange); 94 | this.sendMessage(PBM_SETSTEP, this._step, 0); 95 | this.sendMessage(PBM_SETPOS, this._value, 0); 96 | 97 | super.onHandleCreated(e); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/dguihub/rename.sh: -------------------------------------------------------------------------------- 1 | #sed -i 's/dgui/dguihub/g' *.d 2 | #sed -i 's/dgui/dguihub/g' ./core/*.d 3 | sed -i 's/dguihubhub/dguihub/g' ./core/*.d 4 | sed -i 's/dgui\./dguihub\./g' ./core/controls/*.d 5 | sed -i 's/dgui\./dguihub\./g' ./core/dialogs/*.d 6 | sed -i 's/dgui\./dguihub\./g' ./core/events/*.d 7 | sed -i 's/dgui\./dguihub\./g' ./core/interfaces/*.d 8 | sed -i 's/dgui\./dguihub\./g' ./core/menu/*.d 9 | sed -i 's/dgui\./dguihub\./g' ./layout/*.d 10 | 11 | -------------------------------------------------------------------------------- /src/dguihub/resources.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.resources; 10 | 11 | import dguihub.core.charset; 12 | import dguihub.core.winapi; 13 | import dguihub.core.geometry; 14 | import dguihub.core.utils; 15 | import dguihub.core.exception; 16 | import dguihub.canvas; 17 | 18 | final class Resources { 19 | private static Resources _rsrc; 20 | 21 | private this() { 22 | 23 | } 24 | 25 | public Icon getIcon(ushort id) { 26 | return getIcon(id, nullSize); 27 | } 28 | 29 | public Icon getIcon(ushort id, Size sz) { 30 | HICON hIcon = loadImage(getHInstance(), cast(wchar*)id, IMAGE_ICON, 31 | sz.width, sz.height, LR_LOADTRANSPARENT | (sz == nullSize ? LR_DEFAULTSIZE : 0)); 32 | 33 | if (!hIcon) { 34 | throwException!(GDIException)("Cannot load Icon: '%d'", id); 35 | } 36 | 37 | return Icon.fromHICON(hIcon); 38 | } 39 | 40 | public Bitmap getBitmap(ushort id) { 41 | HBITMAP hBitmap = loadImage(getHInstance(), cast(wchar*)id, 42 | IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT | LR_DEFAULTSIZE); 43 | 44 | if (!hBitmap) { 45 | throwException!(GDIException)("Cannot load Bitmap: '%d'", id); 46 | } 47 | 48 | return Bitmap.fromHBITMAP(hBitmap); 49 | } 50 | 51 | public T* getRaw(T)(ushort id, char* rt) { 52 | HRSRC hRsrc = FindResourceW(null, MAKEINTRESOURCEW(id), rt); 53 | 54 | if (!hRsrc) { 55 | throwException!(GDIException)("Cannot load Custom Resource: '%d'", id); 56 | } 57 | 58 | return cast(T*)LockResource(LoadResource(null, hRsrc)); 59 | } 60 | 61 | @property public static Resources instance() { 62 | if (!_rsrc) { 63 | _rsrc = new Resources(); 64 | } 65 | 66 | return _rsrc; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/dguihub/richtextbox.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | 10 | /* 11 | From MSDN 12 | 13 | Rich Edit version DLL Window Class 14 | ---- 15 | 1.0 Riched32.dll RICHEDIT_CLASS 16 | 2.0 Riched20.dll RICHEDIT_CLASS 17 | 3.0 Riched20.dll RICHEDIT_CLASS 18 | 4.1 Msftedit.dll MSFTEDIT_CLASS 19 | 20 | Windows XP SP1: Includes Microsoft Rich Edit 4.1, Microsoft Rich Edit 3.0, and a Microsoft Rich Edit 1.0 emulator. 21 | Windows XP: Includes Microsoft Rich Edit 3.0 with a Microsoft Rich Edit 1.0 emulator. 22 | Windows Me: Includes Microsoft Rich Edit 1.0 and 3.0. 23 | Windows 2000: Includes Microsoft Rich Edit 3.0 with a Microsoft Rich Edit 1.0 emulator. 24 | Windows NT 4.0: Includes Microsoft Rich Edit 1.0 and 2.0. 25 | Windows 98: Includes Microsoft Rich Edit 1.0 and 2.0. 26 | Windows 95: Includes only Microsoft Rich Edit 1.0. However, Riched20.dll is compatible with Windows 95 and may be installed by an application that requires it. 27 | */ 28 | 29 | module dguihub.richtextbox; 30 | 31 | public import dguihub.core.controls.textcontrol; 32 | 33 | class RichTextBox : TextControl { 34 | private static int _refCount = 0; 35 | private static HMODULE _hRichDLL; 36 | 37 | public override void dispose() { 38 | --_refCount; 39 | 40 | if (!_refCount) { 41 | FreeLibrary(_hRichDLL); 42 | _hRichDLL = null; 43 | } 44 | 45 | super.dispose(); 46 | } 47 | 48 | public void redo() { 49 | this.sendMessage(EM_REDO, 0, 0); 50 | } 51 | 52 | protected override void createControlParams(ref CreateControlParams ccp) { 53 | // Probably the RichTextbox ignores the wParam parameter in WM_PAINT 54 | 55 | ++_refCount; 56 | 57 | if (!_hRichDLL) { 58 | _hRichDLL = loadLibrary("RichEd20.dll"); // Load the standard version 59 | } 60 | 61 | this.setStyle(ES_MULTILINE | ES_WANTRETURN, true); 62 | ccp.superclassName = WC_RICHEDIT; 63 | ccp.className = WC_DRICHEDIT; 64 | 65 | super.createControlParams(ccp); 66 | } 67 | 68 | protected override void onHandleCreated(EventArgs e) { 69 | super.onHandleCreated(e); 70 | 71 | this.sendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE | ENM_UPDATE); 72 | this.sendMessage(EM_SETBKGNDCOLOR, 0, this._backColor.colorref); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/dguihub/scrollbar.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.scrollbar; 10 | 11 | import dguihub.core.controls.control; //?? Control ?? 12 | import dguihub.core.winapi; 13 | 14 | enum ScrollBarType { 15 | vertical = SB_VERT, 16 | horizontal = SB_HORZ, 17 | separate = SB_CTL, 18 | } 19 | 20 | class ScrollBar : Control { 21 | private ScrollBarType _sbt; 22 | 23 | public this() { 24 | this._sbt = ScrollBarType.separate; 25 | } 26 | 27 | private this(Control c, ScrollBarType sbt) { 28 | this._handle = c.handle; 29 | this._sbt = sbt; 30 | } 31 | 32 | private void setInfo(uint mask, SCROLLINFO* si) { 33 | si.cbSize = SCROLLINFO.sizeof; 34 | si.fMask = mask | SIF_DISABLENOSCROLL; 35 | 36 | SetScrollInfo(this._handle, this._sbt, si, true); 37 | } 38 | 39 | private void getInfo(uint mask, SCROLLINFO* si) { 40 | si.cbSize = SCROLLINFO.sizeof; 41 | si.fMask = mask; 42 | 43 | GetScrollInfo(this._handle, this._sbt, si); 44 | } 45 | 46 | public void setRange(uint min, uint max) { 47 | if (this.created) { 48 | SCROLLINFO si; 49 | si.nMin = min; 50 | si.nMax = max; 51 | 52 | this.setInfo(SIF_RANGE, &si); 53 | } 54 | } 55 | 56 | public void increment(int amount = 1) { 57 | this.position = this.position + amount; 58 | } 59 | 60 | public void decrement(int amount = 1) { 61 | this.position = this.position - amount; 62 | } 63 | 64 | @property public uint minRange() { 65 | if (this.created) { 66 | SCROLLINFO si; 67 | 68 | this.getInfo(SIF_RANGE, &si); 69 | return si.nMin; 70 | } 71 | 72 | return -1; 73 | } 74 | 75 | @property public uint maxRange() { 76 | if (this.created) { 77 | SCROLLINFO si; 78 | 79 | this.getInfo(SIF_RANGE, &si); 80 | return si.nMax; 81 | } 82 | 83 | return -1; 84 | } 85 | 86 | @property public uint position() { 87 | if (this.created) { 88 | SCROLLINFO si; 89 | 90 | this.getInfo(SIF_POS, &si); 91 | return si.nPos; 92 | } 93 | 94 | return -1; 95 | } 96 | 97 | @property public void position(uint p) { 98 | if (this.created) { 99 | SCROLLINFO si; 100 | si.nPos = p; 101 | 102 | this.setInfo(SIF_POS, &si); 103 | } 104 | } 105 | 106 | @property public uint page() { 107 | if (this.created) { 108 | SCROLLINFO si; 109 | 110 | this.getInfo(SIF_PAGE, &si); 111 | return si.nPage; 112 | } 113 | 114 | return -1; 115 | } 116 | 117 | @property public void page(uint p) { 118 | if (this.created) { 119 | SCROLLINFO si; 120 | si.nPage = p; 121 | 122 | this.setInfo(SIF_PAGE, &si); 123 | } 124 | } 125 | 126 | public static ScrollBar fromControl(Control c, ScrollBarType sbt) { 127 | assert(sbt !is ScrollBarType.separate, "ScrollBarType.separate not allowed here"); 128 | return new ScrollBar(c, sbt); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/dguihub/semver.d: -------------------------------------------------------------------------------- 1 | /** 2 | * Module containing [semantic version](http://semver.org/) 3 | */ 4 | module dguihub.semver; 5 | 6 | /** 7 | * Tagged library version (with *v* prefix) 8 | */ 9 | enum VERSION = "0.1.3"; 10 | enum TAG_VERSION = "v" ~ VERSION; 11 | -------------------------------------------------------------------------------- /src/dguihub/statusbar.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.statusbar; 10 | 11 | import std.utf : toUTFz; 12 | import dguihub.core.controls.subclassedcontrol; 13 | 14 | final class StatusPart { 15 | private StatusBar _owner; 16 | private string _text; 17 | private int _width; 18 | 19 | package this(StatusBar sb, string txt, int w) { 20 | this._owner = sb; 21 | this._text = txt; 22 | this._width = w; 23 | } 24 | 25 | @property public string text() { 26 | return this._text; 27 | } 28 | 29 | @property public void text(string s) { 30 | this._text = s; 31 | 32 | if (this._owner && this._owner.created) { 33 | this._owner.sendMessage(SB_SETTEXTW, MAKEWPARAM(this.index, 0), 34 | cast(LPARAM)toUTFz!(wchar*)(s)); 35 | } 36 | } 37 | 38 | @property public int width() { 39 | return this._width; 40 | } 41 | 42 | @property public int index() { 43 | foreach (int i, StatusPart sp; this._owner.parts) { 44 | if (sp is this) { 45 | return i; 46 | } 47 | } 48 | 49 | return -1; 50 | } 51 | 52 | @property public StatusBar statusBar() { 53 | return this._owner; 54 | } 55 | } 56 | 57 | class StatusBar : SubclassedControl { 58 | private Collection!(StatusPart) _parts; 59 | private bool _partsVisible = false; 60 | 61 | public StatusPart addPart(string s, int w) { 62 | if (!this._parts) { 63 | this._parts = new Collection!(StatusPart)(); 64 | } 65 | 66 | StatusPart sp = new StatusPart(this, s, w); 67 | this._parts.add(sp); 68 | 69 | if (this.created) { 70 | StatusBar.insertPart(sp); 71 | } 72 | 73 | return sp; 74 | } 75 | 76 | public StatusPart addPart(int w) { 77 | return this.addPart(null, w); 78 | } 79 | 80 | /* 81 | public void removePanel(int idx) 82 | { 83 | 84 | } 85 | */ 86 | 87 | @property public bool partsVisible() { 88 | return this._partsVisible; 89 | } 90 | 91 | @property public void partsVisible(bool b) { 92 | this._partsVisible = b; 93 | 94 | if (this.created) { 95 | this.setStyle(SBARS_SIZEGRIP, b); 96 | } 97 | } 98 | 99 | @property public StatusPart[] parts() { 100 | if (this._parts) { 101 | return this._parts.get(); 102 | } 103 | 104 | return null; 105 | } 106 | 107 | private static void insertPart(StatusPart stp) { 108 | StatusBar owner = stp.statusBar; 109 | StatusPart[] sparts = owner.parts; 110 | uint[] parts = new uint[sparts.length]; 111 | 112 | foreach (int i, StatusPart sp; sparts) { 113 | if (!i) { 114 | parts[i] = sp.width; 115 | } else { 116 | parts[i] = parts[i - 1] + sp.width; 117 | } 118 | } 119 | 120 | owner.sendMessage(SB_SETPARTS, sparts.length, cast(LPARAM)parts.ptr); 121 | 122 | foreach (int i, StatusPart sp; sparts) { 123 | owner.sendMessage(SB_SETTEXTW, MAKEWPARAM(i, 0), cast(LPARAM)toUTFz!(wchar*)(sp.text)); 124 | } 125 | } 126 | 127 | protected override void createControlParams(ref CreateControlParams ccp) { 128 | this._dock = DockStyle.bottom; //Force dock 129 | 130 | ccp.superclassName = WC_STATUSBAR; 131 | ccp.className = WC_DSTATUSBAR; 132 | 133 | if (this._partsVisible) { 134 | this.setStyle(SBARS_SIZEGRIP, true); 135 | } 136 | 137 | super.createControlParams(ccp); 138 | } 139 | 140 | protected override void onHandleCreated(EventArgs e) { 141 | if (this._parts) { 142 | foreach (StatusPart sp; this._parts) { 143 | StatusBar.insertPart(sp); 144 | } 145 | } 146 | 147 | super.onHandleCreated(e); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/dguihub/textbox.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.textbox; 10 | 11 | import dguihub.core.controls.textcontrol; 12 | 13 | enum CharacterCasing { 14 | normal = 0, 15 | uppercase = ES_UPPERCASE, 16 | lowercase = ES_LOWERCASE, 17 | } 18 | 19 | class TextBox : TextControl { 20 | private CharacterCasing _chChasing = CharacterCasing.normal; 21 | private uint _maxLength = 0; 22 | 23 | @property public final bool multiline() { 24 | return cast(bool)(this.getStyle() & ES_MULTILINE); 25 | } 26 | 27 | @property public final void multiline(bool b) { 28 | this.setStyle(ES_MULTILINE, b); 29 | } 30 | 31 | @property public final uint maxLength() { 32 | if (!this._maxLength) { 33 | if (this.getStyle() & ES_MULTILINE) { 34 | return 0xFFFFFFFF; 35 | } else { 36 | return 0xFFFFFFFE; 37 | } 38 | } 39 | 40 | return this._maxLength; 41 | } 42 | 43 | @property public final void maxLength(uint len) { 44 | this._maxLength = len; 45 | 46 | if (!len) { 47 | if (this.getStyle() & ES_MULTILINE) { 48 | len = 0xFFFFFFFF; 49 | } else { 50 | len = 0xFFFFFFFE; 51 | } 52 | } 53 | 54 | if (this.created) { 55 | this.sendMessage(EM_SETLIMITTEXT, len, 0); 56 | } 57 | } 58 | 59 | @property public final CharacterCasing characterCasing() { 60 | return this._chChasing; 61 | } 62 | 63 | @property public final void characterCasing(CharacterCasing ch) { 64 | this._chChasing = ch; 65 | 66 | if (this.created) { 67 | this.setStyle(this._chChasing, false); //Remove Old Style 68 | this.setStyle(ch, true); //Add New Style 69 | } 70 | } 71 | 72 | @property public final void numbersOnly(bool b) { 73 | this.setStyle(ES_NUMBER, b); 74 | } 75 | 76 | @property public final void passwordText(bool b) { 77 | this.setStyle(ES_PASSWORD, b); 78 | } 79 | 80 | protected override void createControlParams(ref CreateControlParams ccp) { 81 | this.setExStyle(WS_EX_CLIENTEDGE, true); 82 | this.setStyle(ES_AUTOHSCROLL | this._chChasing, true); 83 | ccp.superclassName = WC_EDIT; 84 | ccp.className = WC_DEDIT; 85 | 86 | this.height = 20; //E questo cos'è? 87 | super.createControlParams(ccp); 88 | } 89 | 90 | protected override void onHandleCreated(EventArgs e) { 91 | if (this._maxLength) { 92 | this.sendMessage(EM_SETLIMITTEXT, this._maxLength, 0); 93 | } 94 | 95 | super.onHandleCreated(e); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/dguihub/timer.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.timer; 10 | 11 | import dguihub.core.interfaces.idisposable; 12 | import dguihub.core.winapi; 13 | import dguihub.core.events.event; 14 | import dguihub.core.events.eventargs; 15 | import dguihub.core.exception; 16 | 17 | final class Timer : IDisposable { 18 | private alias Timer[uint] timerMap; 19 | 20 | public Event!(Timer, EventArgs) tick; 21 | 22 | private static timerMap _timers; 23 | private uint _timerId = 0; 24 | private uint _time = 0; 25 | 26 | public ~this() { 27 | this.dispose(); 28 | } 29 | 30 | extern (Windows) private static void timerProc(HWND hwnd, uint msg, uint idEvent, uint t) { 31 | if (idEvent in _timers) { 32 | _timers[idEvent].onTick(EventArgs.empty); 33 | } else { 34 | throwException!(Win32Exception)("Unknown Timer: '%08X'", idEvent); 35 | } 36 | } 37 | 38 | public void dispose() { 39 | if (this._timerId) { 40 | if (!KillTimer(null, this._timerId)) { 41 | throwException!(Win32Exception)("Cannot Dispose Timer"); 42 | } 43 | 44 | _timers.remove(this._timerId); 45 | this._timerId = 0; 46 | } 47 | } 48 | 49 | @property public uint time() { 50 | return this._time; 51 | } 52 | 53 | @property public void time(uint t) { 54 | this._time = t >= 0 ? t : t * (-1); //Take the absolute value. 55 | } 56 | 57 | public void start() { 58 | if (!this._timerId) { 59 | this._timerId = SetTimer(null, 0, this._time, cast(TIMERPROC) /*FIXME may throw*/ &Timer 60 | .timerProc); 61 | 62 | if (!this._timerId) { 63 | throwException!(Win32Exception)("Cannot Start Timer"); 64 | } 65 | 66 | this._timers[this._timerId] = this; 67 | } 68 | } 69 | 70 | public void stop() { 71 | this.dispose(); 72 | } 73 | 74 | private void onTick(EventArgs e) { 75 | this.tick(this, e); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/dguihub/tooltip.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.tooltip; 10 | 11 | import dguihub.core.controls.subclassedcontrol; 12 | 13 | enum ToolTipIcons { 14 | none = TTI_NONE, 15 | info = TTI_INFO, 16 | warning = TTI_WARNING, 17 | error = TTI_ERROR, 18 | } 19 | 20 | class ToolTip : SubclassedControl { 21 | private ToolTipIcons _ttIcon = ToolTipIcons.none; 22 | private bool _creating = false; 23 | private Control _ctrl; 24 | private string _title; 25 | 26 | public override void dispose() { 27 | if (this._ctrl) { 28 | this.removeTool(); 29 | } 30 | 31 | super.dispose(); 32 | } 33 | 34 | private void addTool(Control c) { 35 | this._ctrl = c; 36 | 37 | TOOLINFOW ti; 38 | 39 | ti.cbSize = TOOLINFOW.sizeof; 40 | ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND; 41 | ti.lpszText = cast(wchar*)LPSTR_TEXTCALLBACKW; 42 | ti.hwnd = c.parent ? c.parent.handle : c.handle; 43 | ti.uId = cast(uint)c.handle; 44 | 45 | this.sendMessage(TTM_ADDTOOLW, 0, cast(LPARAM)&ti); 46 | } 47 | 48 | private void removeTool() { 49 | TOOLINFOW ti; 50 | 51 | ti.cbSize = TOOLINFOW.sizeof; 52 | ti.hwnd = this._ctrl.parent ? this._ctrl.parent.handle : this._ctrl.handle; 53 | ti.uId = cast(uint)this._ctrl.handle; 54 | 55 | this.sendMessage(TTM_DELTOOLW, 0, cast(LPARAM)&ti); 56 | this._ctrl = null; 57 | } 58 | 59 | @property public void icon(ToolTipIcons tti) { 60 | this._ttIcon = tti; 61 | 62 | if (this.created) { 63 | this.sendMessage(TTM_SETTITLEW, this._ttIcon, cast(LPARAM)toUTFz!(wchar*)(this._title)); 64 | } 65 | } 66 | 67 | @property public string title() { 68 | return this._title; 69 | } 70 | 71 | @property public void title(string s) { 72 | this._title = s; 73 | 74 | if (this.created) { 75 | this.sendMessage(TTM_SETTITLEW, this._ttIcon, cast(LPARAM)toUTFz!(wchar*)(this._title)); 76 | } 77 | } 78 | 79 | @property public void baloonTip(bool b) { 80 | this.setStyle(TTS_BALLOON, b); 81 | } 82 | 83 | @property public void closeButton(bool b) { 84 | this.setStyle(TTS_CLOSE, b); 85 | } 86 | 87 | @property public void alwaysTip(bool b) { 88 | this.setStyle(TTS_ALWAYSTIP, b); 89 | } 90 | 91 | @property public override void parent(Control c) { 92 | if (this._creating) { 93 | super.parent = c; 94 | } else { 95 | throwException!(DGuiException)("A ToolTip cannot have a parent"); 96 | } 97 | } 98 | 99 | public final void activate(Control c) { 100 | if (!this.created) { 101 | this._creating = true; 102 | this.parent = c.parent ? c.parent : c; 103 | this.show(); 104 | this._creating = false; 105 | } 106 | 107 | if (this._ctrl !is c) { 108 | if (this._ctrl) { 109 | this.removeTool(); 110 | } 111 | 112 | this.addTool(c); 113 | } 114 | 115 | this.sendMessage(TTM_ACTIVATE, true, 0); 116 | } 117 | 118 | public override void show() { 119 | if (this._creating) { 120 | super.show(); 121 | } else { 122 | throwException!(DGuiException)("Cannot create a ToolTip directly"); 123 | } 124 | } 125 | 126 | protected override void createControlParams(ref CreateControlParams ccp) { 127 | ccp.superclassName = WC_TOOLTIP; 128 | ccp.className = WC_DTOOLTIP; 129 | ccp.defaultBackColor = SystemColors.colorInfo; 130 | ccp.defaultForeColor = SystemColors.colorInfoText; 131 | 132 | this.setStyle(WS_POPUP | TTS_NOPREFIX, true); 133 | this.setExStyle(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, true); 134 | 135 | /* According To MSDN: 136 | The window procedure for the tooltip control automatically sets the size, position, and visibility of the control. 137 | The height of the tooltip window is based on the height of the font currently selected into the device context 138 | for the tooltip control. 139 | The width varies based on the length of the string currently in the tooltip window. */ 140 | this.bounds = Rect(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT); 141 | 142 | ToolTip.setBit(this._cBits, ControlBits.cannotAddChild | ControlBits.useCachedText, true); 143 | super.createControlParams(ccp); 144 | } 145 | 146 | protected override void onReflectedMessage(ref Message m) { 147 | if (m.msg == WM_NOTIFY) { 148 | NMHDR* pNotify = cast(NMHDR*)m.lParam; 149 | 150 | if (pNotify.code == TTN_GETDISPINFOW) { 151 | NMTTDISPINFOW* pDispInfo = cast(NMTTDISPINFOW*)pNotify; 152 | pDispInfo.lpszText = toUTFz!(wchar*)(this.text); 153 | } 154 | } 155 | 156 | super.onReflectedMessage(m); 157 | } 158 | 159 | protected override void onHandleCreated(EventArgs e) { 160 | if (this._ttIcon !is ToolTipIcons.none || this._title.length) { 161 | this.sendMessage(TTM_SETTITLEW, this._ttIcon, cast(LPARAM)toUTFz!(wchar*)(this._title)); 162 | } 163 | 164 | SetWindowPos(this._handle, cast(HWND)HWND_TOPMOST, 0, 0, 0, 0, 165 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 166 | super.onHandleCreated(e); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/dguihub/trackbar.d: -------------------------------------------------------------------------------- 1 | /** DGui project file. 2 | 3 | Copyright: Trogu Antonio Davide 2011-2013 4 | 5 | License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | 7 | Authors: Trogu Antonio Davide 8 | */ 9 | module dguihub.trackbar; 10 | 11 | import dguihub.core.controls.subclassedcontrol; 12 | 13 | class TrackBar : SubclassedControl { 14 | public Event!(Control, EventArgs) valueChanged; 15 | 16 | private int _minRange = 0; 17 | private int _maxRange = 100; 18 | private int _value = 0; 19 | private int _lastValue = 0; 20 | 21 | @property public uint minRange() { 22 | return this._minRange; 23 | } 24 | 25 | @property public void minRange(uint mr) { 26 | this._minRange = mr; 27 | 28 | if (this.created) { 29 | this.sendMessage(TBM_SETRANGE, true, MAKELPARAM(this._minRange, this._maxRange)); 30 | } 31 | } 32 | 33 | @property public uint maxRange() { 34 | return this._maxRange; 35 | } 36 | 37 | @property public void maxRange(uint mr) { 38 | this._maxRange = mr; 39 | 40 | if (this.created) { 41 | this.sendMessage(TBM_SETRANGE, true, MAKELPARAM(this._minRange, this._maxRange)); 42 | } 43 | } 44 | 45 | @property public int value() { 46 | if (this.created) { 47 | return this.sendMessage(TBM_GETPOS, 0, 0); 48 | } 49 | 50 | return this._value; 51 | } 52 | 53 | @property public void value(int p) { 54 | this._value = p; 55 | 56 | if (this.created) { 57 | this.sendMessage(TBM_SETPOS, true, p); 58 | } 59 | } 60 | 61 | protected override void createControlParams(ref CreateControlParams ccp) { 62 | ccp.superclassName = WC_TRACKBAR; 63 | ccp.className = WC_DTRACKBAR; 64 | this.setStyle(TBS_AUTOTICKS, true); 65 | 66 | assert(this._dock is DockStyle.fill, "TrackBar: Invalid Dock Style"); 67 | 68 | if (this._dock is DockStyle.top || this._dock is DockStyle.bottom 69 | || (this._dock is DockStyle.none && this._bounds.width >= this._bounds.height)) { 70 | this.setStyle(TBS_HORZ, true); 71 | } else if (this._dock is DockStyle.left || this._dock is DockStyle.right 72 | || (this._dock is DockStyle.none && this._bounds.height < this._bounds.width)) { 73 | this.setStyle(TBS_VERT, true); 74 | } 75 | 76 | super.createControlParams(ccp); 77 | } 78 | 79 | protected override void onHandleCreated(EventArgs e) { 80 | this.sendMessage(TBM_SETRANGE, true, MAKELPARAM(this._minRange, this._maxRange)); 81 | this.sendMessage(TBM_SETTIC, 20, 0); 82 | this.sendMessage(TBM_SETPOS, true, this._value); 83 | 84 | super.onHandleCreated(e); 85 | } 86 | 87 | protected override void wndProc(ref Message m) { 88 | if (m.msg == WM_MOUSEMOVE && (cast(MouseKeys)m.wParam) is MouseKeys.left 89 | || m.msg == WM_KEYDOWN && ((cast(Keys)m.wParam) is Keys.left 90 | || (cast(Keys)m.wParam) is Keys.up 91 | || (cast(Keys)m.wParam) is Keys.right || (cast(Keys)m.wParam) is Keys.down)) { 92 | int val = this.value; 93 | 94 | if (this._lastValue != val) { 95 | this._lastValue = val; //Save last position. 96 | this.onValueChanged(EventArgs.empty); 97 | } 98 | } 99 | 100 | super.wndProc(m); 101 | } 102 | 103 | private void onValueChanged(EventArgs e) { 104 | this.valueChanged(this, e); 105 | } 106 | } 107 | --------------------------------------------------------------------------------