Compare commits
No commits in common. "master" and "water-level-widget" have entirely different histories.
master
...
water-leve
@ -1,103 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.22.0 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.10"/>
|
|
||||||
<template class="GwrWindow" parent="GtkApplicationWindow">
|
<template class="GwrWindow" parent="GtkApplicationWindow">
|
||||||
<property name="can_focus">False</property>
|
<property name="default-width">600</property>
|
||||||
<property name="default_width">600</property>
|
<property name="default-height">300</property>
|
||||||
<property name="default_height">300</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGrid">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="column_homogeneous">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GwrWaterLevel" id="remaining">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="level">1.0</property>
|
|
||||||
<property name="style">bottle</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GwrWaterLevel" id="level">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="level">0.0</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Remaining</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Hydration level</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="remaining_value">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="current_value">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header_bar">
|
<object class="GtkHeaderBar" id="header_bar">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="show-close-button">True</property>
|
||||||
<property name="title">Water Reminder</property>
|
<property name="title">Water Reminder</property>
|
||||||
<property name="show_close_button">True</property>
|
</object>
|
||||||
<child>
|
</child>
|
||||||
<object class="GtkButton">
|
<child>
|
||||||
<property name="visible">True</property>
|
<object class="GwrWaterLevel" id="level">
|
||||||
<property name="can_focus">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="action_name">win.add</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="icon_name">list-add-symbolic</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
@ -1,5 +1,5 @@
|
|||||||
project('gnome-water-reminder', 'c', version: '0.1.0',
|
project('gnome-water-reminder', 'c', version: '0.1.0',
|
||||||
meson_version: '>= 0.42.0',
|
meson_version: '>= 0.40.0',
|
||||||
)
|
)
|
||||||
|
|
||||||
i18n = import('i18n')
|
i18n = import('i18n')
|
||||||
|
@ -1,282 +1,60 @@
|
|||||||
#include "gwr-water-level.h"
|
#include "gwr-water-level.h"
|
||||||
#include "gwr-enums.h"
|
|
||||||
|
|
||||||
struct _GwrWaterLevel {
|
struct _GwrWaterLevel {
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
gfloat level;
|
|
||||||
GwrWaterLevelStyle style;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* GwrWaterLevel:
|
|
||||||
*
|
|
||||||
* A widget displaying a glass filled with water.
|
|
||||||
*/
|
|
||||||
G_DEFINE_TYPE(GwrWaterLevel, gwr_water_level, GTK_TYPE_WIDGET)
|
G_DEFINE_TYPE(GwrWaterLevel, gwr_water_level, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
PROP_LEVEL,
|
|
||||||
PROP_STYLE,
|
|
||||||
N_PROPS
|
|
||||||
};
|
|
||||||
|
|
||||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gwr_water_level_set_level:
|
|
||||||
* @self: a #GwrWaterLevel object
|
|
||||||
* @level: the level to set
|
|
||||||
*
|
|
||||||
* Set the water level for this object.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gwr_water_level_set_level(GwrWaterLevel *self,
|
|
||||||
gfloat level)
|
|
||||||
{
|
|
||||||
g_debug("Setting level to %.2f", level);
|
|
||||||
|
|
||||||
if (G_UNLIKELY(level > 1.0)) {
|
|
||||||
g_warning("Value (%.2f) is too large. Scaling down to 1.0", level);
|
|
||||||
level = 1.0;
|
|
||||||
} else if (G_UNLIKELY(level < 0.0)) {
|
|
||||||
g_warning("Value (%.2f) is too small. Scaling up to 0.0", level);
|
|
||||||
level = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->level = level;
|
|
||||||
|
|
||||||
gtk_widget_queue_draw(GTK_WIDGET(self));
|
|
||||||
|
|
||||||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_LEVEL]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gwr_water_level_get_level:
|
|
||||||
* @self: a #GwrWaterLevel object
|
|
||||||
*
|
|
||||||
* @returns: the current water level
|
|
||||||
*/
|
|
||||||
gfloat
|
|
||||||
gwr_water_level_get_level(GwrWaterLevel *self)
|
|
||||||
{
|
|
||||||
return self->level;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gwr_water_level_set_style(GwrWaterLevel *self,
|
|
||||||
GwrWaterLevelStyle style)
|
|
||||||
{
|
|
||||||
g_debug("Setting style to %d", style);
|
|
||||||
|
|
||||||
self->style = style;
|
|
||||||
|
|
||||||
gtk_widget_queue_draw(GTK_WIDGET(self));
|
|
||||||
|
|
||||||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_LEVEL]);
|
|
||||||
}
|
|
||||||
|
|
||||||
GwrWaterLevelStyle
|
|
||||||
gwr_water_level_get_style(GwrWaterLevel *self)
|
|
||||||
{
|
|
||||||
return self->style;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gwr_water_level_draw(GtkWidget *widget, cairo_t *cr)
|
gwr_water_level_draw(GtkWidget *widget, cairo_t *cr)
|
||||||
{
|
{
|
||||||
GwrWaterLevel *self = GWR_WATER_LEVEL(widget);
|
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||||
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
gint width = gtk_widget_get_allocated_width(widget);
|
||||||
gint width = gtk_widget_get_allocated_width(widget);
|
gint height = gtk_widget_get_allocated_height(widget);
|
||||||
gint height = gtk_widget_get_allocated_height(widget);
|
GdkRGBA color;
|
||||||
GdkRGBA color;
|
|
||||||
gint left, right, center;
|
|
||||||
gfloat level_y;
|
|
||||||
|
|
||||||
gtk_render_background(context, cr, 0, 0, width, height);
|
gtk_render_background(context, cr, 0, 0, width, height);
|
||||||
gtk_render_frame(context, cr, 0, 0, width, height);
|
gtk_render_frame(context, cr, 0, 0, width, height);
|
||||||
|
|
||||||
center = left = right = width / 2.0;
|
cairo_arc(cr, width / 2.0, height / 2.0, MIN(width, height) / 2.0, 0, 2 * G_PI);
|
||||||
left -= 3.0 * height / 8.0;
|
gtk_style_context_get_color(context, gtk_style_context_get_state(context), &color);
|
||||||
right += 3.0 * height / 8.0;
|
gdk_cairo_set_source_rgba(cr, &color);
|
||||||
width = right - left;
|
gdk_cairo_set_source_rgba(cr, &color);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
gfloat top_y = width * 0.1;
|
return FALSE;
|
||||||
gint bottom_y = height - (width * 0.1);
|
|
||||||
|
|
||||||
cairo_save(cr);
|
|
||||||
switch (self->style) {
|
|
||||||
case GWR_WATER_LEVEL_STYLE_BOTTLE:
|
|
||||||
{
|
|
||||||
gfloat left_x = left + (width * 0.2);
|
|
||||||
gfloat right_x = right - (width * 0.2);
|
|
||||||
|
|
||||||
cairo_move_to(cr, left_x, bottom_y);
|
|
||||||
cairo_line_to(cr, right_x, bottom_y);
|
|
||||||
cairo_line_to(cr, right_x, top_y + (width * 0.2));
|
|
||||||
cairo_line_to(cr, center + (width * 0.1), top_y + (width * 0.1));
|
|
||||||
cairo_line_to(cr, center + (width * 0.1), top_y);
|
|
||||||
cairo_line_to(cr, center - (width * 0.1), top_y);
|
|
||||||
cairo_line_to(cr, center - (width * 0.1), top_y + (width * 0.1));
|
|
||||||
cairo_line_to(cr, left_x, top_y + (width * 0.2));
|
|
||||||
cairo_close_path(cr);
|
|
||||||
cairo_stroke(cr);
|
|
||||||
|
|
||||||
top_y = top_y + (width * 0.2);
|
|
||||||
level_y = top_y + (bottom_y - top_y) * (1.0 - self->level);
|
|
||||||
cairo_rectangle(cr, left_x, level_y, right_x - left_x, bottom_y - level_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
gint top_left_x = left + (width * 0.1);
|
|
||||||
gint top_right_x = right - (width * 0.1);
|
|
||||||
gint bottom_right_x = right - (width * 0.2);
|
|
||||||
gint bottom_left_x = left + (width * 0.2);
|
|
||||||
level_y = top_y + (bottom_y - top_y) * (1.0 - self->level);
|
|
||||||
|
|
||||||
cairo_move_to(cr, top_left_x, top_y);
|
|
||||||
cairo_line_to(cr, top_right_x, top_y);
|
|
||||||
cairo_line_to(cr, bottom_right_x, bottom_y);
|
|
||||||
cairo_line_to(cr, bottom_left_x, bottom_y);
|
|
||||||
cairo_close_path(cr);
|
|
||||||
cairo_stroke(cr);
|
|
||||||
|
|
||||||
cairo_move_to(cr, bottom_right_x, bottom_y);
|
|
||||||
cairo_line_to(cr, bottom_left_x, bottom_y);
|
|
||||||
cairo_line_to(cr, bottom_left_x - ((top_right_x - bottom_right_x) * self->level), level_y);
|
|
||||||
cairo_line_to(cr, bottom_right_x + ((top_right_x - bottom_right_x) * self->level), level_y);
|
|
||||||
cairo_close_path(cr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cairo_restore(cr);
|
|
||||||
|
|
||||||
gtk_style_context_get_color(context, gtk_style_context_get_state(context), &color);
|
|
||||||
|
|
||||||
gdk_cairo_set_source_rgba(cr, &color);
|
|
||||||
cairo_fill (cr);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gwr_water_level_finalize(GObject *gobject)
|
gwr_water_level_finalize(GObject *gobject)
|
||||||
{
|
{
|
||||||
// Here, you free memory that is associated with your instance.
|
// Here, you free memory that is associated with your instance.
|
||||||
//
|
//
|
||||||
// References to other objects should be freed in dispose instead.
|
// References to other objects should be freed in dispose instead.
|
||||||
|
|
||||||
G_OBJECT_CLASS(gwr_water_level_parent_class)->finalize(gobject);
|
G_OBJECT_CLASS(gwr_water_level_parent_class)->finalize(gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gwr_water_level_destroy(GtkWidget *widget)
|
gwr_water_level_destroy(GtkWidget *widget)
|
||||||
{
|
{
|
||||||
// Here you drop references to other objects.
|
// Here you drop references to other objects.
|
||||||
|
|
||||||
GTK_WIDGET_CLASS(gwr_water_level_parent_class)->destroy(widget);
|
GTK_WIDGET_CLASS(gwr_water_level_parent_class)->destroy(widget);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gwr_water_level_get_preferred_height(GtkWidget *widget, gint *minimum_height, gint *natural_height)
|
|
||||||
{
|
|
||||||
if (minimum_height != NULL) {
|
|
||||||
*minimum_height = 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (natural_height != NULL) {
|
|
||||||
*natural_height = 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gwr_water_level_get_preferred_width(GtkWidget *widget, gint *minimum_width, gint *natural_width)
|
|
||||||
{
|
|
||||||
if (minimum_width != NULL) {
|
|
||||||
*minimum_width = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (natural_width != NULL) {
|
|
||||||
*natural_width = 200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gwr_water_level_set_property(GObject *gobject,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_LEVEL:
|
|
||||||
gwr_water_level_set_level(GWR_WATER_LEVEL(gobject), g_value_get_float(value));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case PROP_STYLE:
|
|
||||||
gwr_water_level_set_style(GWR_WATER_LEVEL(gobject), g_value_get_enum(value));
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gwr_water_level_get_property(GObject *gobject,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_LEVEL:
|
|
||||||
g_value_set_float(value, gwr_water_level_get_level(GWR_WATER_LEVEL(gobject)));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case PROP_STYLE:
|
|
||||||
g_value_set_enum(value, gwr_water_level_get_style(GWR_WATER_LEVEL(gobject)));
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gwr_water_level_class_init(GwrWaterLevelClass *klass)
|
gwr_water_level_class_init(GwrWaterLevelClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
|
||||||
|
|
||||||
gobject_class->set_property = gwr_water_level_set_property;
|
gobject_class->finalize = gwr_water_level_finalize;
|
||||||
gobject_class->get_property = gwr_water_level_get_property;
|
widget_class->destroy = gwr_water_level_destroy;
|
||||||
gobject_class->finalize = gwr_water_level_finalize;
|
widget_class->draw = gwr_water_level_draw;
|
||||||
|
|
||||||
widget_class->destroy = gwr_water_level_destroy;
|
|
||||||
widget_class->get_preferred_width = gwr_water_level_get_preferred_width;
|
|
||||||
widget_class->get_preferred_height = gwr_water_level_get_preferred_height;
|
|
||||||
widget_class->draw = gwr_water_level_draw;
|
|
||||||
|
|
||||||
props[PROP_LEVEL] = g_param_spec_float(
|
|
||||||
"level", "level", "The current water level",
|
|
||||||
0.0, 1.0, 0.0,
|
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
|
|
||||||
props[PROP_STYLE] = g_param_spec_enum(
|
|
||||||
"style", "style", "The style of the water level",
|
|
||||||
GWR_TYPE_WATER_LEVEL_STYLE, GWR_WATER_LEVEL_STYLE_GLASS,
|
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
|
|
||||||
g_object_class_install_properties(gobject_class, N_PROPS, props);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gwr_water_level_init(GwrWaterLevel *self)
|
gwr_water_level_init(GwrWaterLevel *self)
|
||||||
{
|
{}
|
||||||
self->level = 0.0;
|
|
||||||
gtk_widget_set_has_window(GTK_WIDGET(self), FALSE);
|
|
||||||
}
|
|
||||||
|
@ -5,21 +5,9 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GWR_WATER_LEVEL_STYLE_GLASS,
|
|
||||||
GWR_WATER_LEVEL_STYLE_BOTTLE
|
|
||||||
} GwrWaterLevelStyle;
|
|
||||||
|
|
||||||
# define GWR_TYPE_WATER_LEVEL (gwr_water_level_get_type())
|
# define GWR_TYPE_WATER_LEVEL (gwr_water_level_get_type())
|
||||||
G_DECLARE_FINAL_TYPE(GwrWaterLevel, gwr_water_level, GWR, WATER_LEVEL, GtkWidget)
|
G_DECLARE_FINAL_TYPE(GwrWaterLevel, gwr_water_level, GWR, WATER_LEVEL, GtkWidget)
|
||||||
|
|
||||||
void gwr_water_level_set_level(GwrWaterLevel *water_level,
|
|
||||||
gfloat level);
|
|
||||||
gfloat gwr_water_level_get_level(GwrWaterLevel *water_level);
|
|
||||||
void gwr_water_level_set_style(GwrWaterLevel *water_level,
|
|
||||||
GwrWaterLevelStyle style);
|
|
||||||
GwrWaterLevelStyle gwr_water_level_get_style(GwrWaterLevel *water_level);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GWR_WATER_LEVEL_H__ */
|
#endif /* __GWR_WATER_LEVEL_H__ */
|
||||||
|
@ -17,34 +17,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gwr-config.h"
|
#include "gwr-config.h"
|
||||||
|
|
||||||
#include <glib/gi18n-lib.h>
|
|
||||||
#include "gwr-window.h"
|
#include "gwr-window.h"
|
||||||
#include "gwr-water-level.h"
|
#include "gwr-water-level.h"
|
||||||
|
|
||||||
struct _GwrWindow
|
struct _GwrWindow
|
||||||
{
|
{
|
||||||
GtkApplicationWindow parent_instance;
|
GtkApplicationWindow parent_instance;
|
||||||
|
|
||||||
/* Template widgets */
|
/* Template widgets */
|
||||||
GtkHeaderBar *header_bar;
|
GtkHeaderBar *header_bar;
|
||||||
GwrWaterLevel *level;
|
GwrWaterLevel *level;
|
||||||
GwrWaterLevel *remaining;
|
|
||||||
|
|
||||||
GtkLabel *remaining_value;
|
|
||||||
GtkLabel *current_value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GwrWindow, gwr_window, GTK_TYPE_APPLICATION_WINDOW)
|
G_DEFINE_TYPE (GwrWindow, gwr_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||||
|
|
||||||
static void gwr_window_add_action(GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static GActionEntry win_entries[] = {
|
|
||||||
{ "add", gwr_window_add_action, NULL, NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gwr_window_class_init (GwrWindowClass *klass)
|
gwr_window_class_init (GwrWindowClass *klass)
|
||||||
{
|
{
|
||||||
@ -53,53 +39,10 @@ gwr_window_class_init (GwrWindowClass *klass)
|
|||||||
gtk_widget_class_set_template_from_resource (widget_class, "/eu/polonkai/gergely/GnomeWaterReminder/gwr-window.ui");
|
gtk_widget_class_set_template_from_resource (widget_class, "/eu/polonkai/gergely/GnomeWaterReminder/gwr-window.ui");
|
||||||
gtk_widget_class_bind_template_child (widget_class, GwrWindow, header_bar);
|
gtk_widget_class_bind_template_child (widget_class, GwrWindow, header_bar);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GwrWindow, level);
|
gtk_widget_class_bind_template_child (widget_class, GwrWindow, level);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GwrWindow, remaining);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GwrWindow, current_value);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GwrWindow, remaining_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
level_changed(GwrWaterLevel *level,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
GwrWindow *self)
|
|
||||||
{
|
|
||||||
gchar *text;
|
|
||||||
GtkLabel *label = (level == self->level) ? self->current_value : self->remaining_value;
|
|
||||||
|
|
||||||
g_debug("level changed");
|
|
||||||
|
|
||||||
text = g_strdup_printf(_("Value: %.0f%%"), gwr_water_level_get_level (level) * 100);
|
|
||||||
gtk_label_set_text(label, text);
|
|
||||||
g_free(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gwr_window_init (GwrWindow *self)
|
gwr_window_init (GwrWindow *self)
|
||||||
{
|
{
|
||||||
g_type_ensure(GWR_TYPE_WATER_LEVEL);
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (self));
|
|
||||||
|
|
||||||
g_action_map_add_action_entries(G_ACTION_MAP(self), win_entries, G_N_ELEMENTS(win_entries), self);
|
|
||||||
|
|
||||||
g_signal_connect(self->level, "notify::level", G_CALLBACK(level_changed), self);
|
|
||||||
g_signal_connect(self->remaining, "notify::level", G_CALLBACK(level_changed), self);
|
|
||||||
|
|
||||||
level_changed(self->level, NULL, self);
|
|
||||||
level_changed(self->remaining, NULL, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gwr_window_add_water(GwrWindow *self)
|
|
||||||
{
|
|
||||||
gwr_water_level_set_level (self->remaining, gwr_water_level_get_level (self->remaining) - 0.1);
|
|
||||||
gwr_water_level_set_level (self->level, gwr_water_level_get_level (self->level) + 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gwr_window_add_action(GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
gwr_window_add_water(GWR_WINDOW(user_data));
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,4 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GwrWindow, gwr_window, GWR, WINDOW, GtkApplicationWindow)
|
G_DECLARE_FINAL_TYPE (GwrWindow, gwr_window, GWR, WINDOW, GtkApplicationWindow)
|
||||||
|
|
||||||
void gwr_window_add_water(GwrWindow *window);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
89
src/main.c
89
src/main.c
@ -17,88 +17,75 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <libnotify/notify.h>
|
|
||||||
|
|
||||||
#include "gwr-config.h"
|
#include "gwr-config.h"
|
||||||
#include "gwr-window.h"
|
#include "gwr-window.h"
|
||||||
|
|
||||||
static void
|
|
||||||
add_some(NotifyNotification *notification,
|
|
||||||
char *action,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GwrWindow *window = GWR_WINDOW(user_data);
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
if (!notify_notification_close(notification, &error)) {
|
|
||||||
g_warning("Could not close notification: %s", error->message);
|
|
||||||
|
|
||||||
g_clear_error(&error);
|
|
||||||
}
|
|
||||||
|
|
||||||
gwr_window_add_water(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
show_notification(gpointer user_data)
|
|
||||||
{
|
|
||||||
NotifyNotification *notification;
|
|
||||||
GwrWindow *window = GWR_WINDOW(user_data);
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
notification = notify_notification_new(_("Remember to drink water!"), NULL, NULL);
|
|
||||||
notify_notification_set_timeout(notification, 5000);
|
|
||||||
notify_notification_add_action(notification, "add", _("I just drank"), add_some, g_object_ref(window), g_object_unref);
|
|
||||||
|
|
||||||
if (!notify_notification_show(notification, &error)) {
|
|
||||||
g_warning("Could not present notification: %s", error->message);
|
|
||||||
g_clear_error(&error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_activate (GtkApplication *app)
|
on_activate (GtkApplication *app)
|
||||||
{
|
{
|
||||||
GtkWindow *window;
|
GtkWindow *window;
|
||||||
|
|
||||||
|
/* It's good practice to check your parameters at the beginning of the
|
||||||
|
* function. It helps catch errors early and in development instead of
|
||||||
|
* by your users.
|
||||||
|
*/
|
||||||
g_assert (GTK_IS_APPLICATION (app));
|
g_assert (GTK_IS_APPLICATION (app));
|
||||||
|
|
||||||
/* Get the current window or create one if necessary. */
|
/* Get the current window or create one if necessary. */
|
||||||
window = gtk_application_get_active_window (app);
|
window = gtk_application_get_active_window (app);
|
||||||
|
if (window == NULL)
|
||||||
if (window == NULL) {
|
window = g_object_new (GWR_TYPE_WINDOW,
|
||||||
window = g_object_new (GWR_TYPE_WINDOW,
|
"application", app,
|
||||||
"application", app,
|
"default-width", 600,
|
||||||
NULL);
|
"default-height", 300,
|
||||||
}
|
NULL);
|
||||||
|
|
||||||
/* Ask the window manager/compositor to present the window. */
|
/* Ask the window manager/compositor to present the window. */
|
||||||
gtk_window_present (window);
|
gtk_window_present (window);
|
||||||
|
|
||||||
g_timeout_add_seconds(3600, show_notification, window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
gint ret;
|
|
||||||
|
|
||||||
g_autoptr(GtkApplication) app = NULL;
|
g_autoptr(GtkApplication) app = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Set up gettext translations */
|
/* Set up gettext translations */
|
||||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
textdomain (GETTEXT_PACKAGE);
|
textdomain (GETTEXT_PACKAGE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new GtkApplication. The application manages our main loop,
|
||||||
|
* application windows, integration with the window manager/compositor, and
|
||||||
|
* desktop features such as file opening and single-instance applications.
|
||||||
|
*/
|
||||||
app = gtk_application_new ("eu.polonkai.gergely.GnomeWaterReminder", G_APPLICATION_FLAGS_NONE);
|
app = gtk_application_new ("eu.polonkai.gergely.GnomeWaterReminder", G_APPLICATION_FLAGS_NONE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We connect to the activate signal to create a window when the application
|
||||||
|
* has been lauched. Additionally, this signal notifies us when the user
|
||||||
|
* tries to launch a "second instance" of the application. When they try
|
||||||
|
* to do that, we'll just present any existing window.
|
||||||
|
*
|
||||||
|
* Because we can't pass a pointer to any function type, we have to cast
|
||||||
|
* our "on_activate" function to a GCallback.
|
||||||
|
*/
|
||||||
g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);
|
g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);
|
||||||
|
|
||||||
notify_init(_("Water Reminder"));
|
/*
|
||||||
|
* Run the application. This function will block until the applicaiton
|
||||||
|
* exits. Upon return, we have our exit code to return to the shell. (This
|
||||||
|
* is the code you see when you do `echo $?` after running a command in a
|
||||||
|
* terminal.
|
||||||
|
*
|
||||||
|
* Since GtkApplication inherits from GApplication, we use the parent class
|
||||||
|
* method "run". But we need to cast, which is what the "G_APPLICATION()"
|
||||||
|
* macro does.
|
||||||
|
*/
|
||||||
|
ret = g_application_run (G_APPLICATION (app), argc, argv);
|
||||||
|
|
||||||
ret = g_application_run (G_APPLICATION (app), argc, argv);
|
return ret;
|
||||||
|
|
||||||
notify_uninit();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,12 @@ gwr_sources = [
|
|||||||
'gwr-water-level.c',
|
'gwr-water-level.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
gwr_enums = gnome.mkenums_simple('gwr-enums', sources: 'gwr-water-level.h')
|
|
||||||
|
|
||||||
gwr_deps = [
|
gwr_deps = [
|
||||||
dependency('gio-2.0', version: '>= 2.50'),
|
dependency('gio-2.0', version: '>= 2.50'),
|
||||||
dependency('gtk+-3.0', version: '>= 3.22'),
|
dependency('gtk+-3.0', version: '>= 3.22'),
|
||||||
dependency('libnotify', version: '>= 0.7'),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
executable('gnome-water-reminder', gwr_sources, gwr_enums,
|
executable('gnome-water-reminder', gwr_sources,
|
||||||
dependencies: gwr_deps,
|
dependencies: gwr_deps,
|
||||||
install: true,
|
install: true,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user