static void gtk_level_bar_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { GtkLevelBar *self = GTK_LEVEL_BAR (widget); GtkBorder borders; gint num_blocks; gint height, block_height; num_blocks = gtk_level_bar_get_num_blocks (self); gtk_level_bar_get_min_block_size (self, NULL, &block_height); gtk_level_bar_get_borders (self, &borders); height = borders.top + borders.bottom; if (self->priv->orientation == GTK_ORIENTATION_VERTICAL) height += num_blocks * block_height; else height += block_height; if (minimum) *minimum = height; if (natural) *natural = height; }
static void gtk_level_bar_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural) { GtkLevelBar *self = GTK_LEVEL_BAR (widget); GtkBorder borders; gint num_blocks; gint width, block_width; num_blocks = gtk_level_bar_get_num_blocks (self); gtk_level_bar_get_min_block_size (self, &block_width, NULL); gtk_level_bar_get_borders (self, &borders); width = borders.left + borders.right; if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) width += num_blocks * block_width; else width += block_width; if (minimum) *minimum = width; if (natural) *natural = width; }
static gint gtk_level_bar_get_num_block_nodes (GtkLevelBar *self) { if (self->priv->bar_mode == GTK_LEVEL_BAR_MODE_CONTINUOUS) return 2; else return gtk_level_bar_get_num_blocks (self); }
static void gtk_level_bar_draw_fill_discrete (GtkLevelBar *self, cairo_t *cr) { gint num_blocks, i; num_blocks = gtk_level_bar_get_num_blocks (self); for (i = 0; i < num_blocks; i++) gtk_css_gadget_draw (self->priv->block_gadget[i], cr); }
static void gtk_level_bar_snapshot_fill_discrete (GtkLevelBar *self, GtkSnapshot *snapshot) { gint num_blocks, i; num_blocks = gtk_level_bar_get_num_blocks (self); for (i = 0; i < num_blocks; i++) gtk_css_gadget_snapshot (self->priv->block_gadget[i], snapshot); }
static void gtk_level_bar_allocate_trough_discrete (GtkLevelBar *self, const GtkAllocation *allocation, int baseline, GtkAllocation *out_clip) { GtkAllocation block_area, clip; gint num_blocks, i; gint block_width, block_height; gtk_level_bar_get_min_block_size (self, &block_width, &block_height); num_blocks = gtk_level_bar_get_num_blocks (self); if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) { block_width = MAX (block_width, (gint) floor (allocation->width / num_blocks)); block_height = allocation->height; } else { block_width = allocation->width; block_height = MAX (block_height, (gint) floor (allocation->height / num_blocks)); } block_area.x = allocation->x; block_area.y = allocation->y; block_area.width = block_width; block_area.height = block_height; for (i = 0; i < num_blocks; i++) { gtk_css_gadget_allocate (self->priv->block_gadget[i], &block_area, baseline, &clip); gdk_rectangle_intersect (out_clip, &clip, out_clip); if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) block_area.x += block_area.width; else block_area.y += block_area.height; } }
static void gtk_level_bar_measure_trough (GtkCssGadget *gadget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *minimum_baseline, int *natural_baseline, gpointer data) { GtkWidget *widget = gtk_css_gadget_get_owner (gadget); GtkLevelBar *self = GTK_LEVEL_BAR (widget); gint num_blocks, size; gint block_width, block_height; num_blocks = gtk_level_bar_get_num_blocks (self); gtk_level_bar_get_min_block_size (self, &block_width, &block_height); if (orientation == GTK_ORIENTATION_HORIZONTAL) { if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) size = num_blocks * block_width; else size = block_width; } else { if (self->priv->orientation == GTK_ORIENTATION_VERTICAL) size = num_blocks * block_height; else size = block_height; } *minimum = size; *natural = size; }
static void gtk_level_bar_draw_fill_discrete (GtkLevelBar *self, cairo_t *cr, gboolean inverted, cairo_rectangle_int_t *fill_area) { GtkWidget *widget = GTK_WIDGET (self); GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkStateFlags flags = gtk_widget_get_state_flags (widget); gint num_blocks, num_filled, idx; gint block_width, block_height; gint block_draw_width, block_draw_height; GtkBorder block_margin; cairo_rectangle_int_t block_area; gtk_level_bar_get_min_block_size (self, &block_width, &block_height); block_area = *fill_area; num_blocks = gtk_level_bar_get_num_blocks (self); num_filled = (gint) round (self->priv->cur_value) - (gint) round (self->priv->min_value); if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) block_width = MAX (block_width, (gint) floor (block_area.width / num_blocks)); else block_height = MAX (block_height, (gint) floor (block_area.height / num_blocks)); gtk_style_context_save (context); gtk_style_context_add_class (context, STYLE_CLASS_FILL_BLOCK); gtk_style_context_get_margin (context, flags, &block_margin); block_draw_width = block_width - block_margin.left - block_margin.right; block_draw_height = block_height - block_margin.top - block_margin.bottom; if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) { block_draw_height = MAX (block_draw_height, block_area.height - block_margin.top - block_margin.bottom); block_area.y += block_margin.top; if (inverted) block_area.x += block_area.width - block_draw_width; } else { block_draw_width = MAX (block_draw_width, block_area.width - block_margin.left - block_margin.right); block_area.x += block_margin.left; if (inverted) block_area.y += block_area.height - block_draw_height; } for (idx = 0; idx < num_blocks; idx++) { if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) { if (inverted) block_area.x -= block_margin.right; else block_area.x += block_margin.left; } else { if (inverted) block_area.y -= block_margin.bottom; else block_area.y += block_margin.top; } if (idx > num_filled - 1) gtk_style_context_add_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK); gtk_render_background (context, cr, block_area.x, block_area.y, block_draw_width, block_draw_height); gtk_render_frame (context, cr, block_area.x, block_area.y, block_draw_width, block_draw_height); if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL) { if (inverted) block_area.x -= block_draw_width + block_margin.left; else block_area.x += block_draw_width + block_margin.right; } else { if (inverted) block_area.y -= block_draw_height + block_margin.top; else block_area.y += block_draw_height + block_margin.bottom; } } gtk_style_context_restore (context); }