def value(self, path: str) -> None: """Set the current path. This calls the callback function.""" import tooltip self.callback(path) self._location = path tooltip.set_tooltip(self, path) self._text_var.set(self._truncate(path))
def make_widgets(self, master: 'CheckDetails'): if self.master is not None: # If we let items move between lists, the old widgets will become # orphaned! raise ValueError( "Can't move Item objects between lists!" ) self.master = master self.check = ttk.Checkbutton( master.wid_frame, variable=self.state_var, onvalue=1, offvalue=0, takefocus=False, width=0, style='CheckDetails.TCheckbutton', command=self.master.update_allcheck, ) if self.locked: self.check.state(['disabled']) self.val_widgets = [] for value in self.values: wid = tk.Label( master.wid_frame, text=value, justify=tk.LEFT, anchor=tk.W, background='white', ) add_tooltip(wid) if self.hover_text: set_tooltip(wid, self.hover_text) wid.hover_override = True else: set_tooltip(wid) wid.hover_override = False if not self.locked: # Allow clicking on the row to toggle the checkbox wid.bind('<Enter>', self.hover_start, add='+') wid.bind('<Leave>', self.hover_stop, add='+') utils.bind_leftclick(wid, self.row_click, add='+') wid.bind(utils.EVENTS['LEFT_RELEASE'], self.row_unclick, add='+') self.val_widgets.append(wid) utils.add_mousewheel( self.master.wid_canvas, self.check, *self.val_widgets )
def make_widgets(self, master: 'CheckDetails'): if self.master is not None: # If we let items move between lists, the old widgets will become # orphaned! raise ValueError("Can't move Item objects between lists!") self.master = master self.check = ttk.Checkbutton( master.wid_frame, variable=self.state_var, onvalue=1, offvalue=0, takefocus=False, width=0, style='CheckDetails.TCheckbutton', command=self.master.update_allcheck, ) if self.locked: self.check.state(['disabled']) self.val_widgets = [] for value in self.values: wid = tk.Label( master.wid_frame, text=value, justify=tk.LEFT, anchor=tk.W, background='white', ) add_tooltip(wid) if self.hover_text: set_tooltip(wid, self.hover_text) wid.hover_override = True else: set_tooltip(wid) wid.hover_override = False if not self.locked: # Allow clicking on the row to toggle the checkbox wid.bind('<Enter>', self.hover_start, add='+') wid.bind('<Leave>', self.hover_stop, add='+') utils.bind_leftclick(wid, self.row_click, add='+') wid.bind(utils.EVENTS['LEFT_RELEASE'], self.row_unclick, add='+') self.val_widgets.append(wid) utils.add_mousewheel(self.master.wid_canvas, self.check, *self.val_widgets)
def readonly(self, value): self._readonly = bool(value) if self.display is None: # Widget hasn't been added yet, stop. # We update in the widget() method. return if value: new_st = ['disabled'] set_tooltip(self.display, self.readonly_description) else: new_st = ['!disabled'] set_tooltip(self.display, self.description) self.disp_btn.state(new_st) self.display.state(new_st)
def place(self, check_width, head_pos, y): """Position the widgets on the frame.""" self.check.place( x=0, y=y, width=check_width, height=ROW_HEIGHT, ) for text, widget, (x, width) in zip(self.values, self.val_widgets, head_pos): widget.place( x=x + check_width, y=y, width=width, height=ROW_HEIGHT, ) text = str(text) short_text = widget['text'] = truncate(text, width - 5) if not widget.hover_override: set_tooltip(widget, text if short_text != text else '') x += width
def refresh_counts(reload=True): if reload: COMPILE_CFG.load() # Don't re-run the flash function if it's already on. run_flash = not ( count_entity.should_flash or count_overlay.should_flash or count_brush.should_flash ) for bar_var, name, default, tip_blurb in COUNT_CATEGORIES: value = COMPILE_CFG.get_int('Counts', name) if name == 'entity': # The in-engine entity limit is different to VBSP's limit # (that one might include prop_static, lights etc). max_value = default else: # Use or to ensure no divide-by-zero occurs.. max_value = COMPILE_CFG.get_int('Counts', 'max_' + name) or default # If it's hit the limit, make it continously scroll to draw # attention to the bar. if value >= max_value: bar_var.should_flash = True else: bar_var.should_flash = False bar_var.set(100 * value / max_value) set_tooltip(UI['count_' + name], '{}/{} ({:.2%}):\n{}'.format( value, max_value, value / max_value, tip_blurb, )) if run_flash: flash_count()
def place(self, check_width, head_pos, y): """Position the widgets on the frame.""" self.check.place( x=0, y=y, width=check_width, height=ROW_HEIGHT, ) for text, widget, (x, width) in zip( self.values, self.val_widgets, head_pos ): widget.place( x=x+check_width, y=y, width=width, height=ROW_HEIGHT, ) text = str(text) short_text = widget['text'] = truncate(text, width-5) if not widget.hover_override: set_tooltip(widget, text if short_text != text else '') x += width
def sel_item(self, item: Item, event=None): self.prop_name['text'] = item.longName if len(item.authors) == 0: self.prop_author['text'] = '' else: self.prop_author['text'] = ngettext( 'Author: {}', 'Authors: {}', len(item.authors), ).format(', '.join(item.authors)) if item.large_icon is not None: # We have a large icon, use it. self.prop_icon['image'] = item.large_icon width, height = img.tuple_size(ICON_SIZE_LRG) else: # Small icon, shrink the preview. self.prop_icon['image'] = item.icon width, height = img.tuple_size(ICON_SIZE) self.prop_icon_frm.configure(width=width, height=height) self.prop_desc.set_text(item.desc) self.selected.button.state(('!alternate', )) self.selected = item item.button.state(('alternate', )) self.scroll_to(item) if self.sampler: is_playing = self.sampler.is_playing self.sampler.stop() self.sampler.cur_file = item.snd_sample if self.sampler.cur_file: self.samp_button.state(('!disabled', )) if is_playing: # Start the sampler again, so it plays the current item! self.sampler.play_sample() else: self.samp_button.state(('disabled', )) if self.has_def: if self.suggested is None or self.selected == self.suggested: self.prop_reset.state(('disabled', )) else: self.prop_reset.state(('!disabled', )) if self.attr: # Set the attribute items. for attr_id, label in self.attr.items(): val = item.attrs.get(attr_id, label.default) if label.type is AttrTypes.BOOL: label['image'] = (ICON_CHECK if val else ICON_CROSS) elif label.type is AttrTypes.COLOR: label['image'] = img.color_square(val, size=16) # Display the full color when hovering.. # i18n: Tooltip for colour swatch. set_tooltip( label, _('Color: R={r}, G={g}, B={b}').format( r=int(val.x), g=int(val.y), b=int(val.z), )) elif label.type is AttrTypes.LIST: # Join the values (in alphabetical order) label['text'] = ', '.join(sorted(val)) elif label.type is AttrTypes.STRING: # Just a string. label['text'] = str(val) else: raise ValueError('Invalid attribute type: "{}"'.format( label.type))
def load_item_data(): """Refresh the window to use the selected item's data.""" global version_lookup item_data = selected_item.data for ind, pos in enumerate(SUBITEM_POS[selected_item.num_sub]): if pos == -1: wid['subitem', ind]['image'] = img.invis_square(64) else: wid['subitem', ind]['image'] = selected_item.get_icon(pos) wid['subitem', ind]['relief'] = 'flat' wid['subitem', pos_for_item()]['relief'] = 'raised' wid['author']['text'] = ', '.join(item_data.authors) wid['name']['text'] = selected_sub_item.name wid['ent_count']['text'] = item_data.ent_count or '??' wid['desc'].set_text( get_description( global_last=selected_item.item.glob_desc_last, glob_desc=selected_item.item.glob_desc, style_desc=item_data.desc, )) if itemPropWin.can_edit(selected_item.properties()): wid['changedefaults'].state(['!disabled']) else: wid['changedefaults'].state(['disabled']) version_lookup = set_version_combobox(wid['variant'], selected_item) if selected_item.url is None: wid['moreinfo'].state(['disabled']) else: wid['moreinfo'].state(['!disabled']) tooltip.set_tooltip(wid['moreinfo'], selected_item.url) editor_data = item_data.editor.copy() comm_block = Property(editor_data['Type'], []) ( has_inputs, has_outputs, has_secondary, ) = packageLoader.Item.convert_item_io(comm_block, editor_data) del comm_block # We don't use the config. has_timer = any(editor_data.find_all("Properties", "TimerDelay")) editor_bit = next(editor_data.find_all("Editor")) rot_type = editor_bit["MovementHandle", "HANDLE_NONE"].casefold() facing_type = editor_bit["InvalidSurface", ""].casefold() surf_wall = "wall" in facing_type surf_floor = "floor" in facing_type surf_ceil = "ceiling" in facing_type is_embed = any(editor_data.find_all("Exporting", "EmbeddedVoxels")) if has_inputs: if has_secondary: set_sprite(SPR.INPUT, 'in_dual') # Real funnels work slightly differently. if selected_item.id.casefold() == 'item_tbeam': wid['sprite', SPR.INPUT].tooltip_text = _( 'Excursion Funnels accept a on/off ' 'input and a directional input.') else: set_sprite(SPR.INPUT, 'in_norm') else: set_sprite(SPR.INPUT, 'in_none') if has_outputs: if has_timer: set_sprite(SPR.OUTPUT, 'out_tim') else: set_sprite(SPR.OUTPUT, 'out_norm') else: set_sprite(SPR.OUTPUT, 'out_none') set_sprite(SPR.ROTATION, ROT_TYPES.get( rot_type.casefold(), 'rot_none', )) if is_embed: set_sprite(SPR.COLLISION, 'space_embed') else: set_sprite(SPR.COLLISION, 'space_none') face_spr = "surf" if not surf_wall: face_spr += "_wall" if not surf_floor: face_spr += "_floor" if not surf_ceil: face_spr += "_ceil" if face_spr == "surf": # This doesn't seem right - this item won't be placeable at all... LOGGER.warning( "Item <{}> disallows all orientations. Is this right?", selected_item.id, ) face_spr += "_none" set_sprite(SPR.FACING, face_spr) # Now some special overrides for certain classes. if selected_item.id == "ITEM_CUBE": # Cubes - they should show info for the dropper. set_sprite(SPR.FACING, 'surf_ceil') set_sprite(SPR.INPUT, 'in_norm') set_sprite(SPR.COLLISION, 'space_embed') set_sprite(SPR.OUTPUT, 'out_none') set_sprite(SPR.ROTATION, 'rot_36') tooltip.set_tooltip( wid['sprite', SPR.ROTATION], SPRITE_TOOL['rot_36'] + _('This item can be rotated on the floor to face 360 ' 'degrees, for Reflection Cubes only.'), ) item_class = editor_data['ItemClass', ''].casefold() if item_class == "itempaintsplat": # Reflection or normal gel.. set_sprite(SPR.FACING, 'surf_wall_ceil') set_sprite(SPR.INPUT, 'in_norm') set_sprite(SPR.COLLISION, 'space_none') set_sprite(SPR.OUTPUT, 'out_none') set_sprite(SPR.ROTATION, 'rot_paint') elif item_class == 'itemrailplatform': # Track platform - always embeds into the floor. set_sprite(SPR.COLLISION, 'space_embed')
def set_sprite(pos, sprite): """Set one of the property sprites to a value.""" widget = wid['sprite', pos] widget['image'] = img.spr(sprite) tooltip.set_tooltip(widget, SPRITE_TOOL.get(sprite, ''))
def load_item_data(): """Refresh the window to use the selected item's data.""" global version_lookup item_data = selected_item.data for ind, pos in enumerate(SUBITEM_POS[selected_item.num_sub]): if pos == -1: wid['subitem', ind]['image'] = img.invis_square(64) else: wid['subitem', ind]['image'] = selected_item.get_icon(pos) wid['subitem', ind]['relief'] = 'flat' wid['subitem', pos_for_item()]['relief'] = 'raised' wid['author']['text'] = ', '.join(item_data.authors) wid['name']['text'] = selected_sub_item.name wid['ent_count']['text'] = item_data.ent_count or '??' wid['desc'].set_text( get_description( global_last=selected_item.item.glob_desc_last, glob_desc=selected_item.item.glob_desc, style_desc=item_data.desc, ) ) if itemPropWin.can_edit(selected_item.properties()): wid['changedefaults'].state(['!disabled']) else: wid['changedefaults'].state(['disabled']) version_lookup = set_version_combobox(wid['variant'], selected_item) if selected_item.url is None: wid['moreinfo'].state(['disabled']) else: wid['moreinfo'].state(['!disabled']) tooltip.set_tooltip(wid['moreinfo'], selected_item.url) editor_data = item_data.editor.copy() comm_block = Property(selected_item.id, []) ( has_inputs, has_outputs, has_secondary, ) = packageLoader.Item.convert_item_io(comm_block, editor_data) del comm_block # We don't use the config. has_timer = any(editor_data.find_all("Properties", "TimerDelay")) editor_bit = next(editor_data.find_all("Editor")) rot_type = editor_bit["MovementHandle", "HANDLE_NONE"].casefold() facing_type = editor_bit["InvalidSurface", ""].casefold() surf_wall = "wall" in facing_type surf_floor = "floor" in facing_type surf_ceil = "ceiling" in facing_type is_embed = any(editor_data.find_all("Exporting", "EmbeddedVoxels")) if has_inputs: if has_secondary: set_sprite(SPR.INPUT, 'in_dual') # Real funnels work slightly differently. if selected_item.id.casefold() == 'item_tbeam': wid['sprite', SPR.INPUT].tooltip_text = _( 'Excursion Funnels accept a on/off ' 'input and a directional input.' ) else: set_sprite(SPR.INPUT, 'in_norm') else: set_sprite(SPR.INPUT, 'in_none') if has_outputs: if has_timer: set_sprite(SPR.OUTPUT, 'out_tim') else: set_sprite(SPR.OUTPUT, 'out_norm') else: set_sprite(SPR.OUTPUT, 'out_none') set_sprite( SPR.ROTATION, ROT_TYPES.get( rot_type.casefold(), 'rot_none', ) ) if is_embed: set_sprite(SPR.COLLISION, 'space_embed') else: set_sprite(SPR.COLLISION, 'space_none') face_spr = "surf" if not surf_wall: face_spr += "_wall" if not surf_floor: face_spr += "_floor" if not surf_ceil: face_spr += "_ceil" if face_spr == "surf": # This doesn't seem right - this item won't be placeable at all... LOGGER.warning( "Item <{}> disallows all orientations. Is this right?", selected_item.id, ) face_spr += "_none" set_sprite(SPR.FACING, face_spr) # Now some special overrides for certain classes. if selected_item.id == "ITEM_CUBE": # Cubes - they should show info for the dropper. set_sprite(SPR.FACING, 'surf_ceil') set_sprite(SPR.INPUT, 'in_norm') set_sprite(SPR.COLLISION, 'space_embed') set_sprite(SPR.OUTPUT, 'out_none') set_sprite(SPR.ROTATION, 'rot_36') tooltip.set_tooltip( wid['sprite', SPR.ROTATION], SPRITE_TOOL['rot_36'] + _( 'This item can be rotated on the floor to face 360 ' 'degrees, for Reflection Cubes only.' ), ) item_class = editor_data['ItemClass', ''].casefold() if item_class == "itempaintsplat": # Reflection or normal gel.. set_sprite(SPR.FACING, 'surf_wall_ceil') set_sprite(SPR.INPUT, 'in_norm') set_sprite(SPR.COLLISION, 'space_none') set_sprite(SPR.OUTPUT, 'out_none') set_sprite(SPR.ROTATION, 'rot_paint') elif item_class == 'itemrailplatform': # Track platform - always embeds into the floor. set_sprite(SPR.COLLISION, 'space_embed')
def sel_item(self, item: Item, event=None): self.prop_name['text'] = item.longName if len(item.authors) == 0: self.prop_author['text'] = '' else: self.prop_author['text'] = ngettext( 'Author: {}', 'Authors: {}', len(item.authors), ).format( ', '.join(item.authors) ) if item.large_icon is not None: # We have a large icon, use it. self.prop_icon['image'] = item.large_icon width, height = img.tuple_size(ICON_SIZE_LRG) else: # Small icon, shrink the preview. self.prop_icon['image'] = item.icon width, height = img.tuple_size(ICON_SIZE) self.prop_icon_frm.configure(width=width, height=height) self.prop_desc.set_text(item.desc) self.selected.button.state(('!alternate',)) self.selected = item item.button.state(('alternate',)) self.scroll_to(item) if self.sampler: is_playing = self.sampler.is_playing self.sampler.stop() self.sampler.cur_file = item.snd_sample if self.sampler.cur_file: self.samp_button.state(('!disabled',)) if is_playing: # Start the sampler again, so it plays the current item! self.sampler.play_sample() else: self.samp_button.state(('disabled',)) if self.has_def: if self.suggested is None or self.selected == self.suggested: self.prop_reset.state(('disabled',)) else: self.prop_reset.state(('!disabled',)) if self.attr: # Set the attribute items. for attr_id, label in self.attr.items(): val = item.attrs.get(attr_id, label.default) if label.type is AttrTypes.BOOL: label['image'] = ( ICON_CHECK if val else ICON_CROSS ) elif label.type is AttrTypes.COLOR: label['image'] = img.color_square(val, size=16) # Display the full color when hovering.. # i18n: Tooltip for colour swatch. set_tooltip(label, _('Color: R={r}, G={g}, B={b}').format( r=int(val.x), g=int(val.y), b=int(val.z), )) elif label.type is AttrTypes.LIST: # Join the values (in alphabetical order) label['text'] = ', '.join(sorted(val)) elif label.type is AttrTypes.STRING: # Just a string. label['text'] = str(val) else: raise ValueError( 'Invalid attribute type: "{}"'.format(label.type) )