Add the initial version of the water level widget
This commit is contained in:
parent
10cbb64f9a
commit
1ca33bdd9d
@ -1,19 +1,37 @@
|
|||||||
<?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="default-width">600</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="default-height">300</property>
|
<property name="default_width">600</property>
|
||||||
<child type="titlebar">
|
<property name="default_height">300</property>
|
||||||
<object class="GtkHeaderBar" id="header_bar">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="show-close-button">True</property>
|
|
||||||
<property name="title">Water Reminder</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GwrWaterLevel" id="level">
|
<object class="GwrWaterLevel" id="level">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<object class="GtkHeaderBar" id="header_bar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title">Water Reminder</property>
|
||||||
|
<property name="show_close_button">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</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>
|
||||||
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -1,60 +1,207 @@
|
|||||||
#include "gwr-water-level.h"
|
#include "gwr-water-level.h"
|
||||||
|
|
||||||
struct _GwrWaterLevel {
|
struct _GwrWaterLevel {
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
gfloat level;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
self->level = MAX(0, MIN(level, 1.0));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gwr_water_level_draw(GtkWidget *widget, cairo_t *cr)
|
gwr_water_level_draw(GtkWidget *widget, cairo_t *cr)
|
||||||
{
|
{
|
||||||
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
GwrWaterLevel *self = GWR_WATER_LEVEL(widget);
|
||||||
gint width = gtk_widget_get_allocated_width(widget);
|
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||||
gint height = gtk_widget_get_allocated_height(widget);
|
gint width = gtk_widget_get_allocated_width(widget);
|
||||||
GdkRGBA color;
|
gint height = gtk_widget_get_allocated_height(widget);
|
||||||
|
GdkRGBA color;
|
||||||
|
gint left, right;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
cairo_arc(cr, width / 2.0, height / 2.0, MIN(width, height) / 2.0, 0, 2 * G_PI);
|
left = right = width / 2.0;
|
||||||
gtk_style_context_get_color(context, gtk_style_context_get_state(context), &color);
|
left -= 3.0 * height / 8.0;
|
||||||
gdk_cairo_set_source_rgba(cr, &color);
|
right += 3.0 * height / 8.0;
|
||||||
gdk_cairo_set_source_rgba(cr, &color);
|
width = right - left;
|
||||||
cairo_fill (cr);
|
|
||||||
|
|
||||||
return FALSE;
|
cairo_save(cr);
|
||||||
|
|
||||||
|
gint top_left_x = left + (width * 0.1);
|
||||||
|
gint top_y = width * 0.1;
|
||||||
|
gint top_right_x = right - (width * 0.1);
|
||||||
|
gint bottom_right_x = right - (width * 0.2);
|
||||||
|
gint bottom_y = height - (width * 0.1);
|
||||||
|
gint bottom_left_x = left + (width * 0.2);
|
||||||
|
float 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);
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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->finalize = gwr_water_level_finalize;
|
gobject_class->set_property = gwr_water_level_set_property;
|
||||||
widget_class->destroy = gwr_water_level_destroy;
|
gobject_class->get_property = gwr_water_level_get_property;
|
||||||
widget_class->draw = gwr_water_level_draw;
|
gobject_class->finalize = gwr_water_level_finalize;
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@ -8,6 +8,10 @@ G_BEGIN_DECLS
|
|||||||
# 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);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GWR_WATER_LEVEL_H__ */
|
#endif /* __GWR_WATER_LEVEL_H__ */
|
||||||
|
@ -44,5 +44,7 @@ gwr_window_class_init (GwrWindowClass *klass)
|
|||||||
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));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user