1 // Written in the D programming language. 2 3 /** 4 This app is a demo for most of DlangUI library features. 5 6 Synopsis: 7 8 ---- 9 dub run dlangui:example1 10 ---- 11 12 Copyright: Vadim Lopatin, 2014 13 License: Boost License 1.0 14 Authors: Vadim Lopatin, coolreader.org@gmail.com 15 */ 16 module example1; 17 18 import dlangui; 19 import dlangui.dialogs.dialog; 20 import dlangui.dialogs.filedlg; 21 import dlangui.dialogs.msgbox; 22 import std.stdio; 23 import std.conv; 24 import std.utf; 25 import std.algorithm; 26 import std.path; 27 28 import widgets; 29 30 mixin APP_ENTRY_POINT; 31 32 class TimerTest : HorizontalLayout { 33 ulong timerId; 34 TextWidget _counter; 35 int _value; 36 Button _start; 37 Button _stop; 38 override bool onTimer(ulong id) { 39 _value++; 40 _counter.text = to!dstring(_value); 41 return true; 42 } 43 this() { 44 addChild(new TextWidget(null, "Timer test."d)); 45 _counter = new TextWidget(null, "0"d); 46 _counter.fontSize(32); 47 _start = new Button(null, "Start timer"d); 48 _stop = new Button(null, "Stop timer"d); 49 _stop.enabled = false; 50 _start.click = delegate(Widget src) { 51 _start.enabled = false; 52 _stop.enabled = true; 53 timerId = setTimer(1000); 54 return true; 55 }; 56 _stop.click = delegate(Widget src) { 57 _start.enabled = true; 58 _stop.enabled = false; 59 cancelTimer(timerId); 60 return true; 61 }; 62 addChild(_start); 63 addChild(_stop); 64 addChild(_counter); 65 } 66 } 67 68 class TextEditorWidget : VerticalLayout { 69 EditBox _edit; 70 this(string ID) { 71 super(ID); 72 _edit = new EditBox("editor"); 73 _edit.layoutWidth = FILL_PARENT; 74 _edit.layoutHeight = FILL_PARENT; 75 addChild(_edit); 76 } 77 } 78 79 Widget createEditorSettingsControl(EditWidgetBase editor) { 80 HorizontalLayout res = new HorizontalLayout("editor_options"); 81 res.addChild((new CheckBox("wantTabs", "wantTabs"d)).checked(editor.wantTabs).addOnCheckChangeListener(delegate(Widget, bool checked) { editor.wantTabs = checked; return true;})); 82 res.addChild((new CheckBox("useSpacesForTabs", "useSpacesForTabs"d)).checked(editor.useSpacesForTabs).addOnCheckChangeListener(delegate(Widget, bool checked) { editor.useSpacesForTabs = checked; return true;})); 83 res.addChild((new CheckBox("readOnly", "readOnly"d)).checked(editor.readOnly).addOnCheckChangeListener(delegate(Widget, bool checked) { editor.readOnly = checked; return true;})); 84 res.addChild((new CheckBox("showLineNumbers", "showLineNumbers"d)).checked(editor.showLineNumbers).addOnCheckChangeListener(delegate(Widget, bool checked) { editor.showLineNumbers = checked; return true;})); 85 res.addChild((new CheckBox("fixedFont", "fixedFont"d)).checked(editor.fontFamily == FontFamily.MonoSpace).addOnCheckChangeListener(delegate(Widget, bool checked) { 86 if (checked) 87 editor.fontFamily(FontFamily.MonoSpace).fontFace("Courier New"); 88 else 89 editor.fontFamily(FontFamily.SansSerif).fontFace("Arial"); 90 return true; 91 })); 92 res.addChild((new CheckBox("tabSize", "Tab size 8"d)).checked(editor.tabSize == 8).addOnCheckChangeListener(delegate(Widget, bool checked) { 93 if (checked) 94 editor.tabSize(8); 95 else 96 editor.tabSize(4); 97 return true; 98 })); 99 return res; 100 } 101 102 enum : int { 103 ACTION_FILE_OPEN = 5500, 104 ACTION_FILE_SAVE, 105 ACTION_FILE_CLOSE, 106 ACTION_FILE_EXIT, 107 } 108 109 debug(SDLSettings) { 110 import dlangui.core.settings; 111 void testSDL(string fn) { 112 Log.d("Loading SDL from ", fn); 113 Setting s = new Setting(); 114 if (s.load(fn)) { 115 Log.d("JSON:\n", s.toJSON(true)); 116 } else { 117 Log.e("failed to read SDL from ", fn); 118 } 119 } 120 void testSDLSettings() { 121 testSDL(`C:\Users\vlopatin\AppData\Roaming\.dlangide\settings.json`); 122 testSDL("dub.json"); 123 testSDL("test1.sdl"); 124 } 125 } 126 127 /// entry point for dlangui based application 128 extern (C) int UIAppMain(string[] args) { 129 130 debug(SDLSettings) { 131 testSDLSettings(); 132 } 133 134 // always use trace, even for release builds 135 //Log.setLogLevel(LogLevel.Trace); 136 //Log.setFileLogger(new std.stdio.File("ui.log", "w")); 137 138 // resource directory search paths 139 // not required if only embedded resources are used 140 //string[] resourceDirs = [ 141 // appendPath(exePath, "../../../res/"), // for Visual D and DUB builds 142 // appendPath(exePath, "../../../res/mdpi/"), // for Visual D and DUB builds 143 // appendPath(exePath, "../../../../res/"),// for Mono-D builds 144 // appendPath(exePath, "../../../../res/mdpi/"),// for Mono-D builds 145 // appendPath(exePath, "res/"), // when res dir is located at the same directory as executable 146 // appendPath(exePath, "../res/"), // when res dir is located at project directory 147 // appendPath(exePath, "../../res/"), // when res dir is located at the same directory as executable 148 // appendPath(exePath, "res/mdpi/"), // when res dir is located at the same directory as executable 149 // appendPath(exePath, "../res/mdpi/"), // when res dir is located at project directory 150 // appendPath(exePath, "../../res/mdpi/") // when res dir is located at the same directory as executable 151 //]; 152 // setup resource directories - will use only existing directories 153 //Platform.instance.resourceDirs = resourceDirs; 154 155 // embed resources listed in views/resources.list into executable 156 embeddedResourceList.addResources(embedResourcesFromList!("resources.list")()); 157 158 //version (USE_OPENGL) { 159 // // you can turn on subpixel font rendering (ClearType) here 160 //FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; // 161 //} else { 162 // you can turn on subpixel font rendering (ClearType) here 163 FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR; //SubpixelRenderingMode.None; // 164 //} 165 166 // select translation file - for english language 167 Platform.instance.uiLanguage = "en"; 168 // load theme from file "theme_default.xml" 169 Platform.instance.uiTheme = "theme_default"; 170 //Platform.instance.uiTheme = "theme_dark"; 171 172 // you can override default hinting mode here (Normal, AutoHint, Disabled) 173 FontManager.hintingMode = HintingMode.Normal; 174 // you can override antialiasing setting here (0 means antialiasing always on, some big value = always off) 175 // fonts with size less than specified value will not be antialiased 176 FontManager.minAnitialiasedFontSize = 0; // 0 means always antialiased 177 //version (USE_OPENGL) { 178 // // you can turn on subpixel font rendering (ClearType) here 179 FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; // 180 //} else { 181 // you can turn on subpixel font rendering (ClearType) here 182 //FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR; //SubpixelRenderingMode.None; // 183 //} 184 185 // create window 186 //Window window = Platform.instance.createWindow("DlangUI Example 1", null, WindowFlag.Resizable, 800, 700); 187 // Expand window size if content is bigger than 800, 700 (change to above version if you want scrollbars and 800, 700 size) 188 Window window = Platform.instance.createWindow("DlangUI Example 1", null, WindowFlag.Resizable | WindowFlag.ExpandSize, 800, 700); 189 // here you can see window or content resize mode 190 //Window window = Platform.instance.createWindow("DlangUI Example 1", null, WindowFlag.Resizable, 400, 400); 191 //window.windowOrContentResizeMode = WindowOrContentResizeMode.resizeWindow; 192 //window.windowOrContentResizeMode = WindowOrContentResizeMode.scrollWindow; 193 //window.windowOrContentResizeMode = WindowOrContentResizeMode.shrinkWidgets; 194 static if (true) { 195 VerticalLayout contentLayout = new VerticalLayout(); 196 197 TabWidget tabs = new TabWidget("TABS"); 198 tabs.tabClose = delegate(string tabId) { 199 tabs.removeTab(tabId); 200 }; 201 202 //========================================================================= 203 // create main menu 204 205 MenuItem mainMenuItems = new MenuItem(); 206 MenuItem fileItem = new MenuItem(new Action(1, "MENU_FILE"c)); 207 fileItem.add(new Action(ACTION_FILE_OPEN, "MENU_FILE_OPEN"c, "document-open", KeyCode.KEY_O, KeyFlag.Control)); 208 fileItem.add(new Action(ACTION_FILE_SAVE, "MENU_FILE_SAVE"c, "document-save", KeyCode.KEY_S, KeyFlag.Control)); 209 MenuItem openRecentItem = new MenuItem(new Action(13, "MENU_FILE_OPEN_RECENT", "document-open-recent")); 210 openRecentItem.add(new Action(100, "&1: File 1"d)); 211 openRecentItem.add(new Action(101, "&2: File 2"d)); 212 openRecentItem.add(new Action(102, "&3: File 3"d)); 213 openRecentItem.add(new Action(103, "&4: File 4"d)); 214 openRecentItem.add(new Action(104, "&5: File 5"d)); 215 fileItem.add(openRecentItem); 216 fileItem.add(new Action(ACTION_FILE_EXIT, "MENU_FILE_EXIT"c, "document-close"c, KeyCode.KEY_X, KeyFlag.Alt)); 217 218 MenuItem editItem = new MenuItem(new Action(2, "MENU_EDIT")); 219 editItem.add(new Action(EditorActions.Copy, "MENU_EDIT_COPY"c, "edit-copy", KeyCode.KEY_C, KeyFlag.Control)); 220 editItem.add(new Action(EditorActions.Paste, "MENU_EDIT_PASTE"c, "edit-paste", KeyCode.KEY_V, KeyFlag.Control)); 221 editItem.add(new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut", KeyCode.KEY_X, KeyFlag.Control)); 222 editItem.add(new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control)); 223 editItem.add(new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control)); 224 editItem.add(new Action(EditorActions.Indent, "MENU_EDIT_INDENT"c, "edit-indent", KeyCode.TAB, 0)); 225 editItem.add(new Action(EditorActions.Unindent, "MENU_EDIT_UNINDENT"c, "edit-unindent", KeyCode.TAB, KeyFlag.Control)); 226 editItem.add(new Action(20, "MENU_EDIT_PREFERENCES")); 227 228 MenuItem editPopupItem = new MenuItem(null); 229 editPopupItem.add(new Action(EditorActions.Copy, "MENU_EDIT_COPY"c, "edit-copy", KeyCode.KEY_C, KeyFlag.Control)); 230 editPopupItem.add(new Action(EditorActions.Paste, "MENU_EDIT_PASTE"c, "edit-paste", KeyCode.KEY_V, KeyFlag.Control)); 231 editPopupItem.add(new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut", KeyCode.KEY_X, KeyFlag.Control)); 232 editPopupItem.add(new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control)); 233 editPopupItem.add(new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control)); 234 editPopupItem.add(new Action(EditorActions.Indent, "MENU_EDIT_INDENT"c, "edit-indent", KeyCode.TAB, 0)); 235 editPopupItem.add(new Action(EditorActions.Unindent, "MENU_EDIT_UNINDENT"c, "edit-unindent", KeyCode.TAB, KeyFlag.Control)); 236 237 MenuItem viewItem = new MenuItem(new Action(60, "MENU_VIEW")); 238 MenuItem langItem = new MenuItem(new Action(61, "MENU_VIEW_LANGUAGE")); 239 auto onLangChange = delegate (MenuItem item) { 240 if (!item.checked) 241 return false; 242 if (item.id == 611) { 243 // set interface language to english 244 platform.instance.uiLanguage = "en"; 245 } else if (item.id == 612) { 246 // set interface language to russian 247 platform.instance.uiLanguage = "ru"; 248 } 249 return true; 250 }; 251 MenuItem enLang = (new MenuItem(new Action(611, "MENU_VIEW_LANGUAGE_EN"))).type(MenuItemType.Radio).checked(true); 252 MenuItem ruLang = (new MenuItem(new Action(612, "MENU_VIEW_LANGUAGE_RU"))).type(MenuItemType.Radio); 253 enLang.menuItemClick = onLangChange; 254 ruLang.menuItemClick = onLangChange; 255 langItem.add(enLang); 256 langItem.add(ruLang); 257 viewItem.add(langItem); 258 MenuItem themeItem = new MenuItem(new Action(62, "MENU_VIEW_THEME")); 259 MenuItem theme1 = (new MenuItem(new Action(621, "MENU_VIEW_THEME_DEFAULT"))).type(MenuItemType.Radio).checked(true); 260 MenuItem theme2 = (new MenuItem(new Action(622, "MENU_VIEW_THEME_DARK"))).type(MenuItemType.Radio); 261 MenuItem theme3 = (new MenuItem(new Action(623, "MENU_VIEW_THEME_CUSTOM1"))).type(MenuItemType.Radio); 262 auto onThemeChange = delegate (MenuItem item) { 263 if (!item.checked) 264 return false; 265 if (item.id == 621) { 266 platform.instance.uiTheme = "theme_default"; 267 } else if (item.id == 622) { 268 platform.instance.uiTheme = "theme_dark"; 269 } else if (item.id == 623) { 270 platform.instance.uiTheme = "theme_custom1"; 271 } 272 return true; 273 }; 274 theme1.menuItemClick = onThemeChange; 275 theme2.menuItemClick = onThemeChange; 276 theme3.menuItemClick = onThemeChange; 277 themeItem.add(theme1); 278 themeItem.add(theme2); 279 themeItem.add(theme3); 280 viewItem.add(themeItem); 281 282 MenuItem windowItem = new MenuItem(new Action(3, "MENU_WINDOW"c)); 283 windowItem.add(new Action(30, "MENU_WINDOW_PREFERENCES")); 284 windowItem.add(new Action(31, UIString.fromId("MENU_WINDOW_MINIMIZE"))); 285 windowItem.add(new Action(32, UIString.fromId("MENU_WINDOW_MAXIMIZE"))); 286 windowItem.add(new Action(33, UIString.fromId("MENU_WINDOW_RESTORE"))); 287 MenuItem helpItem = new MenuItem(new Action(4, "MENU_HELP"c)); 288 helpItem.add(new Action(40, "MENU_HELP_VIEW_HELP")); 289 MenuItem aboutItem = new MenuItem(new Action(41, "MENU_HELP_ABOUT")); 290 helpItem.add(aboutItem); 291 mainMenuItems.add(fileItem); 292 mainMenuItems.add(editItem); 293 mainMenuItems.add(viewItem); 294 mainMenuItems.add(windowItem); 295 mainMenuItems.add(helpItem); 296 MainMenu mainMenu = new MainMenu(mainMenuItems); 297 contentLayout.addChild(mainMenu); 298 // to let main menu handle keyboard shortcuts 299 contentLayout.keyToAction = delegate(Widget source, uint keyCode, uint flags) { 300 return mainMenu.findKeyAction(keyCode, flags); 301 }; 302 contentLayout.onAction = delegate(Widget source, const Action a) { 303 if (a.id == ACTION_FILE_EXIT) { 304 window.close(); 305 return true; 306 } else if (a.id == 31) { 307 window.minimizeWindow(); 308 return true; 309 } else if (a.id == 32) { 310 window.maximizeWindow(); 311 return true; 312 } else if (a.id == 33) { 313 window.restoreWindow(); 314 return true; 315 } else if (a.id == 41) { 316 window.showMessageBox(UIString.fromRaw("About"d), UIString.fromRaw("DLangUI demo app\n(C) Vadim Lopatin, 2014\nhttp://github.com/buggins/dlangui"d)); 317 return true; 318 } else if (a.id == ACTION_FILE_OPEN) { 319 UIString caption; 320 caption = "Open Text File"d; 321 FileDialog dlg = new FileDialog(caption, window, null); 322 dlg.allowMultipleFiles = true; 323 dlg.addFilter(FileFilterEntry(UIString("FILTER_ALL_FILES", "All files (*)"d), "*")); 324 dlg.addFilter(FileFilterEntry(UIString("FILTER_TEXT_FILES", "Text files (*.txt)"d), "*.txt")); 325 dlg.addFilter(FileFilterEntry(UIString("FILTER_SOURCE_FILES", "Source files"d), "*.d;*.dd;*.c;*.cc;*.cpp;*.h;*.hpp")); 326 dlg.addFilter(FileFilterEntry(UIString("FILTER_EXECUTABLE_FILES", "Executable files"d), "*", true)); 327 //dlg.filterIndex = 2; 328 dlg.dialogResult = delegate(Dialog dlg, const Action result) { 329 if (result.id == ACTION_OPEN.id) { 330 string[] filenames = (cast(FileDialog)dlg).filenames; 331 foreach (filename; filenames) { 332 if (filename.endsWith(".d") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c") 333 || filename.endsWith(".json") || filename.endsWith(".dd") || filename.endsWith(".ddoc") || filename.endsWith(".xml") || filename.endsWith(".html") 334 || filename.endsWith(".html") || filename.endsWith(".css") || filename.endsWith(".log") || filename.endsWith(".hpp")) { 335 // open source file in tab 336 int index = tabs.tabIndex(filename); 337 if (index >= 0) { 338 // file is already opened in tab 339 tabs.selectTab(index, true); 340 } else { 341 SourceEdit editor = new SourceEdit(filename); 342 if (editor.load(filename)) { 343 tabs.addTab(editor, toUTF32(baseName(filename)), null, true); 344 tabs.selectTab(filename); 345 } else { 346 destroy(editor); 347 window.showMessageBox(UIString.fromRaw("File open error"d), UIString.fromRaw("Cannot open file "d ~ toUTF32(filename))); 348 } 349 } 350 } else { 351 Log.d("FileDialog.onDialogResult: ", result, " param=", result.stringParam); 352 window.showMessageBox(UIString.fromRaw("FileOpen result"d), UIString.fromRaw("Filename: "d ~ toUTF32(filename))); 353 } 354 } 355 } 356 357 }; 358 dlg.show(); 359 return true; 360 } 361 //else 362 //return contentLayout.dispatchAction(a); 363 return false; 364 }; 365 mainMenu.menuItemClick = delegate(MenuItem item) { 366 Log.d("mainMenu.onMenuItemListener", item.label); 367 const Action a = item.action; 368 if (a) { 369 return contentLayout.dispatchAction(a); 370 } 371 return false; 372 }; 373 374 // ========= create tabs =================== 375 376 tabs.tabChanged = delegate(string newTabId, string oldTabId) { 377 window.windowCaption = tabs.tab(newTabId).text.value ~ " - dlangui example 1"d; 378 }; 379 tabs.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 380 381 // most of controls example 382 { 383 LinearLayout controls = new VerticalLayout("controls"); 384 controls.layoutHeight(FILL_PARENT); 385 controls.padding = Rect(12.pointsToPixels,12.pointsToPixels,12.pointsToPixels,12.pointsToPixels); 386 387 HorizontalLayout line1 = new HorizontalLayout(); 388 controls.addChild(line1); 389 390 GroupBox gb = new GroupBox("checkboxes", "CheckBox"d); 391 gb.addChild(new CheckBox("cb1", "CheckBox 1"d)); 392 gb.addChild(new CheckBox("cb2", "CheckBox 2"d).checked(true)); 393 gb.addChild(new CheckBox("cb3", "CheckBox disabled"d).enabled(false)); 394 gb.addChild(new CheckBox("cb4", "CheckBox disabled"d).checked(true).enabled(false)); 395 line1.addChild(gb); 396 397 GroupBox gb2 = new GroupBox("radiobuttons", "RadioButton"d); 398 gb2.addChild(new RadioButton("rb1", "RadioButton 1"d).checked(true)); 399 gb2.addChild(new RadioButton("rb2", "RadioButton 2"d)); 400 gb2.addChild(new RadioButton("rb3", "RadioButton disabled"d).enabled(false)); 401 line1.addChild(gb2); 402 403 VerticalLayout col1 = new VerticalLayout(); 404 GroupBox gb3 = new GroupBox("textbuttons", "Button"d, Orientation.Horizontal); 405 gb3.addChild(new Button("tb1", "Button"d)); 406 gb3.addChild(new Button("tb2", "Button disabled"d).enabled(false)); 407 col1.addChild(gb3); 408 GroupBox gb4 = new GroupBox("imagetextbuttons", "ImageTextButton"d, Orientation.Horizontal); 409 gb4.addChild(new ImageTextButton("itb1", "document-open", "Enabled"d)); 410 gb4.addChild(new ImageTextButton("itb2", "document-save", "Disabled"d).enabled(false)); 411 col1.addChild(gb4); 412 GroupBox gbtext = new GroupBox("text", "TextWidget"d, Orientation.Horizontal); 413 gbtext.addChild(new TextWidget("t1", "Red text"d).fontSize(12.pointsToPixels).textColor(0xFF0000)); 414 gbtext.addChild(new TextWidget("t2", "Italic text"d).fontSize(12.pointsToPixels).fontItalic(true)); 415 col1.addChild(gbtext); 416 line1.addChild(col1); 417 418 VerticalLayout col2 = new VerticalLayout(); 419 GroupBox gb31 = new GroupBox("switches", "SwitchButton"d, Orientation.Vertical); 420 gb31.addChild(new SwitchButton("sb1")); 421 gb31.addChild(new SwitchButton("sb2").checked(true)); 422 gb31.addChild(new SwitchButton("sb3").enabled(false)); 423 gb31.addChild(new SwitchButton("sb4").enabled(false).checked(true)); 424 col2.addChild(gb31); 425 line1.addChild(col2); 426 427 VerticalLayout col3 = new VerticalLayout(); 428 GroupBox gb32 = new GroupBox("switches", "ImageButton"d, Orientation.Vertical); 429 gb32.addChild(new ImageButton("ib1", "edit-copy")); 430 gb32.addChild(new ImageButton("ib3", "edit-paste").enabled(false)); 431 col3.addChild(gb32); 432 GroupBox gb33 = new GroupBox("images", "ImageWidget"d, Orientation.Vertical); 433 gb33.addChild(new ImageWidget("cr3_logo", "cr3_logo")); 434 col3.addChild(gb33); 435 line1.addChild(col3); 436 437 438 HorizontalLayout line2 = new HorizontalLayout(); 439 controls.addChild(line2); 440 441 GroupBox gb5 = new GroupBox("scrollbar", "horizontal ScrollBar"d); 442 gb5.addChild(new ScrollBar("sb1", Orientation.Horizontal)); 443 line2.addChild(gb5); 444 GroupBox gb6 = new GroupBox("slider", "horizontal SliderWidget"d); 445 gb6.addChild(new SliderWidget("sb2", Orientation.Horizontal)); 446 line2.addChild(gb6); 447 GroupBox gb7 = new GroupBox("editline1", "EditLine"d); 448 gb7.addChild(new EditLine("ed1", "Some text"d).minWidth(120.pointsToPixels)); 449 line2.addChild(gb7); 450 GroupBox gb8 = new GroupBox("editline2", "EditLine disabled"d); 451 gb8.addChild(new EditLine("ed2", "Some text"d).enabled(false).minWidth(120.pointsToPixels)); 452 line2.addChild(gb8); 453 454 HorizontalLayout line3 = new HorizontalLayout(); 455 line3.layoutWidth(FILL_PARENT); 456 GroupBox gbeditbox = new GroupBox("editbox", "EditBox"d, Orientation.Horizontal); 457 gbeditbox.layoutWidth(FILL_PARENT); 458 EditBox ed1 = new EditBox("ed1", "Some text in EditBox\nOne more line\nYet another text line"); 459 ed1.layoutHeight(FILL_PARENT); 460 gbeditbox.addChild(ed1); 461 line3.addChild(gbeditbox); 462 GroupBox gbtabs = new GroupBox(null, "TabWidget"d); 463 gbtabs.layoutWidth(FILL_PARENT); 464 TabWidget tabs1 = new TabWidget("tabs1"); 465 tabs1.addTab(new TextWidget("tab1", "TextWidget on tab page\nTextWidgets can be\nMultiline"d).maxLines(3), "Tab 1"d); 466 tabs1.addTab(new ImageWidget("tab2", "dlangui-logo1"), "Tab 2"d); 467 tabs1.tabHost.backgroundColor = 0xE0E0E0; 468 tabs1.tabHost.padding = Rect(10.pointsToPixels, 10.pointsToPixels, 10.pointsToPixels, 10.pointsToPixels); 469 gbtabs.addChild(tabs1); 470 line3.addChild(gbtabs); 471 controls.addChild(line3); 472 473 HorizontalLayout line4 = new HorizontalLayout(); 474 line4.layoutWidth(FILL_PARENT); 475 line4.layoutHeight(FILL_PARENT); 476 GroupBox gbgrid = new GroupBox("grid", "StringGridWidget"d, Orientation.Horizontal); 477 StringGridWidget grid = new StringGridWidget("stringgrid"); 478 grid.resize(12, 10); 479 gbgrid.layoutWidth(FILL_PARENT); 480 gbgrid.layoutHeight(FILL_PARENT); 481 grid.layoutWidth(FILL_PARENT); 482 grid.layoutHeight(FILL_PARENT); 483 foreach (index, month; ["January"d, "February"d, "March"d, "April"d, "May"d, "June"d, "July"d, "August"d, "September"d, "October"d, "November"d, "December"d]) 484 grid.setColTitle(cast(int)index, month); 485 for (int y = 0; y < 10; y++) 486 grid.setRowTitle(y, to!dstring(y+1)); 487 //grid.alignment = Align.Right; 488 grid.setColWidth(0, 30.pointsToPixels); 489 grid.autoFit(); 490 import std.random; 491 import std.string; 492 for (int x = 0; x < 12; x++) { 493 for (int y = 0; y < 10; y++) { 494 int n = uniform(0, 10000); 495 grid.setCellText(x, y, to!dstring("%.2f".format(n / 100.0))); 496 } 497 } 498 //grid.autoFit(); 499 gbgrid.addChild(grid); 500 line4.addChild(gbgrid); 501 502 GroupBox gbtree = new GroupBox("tree", "TreeWidget"d, Orientation.Vertical); 503 auto tree = new TreeWidget("gbtree"); 504 //tree.layoutWidth(WRAP_CONTENT).layoutHeight(FILL_PARENT); 505 tree.maxHeight(200.pointsToPixels); 506 TreeItem tree1 = tree.items.newChild("group1", "Group 1"d, "document-open"); 507 tree1.newChild("g1_1", "Group 1 item 1"d); 508 tree1.newChild("g1_2", "Group 1 item 2"d); 509 tree1.newChild("g1_3", "Group 1 item 3"d); 510 TreeItem tree2 = tree.items.newChild("group2", "Group 2"d, "document-save"); 511 tree2.newChild("g2_1", "Group 2 item 1"d, "edit-copy"); 512 tree2.newChild("g2_2", "Group 2 item 2"d, "edit-cut"); 513 tree2.newChild("g2_3", "Group 2 item 3"d, "edit-paste"); 514 tree2.newChild("g2_4", "Group 2 item 4"d); 515 TreeItem tree3 = tree.items.newChild("group3", "Group 3"d); 516 tree3.newChild("g3_1", "Group 3 item 1"d); 517 tree3.newChild("g3_2", "Group 3 item 2"d); 518 TreeItem tree32 = tree3.newChild("g3_3", "Group 3 item 3"d); 519 tree3.newChild("g3_4", "Group 3 item 4"d); 520 tree32.newChild("group3_2_1", "Group 3 item 2 subitem 1"d); 521 tree32.newChild("group3_2_2", "Group 3 item 2 subitem 2"d); 522 tree32.newChild("group3_2_3", "Group 3 item 2 subitem 3"d); 523 tree32.newChild("group3_2_4", "Group 3 item 2 subitem 4"d); 524 tree32.newChild("group3_2_5", "Group 3 item 2 subitem 5"d); 525 tree3.newChild("g3_5", "Group 3 item 5"d); 526 tree3.newChild("g3_6", "Group 3 item 6"d); 527 gbtree.addChild(tree); 528 tree.items.selectItem(tree1); 529 // test adding new tree items 530 HorizontalLayout newTreeItem = new HorizontalLayout(); 531 newTreeItem.layoutWidth = FILL_PARENT; 532 EditLine edNewTreeItem = new EditLine("newTreeItem", "new item"d); 533 edNewTreeItem.layoutWidth = FILL_PARENT; 534 Button btnAddItem = new Button("btnAddTreeItem", "Add"d); 535 Button btnRemoveItem = new Button("btnRemoveTreeItem", "Remove"d); 536 newTreeItem.addChild(edNewTreeItem); 537 newTreeItem.addChild(btnAddItem); 538 newTreeItem.addChild(btnRemoveItem); 539 btnAddItem.click = delegate(Widget source) { 540 import std.random; 541 dstring label = edNewTreeItem.text; 542 string id = "item%d".format(uniform(1000000, 9999999, rndGen)); 543 TreeItem item = tree.items.selectedItem; 544 if (item) { 545 Log.d("Creating new tree item ", id, " ", label); 546 TreeItem newItem = new TreeItem(id, label); 547 item.addChild(newItem); 548 } 549 return true; 550 }; 551 btnRemoveItem.click = delegate(Widget source) { 552 TreeItem item = tree.items.selectedItem; 553 if (item) { 554 Log.d("Removing tree item ", item.id, " ", item.text); 555 item.parent.removeChild(item); 556 } 557 return true; 558 }; 559 gbtree.addChild(newTreeItem); 560 line4.addChild(gbtree); 561 562 controls.addChild(line4); 563 564 tabs.addTab(controls, "Controls"d); 565 } 566 567 LinearLayout layout = new LinearLayout("tab1"); 568 569 570 layout.addChild((new TextWidget()).textColor(0x00802000).text("Text widget 0")); 571 layout.addChild((new TextWidget()).textColor(0x40FF4000).text("Text widget")); 572 layout.addChild(new ProgressBarWidget().progress(300).animationInterval(50)); 573 layout.addChild(new ProgressBarWidget().progress(-1).animationInterval(50)); 574 layout.addChild((new Button("BTN1")).textResource("EXIT")); //.textColor(0x40FF4000) 575 layout.addChild(new TimerTest()); 576 577 static if (true) { 578 579 580 LinearLayout hlayout = new HorizontalLayout(); 581 hlayout.layoutWidth(FILL_PARENT); 582 //hlayout.addChild((new Button()).text("<<")); //.textColor(0x40FF4000) 583 hlayout.addChild((new TextWidget()).text("Several").alignment(Align.Center)); 584 hlayout.addChild((new ImageWidget()).drawableId("btn_radio").padding(Rect(5,5,5,5)).alignment(Align.Center)); 585 hlayout.addChild((new TextWidget()).text("items").alignment(Align.Center)); 586 hlayout.addChild((new ImageWidget()).drawableId("btn_check").padding(Rect(5,5,5,5)).alignment(Align.Center)); 587 hlayout.addChild((new TextWidget()).text("in horizontal layout")); 588 hlayout.addChild((new ImageWidget()).drawableId("exit").padding(Rect(5,5,5,5)).alignment(Align.Center)); 589 hlayout.addChild((new EditLine("editline", "Some text to edit"d)).popupMenu(editPopupItem).alignment(Align.Center).layoutWidth(FILL_PARENT)); 590 hlayout.addChild((new EditLine("passwd", "Password"d)).passwordChar('*').popupMenu(editPopupItem).alignment(Align.Center).layoutWidth(FILL_PARENT)); 591 //hlayout.addChild((new Button()).text(">>")); //.textColor(0x40FF4000) 592 hlayout.backgroundColor = 0x8080C0; 593 layout.addChild(hlayout); 594 595 LinearLayout vlayoutgroup = new HorizontalLayout(); 596 LinearLayout vlayout = new VerticalLayout(); 597 vlayout.addChild((new TextWidget()).text("VLayout line 1").textColor(0x40FF4000)); // 598 vlayout.addChild((new TextWidget()).text("VLayout line 2").textColor(0x40FF8000)); 599 vlayout.addChild((new TextWidget()).text("VLayout line 2").textColor(0x40008000)); 600 vlayout.addChild(new RadioButton("rb1", "Radio button 1"d)); 601 vlayout.addChild(new RadioButton("rb2", "Radio button 2"d)); 602 vlayout.addChild(new RadioButton("rb3", "Radio button 3"d)); 603 vlayout.layoutWidth(FILL_PARENT); 604 vlayoutgroup.addChild(vlayout); 605 vlayoutgroup.layoutWidth(FILL_PARENT); 606 ScrollBar vsb = new ScrollBar("vscroll", Orientation.Vertical); 607 vlayoutgroup.addChild(vsb); 608 layout.addChild(vlayoutgroup); 609 610 ScrollBar sb = new ScrollBar("hscroll", Orientation.Horizontal); 611 layout.addChild(sb.layoutHeight(WRAP_CONTENT).layoutWidth(FILL_PARENT)); 612 613 layout.addChild((new CheckBox("BTN2", "Some checkbox"d))); 614 layout.addChild((new TextWidget()).textColor(0x40FF4000).text("Text widget")); 615 layout.addChild((new ImageWidget()).drawableId("exit").padding(Rect(5,5,5,5))); 616 layout.addChild((new TextWidget()).textColor(0xFF4000).text("Text widget2").padding(Rect(5,5,5,5)).margins(Rect(5,5,5,5)).backgroundColor(0xA0A0A0)); 617 layout.addChild((new RadioButton("BTN3", "Some radio button"d))); 618 layout.addChild((new TextWidget(null, "Text widget3 with very long text"d)).textColor(0x004000)); 619 layout.addChild(new VSpacer()); // vertical spacer to fill extra space 620 621 622 Widget w = parseML(q{ 623 VerticalLayout { 624 id: vlayout 625 margins: Rect { left: 5; right: 3; top: 2; bottom: 4 } 626 padding: Rect { 5, 4, 3, 2 } // same as Rect { left: 5; top: 4; right: 3; bottom: 2 } 627 TextWidget { 628 /* this widget can be accessed via id myLabel1 629 e.g. w.childById!TextWidget("myLabel1") 630 */ 631 id: myLabel1 632 text: "Some text"; padding: 5 633 enabled: false 634 } 635 TextWidget { 636 id: myLabel2 637 text: SOME_TEXT_RESOURCE_ID; margins: 5 638 enabled: true 639 } 640 } 641 }); 642 Log.d("id=", w.id, " text=", w.text, " padding=", w.padding, " margins=", w.margins, 643 " lbl1.text=", w.childById!TextWidget("myLabel1").text, 644 " lbl1.enabled=", w.childById!TextWidget("myLabel1").enabled, 645 " lbl2.text=", w.childById!TextWidget("myLabel2").text 646 ); 647 destroy(w); 648 649 layout.childById("BTN1").click = delegate (Widget w) { 650 Log.d("onClick ", w.id); 651 //w.backgroundImageId = null; 652 //w.backgroundColor = 0xFF00FF; 653 w.textColor = 0xFF00FF; 654 w.styleId = STYLE_BUTTON_NOMARGINS; 655 return true; 656 }; 657 layout.childById("BTN2").click = delegate (Widget w) { Log.d("onClick ", w.id); return true; }; 658 layout.childById("BTN3").click = delegate (Widget w) { Log.d("onClick ", w.id); return true; }; 659 660 } 661 662 layout.layoutHeight(FILL_PARENT).layoutWidth(FILL_PARENT); 663 664 tabs.addTab(layout, "Misc"d); 665 666 static if (true) { 667 // two long lists 668 // left one is list with widgets as items 669 // right one is list with string list adapter 670 HorizontalLayout longLists = new HorizontalLayout("tab2"); 671 longLists.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 672 673 ListWidget list = new ListWidget("list1", Orientation.Vertical); 674 list.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 675 676 StringListAdapter stringList = new StringListAdapter(); 677 WidgetListAdapter listAdapter = new WidgetListAdapter(); 678 listAdapter.add((new TextWidget()).text("This is a list of widgets"d).styleId("LIST_ITEM")); 679 stringList.add("This is a list of strings from StringListAdapter"d); 680 stringList.add("If you type with your keyboard,"d); 681 stringList.add("then you can find the"d); 682 stringList.add("item in the list"d); 683 stringList.add("neat!"d); 684 for (int i = 1; i < 1000; i++) { 685 dstring label = "List item "d ~ to!dstring(i); 686 listAdapter.add((new TextWidget()).text("Widget list - "d ~ label).styleId("LIST_ITEM")); 687 stringList.add("Simple string - "d ~ label); 688 } 689 list.ownAdapter = listAdapter; 690 listAdapter.resetItemState(0, State.Enabled); 691 listAdapter.resetItemState(5, State.Enabled); 692 listAdapter.resetItemState(7, State.Enabled); 693 listAdapter.resetItemState(12, State.Enabled); 694 assert(list.itemEnabled(5) == false); 695 assert(list.itemEnabled(6) == true); 696 list.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 697 list.selectItem(0); 698 699 longLists.addChild(list); 700 701 ListWidget list2 = new StringListWidget("list2"); 702 list2.ownAdapter = stringList; 703 list2.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 704 list2.selectItem(0); 705 longLists.addChild(list2); 706 707 VerticalLayout itemedit = new VerticalLayout(); 708 itemedit.addChild(new TextWidget(null, "New item text:"d)); 709 EditLine itemtext = new EditLine(null, "Text for new item"d); 710 itemedit.addChild(itemtext); 711 Button btn = new Button(null, "Add item"d); 712 itemedit.addChild(btn); 713 longLists.addChild(itemedit); 714 btn.click = delegate(Widget src) 715 { 716 stringList.add(itemtext.text); 717 listAdapter.add((new TextWidget()).text(itemtext.text).styleId("LIST_ITEM")); 718 return true; 719 }; 720 tabs.addTab(longLists, "TAB_LONG_LIST"c); 721 } 722 723 { 724 LinearLayout layout3 = new VerticalLayout("tab3"); 725 // 3 types of buttons: Button, ImageButton, ImageTextButton 726 layout3.addChild(new TextWidget(null, "Buttons in HorizontalLayout"d)); 727 WidgetGroup buttons1 = new HorizontalLayout(); 728 buttons1.addChild(new TextWidget(null, "Button widgets: "d)); 729 buttons1.addChild((new Button("btn1", "Button"d)).tooltipText("Tooltip text for button"d)); 730 buttons1.addChild((new Button("btn2", "Disabled Button"d)).enabled(false)); 731 buttons1.addChild(new TextWidget(null, "ImageButton widgets: "d)); 732 buttons1.addChild(new ImageButton("btn3", "text-plain")); 733 buttons1.addChild(new TextWidget(null, "disabled: "d)); 734 buttons1.addChild((new ImageButton("btn4", "folder")).enabled(false)); 735 layout3.addChild(buttons1); 736 737 WidgetGroup buttons10 = new HorizontalLayout(); 738 buttons10.addChild(new TextWidget(null, "ImageTextButton widgets: "d)); 739 buttons10.addChild(new ImageTextButton("btn5", "text-plain", "Enabled"d)); 740 buttons10.addChild((new ImageTextButton("btn6", "folder", "Disabled"d)).enabled(false)); 741 buttons10.addChild(new TextWidget(null, "SwitchButton widgets: "d)); 742 buttons10.addChild((new SwitchButton("SW1")).checked(true)); 743 buttons10.addChild((new SwitchButton("SW2")).checked(false)); 744 buttons10.addChild((new SwitchButton("SW3")).checked(true).enabled(false)); 745 buttons10.addChild((new SwitchButton("SW4")).checked(false).enabled(false)); 746 layout3.addChild(buttons10); 747 748 WidgetGroup buttons11 = new HorizontalLayout(); 749 buttons11.addChild(new TextWidget(null, "Construct buttons by action (Button, ImageButton, ImageTextButton): "d)); 750 Action FILE_OPEN_ACTION = new Action(ACTION_FILE_OPEN, "MENU_FILE_OPEN"c, "document-open", KeyCode.KEY_O, KeyFlag.Control); 751 buttons11.addChild(new Button(FILE_OPEN_ACTION)); 752 buttons11.addChild(new ImageButton(FILE_OPEN_ACTION)); 753 buttons11.addChild(new ImageTextButton(FILE_OPEN_ACTION)); 754 layout3.addChild(buttons11); 755 756 WidgetGroup buttons12 = new HorizontalLayout(); 757 buttons12.addChild(new TextWidget(null, "The same in disabled state: "d)); 758 buttons12.addChild((new Button(FILE_OPEN_ACTION)).enabled(false)); 759 buttons12.addChild((new ImageButton(FILE_OPEN_ACTION)).enabled(false)); 760 buttons12.addChild((new ImageTextButton(FILE_OPEN_ACTION)).enabled(false)); 761 layout3.addChild(buttons12); 762 763 layout3.addChild(new VSpacer()); 764 layout3.addChild(new TextWidget(null, "CheckBoxes in HorizontalLayout"d)); 765 WidgetGroup buttons2 = new HorizontalLayout(); 766 buttons2.addChild(new CheckBox("btn1", "CheckBox 1"d)); 767 buttons2.addChild(new CheckBox("btn2", "CheckBox 2"d)); 768 //buttons2.addChild(new ResizerWidget()); 769 buttons2.addChild(new CheckBox("btn3", "CheckBox 3"d)); 770 buttons2.addChild(new CheckBox("btn4", "CheckBox 4"d)); 771 layout3.addChild(buttons2); 772 773 layout3.addChild(new VSpacer()); 774 layout3.addChild(new TextWidget(null, "RadioButtons in HorizontalLayout"d)); 775 WidgetGroup buttons3 = new HorizontalLayout(); 776 buttons3.addChild(new RadioButton("btn1", "RadioButton 1"d)); 777 buttons3.addChild(new RadioButton("btn2", "RadioButton 2"d)); 778 buttons3.addChild(new RadioButton("btn3", "RadioButton 3"d)); 779 buttons3.addChild(new RadioButton("btn4", "RadioButton 4"d)); 780 layout3.addChild(buttons3); 781 782 layout3.addChild(new VSpacer()); 783 layout3.addChild(new TextWidget(null, "ImageButtons HorizontalLayout"d)); 784 WidgetGroup buttons4 = new HorizontalLayout(); 785 buttons4.addChild(new ImageButton("btn1", "fileclose")); 786 buttons4.addChild(new ImageButton("btn2", "fileopen")); 787 buttons4.addChild(new ImageButton("btn3", "exit")); 788 layout3.addChild(buttons4); 789 790 layout3.addChild(new VSpacer()); 791 layout3.addChild(new TextWidget(null, "In vertical layouts:"d)); 792 HorizontalLayout hlayout2 = new HorizontalLayout(); 793 hlayout2.layoutHeight(FILL_PARENT); //layoutWidth(FILL_PARENT). 794 795 buttons1 = new VerticalLayout(); 796 buttons1.addChild(new TextWidget(null, "Buttons"d)); 797 buttons1.addChild(new Button("btn1", "Button 1"d)); 798 buttons1.addChild(new Button("btn2", "Button 2"d)); 799 buttons1.addChild((new Button("btn3", "Button 3 - disabled"d)).enabled(false)); 800 buttons1.addChild(new Button("btn4", "Button 4"d)); 801 hlayout2.addChild(buttons1); 802 hlayout2.addChild(new HSpacer()); 803 804 buttons2 = new VerticalLayout(); 805 buttons2.addChild(new TextWidget(null, "CheckBoxes"d)); 806 buttons2.addChild(new CheckBox("btn1", "CheckBox 1"d)); 807 buttons2.addChild(new CheckBox("btn2", "CheckBox 2"d)); 808 buttons2.addChild(new CheckBox("btn3", "CheckBox 3"d)); 809 buttons2.addChild(new CheckBox("btn4", "CheckBox 4"d)); 810 hlayout2.addChild(buttons2); 811 hlayout2.addChild(new HSpacer()); 812 813 buttons3 = new VerticalLayout(); 814 buttons3.addChild(new TextWidget(null, "RadioButtons"d)); 815 buttons3.addChild(new RadioButton("btn1", "RadioButton 1"d)); 816 buttons3.addChild(new RadioButton("btn2", "RadioButton 2"d)); 817 //buttons3.addChild(new ResizerWidget()); 818 buttons3.addChild(new RadioButton("btn3", "RadioButton 3"d)); 819 buttons3.addChild(new RadioButton("btn4", "RadioButton 4"d)); 820 hlayout2.addChild(buttons3); 821 hlayout2.addChild(new HSpacer()); 822 823 buttons4 = new VerticalLayout(); 824 buttons4.addChild(new TextWidget(null, "ImageButtons"d)); 825 buttons4.addChild(new ImageButton("btn1", "fileclose")); 826 buttons4.addChild(new ImageButton("btn2", "fileopen")); 827 buttons4.addChild(new ImageButton("btn3", "exit")); 828 hlayout2.addChild(buttons4); 829 hlayout2.addChild(new HSpacer()); 830 831 WidgetGroup buttons5 = new VerticalLayout(); 832 buttons5.addChild(new TextWidget(null, "ImageTextButtons"d)); 833 buttons5.addChild(new ImageTextButton("btn1", "fileclose", "Close"d)); 834 buttons5.addChild(new ImageTextButton("btn2", "fileopen", "Open"d)); 835 buttons5.addChild(new ImageTextButton("btn3", "exit", "Exit"d)); 836 hlayout2.addChild(buttons5); 837 838 839 layout3.addChild(hlayout2); 840 841 layout3.addChild(new VSpacer()); 842 layout3.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 843 tabs.addTab(layout3, "TAB_BUTTONS"c); 844 } 845 846 TableLayout table = new TableLayout("TABLE"); 847 table.colCount = 2; 848 // headers 849 table.addChild((new TextWidget(null, "Parameter Name"d)).alignment(Align.Right | Align.VCenter)); 850 table.addChild((new TextWidget(null, "Edit Box to edit parameter"d)).alignment(Align.Left | Align.VCenter)); 851 // row 1 852 table.addChild((new TextWidget(null, "Parameter 1 name"d)).alignment(Align.Right | Align.VCenter)); 853 table.addChild((new EditLine("edit1", "Text 1"d)).layoutWidth(FILL_PARENT)); 854 // row 2 855 table.addChild((new TextWidget(null, "Parameter 2 name bla bla"d)).alignment(Align.Right | Align.VCenter)); 856 table.addChild((new EditLine("edit2", "Some text for parameter 2"d)).layoutWidth(FILL_PARENT)); 857 // row 3 858 table.addChild((new TextWidget(null, "Param 3 is disabled"d)).alignment(Align.Right | Align.VCenter).enabled(false)); 859 table.addChild((new EditLine("edit3", "Parameter 3 value"d)).layoutWidth(FILL_PARENT).enabled(false)); 860 // normal readonly combo box 861 ComboBox combo1 = new ComboBox("combo1", ["item value 1"d, "item value 2"d, "item value 3"d, "item value 4"d, "item value 5"d, "item value 6"d]); 862 table.addChild((new TextWidget(null, "Combo box param"d)).alignment(Align.Right | Align.VCenter)); 863 combo1.selectedItemIndex = 3; 864 table.addChild(combo1).layoutWidth(FILL_PARENT); 865 // disabled readonly combo box 866 ComboBox combo2 = new ComboBox("combo2", ["item value 1"d, "item value 2"d, "item value 3"d]); 867 table.addChild((new TextWidget(null, "Disabled combo box"d)).alignment(Align.Right | Align.VCenter)); 868 combo2.enabled = false; 869 combo2.selectedItemIndex = 0; 870 table.addChild(combo2).layoutWidth(FILL_PARENT); 871 872 table.margins(Rect(2,2,2,2)).layoutWidth(FILL_PARENT); 873 tabs.addTab(table, "TAB_TABLE_LAYOUT"c); 874 875 //tabs.addTab((new TextWidget()).id("tab5").textColor(0x00802000).text("Tab 5 contents"), "Tab 5"d); 876 877 //========================================================================== 878 // create Editors test tab 879 VerticalLayout editors = new VerticalLayout("editors"); 880 881 // EditLine sample 882 editors.addChild(new TextWidget(null, "EditLine: Single line editor"d)); 883 EditLine editLine = new EditLine("editline1", "Single line editor sample text"); 884 editors.addChild(createEditorSettingsControl(editLine)); 885 editors.addChild(editLine); 886 editLine.popupMenu = editPopupItem; 887 888 // EditBox sample 889 editors.addChild(new TextWidget(null, "SourceEdit: multiline editor, for source code editing"d)); 890 891 SourceEdit editBox = new SourceEdit("editbox1"); 892 editBox.text = q{#!/usr/bin/env rdmd 893 // Computes average line length for standard input. 894 import std.stdio; 895 896 void main() 897 { 898 ulong lines = 0; 899 double sumLength = 0; 900 foreach (line; stdin.byLine()) 901 { 902 ++lines; 903 sumLength += line.length; 904 } 905 writeln("Average line length: ", 906 lines ? sumLength / lines : 0); 907 } 908 }}; 909 editors.addChild(createEditorSettingsControl(editBox)); 910 editors.addChild(editBox); 911 editBox.popupMenu = editPopupItem; 912 913 editors.addChild(new TextWidget(null, "EditBox: additional view for the same content (split view testing)"d)); 914 SourceEdit editBox2 = new SourceEdit("editbox2"); 915 editBox2.content = editBox.content; // view the same content as first editbox 916 editors.addChild(editBox2); 917 editors.layoutHeight(FILL_PARENT).layoutWidth(FILL_PARENT); 918 919 tabs.addTab(editors, "TAB_EDITORS"c); 920 921 //========================================================================== 922 923 VerticalLayout gridContent = new VerticalLayout("GRID_CONTENT"); 924 gridContent.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 925 HorizontalLayout gridSettings = new HorizontalLayout(); 926 StringGridWidget grid = new StringGridWidget("GRID1"); 927 928 gridSettings.addChild((new CheckBox("fullColumnOnLeft", "fullColumnOnLeft"d)).checked(grid.fullColumnOnLeft).tooltipText("Extends scroll area to show full column at left when scrolled to rightmost column"d).addOnCheckChangeListener(delegate(Widget, bool checked) { grid.fullColumnOnLeft = checked; return true;})); 929 gridSettings.addChild((new CheckBox("fullRowOnTop", "fullRowOnTop"d)).checked(grid.fullRowOnTop).tooltipText("Extends scroll area to show full row at top when scrolled to end row"d).addOnCheckChangeListener(delegate(Widget, bool checked) { grid.fullRowOnTop = checked; return true;})); 930 gridContent.addChild(gridSettings); 931 932 grid.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 933 grid.showColHeaders = true; 934 grid.showRowHeaders = true; 935 grid.resize(30, 50); 936 grid.fixedCols = 3; 937 grid.fixedRows = 2; 938 //grid.rowSelect = true; // testing full row selection 939 grid.multiSelect = true; 940 grid.selectCell(4, 6, false); 941 // create sample grid content 942 for (int y = 0; y < grid.rows; y++) { 943 for (int x = 0; x < grid.cols; x++) { 944 grid.setCellText(x, y, "cell("d ~ to!dstring(x + 1) ~ ","d ~ to!dstring(y + 1) ~ ")"d); 945 } 946 grid.setRowTitle(y, to!dstring(y + 1)); 947 } 948 for (int x = 0; x < grid.cols; x++) { 949 int col = x + 1; 950 dstring res; 951 int n1 = col / 26; 952 int n2 = col % 26; 953 if (n1) 954 res ~= n1 + 'A'; 955 res ~= n2 + 'A'; 956 grid.setColTitle(x, res); 957 } 958 grid.autoFit(); 959 gridContent.addChild(grid); 960 tabs.addTab(gridContent, "Grid"d); 961 962 //========================================================================== 963 // Scroll view example 964 ScrollWidget scroll = new ScrollWidget("SCROLL1"); 965 scroll.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 966 WidgetGroup scrollContent = new VerticalLayout("CONTENT"); 967 scrollContent.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); 968 969 TableLayout table2 = new TableLayout("TABLE2"); 970 table2.colCount = 2; 971 // headers 972 table2.addChild((new TextWidget(null, "Parameter Name"d)).alignment(Align.Right | Align.VCenter)); 973 table2.addChild((new TextWidget(null, "Edit Box to edit parameter"d)).alignment(Align.Left | Align.VCenter)); 974 // row 1 975 table2.addChild((new TextWidget(null, "Parameter 1 name"d)).alignment(Align.Right | Align.VCenter)); 976 table2.addChild((new EditLine("edit1", "Text 1"d)).layoutWidth(FILL_PARENT)); 977 // row 2 978 table2.addChild((new TextWidget(null, "Parameter 2 name bla bla"d)).alignment(Align.Right | Align.VCenter)); 979 table2.addChild((new EditLine("edit2", "Some text for parameter 2 blah blah blah"d)).layoutWidth(FILL_PARENT)); 980 // row 3 981 table2.addChild((new TextWidget(null, "Param 3"d)).alignment(Align.Right | Align.VCenter)); 982 table2.addChild((new EditLine("edit3", "Parameter 3 value"d)).layoutWidth(FILL_PARENT)); 983 // row 4 984 table2.addChild((new TextWidget(null, "Param 4"d)).alignment(Align.Right | Align.VCenter)); 985 table2.addChild((new EditLine("edit3", "Parameter 4 value shdjksdfh hsjdfas hdjkf hdjsfk ah"d)).layoutWidth(FILL_PARENT)); 986 // row 5 987 table2.addChild((new TextWidget(null, "Param 5 - edit text here - blah blah blah"d)).alignment(Align.Right | Align.VCenter)); 988 table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT)); 989 // row 6 990 table2.addChild((new TextWidget(null, "Param 6 - just to fill content widget (DISABLED)"d)).alignment(Align.Right | Align.VCenter).enabled(false)); 991 table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT).enabled(false)); 992 // row 7 993 table2.addChild((new TextWidget(null, "Param 7 - just to fill content widget (DISABLED)"d)).alignment(Align.Right | Align.VCenter).enabled(false)); 994 table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT).enabled(false)); 995 // row 8 996 table2.addChild((new TextWidget(null, "Param 8 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter)); 997 table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT)); 998 table2.margins(Rect(10,10,10,10)).layoutWidth(FILL_PARENT); 999 scrollContent.addChild(table2); 1000 1001 scrollContent.addChild(new TextWidget(null, "Now - some buttons"d)); 1002 scrollContent.addChild(new ImageTextButton("btn1", "fileclose", "Close"d)); 1003 scrollContent.addChild(new ImageTextButton("btn2", "fileopen", "Open"d)); 1004 scrollContent.addChild(new TextWidget(null, "And checkboxes"d)); 1005 scrollContent.addChild(new CheckBox("btn1", "CheckBox 1"d)); 1006 scrollContent.addChild(new CheckBox("btn2", "CheckBox 2"d)); 1007 1008 scroll.contentWidget = scrollContent; 1009 tabs.addTab(scroll, "Scroll"d); 1010 //========================================================================== 1011 // tree view example 1012 TreeWidget tree = new TreeWidget("TREE1"); 1013 tree.layoutWidth(WRAP_CONTENT).layoutHeight(FILL_PARENT); 1014 TreeItem tree1 = tree.items.newChild("group1", "Group 1"d, "document-open"); 1015 tree1.newChild("g1_1", "Group 1 item 1"d); 1016 tree1.newChild("g1_2", "Group 1 item 2"d); 1017 tree1.newChild("g1_3", "Group 1 item 3"d); 1018 TreeItem tree2 = tree.items.newChild("group2", "Group 2"d, "document-save"); 1019 tree2.newChild("g2_1", "Group 2 item 1"d, "edit-copy"); 1020 tree2.newChild("g2_2", "Group 2 item 2"d, "edit-cut"); 1021 tree2.newChild("g2_3", "Group 2 item 3"d, "edit-paste"); 1022 tree2.newChild("g2_4", "Group 2 item 4"d); 1023 TreeItem tree3 = tree.items.newChild("group3", "Group 3"d); 1024 tree3.newChild("g3_1", "Group 3 item 1"d); 1025 tree3.newChild("g3_2", "Group 3 item 2"d); 1026 TreeItem tree32 = tree3.newChild("g3_3", "Group 3 item 3"d); 1027 tree3.newChild("g3_4", "Group 3 item 4"d); 1028 tree32.newChild("group3_2_1", "Group 3 item 2 subitem 1"d); 1029 tree32.newChild("group3_2_2", "Group 3 item 2 subitem 2"d); 1030 tree32.newChild("group3_2_3", "Group 3 item 2 subitem 3"d); 1031 tree32.newChild("group3_2_4", "Group 3 item 2 subitem 4"d); 1032 tree32.newChild("group3_2_5", "Group 3 item 2 subitem 5"d); 1033 tree3.newChild("g3_5", "Group 3 item 5"d); 1034 tree3.newChild("g3_6", "Group 3 item 6"d); 1035 1036 LinearLayout treeLayout = new HorizontalLayout("TREE"); 1037 LinearLayout treeControlledPanel = new VerticalLayout(); 1038 treeLayout.layoutWidth = FILL_PARENT; 1039 treeControlledPanel.layoutWidth = FILL_PARENT; 1040 treeControlledPanel.layoutHeight = FILL_PARENT; 1041 TextWidget treeItemLabel = new TextWidget("TREE_ITEM_DESC"); 1042 treeItemLabel.layoutWidth = FILL_PARENT; 1043 treeItemLabel.layoutHeight = FILL_PARENT; 1044 treeItemLabel.alignment = Align.Center; 1045 treeItemLabel.text = "Sample text"d; 1046 treeControlledPanel.addChild(treeItemLabel); 1047 treeLayout.addChild(tree); 1048 treeLayout.addChild(new ResizerWidget()); 1049 treeLayout.addChild(treeControlledPanel); 1050 1051 tree.selectionChange = delegate(TreeItems source, TreeItem selectedItem, bool activated) { 1052 dstring label = "Selected item: "d ~ toUTF32(selectedItem.id) ~ (activated ? " selected + activated"d : " selected"d); 1053 treeItemLabel.text = label; 1054 }; 1055 1056 tree.items.selectItem(tree.items.child(0)); 1057 1058 tabs.addTab(treeLayout, "Tree"d); 1059 1060 tabs.addTab(new ChartsExample("charts"), "Charts"d); 1061 tabs.addTab((new SampleAnimationWidget("tab6")).layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT), "TAB_ANIMATION"c); 1062 tabs.addTab(new CanvasExample("canvas"), UIString.fromId("TAB_CANVAS")); 1063 tabs.addTab(new IconsExample("icons"), "Icons"d); 1064 1065 static if (BACKEND_GUI && ENABLE_OPENGL) 1066 { 1067 tabs.addTab(new MyOpenglWidget(), "OpenGL"d); 1068 } 1069 1070 //========================================================================== 1071 1072 contentLayout.addChild(tabs); 1073 window.mainWidget = contentLayout; 1074 1075 tabs.selectTab("controls"); 1076 } else { 1077 window.mainWidget = (new Button()).text("sample button"); 1078 } 1079 static if (BACKEND_GUI) { 1080 window.windowIcon = drawableCache.getImage("dlangui-logo1"); 1081 } 1082 window.show(); 1083 //window.windowCaption = "New Window Caption"; 1084 // run message loop 1085 1086 Log.i("HOME path: ", homePath); 1087 Log.i("APPDATA path: ", appDataPath(".dlangui")); 1088 Log.i("Root paths: ", getRootPaths); 1089 1090 return Platform.instance.enterMessageLoop(); 1091 } 1092 1093 static if (ENABLE_OPENGL) { 1094 1095 import bindbc.opengl; 1096 1097 class MyOpenglWidget : VerticalLayout { 1098 this() { 1099 super("OpenGLView"); 1100 layoutWidth = FILL_PARENT; 1101 layoutHeight = FILL_PARENT; 1102 alignment = Align.Center; 1103 // add some UI on top of OpenGL drawable 1104 Widget w = parseML(q{ 1105 VerticalLayout { 1106 alignment: center 1107 layoutWidth: fill; layoutHeight: fill 1108 // background for window - tiled texture 1109 backgroundImageId: "tx_fabric.tiled" 1110 VerticalLayout { 1111 // child widget - will draw using OpenGL here 1112 id: glView 1113 margins: 20 1114 padding: 20 1115 layoutWidth: fill; layoutHeight: fill 1116 1117 //backgroundColor: "#C0E0E070" // semitransparent yellow background 1118 // red bold text with size = 150% of base style size and font face Arial 1119 TextWidget { text: "Some controls to draw on top of OpenGL scene"; textColor: "red"; fontSize: 150%; fontWeight: 800; fontFace: "Arial" } 1120 // arrange controls as form - table with two columns 1121 TableLayout { 1122 colCount: 2 1123 TextWidget { text: "param 1" } 1124 EditLine { id: edit1; text: "some text" } 1125 TextWidget { text: "param 2" } 1126 EditLine { id: edit2; text: "some text for param2" } 1127 TextWidget { text: "some radio buttons" } 1128 // arrange some radio buttons vertically 1129 VerticalLayout { 1130 RadioButton { id: rb1; text: "Item 1" } 1131 RadioButton { id: rb2; text: "Item 2" } 1132 RadioButton { id: rb3; text: "Item 3" } 1133 } 1134 TextWidget { text: "and checkboxes" } 1135 // arrange some checkboxes horizontally 1136 HorizontalLayout { 1137 CheckBox { id: cb1; text: "checkbox 1" } 1138 CheckBox { id: cb2; text: "checkbox 2" } 1139 } 1140 } 1141 VSpacer { layoutWeight: 10 } 1142 HorizontalLayout { 1143 Button { id: btnOk; text: "Ok" } 1144 Button { id: btnCancel; text: "Cancel" } 1145 } 1146 } 1147 } 1148 }); 1149 // setting OpenGL background drawable for one of child widgets 1150 w.childById("glView").backgroundDrawable = DrawableRef(new OpenGLDrawable(&doDraw)); 1151 addChild(w); 1152 } 1153 1154 bool _oldApi; 1155 1156 /// this is OpenGLDrawableDelegate implementation 1157 private void doDraw(Rect windowRect, Rect rc) { 1158 if (!openglEnabled) { 1159 Log.v("GlGears: OpenGL is disabled"); 1160 return; 1161 } 1162 import dlangui.graphics.glsupport : glSupport; 1163 _oldApi = glSupport.legacyMode; 1164 if (_oldApi) { 1165 drawUsingOldAPI(rc); 1166 } else { 1167 drawUsingNewAPI(rc); 1168 } 1169 } 1170 1171 /// Legacy API example (glBegin/glEnd) 1172 void drawUsingOldAPI(Rect rc) { 1173 /* 1174 static bool _initCalled; 1175 if (!_initCalled) { 1176 Log.d("GlGears: calling init()"); 1177 _initCalled = true; 1178 glxgears_init(); 1179 } 1180 glxgears_reshape(rc); 1181 glEnable(GL_LIGHTING); 1182 glEnable(GL_LIGHT0); 1183 glEnable(GL_DEPTH_TEST); 1184 glxgears_draw(); 1185 glDisable(GL_LIGHTING); 1186 glDisable(GL_LIGHT0); 1187 glDisable(GL_DEPTH_TEST); 1188 */ 1189 } 1190 1191 /// New API example (OpenGL3+, shaders) 1192 void drawUsingNewAPI(Rect rc) { 1193 // TODO: put some sample code here 1194 } 1195 /// returns true is widget is being animated - need to call animate() and redraw 1196 @property override bool animating() { return true; } 1197 /// animates window; interval is time left from previous draw, in hnsecs (1/10000000 of second) 1198 override void animate(long interval) { 1199 if (_oldApi) { 1200 // animate legacy API example 1201 // rotate gears 1202 angle += interval * 0.000002f; 1203 } else { 1204 // TODO: animate new API example 1205 } 1206 invalidate(); 1207 } 1208 } 1209 1210 static __gshared GLfloat angle = 0.0; 1211 1212 version (GLLegacyAPI) { 1213 1214 // Sample project for old API: GlxGears 1215 1216 import std.math; 1217 static __gshared GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; 1218 static __gshared GLint gear1, gear2, gear3; 1219 alias M_PI = std.math.PI; 1220 1221 /* 1222 * 1223 * Draw a gear wheel. You'll probably want to call this function when 1224 * building a display list since we do a lot of trig here. 1225 * 1226 * Input: inner_radius - radius of hole at center 1227 * outer_radius - radius at center of teeth 1228 * width - width of gear 1229 * teeth - number of teeth 1230 * tooth_depth - depth of tooth 1231 */ 1232 1233 static void 1234 gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, 1235 GLint teeth, GLfloat tooth_depth) 1236 { 1237 GLint i; 1238 GLfloat r0, r1, r2; 1239 GLfloat angle, da; 1240 GLfloat u, v, len; 1241 1242 r0 = inner_radius; 1243 r1 = outer_radius - tooth_depth / 2.0; 1244 r2 = outer_radius + tooth_depth / 2.0; 1245 1246 da = 2.0 * M_PI / teeth / 4.0; 1247 1248 glShadeModel(GL_FLAT); 1249 1250 glNormal3f(0.0, 0.0, 1.0); 1251 1252 /* draw front face */ 1253 glBegin(GL_QUAD_STRIP); 1254 for (i = 0; i <= teeth; i++) { 1255 angle = i * 2.0 * M_PI / teeth; 1256 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); 1257 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); 1258 if (i < teeth) { 1259 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); 1260 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), 1261 width * 0.5); 1262 } 1263 } 1264 glEnd(); 1265 1266 /* draw front sides of teeth */ 1267 glBegin(GL_QUADS); 1268 da = 2.0 * M_PI / teeth / 4.0; 1269 for (i = 0; i < teeth; i++) { 1270 angle = i * 2.0 * M_PI / teeth; 1271 1272 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); 1273 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); 1274 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), 1275 width * 0.5); 1276 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), 1277 width * 0.5); 1278 } 1279 glEnd(); 1280 1281 glNormal3f(0.0, 0.0, -1.0); 1282 1283 /* draw back face */ 1284 glBegin(GL_QUAD_STRIP); 1285 for (i = 0; i <= teeth; i++) { 1286 angle = i * 2.0 * M_PI / teeth; 1287 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); 1288 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); 1289 if (i < teeth) { 1290 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), 1291 -width * 0.5); 1292 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); 1293 } 1294 } 1295 glEnd(); 1296 1297 /* draw back sides of teeth */ 1298 glBegin(GL_QUADS); 1299 da = 2.0 * M_PI / teeth / 4.0; 1300 for (i = 0; i < teeth; i++) { 1301 angle = i * 2.0 * M_PI / teeth; 1302 1303 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), 1304 -width * 0.5); 1305 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), 1306 -width * 0.5); 1307 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); 1308 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); 1309 } 1310 glEnd(); 1311 1312 /* draw outward faces of teeth */ 1313 glBegin(GL_QUAD_STRIP); 1314 for (i = 0; i < teeth; i++) { 1315 angle = i * 2.0 * M_PI / teeth; 1316 1317 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); 1318 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); 1319 u = r2 * cos(angle + da) - r1 * cos(angle); 1320 v = r2 * sin(angle + da) - r1 * sin(angle); 1321 len = sqrt(u * u + v * v); 1322 u /= len; 1323 v /= len; 1324 glNormal3f(v, -u, 0.0); 1325 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); 1326 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); 1327 glNormal3f(cos(angle), sin(angle), 0.0); 1328 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), 1329 width * 0.5); 1330 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), 1331 -width * 0.5); 1332 u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); 1333 v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); 1334 glNormal3f(v, -u, 0.0); 1335 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), 1336 width * 0.5); 1337 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), 1338 -width * 0.5); 1339 glNormal3f(cos(angle), sin(angle), 0.0); 1340 } 1341 1342 glVertex3f(r1 * cos(0.0), r1 * sin(0.0), width * 0.5); 1343 glVertex3f(r1 * cos(0.0), r1 * sin(0.0), -width * 0.5); 1344 1345 glEnd(); 1346 1347 glShadeModel(GL_SMOOTH); 1348 1349 /* draw inside radius cylinder */ 1350 glBegin(GL_QUAD_STRIP); 1351 for (i = 0; i <= teeth; i++) { 1352 angle = i * 2.0 * M_PI / teeth; 1353 glNormal3f(-cos(angle), -sin(angle), 0.0); 1354 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); 1355 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); 1356 } 1357 glEnd(); 1358 } 1359 1360 1361 static void glxgears_draw() 1362 { 1363 glClear(/*GL_COLOR_BUFFER_BIT | */GL_DEPTH_BUFFER_BIT); 1364 1365 glPushMatrix(); 1366 glRotatef(view_rotx, 1.0, 0.0, 0.0); 1367 glRotatef(view_roty, 0.0, 1.0, 0.0); 1368 glRotatef(view_rotz, 0.0, 0.0, 1.0); 1369 1370 glPushMatrix(); 1371 glTranslatef(-3.0, -2.0, 0.0); 1372 glRotatef(angle, 0.0, 0.0, 1.0); 1373 glCallList(gear1); 1374 glPopMatrix(); 1375 1376 glPushMatrix(); 1377 glTranslatef(3.1, -2.0, 0.0); 1378 glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); 1379 glCallList(gear2); 1380 glPopMatrix(); 1381 1382 glPushMatrix(); 1383 glTranslatef(-3.1, 4.2, 0.0); 1384 glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); 1385 glCallList(gear3); 1386 glPopMatrix(); 1387 1388 glPopMatrix(); 1389 } 1390 1391 1392 /* new window size or exposure */ 1393 static void 1394 glxgears_reshape(Rect rc) 1395 { 1396 GLfloat h = cast(GLfloat) rc.height / cast(GLfloat) rc.width; 1397 glMatrixMode(GL_PROJECTION); 1398 glLoadIdentity(); 1399 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0); 1400 glMatrixMode(GL_MODELVIEW); 1401 glLoadIdentity(); 1402 glTranslatef(0.0, 0.0, -40.0); 1403 } 1404 1405 1406 static void glxgears_init() 1407 { 1408 static GLfloat[4] pos = [ 5.0, 5.0, 10.0, 0.0 ]; 1409 static GLfloat[4] red = [ 0.8, 0.1, 0.0, 1.0 ]; 1410 static GLfloat[4] green = [ 0.0, 0.8, 0.2, 1.0 ]; 1411 static GLfloat[4] blue = [ 0.2, 0.2, 1.0, 1.0 ]; 1412 1413 glLightfv(GL_LIGHT0, GL_POSITION, pos.ptr); 1414 glEnable(GL_CULL_FACE); 1415 glEnable(GL_LIGHTING); 1416 glEnable(GL_LIGHT0); 1417 glEnable(GL_DEPTH_TEST); 1418 1419 /* make the gears */ 1420 gear1 = glGenLists(1); 1421 glNewList(gear1, GL_COMPILE); 1422 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red.ptr); 1423 gear(1.0, 4.0, 1.0, 20, 0.7); 1424 glEndList(); 1425 1426 gear2 = glGenLists(1); 1427 glNewList(gear2, GL_COMPILE); 1428 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green.ptr); 1429 gear(0.5, 2.0, 2.0, 10, 0.7); 1430 glEndList(); 1431 1432 gear3 = glGenLists(1); 1433 glNewList(gear3, GL_COMPILE); 1434 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue.ptr); 1435 gear(1.3, 2.0, 0.5, 10, 0.7); 1436 glEndList(); 1437 1438 glEnable(GL_NORMALIZE); 1439 } 1440 1441 } 1442 }