[recipes] Add a compound timer widget
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Add a compound timer widget
- Date: Sat, 4 Feb 2017 05:10:12 +0000 (UTC)
commit 3d338019916a262a55328ad3e4e6768b708adab2
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Feb 3 07:15:29 2017 +0100
Add a compound timer widget
This is closer to the mockups, although not quite the same.
src/Makefile.am | 2 +
src/gr-time-widget.c | 234 ++++++++++++++++++++++++++++++++++++++++++
src/gr-time-widget.h | 33 ++++++
src/gr-time-widget.ui | 102 ++++++++++++++++++
src/main.c | 2 +
src/recipes-ui.gresource.xml | 1 +
src/recipes.css | 48 +++++++++
7 files changed, 422 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 1714099..feaa315 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -104,6 +104,8 @@ recipes_SOURCES = \
gr-shopping-page.c \
gr-timer.h \
gr-timer.c \
+ gr-time-widget.h \
+ gr-time-widget.c \
gr-timer-widget.h \
gr-timer-widget.c \
gr-toggle-button.h \
diff --git a/src/gr-time-widget.c b/src/gr-time-widget.c
new file mode 100644
index 0000000..bfe02ca
--- /dev/null
+++ b/src/gr-time-widget.c
@@ -0,0 +1,234 @@
+/* gr-time-widget.c:
+ *
+ * Copyright (C) 2017 Matthias Clasen <mclasen redhat com>
+ *
+ * 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/>.
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include "gr-timer.h"
+#include "gr-time-widget.h"
+#include "gr-timer-widget.h"
+
+struct _GrTimeWidget
+{
+ GtkOverlay parent_instance;
+
+ int size;
+ GrTimer *timer;
+ gulong handler;
+
+ GrTimerWidget *timer_widget;
+ GtkWidget *time_remaining;
+ GtkWidget *timer_button_stack;
+ GtkWidget *pause_stack;
+};
+
+G_DEFINE_TYPE (GrTimeWidget, gr_time_widget, GTK_TYPE_OVERLAY)
+
+enum {
+ PROP_0,
+ PROP_TIMER,
+ PROP_SIZE,
+ N_PROPS
+};
+
+GrTimeWidget *
+gr_time_widget_new (void)
+{
+ return g_object_new (GR_TYPE_TIME_WIDGET, NULL);
+}
+
+static void
+remaining_changed (GrTimeWidget *self)
+{
+ guint64 remaining;
+ int seconds;
+ int minutes;
+ int hours;
+ g_autofree char *str = NULL;
+
+ remaining = gr_timer_get_remaining (self->timer);
+ seconds = (int)(remaining / G_TIME_SPAN_SECOND);
+ minutes = seconds / 60;
+ seconds = seconds - 60 * minutes;
+ hours = minutes / 60;
+ minutes = minutes - 60 * hours;
+
+ str = g_strdup_printf ("%02d∶%02d∶%02d", hours, minutes, seconds);
+ gtk_label_set_label (GTK_LABEL (self->time_remaining), str);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+set_timer (GrTimeWidget *self,
+ GrTimer *timer)
+{
+ GrTimer *old = self->timer;
+
+ if (g_set_object (&self->timer, timer)) {
+ if (self->handler) {
+ g_signal_handler_disconnect (old, self->handler);
+ self->handler = 0;
+ }
+ if (timer) {
+ self->handler = g_signal_connect_swapped (timer, "notify::remaining", G_CALLBACK
(remaining_changed), self);
+ remaining_changed (self);
+ }
+ g_object_set (self->timer_widget, "timer", timer, NULL);
+ g_object_notify (G_OBJECT (self), "timer");
+ }
+}
+
+static void
+set_size (GrTimeWidget *self,
+ int size)
+{
+ self->size = size;
+
+ g_object_set (self->timer_widget, "size", size, NULL);
+ g_object_notify (G_OBJECT (self), "size");
+}
+
+static void
+timer_start (GrTimeWidget *self)
+{
+ gr_timer_start (self->timer);
+ gtk_stack_set_visible_child_name (GTK_STACK (self->timer_button_stack), "active");
+ gtk_stack_set_visible_child_name (GTK_STACK (self->pause_stack), "pause");
+}
+
+static void
+timer_pause (GrTimeWidget *self)
+{
+ if (gr_timer_get_active (self->timer)) {
+ gr_timer_stop (self->timer);
+ gtk_stack_set_visible_child_name (GTK_STACK (self->pause_stack), "resume");
+ }
+ else {
+ gr_timer_continue (self->timer);
+ gtk_stack_set_visible_child_name (GTK_STACK (self->pause_stack), "pause");
+ }
+}
+
+static void
+timer_reset (GrTimeWidget *self)
+{
+ gr_timer_reset (self->timer);
+ gtk_stack_set_visible_child_name (GTK_STACK (self->timer_button_stack), "start");
+}
+
+static void
+gr_time_widget_finalize (GObject *object)
+{
+ GrTimeWidget *self = GR_TIME_WIDGET (object);
+
+ if (self->handler)
+ g_signal_handler_disconnect (self->timer, self->handler);
+ g_clear_object (&self->timer);
+
+ G_OBJECT_CLASS (gr_time_widget_parent_class)->finalize (object);
+}
+
+static void
+gr_time_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GrTimeWidget *self = GR_TIME_WIDGET (object);
+
+ switch (prop_id)
+ {
+ case PROP_TIMER:
+ g_value_set_object (value, self->timer);
+ break;
+
+ case PROP_SIZE:
+ g_value_set_int (value, self->size);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gr_time_widget_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GrTimeWidget *self = GR_TIME_WIDGET (object);
+
+ switch (prop_id)
+ {
+ case PROP_TIMER:
+ set_timer (self, g_value_get_object (value));
+ break;
+
+ case PROP_SIZE:
+ set_size (self, g_value_get_int (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gr_time_widget_class_init (GrTimeWidgetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gr_time_widget_finalize;
+ object_class->get_property = gr_time_widget_get_property;
+ object_class->set_property = gr_time_widget_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_TIMER,
+ g_param_spec_object ("timer", NULL, NULL,
+ GR_TYPE_TIMER,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SIZE,
+ g_param_spec_int ("size", NULL, NULL,
+ 1, G_MAXINT, 32,
+ G_PARAM_READWRITE));
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Recipes/gr-time-widget.ui");
+ gtk_widget_class_bind_template_child (widget_class, GrTimeWidget, timer_widget);
+ gtk_widget_class_bind_template_child (widget_class, GrTimeWidget, time_remaining);
+ gtk_widget_class_bind_template_child (widget_class, GrTimeWidget, timer_button_stack);
+ gtk_widget_class_bind_template_child (widget_class, GrTimeWidget, pause_stack);
+
+ gtk_widget_class_bind_template_callback (widget_class, timer_start);
+ gtk_widget_class_bind_template_callback (widget_class, timer_pause);
+ gtk_widget_class_bind_template_callback (widget_class, timer_reset);
+}
+
+static void
+gr_time_widget_init (GrTimeWidget *self)
+{
+ gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->size = 32;
+}
diff --git a/src/gr-time-widget.h b/src/gr-time-widget.h
new file mode 100644
index 0000000..7a9f838
--- /dev/null
+++ b/src/gr-time-widget.h
@@ -0,0 +1,33 @@
+/* gr-time-widget.h:
+ *
+ * Copyright (C) 2017 Matthias Clasen <mclasen redhat com>
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GR_TYPE_TIME_WIDGET (gr_time_widget_get_type())
+
+G_DECLARE_FINAL_TYPE (GrTimeWidget, gr_time_widget, GR, TIME_WIDGET, GtkOverlay)
+
+GrTimeWidget * gr_time_widget_new (void);
+
+G_END_DECLS
diff --git a/src/gr-time-widget.ui b/src/gr-time-widget.ui
new file mode 100644
index 0000000..d7dd856
--- /dev/null
+++ b/src/gr-time-widget.ui
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="recipes">
+ <!-- interface-requires gtk+ 3.10 -->
+ <template class="GrTimeWidget" parent="GtkOverlay">
+ <property name="visible">True</property>
+ <child>
+ <object class="GrTimerWidget" id="timer_widget">
+ <property name="visible">1</property>
+ </object>
+ </child>
+ <child type="overlay">
+ <object class="GtkBox" id="timer_grid">
+ <property name="visible">1</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">20</property>
+ <child>
+ <object class="GtkLabel" id="time_remaining">
+ <property name="visible">1</property>
+ <style>
+ <class name="timer-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="timer_button_stack">
+ <property name="visible">1</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">1</property>
+ <property name="label" translatable="yes">Start</property>
+ <signal name="clicked" handler="timer_start" swapped="yes"/>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="name">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">1</property>
+ <property name="homogeneous">1</property>
+ <property name="spacing">20</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">1</property>
+ <property name="halign">fill</property>
+ <signal name="clicked" handler="timer_pause" swapped="yes"/>
+ <style>
+ <class name="text-button"/>
+ <class name="pause-button"/>
+ </style>
+ <child>
+ <object class="GtkStack" id="pause_stack">
+ <property name="visible">1</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="label" translatable="yes">Pause</property>
+ </object>
+ <packing>
+ <property name="name">pause</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="label" translatable="yes">Continue</property>
+ </object>
+ <packing>
+ <property name="name">resume</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">1</property>
+ <property name="halign">fill</property>
+ <property name="label">Reset</property>
+ <signal name="clicked" handler="timer_reset" swapped="yes"/>
+ <style>
+ <class name="destructive-action"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">active</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/main.c b/src/main.c
index 27d636d..c5315cd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,7 @@
#include "gr-search-page.h"
#include "gr-shopping-page.h"
#include "gr-timer-widget.h"
+#include "gr-time-widget.h"
#include "gr-toggle-button.h"
#include "gr-image-viewer.h"
#include "gr-image-page.h"
@@ -58,6 +59,7 @@ main (int argc, char *argv[])
g_type_ensure (GR_TYPE_SEARCH_PAGE);
g_type_ensure (GR_TYPE_SHOPPING_PAGE);
g_type_ensure (GR_TYPE_TIMER_WIDGET);
+ g_type_ensure (GR_TYPE_TIME_WIDGET);
g_type_ensure (GR_TYPE_TOGGLE_BUTTON);
setlocale (LC_ALL, "");
diff --git a/src/recipes-ui.gresource.xml b/src/recipes-ui.gresource.xml
index ed92828..1d4d00b 100644
--- a/src/recipes-ui.gresource.xml
+++ b/src/recipes-ui.gresource.xml
@@ -20,6 +20,7 @@
<file preprocess="xml-stripblanks">gr-recipe-tile.ui</file>
<file preprocess="xml-stripblanks">gr-search-page.ui</file>
<file preprocess="xml-stripblanks">gr-shopping-page.ui</file>
+ <file preprocess="xml-stripblanks">gr-time-widget.ui</file>
<file preprocess="xml-stripblanks">gr-query-editor.ui</file>
<file preprocess="xml-stripblanks">gr-window.ui</file>
<file preprocess="xml-stripblanks">chef-conflict-dialog.ui</file>
diff --git a/src/recipes.css b/src/recipes.css
index 25ff3f1..bc5ffd9 100644
--- a/src/recipes.css
+++ b/src/recipes.css
@@ -290,3 +290,51 @@ flowbox flowboxchild {
.note.content:backdrop {
background: #cbd6e1;
}
+
+button.osd {
+ padding: 10px;
+}
+
+.cooking {
+ background: black;
+}
+
+.cooking.overlay {
+ background: gray;
+ padding: 40px;
+ border-radius: 20px;
+}
+
+.cooking .heading {
+ font-size: 30px;
+}
+
+.cooking-image {
+ color: #ddd;
+ background: #aaa;
+ min-width: 400px;
+ min-height: 400px;
+}
+
+.timer-label,
+.cooking-label {
+ font-size: 30px;
+ color: #ddd;
+}
+
+.cooking-heading {
+ font-size: 20px;
+ color: #ddd;
+}
+
+.timer-frame border {
+ border: none;
+}
+
+.pause-button {
+ color: #ccc;
+ border-color: #ccc;
+ border-width: 1px;
+ box-shadow: none;
+ background: #444;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]