1 module gui; 2 3 import core.thread; 4 import gtk.MainWindow; 5 import gtk.ListBox; 6 import gtk.Label; 7 import gtk.Notebook; 8 import gdk.Threads : te = threadsEnter, tl = threadsLeave; 9 import gtk.MenuBar; 10 import gtk.Box; 11 import gtk.Menu; 12 import gtk.MenuItem; 13 import std.stdio; 14 import gtk.Statusbar; 15 import gtk.Toolbar; 16 17 import Connection; 18 import std.socket; 19 20 import std.conv; 21 22 public class GUI : Thread 23 { 24 /* Main window (GUI homepage) */ 25 public MainWindow mainWindow; 26 private MenuBar menuBar; 27 private Toolbar toolbar; 28 public Notebook notebook; 29 30 private Statusbar statusBar; 31 32 33 private Connection[] connections; 34 35 private ListBox list; 36 37 38 this() 39 { 40 super(&worker); 41 } 42 43 private void worker() 44 { 45 initializeGUI(); 46 te(); 47 48 tl(); 49 writeln("brg"); 50 while(true) 51 { 52 53 } 54 } 55 56 private void initializeGUI() 57 { 58 initializeMainWindow(); 59 60 /* Test adding a connection */ 61 for(uint i = 0; i < 5; i++) 62 { 63 // connections ~= new Connection(this, parseAddress("0.0.0.0", 7777)); 64 } 65 66 connections ~= new Connection(this, parseAddress("0.0.0.0", 7777), ["testGustav"~to!(string)(connections.length), "bruh"]); 67 68 69 } 70 71 /** 72 * Initializes the main home screen window 73 */ 74 private void initializeMainWindow() 75 { 76 /* Get GTK lock */ 77 te(); 78 79 /* Create a window */ 80 mainWindow = new MainWindow("unamed"); 81 82 /** 83 * Create a Box in vertical layout mode 84 * and adds it to the window 85 * 86 * This lays out components like so: 87 * 88 * |component 1| 89 * |component 2| 90 */ 91 Box box = new Box(GtkOrientation.VERTICAL, 1); 92 93 /** 94 * Add needed components 95 * 96 * Menubar, tabbed pane switcher, statusbar 97 */ 98 menuBar = initializeMenuBar(); 99 box.add(menuBar); 100 101 toolbar = getToolbar(); 102 box.add(toolbar); 103 104 notebook = new Notebook(); 105 notebook.setScrollable(true); 106 box.add(notebook); 107 108 statusBar = new Statusbar(); 109 statusBar.add(new Label("Gustav: Bruh")); 110 111 112 113 box.setChildPacking(notebook, true, true, 0, GtkPackType.START); 114 box.packEnd(statusBar, 0, 0, 0); 115 //notebook.add(createServerTab()); 116 117 118 119 120 /* Add the Box to main window */ 121 mainWindow.add(box); 122 123 mainWindow.showAll(); 124 125 /* Unlock GTK lock */ 126 tl(); 127 128 writeln("unlock gui setup"); 129 } 130 131 private Toolbar getToolbar() 132 { 133 Toolbar toolbar = new Toolbar(); 134 135 /* Status selector dropdown */ 136 import gtk.ComboBox; 137 import gtk.ToolButton; 138 139 // Menu menu = new Menu(); 140 // menu.add(new MenuItem("")); 141 ComboBox statusBox = new ComboBox(); 142 statusBox.setTitle("Status"); 143 144 145 ToolButton setAvail = new ToolButton(""); 146 setAvail.setLabel("available"); 147 setAvail.setIconName("user-available"); 148 toolbar.add(setAvail); 149 150 ToolButton setAway = new ToolButton(""); 151 setAway.setLabel("away"); 152 setAway.setIconName("user-away"); 153 toolbar.add(setAway); 154 155 ToolButton setBusy = new ToolButton(""); 156 setBusy.setLabel("busy"); 157 setBusy.setIconName("user-busy"); 158 toolbar.add(setBusy); 159 160 161 setAvail.addOnClicked(&setStatus); 162 setAway.addOnClicked(&setStatus); 163 setBusy.addOnClicked(&setStatus); 164 165 import gtk.SeparatorToolItem; 166 toolbar.add(new SeparatorToolItem()); 167 168 169 170 ToolButton channelListButton = new ToolButton("folder"); 171 channelListButton.setTooltipText("List channels"); 172 toolbar.add(channelListButton); 173 174 // import gtk.ComboBox; 175 176 // ComboBox d = new ComboBox(); 177 // import gtk.Button; 178 // import gtk.Entry; 179 180 181 // import gtk.Switch; 182 // import gtk.ToolItem; 183 // ToolItem g = new ToolItem(); 184 // g.add(new Switch()); 185 // toolbar.add(g); 186 187 // d.add(new Entry(new Label("1"))); 188 // d.add(new Entry(new Label("2"))); 189 // d.add(new Entry(new Label("3"))); 190 191 // Entry jj; 192 // d.add(new Entry("available")); 193 // d.add(new Entry("away")); 194 // d.add(new Entry("busy")); 195 // import gtk. 196 197 198 // import gtk.ToolItem; 199 // ToolItem h =new ToolItem(); 200 // h.add(d); 201 // toolbar.add(h); 202 203 204 //toolbar.add(new ToolButton("user-available,""Available")); 205 // toolbar.add(new ToolButton("Away")); 206 // toolbar.add(new ToolButton("Busy")); 207 // toolbar.add(new Label("Away")); 208 // toolbar.add(new Label("Busy")); 209 // import gtk.ToolItem; 210 211 // ToolItem toolItem = new ToolItem(); 212 // toolItem.add(new Label("Available")); 213 214 215 // statusBox.add() 216 217 //toolbar.add(statusBox); 218 219 220 221 return toolbar; 222 } 223 224 private void about(MenuItem) 225 { 226 import gtk.AboutDialog; 227 AboutDialog about = new AboutDialog(); 228 229 about.setVersion("21893"); 230 231 /* TODO: License */ 232 /* TODO: Icon */ 233 /* TODO: Buttons or close */ 234 /* TODO: Set version based on compiler flag */ 235 236 about.setLogoIconName("user-available"); 237 about.setArtists(["i wonder if I could commision an artwork from her"]); 238 239 /* Set all the information */ 240 about.setLicense("LICENSE GOES HERE"); 241 about.setComments("A clean GTK+ graphical DNET client"); 242 about.setWebsite("http://deavmi.assigned.network/docs/dnet/site"); 243 about.setDocumenters(["ss","fdsfsd"]); 244 about.setAuthors(["Tristan B. Kildaire (Deavmi) - deavmi@disroot.org"]); 245 246 /* Show the about dialog */ 247 about.showAll(); 248 } 249 250 251 /** 252 * List channels 253 * 254 * Brings up a window listing channels of the current server 255 */ 256 private void listChannels() 257 { 258 import gtk.Window; 259 } 260 261 262 import gtk.ToolButton; 263 private void setStatus(ToolButton x) 264 { 265 /* Get the current connection */ 266 Connection currentConnection = connections[notebook.getCurrentPage()]; 267 268 /* Set the status */ 269 currentConnection.getClient().setStatus(x.getLabel()~",Hey there"); 270 } 271 272 private MenuBar initializeMenuBar() 273 { 274 MenuBar menuBar = new MenuBar(); 275 276 /* Gustav menu */ 277 MenuItem gustavMenuItem = new MenuItem(); 278 gustavMenuItem.setLabel("Gustav"); 279 Menu gustavMenu = new Menu(); 280 gustavMenuItem.setSubmenu(gustavMenu); 281 282 /* Connect option */ 283 MenuItem connectItem = new MenuItem(); 284 connectItem.setLabel("Connect"); 285 connectItem.addOnActivate(&connectButton); 286 gustavMenu.add(connectItem); 287 288 /* Exit option */ 289 MenuItem exitItem = new MenuItem(); 290 exitItem.setLabel("Exit"); 291 exitItem.addOnActivate(&exitButton); 292 gustavMenu.add(exitItem); 293 294 295 /* Help menu */ 296 MenuItem helpMenuItem = new MenuItem(); 297 helpMenuItem.setLabel("Help"); 298 Menu helpMenu = new Menu(); 299 helpMenuItem.setSubmenu(helpMenu); 300 301 /* About option */ 302 MenuItem aboutItem = new MenuItem(); 303 aboutItem.setLabel("About"); 304 aboutItem.addOnActivate(&about); 305 helpMenu.add(aboutItem); 306 307 308 309 310 311 /* Add all menues */ 312 menuBar.add(gustavMenuItem); 313 menuBar.add(helpMenuItem); 314 315 return menuBar; 316 } 317 318 private void exitButton(MenuItem) 319 { 320 writeln("bruh"); 321 322 /* TODO: Implement exit */ 323 324 325 // tl(); 326 //te(); 327 328 329 shutdownConnections(); 330 331 332 // mainWindow.showAll(); 333 334 // tl(); 335 } 336 337 private void connectButton(MenuItem) 338 { 339 connections ~= new Connection(this, parseAddress("0.0.0.0", 7777), ["testGustav"~to!(string)(connections.length), "bruh"]); 340 } 341 342 private void shutdownConnections() 343 { 344 foreach(Connection connection; connections) 345 { 346 /** 347 * TODO: This is called by signal handler, we need no mutexes for signal handler 348 * hence it means that connection 349 */ 350 connection.shutdown(); 351 Thread.sleep(dur!("seconds")(2)); 352 } 353 } 354 355 private void newServer() 356 { 357 358 } 359 360 private Box createServerTab() 361 { 362 Box serverTab = new Box(GtkOrientation.HORIZONTAL, 1); 363 364 serverTab.add(new Label("hello")); 365 366 // serverTab.add(); 367 368 return serverTab; 369 } 370 }