[gnome-control-center] Add CcStrengthBar to display a smaller and neater progress bar
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] Add CcStrengthBar to display a smaller and neater progress bar
- Date: Tue, 14 Feb 2012 17:01:41 +0000 (UTC)
commit 5d1b2d60a4c4bb9768ad2134ac4063d3b689ecc9
Author: Richard Hughes <richard hughsie com>
Date: Tue Feb 14 16:47:59 2012 +0000
Add CcStrengthBar to display a smaller and neater progress bar
This will be used in the power and user-accounts panels.
shell/Makefile.am | 2 +
shell/cc-strength-bar.c | 388 +++++++++++++++++++++++++++++++++++++++++++++++
shell/cc-strength-bar.h | 69 +++++++++
3 files changed, 459 insertions(+), 0 deletions(-)
---
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 5912e0c..58117f8 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -29,6 +29,8 @@ gnome_control_center_SOURCES = \
cc-shell-model.h \
cc-editable-entry.c \
cc-editable-entry.h \
+ cc-strength-bar.c \
+ cc-strength-bar.h \
cc-panel.c \
cc-panel.h \
cc-shell.c \
diff --git a/shell/cc-strength-bar.c b/shell/cc-strength-bar.c
new file mode 100644
index 0000000..cf7492f
--- /dev/null
+++ b/shell/cc-strength-bar.c
@@ -0,0 +1,388 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2010-2012 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by:
+ * Matthias Clasen <mclasen redhat com>
+ * Richard Hughes <richard hughsie com>
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "cc-strength-bar.h"
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UM_TYPE_STRENGTH_BAR, CcStrengthBarPrivate))
+
+struct _CcStrengthBarPrivate
+{
+ gdouble fraction;
+ gint segments;
+};
+
+enum {
+ PROP_0,
+ PROP_FRACTION,
+ PROP_SEGMENTS
+};
+
+G_DEFINE_TYPE (CcStrengthBar, cc_strength_bar, GTK_TYPE_WIDGET);
+
+
+static void
+cc_strength_bar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CcStrengthBar *bar = CC_STRENGTH_BAR (object);
+
+ switch (prop_id) {
+ case PROP_FRACTION:
+ cc_strength_bar_set_fraction (bar, g_value_get_double (value));
+ break;
+ case PROP_SEGMENTS:
+ cc_strength_bar_set_segments (bar, g_value_get_int (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+cc_strength_bar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CcStrengthBar *bar = CC_STRENGTH_BAR (object);
+
+ switch (prop_id) {
+ case PROP_FRACTION:
+ g_value_set_double (value, cc_strength_bar_get_fraction (bar));
+ break;
+ case PROP_SEGMENTS:
+ g_value_set_int (value, cc_strength_bar_get_segments (bar));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+curved_rectangle (cairo_t *cr,
+ double x0,
+ double y0,
+ double width,
+ double height,
+ double radius)
+{
+ double x1;
+ double y1;
+
+ x1 = x0 + width;
+ y1 = y0 + height;
+
+ if (!width || !height) {
+ return;
+ }
+
+ if (width / 2 < radius) {
+ if (height / 2 < radius) {
+ cairo_move_to (cr, x0, (y0 + y1) / 2);
+ cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1) / 2, y0);
+ cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+ cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+ cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+ } else {
+ cairo_move_to (cr, x0, y0 + radius);
+ cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
+ cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+ cairo_line_to (cr, x1, y1 - radius);
+ cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+ cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
+ }
+ } else {
+ if (height / 2 < radius) {
+ cairo_move_to (cr, x0, (y0 + y1) / 2);
+ cairo_curve_to (cr, x0, y0, x0 , y0, x0 + radius, y0);
+ cairo_line_to (cr, x1 - radius, y0);
+ cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+ cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+ cairo_line_to (cr, x0 + radius, y1);
+ cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+ } else {
+ cairo_move_to (cr, x0, y0 + radius);
+ cairo_curve_to (cr, x0 , y0 + radius, x0, y0, x0 + radius, y0);
+ cairo_line_to (cr, x1 - radius, y0);
+ cairo_curve_to (cr, x1 - radius, y0, x1, y0, x1, y0 + radius);
+ cairo_line_to (cr, x1, y1 - radius);
+ cairo_curve_to (cr, x1, y1 - radius, x1, y1, x1 - radius, y1);
+ cairo_line_to (cr, x0 + radius, y1);
+ cairo_curve_to (cr, x0 + radius, y1, x0, y1, x0, y1 - radius);
+ }
+ }
+
+ cairo_close_path (cr);
+}
+
+static gboolean
+cc_strength_bar_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ CcStrengthBar *bar = CC_STRENGTH_BAR (widget);
+ const gint padding_end = 3; /* this is the padding at either end */
+ const gint padding_x = 2; /* this is the padding between elements */
+ gboolean ret;
+ GdkRGBA color;
+ GdkRGBA color2;
+ gdouble section_width;
+ gdouble this_width;
+ gint count;
+ gint last_x;
+ gint width, height;
+ GtkStateFlags state;
+ GtkStyleContext *context;
+ guint i;
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_widget_get_state_flags (widget);
+
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+
+ /* clip */
+ cairo_save (cr);
+ cairo_rectangle (cr,
+ 0, 0,
+ width, height);
+ cairo_clip (cr);
+
+ /* get gutter color */
+ ret = gtk_style_context_lookup_color (context,
+ "@base_color",
+ &color);
+ if (!ret) {
+ /* fall back to white */
+ color.alpha = 1.0f;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ }
+
+ /* border */
+ cairo_set_line_width (cr, 1);
+ gdk_cairo_set_source_rgba (cr, &color);
+ curved_rectangle (cr,
+ 0.5, 0.5,
+ width - 1, height - 1, 4);
+ cairo_fill_preserve (cr);
+ gtk_style_context_get_color (context, state, &color);
+ gdk_cairo_set_source_rgba (cr, &color);
+ cairo_stroke (cr);
+
+ /* get color of bar */
+ if (bar->priv->fraction < 0.25) {
+ ret = gtk_style_context_lookup_color (context,
+ "warning_color",
+ &color);
+ if (!ret) {
+ /* fall back to red */
+ color.alpha = 1.0f;
+ color.red = 0.91;
+ color.green = 0.16;
+ color.blue = 0.16;
+ }
+ } else if (bar->priv->fraction > 0.75) {
+ ret = gtk_style_context_lookup_color (context,
+ "success_color",
+ &color);
+ if (!ret) {
+ /* fall back to green */
+ color.alpha = 1.0f;
+ color.red = 0.45;
+ color.green = 0.82;
+ color.blue = 0.09;
+ }
+ } else {
+ ret = gtk_style_context_lookup_color (context,
+ "selected_bg_color",
+ &color);
+ if (!ret) {
+ /* fall back to blue */
+ color.alpha = 1.0f;
+ color.red = 0.44;
+ color.green = 0.62;
+ color.blue = 0.80;
+ }
+ }
+
+ /* make darker background color */
+ color2.alpha = 1.0f;
+ color2.red = color.red / 1.5;
+ color2.green = color.green / 1.5;
+ color2.blue = color.blue / 1.5;
+
+ /* nothing hardcoded, so set a number based on the width */
+ if (bar->priv->segments == -1)
+ bar->priv->segments = width / 30;
+
+ /* print the bar */
+ section_width = (width - (padding_end * 2) + 2) / (gdouble) bar->priv->segments;
+ count = bar->priv->fraction * (gdouble) bar->priv->segments;
+ last_x = -padding_x + padding_end;
+ for (i = 0; i < count; i++) {
+
+ /* do this for each segment as we're clipping to integers
+ * do avoid antialiased lines */
+ this_width = (section_width * (i + 1)) - last_x - padding_x;
+
+ /* lighter line */
+ cairo_set_line_width (cr, 1);
+ gdk_cairo_set_source_rgba (cr, &color);
+ curved_rectangle (cr,
+ last_x + padding_x + 0.5, 3.0 + 0.5,
+ (gint) this_width, height - 7, 4);
+ cairo_fill (cr);
+
+ /* darker line */
+ gdk_cairo_set_source_rgba (cr, &color2);
+ curved_rectangle (cr,
+ last_x + padding_x + 0.5, 3.0 + 0.5,
+ (gint) this_width, height - 7, 4);
+ cairo_stroke (cr);
+
+ /* square off except the start */
+ if (i != 0) {
+ cairo_move_to (cr,
+ last_x + padding_x + 0.5,
+ 3.0 + 0.5);
+ cairo_line_to (cr,
+ last_x + padding_x + 0.5,
+ height - 3);
+ cairo_stroke (cr);
+ }
+
+ /* square off except the end */
+ if (i != bar->priv->segments - 1) {
+ cairo_move_to (cr,
+ last_x + padding_x + (gint) this_width + 0.5,
+ 3.0 + 0.5);
+ cairo_line_to (cr,
+ last_x + padding_x + (gint) this_width + 0.5,
+ height - 3);
+ cairo_stroke (cr);
+ }
+
+ /* increment counter using integers */
+ last_x += (gint) this_width + padding_x;
+ }
+
+ cairo_restore (cr); /* undo clip */
+
+ return FALSE;
+}
+
+static void
+cc_strength_bar_class_init (CcStrengthBarClass *class)
+{
+ GObjectClass *gobject_class;
+ GtkWidgetClass *widget_class;
+
+ gobject_class = (GObjectClass*)class;
+ widget_class = (GtkWidgetClass*)class;
+
+ gobject_class->set_property = cc_strength_bar_set_property;
+ gobject_class->get_property = cc_strength_bar_get_property;
+
+ widget_class->draw = cc_strength_bar_draw;
+
+ g_object_class_install_property (gobject_class,
+ PROP_FRACTION,
+ g_param_spec_double ("fraction",
+ "Fraction",
+ "Fraction",
+ 0.0, 1.0, 0.0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_SEGMENTS,
+ g_param_spec_int ("segments",
+ "Segments",
+ "Segments",
+ -1, 20, -1,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (class, sizeof (CcStrengthBarPrivate));
+}
+
+static void
+cc_strength_bar_init (CcStrengthBar *bar)
+{
+ gtk_widget_set_has_window (GTK_WIDGET (bar), FALSE);
+ gtk_widget_set_size_request (GTK_WIDGET (bar), 120, 9);
+
+ bar->priv = GET_PRIVATE (bar);
+ bar->priv->fraction = 0.0;
+ bar->priv->segments = -1;
+}
+
+GtkWidget *
+cc_strength_bar_new (void)
+{
+ return (GtkWidget*) g_object_new (UM_TYPE_STRENGTH_BAR, NULL);
+}
+
+void
+cc_strength_bar_set_fraction (CcStrengthBar *bar,
+ gdouble fraction)
+{
+ bar->priv->fraction = fraction;
+
+ g_object_notify (G_OBJECT (bar), "fraction");
+
+ if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
+ gtk_widget_queue_draw (GTK_WIDGET (bar));
+}
+
+gdouble
+cc_strength_bar_get_fraction (CcStrengthBar *bar)
+{
+ return bar->priv->fraction;
+}
+
+gint
+cc_strength_bar_get_segments (CcStrengthBar *bar)
+{
+ return bar->priv->segments;
+}
+
+void
+cc_strength_bar_set_segments (CcStrengthBar *bar,
+ gint segments)
+{
+ bar->priv->segments = segments;
+
+ g_object_notify (G_OBJECT (bar), "segments");
+
+ if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
+ gtk_widget_queue_draw (GTK_WIDGET (bar));
+}
diff --git a/shell/cc-strength-bar.h b/shell/cc-strength-bar.h
new file mode 100644
index 0000000..482d2f9
--- /dev/null
+++ b/shell/cc-strength-bar.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2010 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by:
+ * Matthias Clasen <mclasen redhat com>
+ * Richard Hughes <richard hughsie com>
+ */
+
+#ifndef _CC_STRENGTH_BAR_H_
+#define _CC_STRENGTH_BAR_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_STRENGTH_BAR (cc_strength_bar_get_type ())
+#define CC_STRENGTH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_STRENGTH_BAR, \
+ CcStrengthBar))
+#define CC_STRENGTH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_STRENGTH_BAR, \
+ CcStrengthBarClass))
+#define UM_IS_STRENGTH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_STRENGTH_BAR))
+#define UM_IS_STRENGTH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_STRENGTH_BAR))
+#define CC_STRENGTH_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UM_TYPE_STRENGTH_BAR, \
+ CcStrengthBarClass))
+
+typedef struct _CcStrengthBarClass CcStrengthBarClass;
+typedef struct _CcStrengthBar CcStrengthBar;
+typedef struct _CcStrengthBarPrivate CcStrengthBarPrivate;
+
+struct _CcStrengthBarClass {
+ GtkWidgetClass parent_class;
+};
+
+struct _CcStrengthBar {
+ GtkWidget parent_instance;
+ CcStrengthBarPrivate *priv;
+};
+
+GType cc_strength_bar_get_type (void) G_GNUC_CONST;
+
+GtkWidget *cc_strength_bar_new (void);
+
+void cc_strength_bar_set_fraction (CcStrengthBar *bar,
+ gdouble fraction);
+gdouble cc_strength_bar_get_fraction (CcStrengthBar *bar);
+
+void cc_strength_bar_set_segments (CcStrengthBar *bar,
+ gint segments);
+gint cc_strength_bar_get_segments (CcStrengthBar *bar);
+
+G_END_DECLS
+
+#endif /* _CC_STRENGTH_BAR_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]