def add_file_info_box(self, mainframe, name, labeldict, btncallback, fvar): """ Create and add a infobox containing the info about a loaded savegame. """ title = {'source':'Copy face from source file:', 'target':'To target file:'} frame = LabelFrame(mainframe, text=title[name]) frame.pack(anchor=N, fill=X, expand=1, side=TOP, padx=0, pady=0) frame.columnconfigure(1, weight=1) btn = Button(frame, text='Browse', command=btncallback) btn.grid(column=0, row=0, padx=2, pady=2) field = Entry(frame, width=50, textvariable=fvar) field.grid(column=1, row=0, columnspan=2, padx=2, pady=2, sticky=W+E) l = ('name','gender','level','race','location','save number','playing time') for n, (i, j) in enumerate([(x.capitalize()+':', x) for x in l]): Label(frame, text=i, state=DISABLED).grid(column=0, row=n+1, padx=4, pady=3, sticky=E) labeldict[j] = StringVar() Label(frame, textvariable=labeldict[j]).grid(column=1, row=n+1, padx=4, pady=3, sticky=W) self.screenshot[name] = Label(frame) self.screenshot[name].grid(column=2, row=1, rowspan=len(l), padx=4, pady=4)
def create_widgets(self): ''' Creates all widgets. ''' self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) validate_btn = Button(self, text='Validate weight restrictions', command=self.on_validate_weights) validate_btn.grid(row=0, column=0, padx=10, pady=5, sticky=N + W) panel = LabelFrame(self, text='Weight restrictions') panel.columnconfigure(0, weight=1) panel.rowconfigure(0, weight=1) panel.grid(row=1, column=0, padx=5, pady=5, sticky=E + W + S + N) weight_tab_main = VerticalScrolledFrame(panel) weight_tab_main.grid(row=0, column=0, sticky=E + W + S + N) weights_tab = weight_tab_main.interior self.abs_weights = TextForWeights(weights_tab, 'absolute', 'Input1 <= 0.02', self.current_categories, self.params, 'ABS_WEIGHT_RESTRICTIONS') self.abs_weights.grid(row=0, column=0, padx=10, pady=5, sticky=N + W) self.virtual_weights = TextForWeights(weights_tab, 'virtual', 'Input1 >= 0.34', self.current_categories, self.params, 'VIRTUAL_WEIGHT_RESTRICTIONS') self.virtual_weights.grid(row=1, column=0, padx=10, pady=5, sticky=N + W) self.price_ratio_weights = TextForWeights(weights_tab, 'price ratio', 'Input1/Input2 <= 5', self.current_categories, self.params, 'PRICE_RATIO_RESTRICTIONS', True) self.price_ratio_weights.grid(row=2, column=0, padx=10, pady=5, sticky=N + W)
def create_widgets(self): ''' Creates all widgets. ''' self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) validate_btn = Button(self, text='Validate weight restrictions', command=self.on_validate_weights) validate_btn.grid(row=0, column=0, padx=10, pady=5, sticky=N+W) panel = LabelFrame(self, text='Weight restrictions') panel.columnconfigure(0, weight=1) panel.rowconfigure(0, weight=1) panel.grid(row=1, column=0, padx=5, pady=5, sticky=E+W+S+N) weight_tab_main = VerticalScrolledFrame(panel) weight_tab_main.grid(row=0, column=0, sticky=E+W+S+N) weights_tab = weight_tab_main.interior self.abs_weights = TextForWeights(weights_tab, 'absolute', 'Input1 <= 0.02', self.current_categories, self.params, 'ABS_WEIGHT_RESTRICTIONS') self.abs_weights.grid(row=0, column=0, padx=10, pady=5, sticky=N+W) self.virtual_weights = TextForWeights(weights_tab, 'virtual', 'Input1 >= 0.34', self.current_categories, self.params, 'VIRTUAL_WEIGHT_RESTRICTIONS') self.virtual_weights.grid(row=1, column=0, padx=10, pady=5, sticky=N+W) self.price_ratio_weights = TextForWeights(weights_tab, 'price ratio', 'Input1/Input2 <= 5', self.current_categories, self.params, 'PRICE_RATIO_RESTRICTIONS', True) self.price_ratio_weights.grid(row=2, column=0, padx=10, pady=5, sticky=N+W)
def add_file_info_box(self, mainframe, name, labeldict, btncallback, fvar): """ Create and add a infobox containing the info about a loaded savegame. """ title = { 'source': 'Copy face from source file:', 'target': 'To target file:' } frame = LabelFrame(mainframe, text=title[name]) frame.pack(anchor=N, fill=X, expand=1, side=TOP, padx=0, pady=0) frame.columnconfigure(1, weight=1) btn = Button(frame, text='Browse', command=btncallback) btn.grid(column=0, row=0, padx=2, pady=2) field = Entry(frame, width=50, textvariable=fvar) field.grid(column=1, row=0, columnspan=2, padx=2, pady=2, sticky=W + E) l = ('name', 'gender', 'level', 'race', 'location', 'save number', 'playing time') for n, (i, j) in enumerate([(x.capitalize() + ':', x) for x in l]): Label(frame, text=i, state=DISABLED).grid(column=0, row=n + 1, padx=4, pady=3, sticky=E) labeldict[j] = StringVar() Label(frame, textvariable=labeldict[j]).grid(column=1, row=n + 1, padx=4, pady=3, sticky=W) self.screenshot[name] = Label(frame) self.screenshot[name].grid(column=2, row=1, rowspan=len(l), padx=4, pady=4)
def make_widgets(frame: ttk.LabelFrame, pane: SubPane) -> SelectorWin: """Generate the UI components, and return the base window.""" def for_channel(channel: MusicChannel) -> List[SelItem]: """Get the items needed for a specific channel.""" music_list = [] for music in Music.all(): if music.provides_channel(channel): selitem = SEL_ITEMS[music.id].copy() selitem.snd_sample = music.get_sample(channel) music_list.append(selitem) return music_list # This gets overwritten when making windows. last_selected = { channel: GEN_OPTS.get_val( 'Last_Selected', 'music_' + channel.name.casefold(), '<NONE>', ) for channel in MusicChannel } base_win = WINDOWS[MusicChannel.BASE] = SelectorWin( TK_ROOT, for_channel(MusicChannel.BASE), title=_('Select Background Music - Base'), desc=_('This controls the background music used for a map. Expand ' 'the dropdown to set tracks for specific test elements.'), has_none=True, sound_sys=filesystem, none_desc=_('Add no music to the map at all. Testing Element-specific ' 'music may still be added.'), callback=selwin_callback, callback_params=[MusicChannel.BASE], attributes=[ SelAttr.bool('SPEED', _('Propulsion Gel SFX')), SelAttr.bool('BOUNCE', _('Repulsion Gel SFX')), SelAttr.bool('TBEAM', _('Excursion Funnel Music')), SelAttr.bool('TBEAM_SYNC', _('Synced Funnel Music')), ], ) WINDOWS[MusicChannel.TBEAM] = SelectorWin( TK_ROOT, for_channel(MusicChannel.TBEAM), title=_('Select Excursion Funnel Music'), desc=_('Set the music used while inside Excursion Funnels.'), has_none=True, sound_sys=filesystem, none_desc=_('Have no music playing when inside funnels.'), callback=selwin_callback, callback_params=[MusicChannel.TBEAM], attributes=[ SelAttr.bool('TBEAM_SYNC', _('Synced Funnel Music')), ], ) WINDOWS[MusicChannel.BOUNCE] = SelectorWin( TK_ROOT, for_channel(MusicChannel.BOUNCE), title=_('Select Repulsion Gel Music'), desc=_('Select the music played when players jump on Repulsion Gel.'), has_none=True, sound_sys=filesystem, none_desc=_('Add no music when jumping on Repulsion Gel.'), callback=selwin_callback, callback_params=[MusicChannel.BOUNCE], ) WINDOWS[MusicChannel.SPEED] = SelectorWin( TK_ROOT, for_channel(MusicChannel.SPEED), title=_('Select Propulsion Gel Music'), desc=_('Select music played when players have large amounts of horizontal velocity.'), has_none=True, sound_sys=filesystem, none_desc=_('Add no music while running fast.'), callback=selwin_callback, callback_params=[MusicChannel.SPEED], ) assert set(WINDOWS.keys()) == set(MusicChannel), "Extra channels?" # Widgets we want to remove when collapsing. exp_widgets = [] # type: List[tkinter.Widget] def toggle_btn_enter(event=None): toggle_btn['text'] = BTN_EXPAND_HOVER if is_collapsed else BTN_CONTRACT_HOVER def toggle_btn_exit(event=None): toggle_btn['text'] = BTN_EXPAND if is_collapsed else BTN_CONTRACT def set_collapsed(): """Configure for the collapsed state.""" global is_collapsed is_collapsed = True GEN_OPTS['Last_Selected']['music_collapsed'] = '1' base_lbl['text'] = _('Music: ') toggle_btn_exit() # Set all music to the children - so those are used. set_suggested(WINDOWS[MusicChannel.BASE].chosen_id, sel_item=True) for wid in exp_widgets: wid.grid_remove() def set_expanded(): """Configure for the expanded state.""" global is_collapsed is_collapsed = False GEN_OPTS['Last_Selected']['music_collapsed'] = '0' base_lbl['text'] = _('Base: ') toggle_btn_exit() for wid in exp_widgets: wid.grid() pane.update_idletasks() pane.move() def toggle(event=None): if is_collapsed: set_expanded() else: set_collapsed() pane.update_idletasks() pane.move() frame.columnconfigure(2, weight=1) base_lbl = ttk.Label(frame) base_lbl.grid(row=0, column=1) toggle_btn = ttk.Label(frame, text=' ') toggle_btn.bind('<Enter>', toggle_btn_enter) toggle_btn.bind('<Leave>', toggle_btn_exit) toggle_btn.bind('<ButtonPress-1>', toggle) toggle_btn.grid(row=0, column=0) for row, channel in enumerate(MusicChannel): btn = WINDOWS[channel].widget(frame) if row: exp_widgets.append(btn) btn.grid(row=row, column=2, sticky='EW') for row, text in enumerate([ _('Funnel:'), _('Bounce:'), _('Speed:'), ], start=1): label = ttk.Label(frame, text=text) exp_widgets.append(label) label.grid(row=row, column=1, sticky='EW') if GEN_OPTS.get_bool('Last_Selected', 'music_collapsed', True): set_collapsed() else: set_expanded() for channel, win in WINDOWS.items(): win.sel_item_id(last_selected[channel]) return base_win
def build(self): """widget construction""" lf1 = LabelFrame(self.fr0, text='rgb') lf1.grid(column=0, row=0, sticky='new') lf1.columnconfigure(1, weight=1) vcmdsb = root.register(sb_okay) self.rgbcans = [] rgbsboxes = [] rgbcomps = ['r', 'g', 'b', 'a'] rgbnames = ['red ', 'green', 'blue ', 'alpha'] rgbvars = [self.rvar, self.gvar, self.bvar, self.avar] rgbhandles = [ self.rgbhandle, self.rgbhandle, self.rgbhandle, self.ahandle ] binds = [self.checksb, self.checksb, self.checksb, self.checksba] for ix, comp in enumerate(rgbcomps): Label(lf1, text=rgbnames[ix]).grid(row=3 * ix, column=0) Label(lf1).grid(row=2 + 3 * ix, column=2) self.rgbcans.append( Canvas(lf1, height=self.canvas_h, width=self.canvas_w, bd=0, highlightthickness=0)) self.rgbcans[ix].grid(row=3 * ix, column=1, sticky='ew', padx=self.sliderlength // 2) self.rgbcans[ix].bind("<Configure>", partial(self.resize, can=self.rgbcans[ix])) TtkScale(lf1, self.scale_l, from_=0, to=255, variable=rgbvars[ix], orient='horizontal', command=rgbhandles[ix], tickinterval=20).grid(row=1 + 3 * ix, column=1, sticky='new') rgbsboxes.append( Spinbox(lf1, from_=0, to=255, textvariable=rgbvars[ix], validate='key', validatecommand=(vcmdsb, '%d', '%P', '%S', 0, 255), command=rgbhandles[ix], width=5)) rgbsboxes[ix].grid(row=1 + 3 * ix, column=2, sticky='nw') rgbsboxes[ix].bind('<KeyRelease>', binds[ix]) lf3 = LabelFrame(self.fr0, text='colour mix') lf3.grid(column=1, row=0, sticky='nw') self.cmcan = cmcan = Canvas(lf3, width=30, height=30, bd=0, highlightthickness=0) cmcan.grid(column=0, row=0, sticky='n', columnspan=2) cmcan.grid_propagate(0) vdraw_gradient(self.cmcan, (255, 0, 0), alpha=255) cml = Label(lf3, text='hash\nvalue') cml.grid(column=0, row=1) vcmd = root.register(is_okay) self.en = en = Entry(lf3, width=8, validate='key', validatecommand=(vcmd, '%i', '%P', '%S'), textvariable=self.evar) en.grid(column=1, row=1) en.bind('<KeyRelease>', self.checkhash) lf5 = LabelFrame(lf3, text='related colours') # style='Width.Tlabelframe' lf5.grid(column=0, row=2, sticky='nw', columnspan=2) self.rcls = [] self.rccans = [] relateds = [0, 20, 40, 60, 80, 100] rtexts = ['0% Y', '20% Y', '40% Y', '60% Y', '80% Y', '100% Y'] for ix, rel in enumerate(relateds): Label(lf5, text=rtexts[ix]).grid(row=1 + 2 * ix, column=0, sticky='n') self.rcls.append(Label(lf5)) self.rcls[ix].grid(row=1 + 2 * ix, column=1, sticky='n') self.rccans.append( Canvas(lf5, width=30, height=30, bd=0, highlightthickness=0)) self.rccans[ix].grid(row=2 * ix, column=0, sticky='n', columnspan=2) self.cccan = Canvas(lf5, width=30, height=30, bd=0, highlightthickness=0) self.cccan.grid(column=0, row=12, sticky='n', columnspan=2) self.ccla = Label(lf5, text="comp'y") self.ccla.grid(column=0, row=13, sticky='n') self.ccl = Label(lf5, text="") self.ccl.grid(column=1, row=13, sticky='n') draw_gradient(self.rgbcans[0], (0, 0, 0), (255, 0, 0), width=self.canvas_w) draw_gradient(self.rgbcans[1], (255, 0, 0), (255, 255, 0), width=self.canvas_w) draw_gradient(self.rgbcans[2], (255, 0, 0), (255, 0, 255), width=self.canvas_w) draw_agradient(self.rgbcans[3], (127, 127, 127), (255, 0, 0), width=self.canvas_w) lf4 = LabelFrame(self.fr0, text='yiq') lf4.grid(column=2, row=0, sticky='ew') lf4.columnconfigure(1, weight=1) vcmdyiq = root.register(yiq_okay) self.cans = [] sboxes = [] comps = ['y', 'i', 'q'] names = ['luma', 'i hue', 'q hue'] tkvars = [self.yvar, self.ivar, self.qvar] handles = [self.yhandle, self.iqhandle, self.iqhandle] froms = [0, -100, -100] ticks = [10, 20, 20] for ix, comp in enumerate(comps): Label(lf4, text=names[ix]).grid(row=3 * ix, column=0) Label(lf4).grid(row=2 + 3 * ix, column=2) self.cans.append( Canvas(lf4, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0)) self.cans[ix].grid(row=3 * ix, column=1, sticky='ew', padx=self.sliderlength // 2) self.cans[ix].bind("<Configure>", partial(self.resize_yiq, can=self.cans[ix])) TtkScale(lf4, from_=froms[ix], to=100, variable=tkvars[ix], orient='horizontal', length=self.scale_l, command=handles[ix], tickinterval=ticks[ix]).grid(row=1 + 3 * ix, column=1, sticky='new') sboxes.append( Spinbox(lf4, from_=froms[ix], to=100, textvariable=tkvars[ix], validatecommand=(vcmdyiq, '%d', '%P', '%S', froms[ix], 100), validate='key', command=handles[ix], width=5, increment=1)) sboxes[ix].grid(row=1 + 3 * ix, column=2, sticky='nw') sboxes[ix].bind('<KeyRelease>', self.checksyiq) # assume initial setting 30,100.0,40.56 yiq to_colour = yiq_to_rgb(*(30, 100.0, 40.56)) # print(self.canvas_w) draw_gradient(self.cans[0], yiq_to_rgb(0.0, 100.0, 40.56), yiq_to_rgb(100, 100, 40.56), width=self.canvas_w) draw_gradient(self.cans[1], yiq_to_rgb(30, -100.0, 40.56), to_colour, width=self.canvas_w) draw_gradient(self.cans[2], yiq_to_rgb(30, 100, -100), yiq_to_rgb(30, 100, 100), width=self.canvas_w) self.related(30, 100.0, 40.56) self.canYiq = canYiq = Canvas(lf4, width=self.space, height=self.space) canYiq.grid(column=0, row=9, columnspan=3, pady=25, sticky='n') self.yiqGamut = PhotoImage(file='../../figures/colour_space.png') canYiq.create_image(0, 0, anchor='nw', image=self.yiqGamut) self.ring = circle(canYiq, 300.0, 210.84, self.ring_radius, width=self.ring_width, activeoutline='#555555', tags='ring') canYiq.bind('<Button-1>', self.move_ring) canYiq.tag_bind('ring', '<B1-Motion>', self.move_ring)
def build(self): """Widget construction.""" lf1 = LabelFrame(self.fr0, text='rgb') lf1.grid(column=0, row=0, sticky='new') lf1.columnconfigure(1, weight=1) rl0 = Label(lf1, text='red ') rl0.grid(column=0, row=0, sticky='s') self.rcan = Canvas(lf1, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.rcan.grid(column=1, row=0, sticky='sew', padx=self.sliderlength // 2) self.rcan.bind("<Configure>", self.resize_rcan) rsc = TtkScale(lf1, self.scale_l, from_=0, to=255, variable=self.rvar, orient='horizontal', command=self.rhandle, tickinterval=20) rsc.grid(column=1, row=1, sticky='new') vcmdsb = root.register(sb_okay) rsb = Spinbox(lf1, from_=0, to=255, textvariable=self.rvar, validate='key', validatecommand=(vcmdsb, '%d', '%P', '%S', 255), command=self.rhandle, width=5) rsb.grid(column=2, row=1, sticky='nw') rsb.bind('<KeyRelease>', self.checksb) rel = Label(lf1) rel.grid(column=2, row=2) gl0 = Label(lf1, text='green') gl0.grid(column=0, row=3) self.gcan = Canvas(lf1, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.gcan.grid(column=1, row=3, sticky='sew', padx=self.sliderlength // 2) self.gcan.bind("<Configure>", self.resize_gcan) gsc = TtkScale(lf1, self.scale_l, from_=0, to=255, variable=self.gvar, orient='horizontal', command=self.ghandle, tickinterval=20) gsc.grid(column=1, row=4, sticky='new') gsb = Spinbox(lf1, from_=0, to=255, textvariable=self.gvar, validate='key', validatecommand=(vcmdsb, '%d', '%P', '%S', 255), command=self.ghandle, width=5) gsb.grid(column=2, row=4, sticky='nw') gsb.bind('<KeyRelease>', self.checksb) gel = Label(lf1) gel.grid(column=2, row=5) bl0 = Label(lf1, text='blue ') bl0.grid(column=0, row=6, sticky='s') self.bcan = Canvas(lf1, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.bcan.grid(column=1, row=6, sticky='new', padx=self.sliderlength // 2) self.bcan.bind("<Configure>", self.resize_bcan) bsc = TtkScale(lf1, self.scale_l, from_=0, to=255, variable=self.bvar, orient='horizontal', command=self.bhandle, tickinterval=20) bsc.grid(column=1, row=7, sticky='new') bsb = Spinbox(lf1, from_=0, to=255, textvariable=self.bvar, validate='key', validatecommand=(vcmdsb, '%d', '%P', '%S', 255), command=self.bhandle, width=5) bsb.grid(column=2, row=7, sticky='nw') bsb.bind('<KeyRelease>', self.checksb) bel = Label(lf1) bel.grid(column=2, row=8) lf3 = LabelFrame(self.fr0, text='colour mix') lf3.grid(column=1, row=0, sticky='nw') self.cmcan = cmcan = Canvas(lf3, width=30, height=30, bd=0, highlightthickness=0) cmcan.grid(column=0, row=0, sticky='n', columnspan=2) cmcan.grid_propagate(0) vdraw_gradient(self.cmcan, (255, 0, 0), alpha=255) cml = Label(lf3, text='hash\nvalue') cml.grid(column=0, row=1) vcmd = root.register(is_okay) self.ent0 = ent0 = Entry(lf3, width=8, validate='key', validatecommand=(vcmd, '%i', '%P', '%S'), textvariable=self.evar) ent0.grid(column=1, row=1) ent0.bind('<KeyRelease>', self.checkhash) lf5 = LabelFrame(lf3, text='related colours', style='Wide.TLabelframe') lf5.grid(column=0, row=2, sticky='nw', columnspan=2) self.srcls = [] self.vrcls = [] self.srccans = [] self.vrccans = [] relateds = [25, 50, 75, 100] stexts = ['25% sat', '50% sat', '75% sat', '100% sat'] vtexts = ['25% val', '50% val', '75% val', '100% val'] for ix, rel in enumerate(relateds): Label(lf5, text=stexts[ix]).grid(row=1 + 2 * ix, column=0, sticky='n') self.srcls.append(Label(lf5)) self.srcls[ix].grid(row=1 + 2 * ix, column=1, sticky='n') self.srccans.append( Canvas(lf5, width=30, height=30, bd=0, highlightthickness=0)) self.srccans[ix].grid(row=2 * ix, column=0, sticky='n', columnspan=2) Label(lf5, text=vtexts[ix]).grid(row=9 + 2 * ix, column=0, sticky='n') self.vrcls.append(Label(lf5)) self.vrcls[ix].grid(row=9 + 2 * ix, column=1, sticky='n') self.vrccans.append( Canvas(lf5, width=30, height=30, bd=0, highlightthickness=0)) self.vrccans[ix].grid(row=8 + 2 * ix, column=0, sticky='n', columnspan=2) self.cccan = Canvas(lf5, width=30, height=30, bd=0, highlightthickness=0) self.cccan.grid(column=0, row=17, sticky='n', columnspan=2) self.ccla = Label(lf5, text="comp'y") self.ccla.grid(column=0, row=18, sticky='n') self.ccl = Label(lf5, text="") self.ccl.grid(column=1, row=18, sticky='n') al0 = Label(lf1, text='alpha') al0.grid(column=0, row=10, sticky='s') self.acan = Canvas(lf1, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.acan.grid(column=1, row=10, sticky='new', padx=self.sliderlength // 2) self.acan.bind("<Configure>", self.resize_acan) asc = TtkScale(lf1, self.scale_l, from_=0, to=255, variable=self.avar, orient='horizontal', command=self.ahandle, tickinterval=20) asc.grid(column=1, row=11, sticky='new') asb = Spinbox(lf1, from_=0, to=255, textvariable=self.avar, validate='key', validatecommand=(vcmdsb, '%d', '%P', '%S', 255), command=self.ahandle, width=5) asb.grid(column=2, row=11, sticky='nw') asb.bind('<KeyRelease>', self.checksba) ael = Label(lf1, text=' ') ael.grid(column=2, row=12, sticky='s') draw_gradient(self.rcan, (0, 0, 0), (255, 0, 0), width=self.canvas_w) draw_gradient(self.gcan, (255, 0, 0), (255, 0, 255), width=self.canvas_w) draw_gradient(self.bcan, (255, 0, 0), (255, 255, 0), width=self.canvas_w) draw_agradient(self.acan, (127, 127, 127), (255, 0, 0), width=self.canvas_w) lf4 = LabelFrame(self.fr0, text='hsv') lf4.grid(column=2, row=0, sticky='news') lf4.columnconfigure(1, weight=1) hl0 = Label(lf4, text='hue ') hl0.grid(column=0, row=0, sticky='s') self.hcan = Canvas(lf4, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.hcan.grid(column=1, row=0, sticky='sew', padx=self.sliderlength // 2) self.hcan.bind("<Configure>", self.resize_hcan) hsc = TtkScale(lf4, self.scale_l, from_=0, to=360, variable=self.hvar, orient='horizontal', command=self.hhandle, tickinterval=30) hsc.grid(column=1, row=1, sticky='new') vcmdsb = root.register(sb_okay) hsb = Spinbox(lf4, from_=0, to=360, textvariable=self.hvar, validate='key', validatecommand=(vcmdsb, '%P', '%S', 360), command=self.hhandle, width=5) hsb.grid(column=2, row=1, sticky='nw') hsb.bind('<KeyRelease>', self.checksbh) hel = Label(lf4) hel.grid(column=2, row=2) sl0 = Label(lf4, text='sat ') sl0.grid(column=0, row=3) self.scan = Canvas(lf4, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.scan.grid(column=1, row=3, sticky='sew', padx=self.sliderlength // 2) self.scan.bind("<Configure>", self.resize_scan) ssc = TtkScale(lf4, self.scale_l, from_=0, to=100, variable=self.svar, orient='horizontal', command=self.shandle, tickinterval=10) ssc.grid(column=1, row=4, sticky='new') ssb = Spinbox(lf4, from_=0, to=100, textvariable=self.svar, validate='key', validatecommand=(vcmdsb, '%P', '%S', 100), command=self.shandle, width=5) ssb.grid(column=2, row=4, sticky='nw') ssb.bind('<KeyRelease>', self.checksb100) sel = Label(lf4) sel.grid(column=2, row=5) vl0 = Label(lf4, text='value') vl0.grid(column=0, row=6, sticky='s') self.vcan = Canvas(lf4, width=self.canvas_w, height=self.canvas_h, bd=0, highlightthickness=0) self.vcan.grid(column=1, row=6, sticky='new', padx=self.sliderlength // 2) self.vcan.bind("<Configure>", self.resize_vcan) vsc = TtkScale(lf4, self.scale_l, from_=0, to=100, variable=self.vvar, orient='horizontal', command=self.vhandle, tickinterval=10) vsc.grid(column=1, row=7, sticky='new') vsb = Spinbox(lf4, from_=0, to=100, textvariable=self.vvar, validate='key', validatecommand=(vcmdsb, '%P', '%S', 100), command=self.vhandle, width=5) vsb.grid(column=2, row=7, sticky='nw') vsb.bind('<KeyRelease>', self.checksb100) vel = Label(lf4) vel.grid(column=2, row=8) # assume initial setting 0,100,100 hsv to_colour = hsv_to_rgb(*(0, 100, 100)) hue_gradient(self.hcan, width=self.canvas_w) draw_gradient(self.scan, (255, 255, 255), to_colour, width=self.canvas_w) draw_gradient(self.vcan, (0, 0, 0), to_colour, width=self.canvas_w) self.can_hsv = can_hsv = Canvas(lf4, width=self.wheel_w, height=self.wheel_w, bg='#d9d9d9') can_hsv.grid(column=0, row=9, columnspan=3, pady=25, sticky='n') self.hsv_gamut = PhotoImage(file='../figures/colour_wheel.png') can_hsv.create_image(0, 0, anchor='nw', image=self.hsv_gamut) self.ring = circle(can_hsv, 307, 158, self.ring_radius, width=self.ring_width, outline='#555555', activeoutline='black', tags='ring') can_hsv.bind('<Button-1>', self.click_ring) can_hsv.tag_bind('ring', '<B1-Motion>', self.drag_ring) self.related(0, 100, 100, 255, 0, 0)
class Histogram(Frame): def __init__(self, parent, master): super(Histogram, self).__init__(parent) self.window = master #type:VisAnaWindow self.parent = parent self.param_y = None self.param_x = None self.ds = self.window.ds #type:DataSource self.columnconfigure(1, weight=1) self.rowconfigure(1, weight=1) self.tframe = LabelFrame(self, text="Tooltip") #self.tframe.grid(column=0, row=1, sticky=(S,W,N,E)) self.tframe.rowconfigure(0, weight=1) self.tframe.columnconfigure(0, weight=1) self.tooltip = StringVar(self.tframe) self.tlabel = Label(self.tframe, textvariable=self.tooltip, justify="left", anchor="nw", wraplength=200) self.tlabel.grid(column=0, row=0, sticky=(W, N)) self.select_rect = None if self.ds is None: self.settings = Label( self, text="No data, please open a file via File -> Open") self.settings.grid(column=1, row=1, sticky=(S, W, N, E)) return self.settings = HControls(self, self.ds.base().get_attr_names()) self.settings.grid(column=0, row=0, sticky=(S, W, N, E)) self.apply_settings() ################### # PLOT-EVENT HANDLER ## is called by the plot to confirm if the mouseevent was inside/on a plotted line or a marker def handle_pick(self, line, mouseevent): if mouseevent.button == 1: return self.handle_mouse_event(mouseevent) else: return False, dict() ## is called to to do something when the mouse hovers over the plot and has changed its position. ## if no mousebutton is pressed and no points were selected, a hover-tooltip is shown. ## if the left button is pressed, (re-)draw the selection indicator def handle_hover(self, mouseevent): if not mouseevent.button in [1, 3] and self.select_rect is None: isover, props = self.handle_mouse_event(mouseevent) if isover: self.draw_tooltip(mouseevent, props["ind"]) elif mouseevent.button in [1, 3]: ## handle case if mouse is outside the canvas if mouseevent.xdata == None: xmin = self.mouse_pressed[0] xmax = self.mouse_pressed[0] ymin = self.mouse_pressed[1] ymax = self.mouse_pressed[1] else: xmin = min(mouseevent.xdata, self.mouse_pressed[0]) xmax = max(mouseevent.xdata, self.mouse_pressed[0]) ymin = min(mouseevent.ydata, self.mouse_pressed[1]) ymax = max(mouseevent.ydata, self.mouse_pressed[1]) bbox = (xmin, ymin, xmax, ymax) self.clean_tooltip(True, emit=False) bbox2 = self.ax.transData.transform(bbox) c_height = self.canvas.figure.bbox.height bbox3 = (bbox2[0], c_height - bbox2[1], bbox2[2], c_height - bbox2[3]) self.select_rect = self.canvas.get_tk_widget().create_rectangle( bbox3, dash=".", outline=self.fgcol) ## is called whenever a mousebutton is clicked while the mouse is over the plot. ## if the left button is pushed, we begin to draw a selection area def handle_mouse_down(self, mouseevent): if mouseevent.button in [1, 3]: self.clean_tooltip(True) self.mouse_pressed = (mouseevent.xdata, mouseevent.ydata) ## is called whenever a mouse button is released while hovering over the plot ## if the left button was pressed and there are points within the selection area, select those points and show a ## tooltip containing information about those selected points. If not, clean up. def handle_mouse_up(self, mouseevent): if mouseevent.button in [1, 3]: ## handle case if mouse is outside the canvas if mouseevent.xdata == None: xmin = self.mouse_pressed[0] xmax = self.mouse_pressed[0] ymin = self.mouse_pressed[1] ymax = self.mouse_pressed[1] else: xmin = min(mouseevent.xdata, self.mouse_pressed[0]) xmax = max(mouseevent.xdata, self.mouse_pressed[0]) ymin = min(mouseevent.ydata, self.mouse_pressed[1]) ymax = max(mouseevent.ydata, self.mouse_pressed[1]) if xmin == xmax and ymin == ymax: self.clean_tooltip(True) else: if mouseevent.button == 1: if self.param_x == self.ds.get_time_colname(): xmin = mdates.num2date(xmin) xmax = mdates.num2date(xmax) if self.param_y == self.ds.get_time_colname(): ymin = mdates.num2date(ymin) ymax = mdates.num2date(ymax) self.ds.select("ss_selected", self.param_x, xmin, xmax, "ss_show") self.ds.select("ss_selected", self.param_y, ymin, ymax, "ss_selected") ind = self.ds.df("ss_selected").index.values if len(ind) > 0: text = "Selected area from ({:.1f}; {:.1f})\n\t to ({:.1f}; {:.1f})"\ .format(xmin,ymin,xmax,ymax) self.draw_tooltip(mouseevent, ind, True) self.window.history.add(text) else: self.clean_tooltip(True) else: self.clean_tooltip(True, emit=False) self.ax.set_xlim((xmin, xmax), emit=False) self.ax.set_ylim((ymin, ymax)) self.canvas.draw() ## handle any mouse event where it has to be clarified whether there's a marker under the mouse or not. If so, ## return all index values of the concerning markers. def handle_mouse_event(self, mouseevent, radius=5): """ find the points within a certain radius from the mouse in data coords and attach the index numbers of the found elements which are the data points that were picked """ self.clean_tooltip() # print("PICKER") # print(mouseevent, vars(mouseevent)) if self.param_x == self.ds.get_time_colname( ) or self.param_y == self.ds.get_time_colname(): return False, dict() xydata = self.ax.transData.transform( self.ds.df("ss_show")[[self.param_x, self.param_y]]).transpose() try: mxy = self.ax.transData.transform( [mouseevent.xdata, mouseevent.ydata]) except ValueError: return False, dict() xdata = xydata[0] ydata = xydata[1] mousex = mxy[0] mousey = mxy[1] if mouseevent.xdata is None: return False, dict() d = pd.np.sqrt((xdata - mousex)**2. + (ydata - mousey)**2.) ind = self.ds.df("ss_show").index.values[pd.np.nonzero( pd.np.less_equal(d, radius))[0]] if len(ind) > 0: props = dict(ind=ind) return True, props else: return False, dict() ## draws a tooltip and generates the information it contains from an event with/and a list of index values def draw_tooltip(self, event, ind=None, selected=False): if ind is None: ind = event.ind #event = event.mouseevent # Generate the Tooltip-String selstr = "" if selected: selstr = "selected " if len(ind) is 1: text = selstr + "value:" self.ds.select_ids("ss_selected", ind, "ss_show") for col, cdata in self.ds.df("ss_selected").iteritems(): text += '\n{}: {}'.format(col, cdata[ind[0]]) else: text = selstr + "%s values:" % len(ind) if not selected: self.ds.select_ids("ss_selected", ind, "ss_show") self.ds.aggregate("ss_sel_aggremin", "MIN", in_table="ss_selected") self.ds.aggregate("ss_sel_aggremax", "MAX", in_table="ss_selected") for col, cdata in self.ds.df("ss_sel_aggremin").iteritems(): #text += '\n{}:\n min:\t{}\n max:\t{}'.format(col, cdata[0], self.ds.df("ss_sel_aggremax")[col][0]) text += '\n{}: {} to {}'.format( col, cdata[0], self.ds.df("ss_sel_aggremax")[col][0]) # write the tooltip self.tooltip.set(text) # # Draw the box and write the string on it # # c_height = self.canvas.figure.bbox.height # c_width = self.canvas.figure.bbox.width # y = c_height - event.y # x = event.x # # # get bounding box of a possible tooltip # self.plot_tooltip = self.canvas.get_tk_widget().create_text(x + 2, y, anchor=tk.NW, text=text) # bbox = self.canvas.get_tk_widget().bbox(self.plot_tooltip) # self.canvas.get_tk_widget().delete(self.plot_tooltip) # # # print("bbox:", bbox) # # # make sure the tooltip is within bounds # if bbox[2] > c_width: # adj = -2 # if bbox[3] > c_height: # anchor = tk.SE # else: # anchor = tk.NE # else: # adj = 2 # if bbox[3] > c_height: # anchor = tk.SW # else: # anchor = tk.NW # # get the new bounding box # if anchor is not tk.NW: # =^= the anchor had to be modified # self.plot_tooltip = self.canvas.get_tk_widget().create_text(x + adj, y, anchor=anchor, text=text) # bbox = self.canvas.get_tk_widget().bbox(self.plot_tooltip) # self.canvas.get_tk_widget().delete(self.plot_tooltip) # # self.plot_tooltip_rect = self.canvas.get_tk_widget().create_rectangle(bbox, fill="yellow") # self.plot_tooltip = self.canvas.get_tk_widget().create_text(x + adj, y, anchor=anchor, text=text) ## remove the tooltip if shown def clean_tooltip(self, with_select_rect=False, emit=True): self.tooltip.set("") if with_select_rect and self.select_rect is not None: self.canvas.get_tk_widget().delete(self.select_rect) self.select_rect = None #if emit: #self.action_str = None #TO-DO #self.trigger_update(self.TIMELINE_SELECTION) #### Handle Signals from Outside def apply_settings(self, ev=None): self.lgvar = self.settings.doLog() self.redraw_plot() def redraw_plot(self): self.window.status.set("Redraw Histogram...") self.draw_plot() self.window.status.set("") # the underlying data changed, called by VisAnaWindow.openFile def ds_changed(self): olds = self.ds self.ds = self.window.ds if olds is None: self.settings.destroy() newcols = self.window.calc.get_all_columns(with_time=True, with_custom=False) self.settings = HControls(self, newcols) self.settings.grid(column=0, row=0, sticky=(S, W, N, E)) # a cluster recalculation was processed, called by VisAnaWindow.redo_plots def cluster_changed(self, in_table): self.ds.link("h_show", in_table) self.apply_settings() def draw_plot(self): self.clean_tooltip(True) self.fig = Figure(figsize=(5, 5), dpi=100) #type:Figure self.ax = self.fig.add_subplot(111) #type:Axes self.ax.clear() self.ax.grid(True) tabl = self.ds.get_data("h_show") d = tabl.df() if tabl.centroids is not None: k = len(tabl.centroids) cluster_params = self.window.calc.cluster_params print("hist ", cluster_params) # subplot_num = 0 # print(self.centroids) y_pos = pd.np.arange(len(cluster_params)) # print(y_pos) width = 0.95 / k # colors = ["#d62728", "blue", "green", "brown"] max_y_val = 0 for c in range(0, k): # subplot_num += 1 ystdev = [] one_value_cluster = d.loc[d['_cluster'] == c] # for i in range(0, len(datasource.GRAIN_COLS)): for i in range(0, len(cluster_params)): col = one_value_cluster[cluster_params[i]] stdev = pd.np.std(col) ystdev.append(stdev) cen = [ tabl.centroids[c][i] for i in range(0, len(cluster_params)) ] ## cluster label for legend c_label = "Cluster " + str(c) self.ax.bar( y_pos + width * (c - (k / 2.3)), cen, width, align="center", log=self.lgvar, #alpha=0.75, color=COLORS[c], ecolor="black", yerr=ystdev, label=c_label) for i in range(0, len(cen)): y_val = cen[i] + ystdev[i] #print("y_val:",str(y_val)) if y_val > max_y_val: max_y_val = y_val #print("new max_y_val:",str(max_y_val)) #print("cen:",str(cen)) #print("ysdtev:",str(ystdev)) #print("ypos:",str(y_pos)) self.ax.grid(True) # self.ax.set_xticklabels # self.ax.set_ylim(0, 1, emit=False) #max_y_val = max(map(max, tabl.centroids)) self.ax.set_ylim(0, max_y_val * 1.05, emit=False) self.ax.set_xticks(y_pos + width / 4) self.ax.set_xticklabels(cluster_params) # self.ax.callbacks.connect('xlim_changed', self.handle_view_change) # self.ax.callbacks.connect('ylim_changed', self.handle_view_change) ## add legend self.ax.legend(loc="upper right", shadow=True) else: cluster_params = [ col for col in self.window.calc.get_all_columns(after_calc=True) if col not in ["OutdoorTemp", "RelHumidity", "Daytime"] ] print("hist ", cluster_params) # subplot_num = 0 # print(self.centroids) y_pos = pd.np.arange(len(cluster_params)) # print(y_pos) width = 0.95 / 1 # colors = ["#d62728", "blue", "green", "brown"] # subplot_num += 1 ystdev = [] one_value_cluster = d # for i in range(0, len(datasource.GRAIN_COLS)): for i in range(0, len(cluster_params)): col = one_value_cluster[cluster_params[i]] stdev = pd.np.std(col) ystdev.append(stdev) cen = d[cluster_params].mean(axis=0) print(type(cen), type(cen.max()), cen.max()) ## cluster label for legend self.ax.bar( y_pos + width * (0 - (1 / 2.3)), cen, width, align="center", log=self.lgvar, # alpha=0.75, color="blue", ecolor="black", yerr=ystdev) self.ax.grid(True) # self.ax.set_xticklabels # self.ax.set_ylim(0, 1, emit=False) max_y_val = cen.max() self.ax.set_ylim(0, max_y_val * 1.1, emit=False) self.ax.set_xticks(y_pos + width / 4) self.ax.set_xticklabels(cluster_params) ## add legend # self.ax.legend(loc="upper right", shadow=True) self.canvas = FigureCanvasTkAgg(self.fig, self) #type:FigureCanvasTkAgg self.canvas.get_tk_widget().grid(column=1, row=0, sticky=(N, E, W, S), rowspan=2)
def create_widgets(self): """Populate object and its widgets.""" self.variable = {} self.label = {} self.widget = {} self.tab = {} self.group = {} self.notebook = Notebook(self) self.notebook.pack(fill="both", expand=True) if self.fields is None: return for i, (name, desc) in enumerate(self.fields.items()): if "tab" not in desc: desc["tab"] = "main" if desc["tab"] not in self.tab: parent = Frame(self.notebook) parent.columnconfigure([0, 1], weight=1, minsize=self.column_minsize) self.notebook.add(parent, text=desc["tab"].capitalize()) self.tab[desc["tab"]] = parent else: parent = self.tab[desc["tab"]] if "group" in desc: if desc["group"] not in self.group: group = LabelFrame(parent, text=desc["group"].capitalize()) group.columnconfigure([0, 1], weight=1, minsize=self.column_minsize) group.grid( row=i, column=0, columnspan=2, sticky="ew", padx=self.padx, pady=9 * self.pady, ) self.group[desc["group"]] = group else: group = self.group[desc["group"]] parent = group if "values" in desc: values = list(desc["values"]) if "type" not in desc: # if no type is given, first guess it based on a default value, # or infer from the first valid value. if "default" in desc and desc["default"] is not None: desc["type"] = type(desc["default"]) elif "values" in desc: desc["type"] = type([v for v in values if v is not None][0]) else: raise ValueError( f"could not infer type, please specify: {desc}") if "default" not in desc: # if no default is given, use the first value (even if None), # or infer from type. if "values" in desc: desc["default"] = [v for v in values][0] elif "type" in desc: desc["default"] = desc["type"]() else: raise ValueError( f"could not infer default, please specify: {desc}") if desc["type"] is int or desc["type"] is np.int64: self.variable[name] = IntVar(self) elif desc["type"] is bool: self.variable[name] = BooleanVar(self) elif desc["type"] is str: self.variable[name] = StringVar(self) elif desc["type"] is float: self.variable[name] = DoubleVar(self) if "values" in desc: values = [np.round(v, 2) for v in values] else: raise ValueError(f"unknown type '{desc['type']}' for '{name}'") if "text" in desc: text = desc["text"] else: text = name.capitalize() if "widget" not in desc: # TODO(schneiderfelipe): should this be default? desc["widget"] = Combobox if desc["widget"] is Checkbutton: self.widget[name] = desc["widget"]( parent, variable=self.variable[name], text=text) elif "values" in desc: self.widget[name] = desc["widget"]( parent, textvariable=self.variable[name], values=values) else: self.widget[name] = desc["widget"]( parent, textvariable=self.variable[name]) self.widget[name].grid(row=i, column=1, sticky="ew", padx=self.padx, pady=self.pady) if "help" in desc: create_tooltip(self.widget[name], desc["help"]) if desc["widget"] is not Checkbutton: self.label[name] = Label(parent, text=text + ":") self.label[name].grid( row=i, column=0, sticky="ew", padx=self.padx, pady=self.pady, ) if "visible" not in desc: desc["visible"] = True self.init_widgets()
class GameTab(Frame): def __init__(self, master): Frame.__init__(self, master) self._main_window = self.master.master self._land_land_roll = False self._heading = Frame(self) self._inventory_display = Frame(self) self._die_field = Frame(self) self._score_field = LabelFrame(self) self._turn_order = Frame(self) self.die = None if self._main_window.is_game_in_progress.get(): self._load_content() @property def _current_player(self): return self._main_window.engine.aktivjatekos def reset_content(self): self._heading.destroy() self._heading = Frame(self) self._inventory_display.destroy() self._inventory_display = Frame(self) self._die_field.destroy() self._die_field = Frame(self) self._score_field.destroy() self._score_field = LabelFrame(self) self._turn_order.destroy() self._turn_order = Frame(self) if self.die: self.die.destroy() self.die = None self._load_content() def _load_content(self): self.master.tab( 1, state=NORMAL) # TODO fix it when window is being resized. self._build_heading(0) self._build_inventory_display(1) self._build_score_field(2) self._build_state_display(3) self._horizontal_line(4) self._build_die_field(5) self._horizontal_line(6) self._build_turn_order(7) def _build_heading(self, position): flag = Gallery.get( f"flag_{self._current_player.empire.adjective.lower()}") Label(self._heading, text=self._current_player.name).grid(row=0, column=0) Label(self._heading, image=flag).grid(row=1, column=0) self._heading.grid(row=position, column=0, pady=5) def _build_inventory_display(self, position): gold_frame = LabelFrame(self._inventory_display, text=s.language.treasure) Label(gold_frame, image=Gallery.get("penz-d2")).grid(row=0, column=0) Label(gold_frame, textvariable=self._current_player.gold).grid(row=0, column=1) gold_frame.grid(row=0, column=0, sticky=N + E + W + S, padx=5) crew_frame = LabelFrame(self._inventory_display, text=s.language.crew) Label(crew_frame, image=Gallery.get("crew")).grid(row=0, column=0) Label(crew_frame, textvariable=self._current_player.crew).grid(row=0, column=1) crew_frame.grid(row=0, column=1, sticky=N + E + W + S, padx=5) self._inventory_display.grid(row=position, column=0) self._inventory_display.columnconfigure( ALL, minsize=(self.master.width - 20) / 2) def _horizontal_line(self, position): Separator(self, orient=HORIZONTAL).grid(row=position, column=0, sticky=E + W, padx=5, pady=5) def _build_score_field(self, position): self._score_field.config(text=s.language.scores) score_fields = {} target_empires = [empire.value for empire in Empires] target_empires.remove(self._current_player.empire) for index, empire in enumerate(target_empires): score_fields[empire.adjective] = Frame(self._score_field) flag = Gallery.get(f"flag_{empire.adjective.lower()}") Label(score_fields[empire.adjective], image=flag).grid(row=0, column=0) Label(score_fields[empire.adjective], text=':').grid(row=0, column=1) Label(score_fields[empire.adjective], textvariable=self._current_player.scores[ empire.adjective]).grid(row=0, column=2) score_fields[empire.adjective].grid(row=int((index / 2) % 2), column=index % 2, sticky=E + W) self._score_field.grid(row=position, column=0) self._score_field.columnconfigure(ALL, minsize=(self.master.width - 34) / 2) def _build_die_field(self, position): self._die_field.columnconfigure(0, weight=1) self._die_field.rowconfigure(0, weight=1) self._die_field.grid(row=position, column=0, ipady=5, ipadx=5) should_miss_turn = self._current_player.turns_to_miss.get() if should_miss_turn > 0: self._build_miss_turn_button(should_miss_turn) else: self._build_die() def _build_miss_turn_button(self, should_miss_turn): if should_miss_turn > 1: message = s.language.miss_turn % should_miss_turn else: message = s.language.miss_turn_last_time Button(self._die_field, text=message, command=self._main_window.engine.kimaradas).pack() if "leviathan" in self._current_player.states: command = self._main_window.engine.leviathan_kijatszasa Button(self._die_field, text=s.language.play_leviathan, command=command).pack() def _build_die(self): self._die_field.config(relief=RAISED, bd=2) self.die = Die(self._die_field, self.master.width / 4, self._current_player.color, self._current_player.secondary_color, self._current_player.last_roll) castaway_tiles = self._main_window.game_board.locations["castaways"] player_is_on_castaway_island = self._current_player.coordinates in castaway_tiles player_has_no_crew = not self._current_player.crew.get() if player_is_on_castaway_island and player_has_no_crew: self.die.bind('<Button-1>', self._main_window.engine.szamuzottek) else: self.die.bind('<Button-1>', self._roll_die) self.die.grid(row=0, column=0) def _build_turn_order(self, position): players = [] turn_order_label = Label(self._turn_order, text=s.language.turn_order) turn_order_label.grid(row=0, column=0, sticky=W) for index, player_name in enumerate(self._main_window.player_order): player = self._main_window.players[player_name] players.append( Label(self._turn_order, text=str(index + 1) + '. ' + player.name, bg=player.color, fg=player.secondary_color)) players[-1].grid(row=index + 1, column=0, sticky=W, padx=10) self._turn_order.grid(row=position, column=0, sticky=W, padx=5) def _build_state_display(self, position): state_field = LabelFrame(self, text=s.language.cards, relief=RAISED, width=self.master.width - 31) state_slots_per_row = int((self.master.width - 31) / 32) state_slot_height = 24 + ( (int(len(self._current_player.states) / state_slots_per_row) + 1) * 32) if self._current_player.states: for index, state in enumerate(self._current_player.states): if state not in self._main_window.engine.nemKartyaStatusz: if state in self._main_window.engine.eventszotar.keys(): origin = self._main_window.engine.eventszotar prefix = "event" else: origin = self._main_window.engine.kincsszotar prefix = "treasure" icon = f"{prefix}_{self._main_window.engine.eventszotar[state].kep}_i" icon = icon[(icon.find('_') + 1):] button = Button( state_field, image=Gallery.get(icon), command=lambda s=state: origin[s].megjelenik(1)) button.grid(row=int(index / state_slots_per_row), column=index % state_slots_per_row) state_field.config(height=state_slot_height) if state_field.winfo_children(): state_field.grid(row=position, column=0) state_field.grid_propagate(False) def _roll_die(self, event): if self._land_land_roll: self._main_window.game_board.turn_off_blinker() self._main_window.engine.dobasMegtortent.set(False) if not self._main_window.engine.dobasMegtortent.get(): dobas = self.die.roll() if "landland" in self._current_player.states: debug("New roll is possible because of Land, land! bonus.") self._main_window.status_bar.log(s.language.land_log) self._current_player.remove_state("landland") self._land_land_roll = True else: self._main_window.status_bar.log('') self._die_field.config(relief=SUNKEN) self._main_window.engine.set_dobasMegtortent() self._main_window.is_turn_in_progress.set(1) self._main_window.engine.aktivjatekos.last_roll = dobas self._main_window.engine.mozgas(dobas, 1) def disable_additional_roll(self): if self._land_land_roll is False: self._main_window.status_bar.log('') self._die_field.config(relief=SUNKEN) self._land_land_roll = False
def crea_GUI(self): root = self.root #Menús self.menubar = Menu(root, tearoff=0) m_archivo = Menu(self.menubar, tearoff=0) m_archivo.add_command(label='Abrir', command=self.abrir_dataset, accelerator='Ctrl+O') m_archivo.add_separator() m_archivo.add_command(label='Salir', command=self.cerrar_aplicacion) self.menubar.add_cascade(label='Archivo', menu=m_archivo) m_proyecto = Menu(self.menubar, tearoff=0) m_proyecto.add_command(label='Abrir', command=self.abrir_proyecto, state="disabled") m_proyecto.add_separator() m_proyecto.add_checkbutton(label='Clase al final', onvalue=True, offvalue=False, variable=self.clase_al_final) self.menubar.add_cascade(label='Proyecto', menu=m_proyecto) self.m_configuracion = Menu(self.menubar, tearoff=0) self.m_configuracion.add_command( label='Ruta datasets', command=lambda: self.rutas('datasets')) self.m_configuracion.add_command( label='Ruta resultados', command=lambda: self.rutas('resultados')) self.m_configuracion.add_checkbutton(label='Rutas relativas', onvalue=True, offvalue=False, variable=self.rutas_relativas, command=self.cambia_rutas) self.m_configuracion.add_separator() #TODO Revisar self.v_tamanyo_muestra, no la uso # self.v_tamanyo_muestra = StringVar(root, 'Tamaño muestra ({:,})'.\ # format(self._tamanyo_muestra)) self.m_cfg_tamanyo_muestra = \ self.m_configuracion.add_command(label='Tamaño muestra ({:,})'.\ format(self._tamanyo_muestra), command=lambda: self.tamanyo_muestra(\ self._tamanyo_muestra)) self.m_configuracion.add_separator() self.m_configuracion.add_checkbutton(label='Utiliza sha1', onvalue=True, offvalue=False, variable=self.usa_sha1) self.menubar.add_cascade(label='Configuración', menu=self.m_configuracion) m_ver = Menu(self.menubar, tearoff=0) self.v_tipo_dataset = StringVar(self.root, 'Dataset original') m_ver.add_radiobutton(label='Dataset original', value='Dataset original', variable=self.v_tipo_dataset, command=self.muestra_atributos_y_clase) m_ver.add_radiobutton(label='Dataset sin evidencias incompletas', value='Dataset sin evidencias incompletas', variable=self.v_tipo_dataset, command=self.muestra_atributos_y_clase) m_ver.add_radiobutton(label='Dataset sin atributos constantes', value='Dataset sin atributos constantes', variable=self.v_tipo_dataset, command=self.muestra_atributos_y_clase) m_ver.add_radiobutton(label='Catálogo', value='Catálogo', variable=self.v_tipo_dataset, command=self.muestra_atributos_y_clase) m_ver.add_radiobutton(label='Catálogo Robusto', value='Catálogo Robusto', variable=self.v_tipo_dataset, command=self.muestra_atributos_y_clase) m_ver.add_separator() m_ver.add_checkbutton(label='Log del proceso', onvalue=True, offvalue=False, variable=self.mostrar_proceso, state='disabled') self.menubar.add_cascade(label='Ver', menu=m_ver) root.config(menu=self.menubar) #Dataset de clasificación lf_dataset = LabelFrame(root, text='Dataset de Clasificación') lf_dataset.pack(fill='both', expand=True, padx=5, pady=5) Label(lf_dataset, text='Nombre:').grid(row=0, column=0, sticky='e') self.v_nombre_dataset = StringVar(root, '-------') self.l_nombre_dataset = Label(lf_dataset, textvariable=self.v_nombre_dataset) self.l_nombre_dataset.grid(row=0, column=1, sticky='w') Label(lf_dataset, text='Tamaño:').grid(row=0, column=2, sticky='e') self.v_tamanyo_dataset = StringVar(root, '-------') Label(lf_dataset, textvariable=self.v_tamanyo_dataset).grid(row=0, column=3, sticky='w') Label(lf_dataset, text='Ubicación:').grid(row=1, column=0, sticky='e') self.v_ruta_dataset = StringVar(root, '-------------------------') #TODO Expandir en columnas 1-3, puede ser muy larga Label(lf_dataset, textvariable=self.v_ruta_dataset).grid(row=1, column=1, sticky='w', columnspan=3) #Dataset de clasificación / Muestra lf_dataset_muestra = LabelFrame(lf_dataset, text='Muestra') lf_dataset_muestra.grid(row=2, column=0, sticky='nsew', columnspan=4, padx=5, pady=5) self.sb_v_t_muestra = Scrollbar(lf_dataset_muestra) self.sb_v_t_muestra.grid(row=0, column=1, sticky='sn') self.sb_h_t_muestra = Scrollbar(lf_dataset_muestra, orient='horizontal') self.sb_h_t_muestra.grid(row=1, column=0, sticky='ew') self.t_muestra = Text(lf_dataset_muestra, yscrollcommand=self.sb_v_t_muestra.set, xscrollcommand=self.sb_h_t_muestra.set, bd=0, wrap='none', state='disabled', height=8) self.t_muestra.grid(row=0, column=0, sticky='nswe') self.sb_v_t_muestra.config(command=self.t_muestra.yview) self.sb_h_t_muestra.config(command=self.t_muestra.xview) lf_dataset_muestra.rowconfigure(0, weight=1) lf_dataset_muestra.columnconfigure(0, weight=1) lf_dataset.rowconfigure(2, weight=3) lf_dataset.columnconfigure(1, weight=1) lf_dataset.columnconfigure(3, weight=1) #Dataset de clasificación / Evidencias lf_dataset_evidencias = LabelFrame(lf_dataset, text='Evidencias') lf_dataset_evidencias.grid(row=3, column=0, sticky='nsew', padx=5, pady=5) Label(lf_dataset_evidencias, text='Total:').grid(row=0, column=0, sticky='e') self.v_evidencias_total = StringVar(root, '-------') Label(lf_dataset_evidencias, textvariable=self.v_evidencias_total).\ grid(row=0, column=1, sticky='w') Label(lf_dataset_evidencias, text='Completas:').grid(row=1, column=0, sticky='e') self.v_evidencias_completas = StringVar(root, '-------') Label(lf_dataset_evidencias, textvariable=self.v_evidencias_completas).\ grid(row=1, column=1, sticky='w') Label(lf_dataset_evidencias, text='Únicas:').grid(row=2, column=0, sticky='e') self.v_evidencias_catalogo = StringVar(root, '-------') Label(lf_dataset_evidencias, textvariable=self.v_evidencias_catalogo).\ grid(row=2, column=1, sticky='w') Label(lf_dataset_evidencias, text='Robustas:').grid(row=3, column=0, sticky='e') self.v_evidencias_robustas = StringVar(root, '-------') Label(lf_dataset_evidencias, textvariable=self.v_evidencias_robustas).\ grid(row=3, column=1, sticky='w') #Dataset de clasificación / Atributos lf_dataset_clase_y_atributos = LabelFrame(lf_dataset, text='Clase y atributos') lf_dataset_clase_y_atributos.grid(row=3, column=1, sticky='nsew', columnspan=3, padx=5, pady=5) PROPIEDADES_ATRIBUTOS = ('Nombre', 'count', 'unique', 'top', 'freq', 'mean', 'std', 'min', '25%', '50%', '75%', 'max') self.sb_h_tv_clase = Scrollbar(lf_dataset_clase_y_atributos, orient='horizontal') self.sb_h_tv_clase.grid(row=1, column=0, sticky='ew') self.tv_clase = Treeview(lf_dataset_clase_y_atributos, columns=PROPIEDADES_ATRIBUTOS, height=1, xscrollcommand=self.sb_h_tv_clase.set) self.tv_clase.grid(row=0, column=0, sticky='ew') self.sb_h_tv_clase.config(command=self.tv_clase.xview) self.tv_clase.heading("#0", text="#") self.tv_clase.column("#0", minwidth=30, width=40, stretch=False) self.sb_v_tv_atributos = Scrollbar(lf_dataset_clase_y_atributos) self.sb_v_tv_atributos.grid(row=2, column=1, sticky='sn') self.sb_h_tv_atributos = Scrollbar(lf_dataset_clase_y_atributos, orient='horizontal') self.sb_h_tv_atributos.grid(row=3, column=0, sticky='ew') self.tv_atributos = Treeview(lf_dataset_clase_y_atributos, columns=PROPIEDADES_ATRIBUTOS, yscrollcommand=self.sb_v_tv_atributos.set, xscrollcommand=self.sb_h_tv_atributos.set) self.tv_atributos.grid(row=2, column=0, sticky='nsew') self.tv_atributos.bind('<ButtonRelease-1>', self.selectItem) self.sb_v_tv_atributos.config(command=self.tv_atributos.yview) self.sb_h_tv_atributos.config(command=self.tv_atributos.xview) self.tv_atributos.heading("#0", text="#") self.tv_atributos.column("#0", minwidth=30, width=40, stretch=False) for i in PROPIEDADES_ATRIBUTOS: self.tv_clase.heading(i, text=i) self.tv_clase.column(i, minwidth=50, width=50, stretch=False) self.tv_atributos.heading(i, text=i) self.tv_atributos.column(i, minwidth=50, width=50, stretch=False) lf_dataset_clase_y_atributos.rowconfigure(2, weight=1) lf_dataset_clase_y_atributos.columnconfigure(0, weight=1) lf_dataset.rowconfigure(3, weight=1)