def on_draw(self, area, ctx): """Actual signal callback that triggers all the drawing.""" # May happen on empty charts: max_layers = self.max_layers if max_layers <= 0: max_layers = 1 draw_empty = True else: draw_empty = False # Figure out the background color of the drawing area alloc = area.get_allocation() # Calculate the font size of the inner label. # Make it smaller if not enough place but cut off at a size of 12 inner_circle = (1.4 / max_layers) inner_circle *= min(alloc.width, alloc.height) / 2 font_size = min(12, inner_circle / 3) # Draw the center text: _draw_center_text( ctx, alloc.width / 2, alloc.height / 2, '<span color="#333"><small>{size}</small></span>'.format( size=size_to_human_readable(self.total_size) ), font_size=font_size ) bg = self.get_toplevel().get_style_context().get_background_color(0) if not draw_empty: for segment in reversed(self._segment_list): segment.draw(ctx, alloc, max_layers, bg) else: ctx.arc( alloc.width / 2, alloc.height / 2, inner_circle / 2, 0, 2 * math.pi ) ctx.stroke() if self._selected_segment is None or draw_empty: return for segment in self._segment_list: if segment.layer != self._selected_segment.layer: continue if segment is not self._selected_segment: if segment.size < ANGLE_LIMIT_TOOLTIP: continue x, y = segment.middle_point(alloc, max_layers) _draw_tooltip( ctx, alloc, x, y, 8, segment.middle_angle(), segment.tooltip )
def on_draw(self, area, ctx): """Actual signal callback that triggers all the drawing.""" # May happen on empty charts: max_layers = self.max_layers if max_layers <= 0: max_layers = 1 draw_empty = True else: draw_empty = False # Figure out the background color of the drawing area alloc = area.get_allocation() # Caluclate the font size of the inner label. # Make it smaller if not enough place but cut off at a size of 12 inner_circle = (1.4 / max_layers) inner_circle *= min(alloc.width, alloc.height) / 2 font_size = min(12, inner_circle / 3) # Draw the center text: _draw_center_text( ctx, alloc.width / 2, alloc.height / 2, '<span color="#333"><small>{size}</small></span>'.format( size=size_to_human_readable(self.total_size) ), font_size=font_size ) bg = self.get_toplevel().get_style_context().get_background_color(0) if not draw_empty: for segment in reversed(self._segment_list): segment.draw(ctx, alloc, max_layers, bg) else: ctx.arc( alloc.width / 2, alloc.height / 2, inner_circle / 2, 0, 2 * math.pi ) ctx.stroke() if self._selected_segment is None or draw_empty: return for segment in self._segment_list: if segment.layer != self._selected_segment.layer: continue if segment is not self._selected_segment: if segment.size < ANGLE_LIMIT_TOOLTIP: continue x, y = segment.middle_point(alloc, max_layers) _draw_tooltip( ctx, alloc, x, y, 8, segment.middle_angle(), segment.tooltip )
def _du_finished(self, du_proc, result): """Called when the coreutil du finished running. Harvest results.""" result, du_data, _ = du_proc.communicate_utf8_finish(result) if du_data: kbytes = int(''.join([num for num in du_data if num.isdigit()])) text = size_to_human_readable(kbytes * 1024) else: text = '' self.remove(self.get_child()) self.add(Gtk.Label(text)) self.show_all()
def push(self, prefix, path): """Push a new path to the label, removing the old one.""" if prefix.lower() == 'keeping': return try: buf = os.stat(path) self._size_sum += buf.st_size except OSError: pass text = REMOVED_LABEL.format(t=prefix, s=size_to_human_readable(self._size_sum), p=GLib.markup_escape_text(path)) self.set_markup(text)
def push(self, prefix, path): """Push a new path to the label, removing the old one.""" if prefix.lower() == 'keeping': return try: buf = os.stat(path) self._size_sum += buf.st_size except OSError: pass text = REMOVED_LABEL.format( t=prefix, s=size_to_human_readable(self._size_sum), p=GLib.markup_escape_text(path) ) self.set_markup(text)
def __init__(self, name, path, themed_icon, fill_level=None): Gtk.ListBoxRow.__init__(self) self.set_size_request(-1, 80) self.set_can_focus(False) # CSS Name self.set_name('ShredderLocationEntry') self.path, self.name = path, name name_label = Gtk.Label('<b>{}</b>'.format( GLib.markup_escape_text(name))) name_label.set_use_markup(True) name_label.set_hexpand(True) name_label.set_halign(Gtk.Align.START) path_label = Gtk.Label('<small>{}</small>'.format( GLib.markup_escape_text(path))) path_label.set_use_markup(True) path_label.set_hexpand(True) path_label.set_halign(Gtk.Align.START) icon_img = Gtk.Image.new_from_gicon(themed_icon, Gtk.IconSize.DIALOG) icon_img.props.pixel_size = 64 icon_img.set_halign(Gtk.Align.START) icon_img.set_margin_start(3) icon_img.set_margin_end(10) icon_img.set_vexpand(True) icon_img.set_valign(Gtk.Align.FILL) self.check_box = Gtk.Switch() self.check_box.connect('notify::active', self.on_check_box_toggled) self.check_box.set_tooltip_text('Prefer this directory?') self.check_box.set_margin_end(5) self.check_box.set_margin_top(13) self.check_box.set_can_focus(False) self.separator = Gtk.Separator() self.separator.set_hexpand(True) self.separator.set_halign(Gtk.Align.FILL) ####################### # Put it all together # ####################### grid = Gtk.Grid() self.add(grid) # Quick-select button with arrow inside: shortcut_btn = Gtk.Button() shortcut_btn.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE)) shortcut_btn.set_relief(Gtk.ReliefStyle.NONE) shortcut_btn.set_vexpand(False) shortcut_btn.set_valign(Gtk.Align.START) shortcut_btn.set_margin_top(17) shortcut_btn.set_margin_end(15) shortcut_btn.set_opacity(0.7) shortcut_btn.set_can_focus(False) shortcut_btn.set_size_request(-1, 28) shortcut_btn.connect('clicked', lambda *_: self.emit('shortcut')) grid.attach(icon_img, 0, 0, 5, 5) grid.attach(name_label, 5, 2, 1, 1) grid.attach(path_label, 5, 3, 1, 1) grid.attach(self.check_box, 7, 2, 1, 1) grid.attach(shortcut_btn, 8, 2, 1, 1) grid.attach(self.separator, 0, 8, 9, 1) if fill_level is not None: level_bar = Gtk.LevelBar() level_bar.set_valign(Gtk.Align.START) level_bar.set_halign(Gtk.Align.END) level_bar.set_vexpand(False) level_bar.set_size_request(150, 10) level_bar.set_margin_end(20) level_bar.set_margin_top(20) # Define new values for 'high' and 'low' level_bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_HIGH) level_bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_LOW) level_bar.add_offset_value(Gtk.LEVEL_BAR_OFFSET_LOW, 0.75) level_bar.add_offset_value(Gtk.LEVEL_BAR_OFFSET_HIGH, 0.25) level_label = Gtk.Label() level_label.set_valign(Gtk.Align.START) level_label.set_halign(Gtk.Align.END) level_label.set_margin_end(20) level_label.set_vexpand(False) used, total = fill_level # Watch for zero division: if total > 0: percent = int(used / total * 100) else: percent = 100 level_label.set_markup('<small>{f} / {t} - {p}%</small>'.format( f=size_to_human_readable(used), t=size_to_human_readable(total), p=percent)) level_bar.set_value(percent / 100) grid.attach(level_label, 6, 3, 1, 1) grid.attach(level_bar, 6, 2, 1, 1) else: size_widget = DeferSizeLabel(path) size_widget.set_margin_top(15) size_widget.set_margin_end(20) grid.attach(size_widget, 6, 2, 1, 1)
def __init__(self, name, path, themed_icon, fill_level=None): Gtk.ListBoxRow.__init__(self) self.set_size_request(-1, 80) self.set_can_focus(False) self.themed_icon = themed_icon # CSS Name self.set_name('ShredderLocationEntry') self.path, self.name = path, name name_label = Gtk.Label( '<b>{}</b>'.format(GLib.markup_escape_text(name)) ) name_label.set_use_markup(True) name_label.set_hexpand(True) name_label.set_halign(Gtk.Align.START) path_label = Gtk.Label( '<small>{}</small>'.format(GLib.markup_escape_text(path)) ) path_label.set_use_markup(True) path_label.set_hexpand(True) path_label.set_halign(Gtk.Align.START) icon_img = Gtk.Image.new_from_gicon( themed_icon, Gtk.IconSize.DIALOG ) icon_img.props.pixel_size = 64 icon_img.set_halign(Gtk.Align.START) icon_img.set_margin_start(3) icon_img.set_margin_end(10) icon_img.set_vexpand(True) icon_img.set_valign(Gtk.Align.FILL) self.check_box = Gtk.Switch() self.check_box.connect('notify::active', self.on_check_box_toggled) self.check_box.set_tooltip_text('Prefer this directory?') self.check_box.set_margin_end(5) self.check_box.set_margin_top(13) self.check_box.set_can_focus(False) self.separator = Gtk.Separator() self.separator.set_hexpand(True) self.separator.set_halign(Gtk.Align.FILL) ####################### # Put it all together # ####################### grid = Gtk.Grid() self.add(grid) # Quick-select button with arrow inside: shortcut_btn = Gtk.Button() shortcut_btn.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE)) shortcut_btn.set_relief(Gtk.ReliefStyle.NONE) shortcut_btn.set_vexpand(False) shortcut_btn.set_valign(Gtk.Align.START) shortcut_btn.set_margin_top(17) shortcut_btn.set_margin_end(15) shortcut_btn.set_opacity(0.7) shortcut_btn.set_can_focus(False) shortcut_btn.set_size_request(-1, 28) shortcut_btn.connect('clicked', lambda *_: self.emit('shortcut')) grid.attach(icon_img, 0, 0, 5, 5) grid.attach(name_label, 5, 2, 1, 1) grid.attach(path_label, 5, 3, 1, 1) grid.attach(self.check_box, 7, 2, 1, 1) grid.attach(shortcut_btn, 8, 2, 1, 1) grid.attach(self.separator, 0, 8, 9, 1) if fill_level is not None: level_bar = Gtk.LevelBar() level_bar.set_valign(Gtk.Align.START) level_bar.set_halign(Gtk.Align.END) level_bar.set_vexpand(False) level_bar.set_size_request(150, 10) level_bar.set_margin_end(20) level_bar.set_margin_top(20) # Define new values for 'high' and 'low' level_bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_HIGH) level_bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_LOW) level_bar.add_offset_value(Gtk.LEVEL_BAR_OFFSET_LOW, 0.75) level_bar.add_offset_value(Gtk.LEVEL_BAR_OFFSET_HIGH, 0.25) level_label = Gtk.Label() level_label.set_valign(Gtk.Align.START) level_label.set_halign(Gtk.Align.END) level_label.set_margin_end(20) level_label.set_vexpand(False) used, total = fill_level # Watch for zero division: if total > 0: percent = int(used / total * 100) else: percent = 100 level_label.set_markup( '<small>{f} / {t} - {p}%</small>'.format( f=size_to_human_readable(used), t=size_to_human_readable(total), p=percent ) ) level_bar.set_value(percent / 100) grid.attach(level_label, 6, 3, 1, 1) grid.attach(level_bar, 6, 2, 1, 1) else: size_widget = DeferSizeLabel(path) size_widget.set_margin_top(15) size_widget.set_margin_end(20) grid.attach(size_widget, 6, 2, 1, 1)