grid_notebook.py
directory : D:\2018_py_proj\TkGridGUI\tkgridgui
Line Count : 1490
Line Clip Size : No Clipping
tab_of_notebook_changed Word MatchCase (0)
1
2
3 from __future__ import print_function
4 from __future__ import unicode_literals
5
6 from future import standard_library
7 standard_library.install_aliases()
8 from builtins import range
9 from builtins import object
10 """
11 Notebook widget where grid geometry manager layout is defined.
12
13 Each target position on the target GUI has a Tk widget type and generic name (like Button_1).
14
15 More proper names can be added later (e.g. Button_1 can be named as Button_SaveFile)
16 Detailed widget properties like color, style or text are assigned outside this file.
17 These widgets only define locations and widget type.
18 """
19
20 import sys
21
22
23 from tkinter import *
24 import tkinter.messagebox
25 from tkinter import Button, Canvas, Checkbutton, Entry, Frame, Label, LabelFrame
26 from tkinter import Listbox, Message, Radiobutton, Spinbox, Text
27 from tkinter import OptionMenu
28 from tkinter.ttk import Combobox, Progressbar, Separator, Treeview, Style, Notebook
29
30 from tkgridgui.edit_Dialog import Edit_Properties_Dialog
31 from tkgridgui.wt_select_Dialog import Wt_Select_Dialog
32 from tkgridgui.comp_tree import CNode, ComponentTree
33
34 supportedTkWidgetSet = set( ['Button', 'Canvas', 'Checkbutton',
35 'Combobox', 'Entry', 'Frame','Label', 'LabelFrame','Listbox', 'Message',
36 'Menubutton', 'Notebook' ,'OptionMenu','Progressbar',
37 'Radiobutton', "RadioGroup", 'Scale', 'Separator', 'Spinbox', 'Text', 'Treeview', 'Tab'] )
38
39
40 CONTROLS = [
41 ("Button", "#7CFC00"),
42 ("Canvas", "#40E0D0"),
43 ("Checkbutton", "#66CDAA"),
44 ("Combobox", "#CD853F"),
45 ("Entry", "#3CB371"),
46 ("Frame", "#F0E68C"),
47 ("Label", "#FFA500"),
48 ("LabelFrame", "#FF7F50"),
49 ("Listbox", "#F08080"),
50 ("Message", "#D8BFD8"),
51 ("Menubutton", "#DA70D6"),
52 ("Notebook", "#FA8072"),
53 ("OptionMenu", "#9370DB"),
54 ("Progressbar", "#FF69B4"),
55 ("Radiobutton", "#FFFF00"),
56 ("RadioGroup", "#FFD700"),
57 ("Scale", "#FF4500"),
58 ("Separator", "#DC143C"),
59 ("Spinbox", "#1E90FF"),
60 ("Text", "#D2B48C"),
61 ("Treeview", "#BC8F8F"),
62 ]
63
64 ContainerControlsL = ['Frame','LabelFrame','Notebook','RadioGroup','Tab']
65
66 CONTROL_COLOR_D = {}
67 CONTROL_NEXT_NUMBER_D = {}
68
69 for widget_type, color in CONTROLS:
70 CONTROL_COLOR_D[widget_type] = color
71 CONTROL_NEXT_NUMBER_D[widget_type] = 1
72
73 CONTROL_COLOR_D['Tab'] = '#cccccc'
74 CONTROL_NEXT_NUMBER_D['Tab'] = 1
75
76 def intCast( val=0 ):
77 try:
78 return int(val)
79 except:
80 return 0
81
82 MAX_NUM_COLS = 10
83 MAX_NUM_ROWS = 15
84
85 class NotebookGridDes( Frame ):
86 """A ttk.Notebook used to design grid geometry manager layouts"""
87
88
89 def __init__(self, grid_gui, mainFrame, MainWin, name='grid_notebook', num_cols=5, num_rows=8):
90 """Create ttk.Notebook used to design grid geometry manager layouts"""
91
92 self.grid_gui = grid_gui
93 self.mainFrame = mainFrame
94 self.MainWin = MainWin
95
96 self.num_cols_inp = num_cols
97 self.num_rows_inp = num_rows
98 self.tab_num_rows_colsD = {}
99
100 Frame.__init__(self, mainFrame, name=name)
101 self.pack(expand=Y, fill=BOTH)
102
103 self.notebook = None
104 self.initialize_NotebookGridDes()
105
106 def initialize_NotebookGridDes(self):
107 self.tabLabelL = []
108 self.nbFrameL = []
109
110
111 self.colInsertWidgetD = {}
112 self.rowInsertWidgetD = {}
113
114 self.colWeightsWidgetD = {}
115 self.rowWeightsWidgetD = {}
116
117 self.interface_gridBoxWidgetD = {}
118 self.default_label_font = ("Courier", 8, "normal")
119
120
121 self.defined_target_widgetD = {}
122 self.label_obj_from_nameD = {}
123
124
125 del self.notebook
126 self.notebook = Notebook(self, name='main')
127 self.notebook.pack(fill=BOTH, expand=Y, padx=2, pady=3)
128
129 self.current_label_being_edited = None
130
131
132 self.must_confirm_box_h = True
133 self.box_h = 46
134 self.box_h3 = self.box_h // 3
135 self.box_h23 = (self.box_h * 2) // 3
136
137 self.must_confirm_box_w = True
138 self.box_w = 116
139 self.box_w3 = self.box_w // 3
140 self.box_w23 = (self.box_w * 2) // 3
141
142 self.drag_set = set()
143
144
145 self.create_tab(tab_label="Main")
146
147
148
149 def highlight_grid_widget(self, widget_name):
150 if widget_name in self.label_obj_from_nameD:
151 _, _, _, _, label = self.label_obj_from_nameD[ widget_name ]
152 label['font'] = ("Helvetica", 12, "bold italic underline")
153
154 def unhighlight_grid_widget(self, widget_name):
155 if widget_name in self.label_obj_from_nameD:
156 _, _, _, _, label = self.label_obj_from_nameD[ widget_name ]
157 label['font'] = self.default_label_font
158
159
160 def set_label_text_bg_from_widget_name(self, widget_name, placementWidgetType, Labelobj, row_target, col_target):
161 """Try to add some helpful info onto line3 of labels"""
162
163 Labelobj["background"] = CONTROL_COLOR_D[ placementWidgetType ]
164
165 if widget_name not in self.label_obj_from_nameD:
166
167 Labelobj["text" ] = "(%d,%d)\n%s\n" % (row_target, col_target, widget_name)
168 else:
169 def fitted_line3( s ):
170 if len(s)<15:
171 return s
172 return s[:12] + '...'
173
174 line3 = ''
175
176
177 if widget_name in self.grid_gui.target_app.compObjD:
178 c = self.grid_gui.target_app.compObjD[ widget_name ]
179 text = c.user_tkOptionD.get('text','')
180
181 if text and (text != widget_name):
182 line3 = fitted_line3( text )
183 elif c.user_tkOptionD.get('docstring',''):
184 line3 = fitted_line3( c.user_tkOptionD.get('docstring','') )
185
186 Labelobj["text" ] = "(%d,%d)\n%s\n%s" % (row_target, col_target, widget_name, line3)
187
188
189 def set_row_column_weights_from_target_app(self):
190 """Needs to set all weight Label widgets to show row/col weights"""
191
192
193
194 rowD, colD = self.grid_gui.target_app.get_a_full_desc_of_weights()
195
196 for (tab_label, col_interface), label in list(self.colWeightsWidgetD.items()):
197 col_target = col_interface - 1
198 if (tab_label, col_target) in colD:
199 wt = colD[ (tab_label, col_target) ]
200 else:
201 wt = 0
202
203 label["text" ] = "col:%i\nwt:%s"%(col_target, wt)
204 if wt > 0:
205 label["background"] = "#ff6060"
206 else:
207 label["background"] = "#daa520"
208
209 for (tab_label, row_interface), label in list(self.rowWeightsWidgetD.items()):
210 row_target = row_interface - 1
211 if (tab_label, row_target) in rowD:
212 wt = rowD[ (tab_label, row_target) ]
213 else:
214 wt = 0
215
216 label["text" ] = "row:%i\nwt:%s"%(row_target, wt)
217 if wt > 0:
218 label["background"] = "#ff6060"
219 else:
220 label["background"] = "#daa520"
221
222 def repaint_all_labels(self):
223
224
225 for tab_label in self.tabLabelL:
226 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
227
228 for row_target in range( num_rows ):
229 row_interface = row_target + 1
230 for col_target in range( num_cols ):
231 col_interface = col_target + 1
232 label = self.interface_gridBoxWidgetD[ (tab_label, row_interface, col_interface) ]
233 label["text" ] = "(%d,%d)\n\n" % (row_target, col_target)
234 label["background"] = "#FFFACD"
235
236
237
238
239 row_col_spanL = []
240
241 for widget_name, (tab_label, row_target, col_target, widget_type, label) in list(self.label_obj_from_nameD.items()):
242
243 row_interface = row_target + 1
244 col_interface = col_target + 1
245 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
246
247 label = self.interface_gridBoxWidgetD[(tab_label, row_interface, col_interface)]
248 self.set_label_text_bg_from_widget_name( widget_name, widget_type, label, row_target, col_target )
249
250
251
252
253
254 target_comp = self.grid_gui.target_app.compObjD[ widget_name ]
255 rowspan = max(1, intCast( target_comp.user_tkOptionD.get('rowspan',1) ))
256 columnspan = max(1, intCast( target_comp.user_tkOptionD.get('columnspan',1) ))
257 if rowspan>1 or columnspan>1:
258
259 for i in range( int(columnspan) ):
260 for j in range( int(rowspan) ):
261 if i!=0 or j!=0:
262 col_interface = col_target + 1 + i
263 row_interface = row_target + 1 + j
264
265 ctarg = col_target + i
266 rtarg = row_target + j
267
268
269
270 if (ctarg < num_cols) and (rtarg < num_rows):
271
272
273 label = self.interface_gridBoxWidgetD[(tab_label, row_interface, col_interface)]
274
275
276
277 if rowspan>1 and columnspan>1:
278 text = "(%d,%d)\n%s\n%s" % (row_target, col_target, widget_name, 'col+rowspan')
279 elif rowspan>1:
280 text = "(%d,%d)\n%s\n%s" % (row_target, col_target, widget_name, 'rowspan')
281 else:
282 text = "(%d,%d)\n%s\n%s" % (row_target, col_target, widget_name, 'columnspan')
283
284 bg = CONTROL_COLOR_D[widget_type]
285
286 row_col_spanL.append( (label, text, bg, tab_label, row_interface, col_interface) )
287
288 if row_col_spanL:
289 for (label, text, bg, tab_label, row_interface, col_interface) in row_col_spanL:
290 if self.widget_is_empty(label):
291 label["text" ] = text
292 label["background"] = bg
293 else:
294 label = self.interface_gridBoxWidgetD[(tab_label, row_interface, col_interface)]
295 sL = label["text"].split('\n')
296 sL[-1] = '???SPAN ERROR???'
297 label["text"] = '\n'.join(sL)
298 label["background"] = "#ff9797"
299
300
301 def set_complete_list_of_widgets(self, widgetL):
302 """
303 Start over with full list of tuples describing all the widgets.
304 Tuples = (widget_type, widget_name, tab_label, row_target, col_target)
305 """
306
307
308
309 ct = ComponentTree()
310 for (widget_type, widget_name, tab_label, row, col) in widgetL:
311 c = self.grid_gui.target_app.compObjD[ widget_name ]
312 ct.add_node( CNode(widget_name, tab_label, c) )
313
314 cnodeL = ct.get_ordered_components()
315 cL = [cnode.component for cnode in cnodeL]
316 widgetL = [(c.widget_type, c.widget_name, c.tab_label, c.row, c.col) for c in cL ]
317
318
319
320
321 self.initialize_NotebookGridDes()
322
323 for widget_type, color in CONTROLS:
324 CONTROL_NEXT_NUMBER_D[widget_type] = 1
325 CONTROL_NEXT_NUMBER_D['Tab'] = 1
326
327
328 for (widget_type, widget_name, tab_label, row_target, col_target) in widgetL:
329 try:
330 num = int( widget_name.split('_')[-1] )
331 CONTROL_NEXT_NUMBER_D[widget_type] = max(num+1, CONTROL_NEXT_NUMBER_D[widget_type])
332 except:
333 print("ERROR... Widget Number is SURELY Screwed Up.")
334 print( (widget_type, widget_name, tab_label, row_target, col_target) )
335
336
337 row_col_spanL = []
338 for (placementWidgetType, widget_name, tab_label, row_target, col_target) in widgetL:
339
340
341
342 if (placementWidgetType in ContainerControlsL) and (widget_name not in self.tabLabelL):
343 self.create_tab(tab_label=widget_name)
344 elif tab_label not in self.tabLabelL:
345 self.create_tab(tab_label=tab_label)
346
347
348 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
349 if col_target >= num_cols:
350 self.set_current_tab_by_label( tab_label )
351 for ic in range(num_cols, col_target+1):
352 self.insert_column( ic )
353 if row_target >= num_rows:
354 self.set_current_tab_by_label( tab_label )
355 for ir in range(num_rows, row_target+1):
356 self.insert_row( ir )
357
358
359 self.defined_target_widgetD[(tab_label, row_target, col_target)] = placementWidgetType
360 row_interface, col_interface = row_target+1, col_target+1
361
362 label = self.interface_gridBoxWidgetD[(tab_label, row_interface, col_interface)]
363 self.set_label_text_bg_from_widget_name( widget_name, placementWidgetType, label, row_target, col_target )
364
365
366
367 self.label_obj_from_nameD[ widget_name ] = (tab_label, row_target, col_target, placementWidgetType, label)
368
369
370
371 self.repaint_all_labels()
372
373
374 self.grid_gui.refresh_preview_win()
375
376
377 def make_complete_list_of_widgets(self):
378 """Return info about all of the placed widgets"""
379 widgetL = []
380
381 for widget_name, (tab_label, row_target, col_target, widget_type, label) in list(self.label_obj_from_nameD.items()):
382 widgetL.append( (widget_type, widget_name, tab_label, row_target, col_target) )
383
384 return widgetL
385
386 def current_tab_label(self):
387 """return the label of the current tab."""
388 return self.notebook.tab( self.notebook.select(), 'text' )
389
390 def current_tab_index(self):
391 """return the index of the current tab."""
392 return self.notebook.index('current')
393
394 def set_current_tab_by_label(self, tab_label):
395 """Switch to the tab with label "tab_label"."""
396 try:
397 i = self.tabLabelL.index( tab_label )
398 except:
399 i = 0
400 self.set_status_msg( "Error... could not find tab label " + tab_label, also_print=True)
401 self.notebook.select(i)
402
403 def get_tab_index_by_label(self, tab_label):
404 """return the tab index for label "tab_label"."""
405 try:
406 i = self.tabLabelL.index( tab_label )
407 except:
408 i = 0
409 self.set_status_msg( "Error... could not find tab label " + tab_label, also_print=True)
410 return i
411
412
413 def find_empty_space_on_tab(self, tab_label):
414 """return a (row_target, col_target) on "tab_label" notebook page."""
415 try:
416 i = self.tabLabelL.index( tab_label )
417 except:
418 self.set_status_msg( "Error... could not find tab label OR empty space " + tab_label, also_print=True)
419 return (None, None)
420
421 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
422
423
424 for col_target in range( num_cols ):
425 for row_target in range( num_rows ):
426
427 if self.defined_target_widgetD[(tab_label, row_target, col_target)] == '':
428 return (row_target, col_target)
429
430
431 self.set_status_msg( "Error... could not empty space on: " + tab_label, also_print=True)
432 return (None, None)
433
434
435
436 def set_status_msg(self, msg, also_print=False):
437 """Set the status message in the main window"""
438 if also_print:
439 print( msg )
440
441 self.MainWin.statusMessage.set( msg )
442
443 def make_col_control(self, tab_label, col_interface):
444 """Make a control Label on "tab_label" for column."""
445
446 i_tab = self.get_tab_index_by_label( tab_label )
447 nbFrame = self.nbFrameL[ i_tab ]
448
449 col_target = col_interface - 1
450
451 label = Label(nbFrame, width=16)
452 s = "col:%i"%col_target
453 label["text" ] = "+" + s.center(14," ") + "+"
454 label["font" ] = self.default_label_font
455 label["background"] = "#87CEFA"
456 label["relief"] = "raised"
457
458 self.colInsertWidgetD[tab_label, col_interface] = label
459
460 label.grid(row=0, column=col_interface)
461
462 label.bind("<Button-1>", self.onColInsertClicked)
463 label.bind("<Enter>", self.onColControlEnter)
464 label.bind("<Leave>", self.onControlLeave)
465 label.bind("<Motion>", self.onColControlMove)
466
467
468 row_weight_controls = 99
469
470 label = Label(nbFrame, width=8)
471 label["text" ] = "col:%i\nwt:0"%col_target
472 label["font" ] = ("Courier", 10, "normal")
473 label["background"] = "#daa520"
474 label["relief"] = "raised"
475
476 self.colWeightsWidgetD[tab_label, col_interface] = label
477
478 label.grid(row=row_weight_controls, column=col_interface)
479
480 label.bind("<Button-1>", self.onSetColumnWeightClicked)
481
482
483
484 def make_row_control(self, tab_label, row_interface):
485 """Make a control Label on "tab_label" for row."""
486
487 i_tab = self.get_tab_index_by_label( tab_label )
488 nbFrame = self.nbFrameL[ i_tab ]
489
490 row_target = row_interface - 1
491
492 label = Label(nbFrame, width=8)
493 label["text" ] = "+\nrow:%i\n+"%row_target
494 label["font" ] = self.default_label_font
495 label["background"] = "#87CEFA"
496 label["relief"] = "raised"
497
498 self.rowInsertWidgetD[tab_label, row_interface] = label
499
500 label.grid(row=row_interface, column=0)
501
502 label.bind("<Button-1>", self.onRowInsertClicked)
503 label.bind("<Enter>", self.onRowControlEnter)
504 label.bind("<Leave>", self.onControlLeave)
505 label.bind("<Motion>", self.onRowControlMove)
506
507
508 col_weight_controls = 99
509
510 label = Label(nbFrame, width=8)
511 label["text" ] = "row:%i\nwt:0"%row_target
512 label["font" ] = ("Courier", 10, "normal")
513 label["background"] = "#daa520"
514 label["relief"] = "raised"
515
516 self.rowWeightsWidgetD[tab_label, row_interface] = label
517
518 label.grid(row=row_interface, column=col_weight_controls)
519
520 label.bind("<Button-1>", self.onSetRowWeightClicked)
521
522
523 def target_grid_is_empty(self, tab_label, row_target, col_target):
524 """See if position on notebook tab_label is empty"""
525 if self.defined_target_widgetD[(tab_label, row_target, col_target)]:
526 return False
527 else:
528 return True
529
530 def current_grid_is_empty(self, row_target, col_target):
531 """See if position on CURRENT notebook tab_label is empty"""
532 tab_label = self.current_tab_label()
533 return self.target_grid_is_empty( tab_label, row_target, col_target )
534
535 def widget_is_empty(self, widget):
536 """Given a Label widget, see if it is available for widget placement"""
537 sL = widget["text"].split('\n')
538 if len(sL)==3:
539 if sL[1].strip() == '':
540 return True
541 return False
542
543 def widget_is_container(self, label_widget):
544 _, _, widget_name, _ = self.get_all_widget_info( label_widget )
545 _, _, _, widget_type, _ = self.label_obj_from_nameD.get( widget_name, '' )
546
547 if widget_type in ContainerControlsL:
548 return True
549 else:
550 return False
551
552 def get_widget_type(self, label_widget):
553 _, _, widget_name, _ = self.get_all_widget_info( label_widget )
554 _, _, _, widget_type, _ = self.label_obj_from_nameD.get( widget_name, '' )
555 return widget_type
556
557 def get_widget_rc_target(self, widget):
558 """Given a Label widget, get the row_target, col_target from the "text" string."""
559
560
561 sL = widget["text"].split('\n')
562 row, col = sL[0][1:-1].split(',')
563 row_target, col_target = int(row), int(col)
564 return row_target, col_target
565
566
567
568
569
570
571
572 def get_all_widget_info(self, label_widget):
573 """Given a Label widget, get the row_target, col_target, name and line3 from the "text" string."""
574
575
576 sL = label_widget["text"].split('\n')
577 row, col = sL[0][1:-1].split(',')
578 row_target, col_target = int(row), int(col)
579
580 widget_name = sL[1]
581 line3 = sL[2]
582
583 return row_target, col_target, widget_name, line3
584
585
586
587
588
589
590 def make_target_grid_label(self, tab_label, row_target, col_target):
591 """
592 Add a Label object to represent target GUI grid location.
593 These positions are all empty right now.
594 """
595
596 i_tab = self.get_tab_index_by_label( tab_label )
597 nbFrame = self.nbFrameL[ i_tab ]
598
599 row_interface = row_target + 1
600 col_interface = col_target + 1
601
602 label = Label(nbFrame, width=16)
603 label["text" ] = "(%d,%d)\n\n" % (row_target, col_target)
604 label["font" ] = self.default_label_font
605 label["background"] = "#FFFACD"
606 label["relief"] = "groove"
607
608 self.interface_gridBoxWidgetD[(tab_label, row_interface,col_interface)] = label
609 self.defined_target_widgetD[(tab_label, row_target, col_target)] = ''
610
611 label.grid(row=row_interface, column=col_interface)
612
613 label.bind("<Enter>", self.onGridBoxEnter)
614 label.bind("<Leave>", self.onGridBoxLeave)
615 label.bind("<Button-1>", self.onGridBoxClicked)
616
617 label.bind("<Button-3>", self.onGridBoxRightClicked)
618
619
620 label.bind('<B1-Motion>', self.onLeftDrag)
621 label.bind("<ButtonRelease-1>", self.onLeftDrop)
622
623
624 def onLeftDrag(self, event):
625
626
627
628 xroot = event.widget.winfo_rootx()
629 yroot = event.widget.winfo_rooty()
630
631 try:
632 w2 = self.winfo_containing(event.x+xroot, event.y+yroot)
633
634 except:
635 w2 = None
636
637
638 for w in self.drag_set:
639 if w != w2:
640 if self.widget_is_empty( w ):
641 w["background"] = "#FFFACD"
642
643 else:
644 widget_type = self.get_widget_type(w)
645 w["background"] = CONTROL_COLOR_D[ widget_type ]
646
647 self.drag_set.clear()
648
649
650 if w2 is not None and (w2 != event.widget):
651 self.drag_set.add( w2 )
652 if self.widget_is_empty( w2 ) or self.widget_is_container(w2):
653 w2["background"] = "#FF00FF"
654
655 def onLeftDrop(self, event):
656
657 xroot = event.widget.winfo_rootx()
658 yroot = event.widget.winfo_rooty()
659
660
661 w2 = self.winfo_containing(event.x+xroot, event.y+yroot)
662
663
664
665 if self.drag_set:
666
667 old_row_target, old_col_target, widget_name, line3 = self.get_all_widget_info( event.widget )
668 new_row_target, new_col_target = self.get_widget_rc_target( w2 )
669
670
671 if (old_row_target != new_row_target) or ( old_col_target != new_col_target):
672
673 if widget_name.startswith('Tab_'):
674 self.grid_gui.target_app.arrange_notebook_tabs( widget_name, new_row_target, new_col_target )
675
676 s = 'Dropped Widget=%s on %s'% (event.widget["text"].replace('\n',' '), w2["text"].replace('\n',' '))
677 self.set_status_msg(s)
678 self.move_widget_on_current_tab( event.widget, new_row_target, new_col_target, w2)
679
680 self.repaint_all_labels()
681
682 def move_widget_on_current_tab(self, widget, new_row_target, new_col_target, w2):
683 """Move widget from current location to new location. (might move to another tab)"""
684
685 tab_label = self.current_tab_label()
686
687
688 if self.target_grid_is_empty( tab_label, new_row_target, new_col_target):
689 w2_type = ''
690 else:
691 w2_row_target, w2_col_target, w2_name, w2_line3 = self.get_all_widget_info( w2 )
692 w2_type = self.defined_target_widgetD[(tab_label, w2_row_target, w2_col_target)]
693
694
695
696 if w2_type == '':
697
698 old_row_target, old_col_target, widget_name, line3 = self.get_all_widget_info( widget )
699 placementWidgetType = self.defined_target_widgetD[(tab_label, old_row_target, old_col_target)]
700
701
702 self.defined_target_widgetD[(tab_label, old_row_target, old_col_target)] = ''
703 widget["text" ] = "(%d,%d)\n\n" % (old_row_target, old_col_target)
704 widget["font" ] = self.default_label_font
705 widget["background"] = "#FFFACD"
706
707
708 self.defined_target_widgetD[(tab_label, new_row_target, new_col_target)] = placementWidgetType
709 new_row_interface, new_col_interface = new_row_target + 1, new_col_target + 1
710
711 self.label_obj_from_nameD[ widget_name ] = (tab_label, new_row_target, new_col_target, placementWidgetType, widget)
712
713 label = self.interface_gridBoxWidgetD[(tab_label, new_row_interface, new_col_interface)]
714
715 self.set_label_text_bg_from_widget_name( widget_name, placementWidgetType, label, new_row_target, new_col_target )
716
717
718
719 s = "Moved widget "+widget_name+" at (%s,%i,%i)"%(tab_label, old_row_target, old_col_target) +\
720 " to (%s,%i,%i)"%(tab_label, new_row_target, new_col_target)
721
722 self.set_status_msg(s)
723
724 self.grid_gui.refresh_preview_win()
725
726 elif self.widget_is_container( w2 ) and (w2 != widget) :
727
728 old_row_target, old_col_target, widget_name, line3 = self.get_all_widget_info( widget )
729
730 w2_type = self.get_widget_type( w2 )
731 w2["background"] = CONTROL_COLOR_D[ w2_type ]
732
733
734 if self.target_grid_is_empty( w2_name, old_row_target, old_col_target):
735 new_row_target, new_col_target = old_row_target, old_col_target
736 else:
737 new_row_target, new_col_target = self.find_empty_space_on_tab( w2_name )
738
739 if new_row_target is not None:
740
741 old_row_target, old_col_target, widget_name, line3 = self.get_all_widget_info( widget )
742 placementWidgetType = self.defined_target_widgetD[(tab_label, old_row_target, old_col_target)]
743
744
745 self.defined_target_widgetD[(tab_label, old_row_target, old_col_target)] = ''
746 widget["text" ] = "(%d,%d)\n\n" % (old_row_target, old_col_target)
747 widget["font" ] = self.default_label_font
748 widget["background"] = "#FFFACD"
749
750
751 self.defined_target_widgetD[(w2_name, new_row_target, new_col_target)] = placementWidgetType
752 new_row_interface, new_col_interface = new_row_target + 1, new_col_target + 1
753
754 self.label_obj_from_nameD[ widget_name ] = (w2_name, new_row_target, new_col_target, placementWidgetType, widget)
755
756 label = self.interface_gridBoxWidgetD[(w2_name, new_row_interface, new_col_interface)]
757 self.set_label_text_bg_from_widget_name( widget_name, placementWidgetType, label, row_target, col_target )
758
759
760
761
762 s = 'Moved widget "%s" to tab_label "%s" (%s,%s)'%(widget_name, w2_name, new_row_target, new_col_target)
763
764
765
766 self.set_status_msg( s )
767
768 self.grid_gui.refresh_preview_win()
769
770 else:
771 s = "Error... tried to move widget to Occupied Target Location (%i,%i)"%(new_row_target, new_col_target)
772
773 self.set_status_msg( s )
774
775
776 def create_tab(self, tab_label="New Tab"):
777 """Add new tab to grid notebook for Label objects."""
778
779 nbFrame = Frame(self.notebook, name='panel_%i'%len(self.tabLabelL) )
780 self.tabLabelL.append( tab_label )
781 self.nbFrameL.append( nbFrame )
782
783 nbFrame.pack(side=TOP, fill=BOTH, expand=Y)
784
785
786 for row_interface in range(1, self.num_rows_inp+1):
787 self.make_row_control( tab_label, row_interface)
788
789 for col_interface in range(1, self.num_cols_inp+1):
790 self.make_col_control( tab_label, col_interface )
791
792
793 """Show only num_row x num_col widgets... i.e. No scroll currently available"""
794 self.tab_num_rows_colsD[ tab_label ] = (self.num_rows_inp, self.num_cols_inp)
795 for row_target in range( self.num_rows_inp ):
796 for col_target in range( self.num_cols_inp ):
797 self.make_target_grid_label( tab_label, row_target, col_target)
798
799
800 self.notebook.add(nbFrame, text=tab_label, underline=0, padding=2)
801
802
803 def append_column(self):
804 """Append a column to the grid of the current notebook tab."""
805 tab_label = self.current_tab_label()
806
807
808 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
809 num_cols += 1
810 self.tab_num_rows_colsD[ tab_label ] = (num_rows, num_cols)
811
812 end_col_interface = num_cols
813 self.make_col_control( tab_label, end_col_interface )
814
815
816 end_col_target = end_col_interface - 1
817 for row_target in range( num_rows ):
818 self.make_target_grid_label( tab_label, row_target, end_col_target)
819
820 def insert_column(self, col_target):
821 """Insert a column into the grid of the current notebook tab."""
822 tab_label = self.current_tab_label()
823
824 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
825 if num_cols >= MAX_NUM_COLS:
826 tkinter.messagebox.showinfo("Insert Warning...",
827 "Can NOT have more than %i columns\n\n"%MAX_NUM_COLS\
828 +"For now, simply use Frame objects to expand the grid area.")
829 return
830
831 self.append_column()
832
833
834
835 copy_defined_target_widgetD = self.defined_target_widgetD.copy()
836 copy_label_obj_from_nameD = self.label_obj_from_nameD.copy()
837
838
839 self.defined_target_widgetD = {}
840 for key in list(copy_defined_target_widgetD.keys()):
841 self.defined_target_widgetD[key] = ''
842
843 self.label_obj_from_nameD = {}
844
845 for widget_name,(wtab_label, wrow_target, wcol_target, placementWidgetType, wLabelobj) in list(copy_label_obj_from_nameD.items()):
846
847 placementWidgetType = copy_defined_target_widgetD[ (wtab_label, wrow_target, wcol_target) ]
848
849 if (tab_label==wtab_label) and (wcol_target>=col_target):
850
851 self.label_obj_from_nameD[ widget_name ] = (wtab_label, wrow_target, wcol_target+1, placementWidgetType, wLabelobj)
852 target_comp = self.grid_gui.target_app.compObjD[ widget_name ]
853 target_comp.row = target_comp.col + 1
854
855 self.defined_target_widgetD[ (wtab_label, wrow_target, wcol_target+1) ] = placementWidgetType
856
857
858
859
860
861
862 else:
863 self.label_obj_from_nameD[ widget_name ] = (wtab_label, wrow_target, wcol_target, placementWidgetType, wLabelobj)
864
865 self.defined_target_widgetD[ (wtab_label, wrow_target, wcol_target) ] = placementWidgetType
866
867
868 self.repaint_all_labels()
869 self.grid_gui.refresh_preview_win()
870 self.set_status_msg('Inserted Column at col:%s'%col_target)
871
872 def append_row(self):
873 """Append a new row at the bottom of the current notebook tab."""
874 tab_label = self.current_tab_label()
875
876
877 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
878 num_rows += 1
879 self.tab_num_rows_colsD[ tab_label ] = (num_rows, num_cols)
880
881 end_row_interface = num_rows
882 self.make_row_control( tab_label, end_row_interface )
883
884
885 end_row_target = end_row_interface - 1
886 for col_target in range( num_cols ):
887 self.make_target_grid_label( tab_label, end_row_target, col_target)
888
889 def insert_row(self, row_target):
890 """Insert a row into the grid of the current notebook tab."""
891 tab_label = self.current_tab_label()
892
893
894 num_rows, num_cols = self.tab_num_rows_colsD[ tab_label ]
895 if num_rows >= MAX_NUM_ROWS:
896 tkinter.messagebox.showinfo("Insert Warning...",
897 "Can NOT have more than %i rows\n\n"%MAX_NUM_ROWS\
898 +"For now, simply use Frame objects to expand the grid area.")
899 return
900
901
902 self.append_row()
903
904
905
906
907 copy_defined_target_widgetD = self.defined_target_widgetD.copy()
908 copy_label_obj_from_nameD = self.label_obj_from_nameD.copy()
909
910
911 self.defined_target_widgetD = {}
912 for key in list(copy_defined_target_widgetD.keys()):
913 self.defined_target_widgetD[key] = ''
914
915 self.label_obj_from_nameD = {}
916
917 for widget_name,(wtab_label, wrow_target, wcol_target, placementWidgetType, wLabelobj) in list(copy_label_obj_from_nameD.items()):
918
919 placementWidgetType = copy_defined_target_widgetD[ (wtab_label, wrow_target, wcol_target) ]
920
921 if (tab_label==wtab_label) and (wrow_target>=row_target):
922
923 self.label_obj_from_nameD[ widget_name ] = (wtab_label, wrow_target+1, wcol_target, placementWidgetType, wLabelobj)
924 target_comp = self.grid_gui.target_app.compObjD[ widget_name ]
925 target_comp.row = target_comp.row + 1
926
927 self.defined_target_widgetD[ (wtab_label, wrow_target+1, wcol_target) ] = placementWidgetType
928
929 else:
930 self.label_obj_from_nameD[ widget_name ] = (wtab_label, wrow_target, wcol_target, placementWidgetType, wLabelobj)
931
932 self.defined_target_widgetD[ (wtab_label, wrow_target, wcol_target) ] = placementWidgetType
933
934
935 self.repaint_all_labels()
936 self.grid_gui.refresh_preview_win()
937 self.set_status_msg('Inserted Row at row:%s'%row_target)
938
939 def onSetColumnWeightClicked(self, event):
940 tab_label = self.current_tab_label()
941
942 sL = event.widget["text"].split('\n')
943 col = int( sL[0].split(':')[-1] )
944
945
946
947 dialog = Wt_Select_Dialog(self.master, "Column %i Weight"%col)
948
949 if dialog.result is not None:
950 wt = intCast( dialog.result['weight'] )
951
952 self.grid_gui.target_app.set_a_col_weight(tab_label, col, wt)
953
954 event.widget["text" ] = "col:%i\nwt:%s"%(col, wt)
955 if wt > 0:
956 event.widget["background"] = "#ff6060"
957 else:
958 event.widget["background"] = "#daa520"
959
960 self.grid_gui.refresh_preview_win()
961
962 self.set_status_msg('Set Column Weight=%s at col:%s'%(wt, col) )
963
964
965 def onSetRowWeightClicked(self, event):
966 tab_label = self.current_tab_label()
967
968 sL = event.widget["text"].split('\n')
969 row = int( sL[0].split(':')[-1] )
970
971
972
973 dialog = Wt_Select_Dialog(self.master, "Row %i Weight"%row)
974
975 if dialog.result is not None:
976 wt = intCast( dialog.result['weight'] )
977
978 self.grid_gui.target_app.set_a_row_weight(tab_label, row, wt)
979
980 event.widget["text" ] = "row:%i\nwt:%s"%(row, wt)
981 if wt > 0:
982 event.widget["background"] = "#ff6060"
983 else:
984 event.widget["background"] = "#daa520"
985
986 self.grid_gui.refresh_preview_win()
987
988 self.set_status_msg('Set Row Weight=%s at row:%s'%(wt, row) )
989
990
991 def onColInsertClicked(self, event):
992 """Col Control is Clicked. Will Insert or Delete a Col"""
993 tab_label = self.current_tab_label()
994
995
996
997
998
999 sL = event.widget["text"].split()
1000 col_target = int( sL[1].strip().split(':')[-1] )
1001
1002 x = int( event.x )
1003 if x < self.box_w3:
1004
1005 self.set_status_msg("Insert a new col at col_target #%i"%col_target)
1006
1007 self.insert_column( col_target )
1008 elif x > self.box_w23:
1009 self.set_status_msg("Insert a new col at col_target #%i"%(col_target+1) )
1010
1011 self.insert_column( col_target+1 )
1012 else:
1013 self.set_status_msg("")
1014
1015
1016 def onRowInsertClicked(self, event):
1017 """Row Control is Clicked. Will Insert or Delete a Row."""
1018 tab_label = self.current_tab_label()
1019
1020
1021
1022
1023
1024 sL = event.widget["text"].split('\n')
1025 row = int( sL[1].strip().split(':')[-1] )
1026
1027 y = int( event.y )
1028
1029 if y < self.box_h3:
1030
1031 self.set_status_msg("Insert a new row at row #%i"%row)
1032 self.insert_row( row )
1033 elif y > self.box_h23:
1034 self.set_status_msg("Insert a new row at row #%i"%(row+1))
1035 self.insert_row( row+1 )
1036 else:
1037 self.set_status_msg("")
1038
1039 def onRowControlMove(self, event):
1040 """Movement inside a Row Control. Changes cursor for Insert and Delete."""
1041 y = int( event.y )
1042
1043 if y < self.box_h3:
1044
1045 event.widget.config(cursor='plus')
1046 elif y > self.box_h23:
1047
1048 event.widget.config(cursor='plus')
1049 else:
1050
1051 event.widget.config(cursor='arrow')
1052
1053 def onColControlMove(self, event):
1054 """Movement inside a Col Control. Changes cursor for Insert and Delete."""
1055 x = int( event.x )
1056
1057 if x < self.box_w3:
1058
1059 event.widget.config(cursor='plus')
1060 elif x > self.box_w23:
1061
1062 event.widget.config(cursor='plus')
1063 else:
1064
1065 event.widget.config(cursor='arrow')
1066
1067
1068
1069 def onRowControlEnter(self, event):
1070 """When cursor moves inside a Row Control. Changes widget border relief."""
1071 event.widget["relief"] = "sunken"
1072
1073
1074 if self.must_confirm_box_h:
1075 self.must_confirm_box_h = False
1076 self.box_h = event.widget.winfo_height()
1077 self.box_h3 = self.box_h // 3
1078 self.box_h23 = (self.box_h * 2) // 3
1079
1080
1081 def onColControlEnter(self, event):
1082 """When cursor moves inside a Col Control. Changes widget border relief."""
1083 event.widget["relief"] = "sunken"
1084
1085
1086 if self.must_confirm_box_w:
1087 self.must_confirm_box_w = False
1088 self.box_w = event.widget.winfo_width()
1089 self.box_w3 = self.box_w // 3
1090 self.box_w23 = (self.box_w * 2) // 3
1091
1092
1093 def onControlLeave(self, event):
1094 """Restore widget border relief when cursor leaves Row or Col Control."""
1095 event.widget["relief"] = "raised"
1096
1097
1098 def onGridBoxEnter(self, event):
1099 """When cursor moves inside a Grid Box change widget border relief."""
1100 event.widget["relief"] = "ridge"
1101
1102
1103
1104
1105 background = event.widget.cget("background")
1106 if background == "#FFFACD":
1107 event.widget["background"] = "#FFFFEE"
1108
1109 if self.must_confirm_box_h:
1110 self.must_confirm_box_h = False
1111 self.box_h = event.widget.winfo_height()
1112 self.box_h3 = self.box_h // 3
1113 self.box_h23 = (self.box_h * 2) // 3
1114
1115 self.must_confirm_box_w = False
1116 self.box_w = event.widget.winfo_width()
1117 self.box_w3 = self.box_w // 3
1118 self.box_w23 = (self.box_w * 2) // 3
1119
1120
1121 if not self.widget_is_empty(event.widget):
1122 _, _, widget_name, _ = self.get_all_widget_info( event.widget )
1123 if widget_name in self.grid_gui.target_app.compObjD:
1124 target_comp = self.grid_gui.target_app.compObjD[ widget_name ]
1125
1126 target_comp.highlight_pw_widget()
1127
1128 def set_label_widget_background(self, label_widget):
1129
1130 tab_label = self.current_tab_label()
1131 row_target, col_target = self.get_widget_rc_target( label_widget )
1132 placementWidgetType = self.defined_target_widgetD[(tab_label, row_target, col_target)]
1133
1134 if placementWidgetType:
1135 label_widget["background"] = CONTROL_COLOR_D[placementWidgetType]
1136 else:
1137 label_widget["background"] = "#FFFACD"
1138
1139
1140
1141 def onGridBoxLeave(self, event):
1142 """Restore Grid Box border relief when cursor leaves."""
1143
1144 if event.widget == self.current_label_being_edited:
1145 return
1146
1147 event.widget["relief"] = "groove"
1148
1149
1150
1151
1152 self.set_label_widget_background( event.widget )
1153
1154
1155 if not self.widget_is_empty(event.widget):
1156 _, _, widget_name, _ = self.get_all_widget_info( event.widget )
1157 if widget_name in self.grid_gui.target_app.compObjD:
1158 target_comp = self.grid_gui.target_app.compObjD[ widget_name ]
1159
1160 target_comp.unhighlight_pw_widget()
1161
1162
1163 def onGridBoxClicked(self, event):
1164 """
1165 Detect a Click on Label widget in main grid.
1166 Each Label widget represents GUI widget that will be added to created GUI.
1167 """
1168
1169 tab_label = self.current_tab_label()
1170
1171 row_target, col_target = self.get_widget_rc_target( event.widget )
1172
1173 row_interface, col_interface = row_target+1, col_target+1
1174
1175
1176
1177
1178
1179
1180
1181 s_dup = self.grid_gui.dup_widget_label["text"].strip()
1182
1183 if tab_label.startswith('Notebook'):
1184 placementWidgetType = 'Tab'
1185 self.dup_source_widget_name = ''
1186 self.set_status_msg(" Only Tab Inserts Allowed on Notebook" , also_print=True)
1187
1188 elif s_dup and s_dup.startswith('('):
1189 sL = self.grid_gui.dup_widget_label["text"].split('\n')
1190
1191
1192 self.dup_source_widget_name = sL[1]
1193 placementWidgetType = self.dup_source_widget_name.split('_')[0]
1194
1195 else:
1196 placementWidgetType = self.MainWin.placementWidgetType_svar.get()
1197 self.dup_source_widget_name = ''
1198
1199
1200
1201 if ((tab_label, row_target, col_target) in self.defined_target_widgetD) and \
1202 self.defined_target_widgetD[(tab_label, row_target, col_target)]:
1203
1204
1205 ptype = self.defined_target_widgetD[ (tab_label, row_target, col_target) ]
1206 self.set_status_msg(ptype + " Widget is at (%i, %i) "%(row_target, col_target) )
1207
1208
1209
1210 if self.grid_gui.dup_widget_label["text" ] == event.widget["text"]:
1211
1212
1213
1214
1215 val = self.grid_gui.MainWin.placementWidgetType_svar.get()
1216 self.grid_gui.set_placement_widget_label( val )
1217
1218 else:
1219 self.grid_gui.set_duplication_widget_label( event.widget )
1220
1221
1222 else:
1223
1224
1225 if placementWidgetType in supportedTkWidgetSet:
1226
1227 num_widget = CONTROL_NEXT_NUMBER_D[placementWidgetType]
1228 CONTROL_NEXT_NUMBER_D[placementWidgetType] += 1
1229 widget_name = placementWidgetType + "_%i"%num_widget
1230
1231 if tab_label.startswith('Notebook'):
1232
1233 self.grid_gui.target_app.add_tab_to_notebook(row_target, col_target, widget_name, tab_label)
1234
1235 self.defined_target_widgetD[(tab_label, row_target, col_target)] = placementWidgetType
1236
1237 label = self.interface_gridBoxWidgetD[(tab_label, row_interface, col_interface)]
1238 self.set_label_text_bg_from_widget_name( widget_name, placementWidgetType, label, row_target, col_target )
1239
1240
1241
1242 self.label_obj_from_nameD[ widget_name ] = (tab_label, row_target, col_target, placementWidgetType, label)
1243
1244 self.set_status_msg("Placing widget "+placementWidgetType+" at (%s, %i,%i)"%(tab_label, row_target, col_target))
1245
1246
1247
1248
1249 if placementWidgetType in ContainerControlsL:
1250 self.create_tab(tab_label=widget_name)
1251
1252 self.grid_gui.refresh_preview_win()
1253 self.repaint_all_labels()
1254
1255 else:
1256 self.set_status_msg("Widget "+placementWidgetType+" NOT Recognized", also_print=True)
1257
1258
1259 def onGridBoxRightClicked(self, event):
1260 """
1261 Detect a RightClick on Label widget in current grid.
1262 If the Label widget is assigned, then it will be edited.
1263 """
1264
1265 tab_label = self.current_tab_label()
1266
1267 row_target, col_target = self.get_widget_rc_target( event.widget )
1268
1269 row_interface, col_interface = row_target+1, col_target+1
1270
1271
1272
1273
1274
1275
1276 placementWidgetType = self.MainWin.placementWidgetType_svar.get()
1277
1278
1279
1280 if ((tab_label, row_target, col_target) in self.defined_target_widgetD) and \
1281 self.defined_target_widgetD[(tab_label, row_target, col_target)]:
1282
1283
1284 ptype = self.defined_target_widgetD[ (tab_label, row_target, col_target) ]
1285 self.set_status_msg('Editing ' +ptype + " Widget at (%i, %i) "%(row_target, col_target) )
1286
1287
1288
1289 label = self.interface_gridBoxWidgetD[(tab_label, row_interface, col_interface)]
1290
1291
1292 _, _, widget_name, _ = self.get_all_widget_info( label )
1293
1294 self.highlight_grid_widget( widget_name )
1295
1296
1297
1298 if 1:
1299
1300 target_comp = self.grid_gui.target_app.compObjD[ widget_name ]
1301 dialogOptionsD = {}
1302 for key,val in list(target_comp.default_tkOptionD.items()):
1303 dialogOptionsD[key] = (val, "def.")
1304
1305 for key,val in list(target_comp.user_tkOptionD.items()):
1306 dialogOptionsD[key] = (val, "USER VALUE")
1307
1308 dialogOptionsD['child_widget_list'] = self.grid_gui.target_app.get_names_of_containers_widgets( widget_name )
1309
1310
1311 target_comp.highlight_pw_widget()
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321 self.current_label_being_edited = event.widget
1322
1323 dialog = Edit_Properties_Dialog(self.master, widget_name, dialogOptionsD=dialogOptionsD)
1324
1325 self.current_label_being_edited = None
1326
1327 def unhighlight_edited_widget():
1328
1329 self.unhighlight_grid_widget( widget_name )
1330 if target_comp is not None:
1331 target_comp.unhighlight_pw_widget()
1332
1333
1334 if dialog.result is None:
1335 self.master.after( 500, unhighlight_edited_widget )
1336 else:
1337
1338 if ("DeleteWidget" in dialog.result) and (dialog.result["DeleteWidget"]=="yes"):
1339
1340 unhighlight_edited_widget()
1341
1342 _, _, _, widget_type, _ = self.label_obj_from_nameD.get( widget_name, '' )
1343
1344 if widget_type in ContainerControlsL:
1345
1346 self.grid_gui.target_app.removeContainerByName( widget_name )
1347
1348 else:
1349
1350 self.delete_widget_by_name( widget_name )
1351 self.grid_gui.target_app.delComponentByName( widget_name )
1352
1353 else:
1354 self.master.after( 500, unhighlight_edited_widget )
1355
1356
1357 if target_comp is not None:
1358 target_comp.user_tkOptionD.update( dialog.result )
1359 if target_comp.widget_type != "Tab":
1360 target_comp.set_user_properties()
1361
1362
1363 if target_comp.widget_type == "Canvas":
1364 target_comp.pw_widget.native_widget.delete( 'all' )
1365 w = int(target_comp.user_tkOptionD['width'])
1366 h = int(target_comp.user_tkOptionD['height'])
1367 target_comp.pw_widget.native_widget.create_text(w//2,h//2, text=target_comp.widget_name,
1368 fill="black", width=w, anchor='center')
1369 elif target_comp.widget_type == "Tab":
1370 self.grid_gui.target_app.change_notebook_tab_label( target_comp.widget_name, target_comp.user_tkOptionD['text'] )
1371
1372 self.grid_gui.refresh_preview_win()
1373
1374
1375
1376
1377 self.repaint_all_labels( )
1378
1379 if self.grid_gui.PreviewWin is not None:
1380 self.grid_gui.PreviewWin.maybe_resize_preview_win()
1381
1382
1383
1384 def delete_widget_by_name(self, widget_name):
1385
1386 (tab_label, row_target, col_target, placementWidgetType, label) = self.label_obj_from_nameD[ widget_name ]
1387
1388 if placementWidgetType in ContainerControlsL:
1389 self.set_status_msg("Can NOT delete Containeer Widget "+placementWidgetType+\
1390 " at (%s,%i,%i)"%(tab_label, row_target, col_target), also_print=True)
1391
1392 tkinter.messagebox.showinfo("Delete Warning...",
1393 "Can NOT delete Containeer Widget "+placementWidgetType+'\n\n'+\
1394 " at (%s,%i,%i)"%(tab_label, row_target, col_target))
1395
1396 else:
1397
1398 num_widget = int( widget_name.split('_')[-1] )
1399 if CONTROL_NEXT_NUMBER_D[placementWidgetType] == num_widget + 1:
1400 CONTROL_NEXT_NUMBER_D[placementWidgetType] = num_widget
1401
1402 self.defined_target_widgetD[(tab_label, row_target, col_target)] = ''
1403
1404 label["text" ] = "(%d,%d)\n\n" % (row_target, col_target)
1405 label["background"] = "#FFFACD"
1406
1407 del self.label_obj_from_nameD[ widget_name ]
1408
1409 self.set_status_msg("Deleted widget "+placementWidgetType+\
1410 " at (%s,%i,%i)"%(tab_label, row_target, col_target), also_print=True)
1411
1412 self.grid_gui.refresh_preview_win()
1413
1414
1415
1416
1417 if __name__ == '__main__':
1418
1419 from tkgridgui.target_tk_app_def import TargetTkAppDef
1420 from tkgridgui.preview_win import PreviewWin
1421
1422 class MockGridGUI(object):
1423 def __init__(self, MainWin):
1424 self.MainWin = MainWin
1425 topFrame = Frame( MainWin )
1426
1427 self.grid_frame = Frame(topFrame)
1428 self.grid_notebook = NotebookGridDes( self, self.grid_frame, MainWin, num_cols=6, num_rows=10)
1429 self.grid_frame.pack(anchor=N, side=LEFT)
1430
1431 topFrame.pack(fill=BOTH, expand=Y)
1432
1433
1434 statframe = Frame(MainWin)
1435 MainWin.statusMessage = StringVar()
1436 MainWin.statusMessage.set('Welcome to TkGridGUI')
1437 self.statusbar = Label(statframe, textvariable=MainWin.statusMessage,
1438 relief=SUNKEN, anchor=W)
1439 self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM)
1440 statframe.pack(anchor=SW, fill=X, side=BOTTOM)
1441
1442
1443 MainWin.placementWidgetType_svar=StringVar()
1444 MainWin.placementWidgetType_svar.set('Button')
1445 MainWin.bind("<Key>", self.key_set_placement_widget)
1446
1447 self.target_app = TargetTkAppDef( name='myApp')
1448 self.PreviewWin = None
1449
1450 def key_set_placement_widget(self, event):
1451 """When the user hits a number key, set the placementWidgetType to that index of CONTROLS"""
1452 try:
1453 i = int( event.char )
1454 MainWin.placementWidgetType_svar.set( CONTROLS[i][0] )
1455 msg = 'placementWidgetType_svar set to:' + CONTROLS[i][0]
1456
1457 self.MainWin.statusMessage.set( msg )
1458 except:
1459 pass
1460
1461 def refresh_preview_win(self):
1462 """Get all widget info from grid_notebook and pass into to target_app."""
1463 if self.PreviewWin is None:
1464 self.PreviewWin = PreviewWin( self.MainWin )
1465 self.target_app.set_PreviewWin( self.PreviewWin )
1466
1467
1468 widgetL = self.grid_notebook.make_complete_list_of_widgets()
1469
1470 for w in widgetL:
1471
1472 (widget_type, widget_name, tab_label, row_target, col_target) = w
1473
1474 self.target_app.maybe_add_component( widget_type=widget_type,
1475 widget_name=widget_name,
1476 tab_label=tab_label,
1477 row=row_target, col=col_target)
1478 self.target_app.show_preview()
1479
1480
1481 root = Tk()
1482 MainWin = root
1483 MainWin.title('Main Window')
1484
1485 MainWin.config(background='#FFFACD')
1486
1487 grid_gui = MockGridGUI( MainWin )
1488
1489 MainWin.mainloop()
1490