~tristan957/tllt-cp

a0126bd10dd21332538ebcd4cdd91ffbc1adfbd8 — Tristan Partin 1 year, 6 months ago db549b5
Implement the UI for user feedback
M data/tllt-cp-resources.gresource.xml => data/tllt-cp-resources.gresource.xml +1 -0
@@ 1,6 1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/ht/sr/git/tristan957/tllt-cp">
    <file preprocess="xml-stripblanks">ui/tllt-cp-feedback-dialog.ui</file>
    <file preprocess="xml-stripblanks">ui/tllt-cp-login-window.ui</file>
    <file preprocess="xml-stripblanks">ui/tllt-cp-recipe-list-item.ui</file>
    <file preprocess="xml-stripblanks">ui/tllt-cp-new-recipe-window.ui</file>

A data/ui/tllt-cp-feedback-dialog.ui => data/ui/tllt-cp-feedback-dialog.ui +80 -0
@@ 0,0 1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <template class="TlltCpFeedbackDialog" parent="GtkMessageDialog">
    <property name="can_focus">False</property>
    <property name="modal">True</property>
    <property name="window_position">center-on-parent</property>
    <property name="type_hint">dialog</property>
    <property name="skip_taskbar_hint">True</property>
    <property name="skip_pager_hint">True</property>
    <property name="message_type">question</property>
    <property name="text" translatable="yes">How would you like future recipes to turn out?</property>
    <child internal-child="vbox">
      <object class="GtkBox">
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <property name="spacing">2</property>
        <child internal-child="action_area">
          <object class="GtkButtonBox">
            <property name="can_focus">False</property>
            <property name="margin_top">15</property>
            <property name="homogeneous">True</property>
            <property name="layout_style">expand</property>
            <child>
              <object class="GtkButton">
                <property name="label" translatable="yes">Less Toasty</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="on_less_toasty_clicked" object="TlltCpFeedbackDialog" swapped="no"/>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton">
                <property name="label" translatable="yes">The Same</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="on_the_same_clicked" object="TlltCpFeedbackDialog" swapped="no"/>
                <style>
                  <class name="suggested-action"/>
                </style>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton">
                <property name="label" translatable="yes">More Toasty</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="on_more_toasty_clicked" object="TlltCpFeedbackDialog" swapped="no"/>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">0</property>
          </packing>
        </child>
      </object>
    </child>
  </template>
</interface>

M src/meson.build => src/meson.build +1 -0
@@ 1,6 1,7 @@
sources = [
	'main.c',
	'tllt-cp-application.c',
	'tllt-cp-feedback-dialog.c',
	'tllt-cp-login-window.c',
	'tllt-cp-new-recipe-window.c',
	'tllt-cp-recipe-list-item.c',

A src/tllt-cp-feedback-dialog.c => src/tllt-cp-feedback-dialog.c +133 -0
@@ 0,0 1,133 @@
#include <glib-object.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>

#include "tllt-cp-feedback-dialog.h"
#include "tllt-cp.h"

struct _TlltCpFeedbackDialog
{
	GtkMessageDialog parent_instance;
};

typedef struct TlltCpFeedbackDialogPrivate
{
	TlltCpUser *user;
} TlltCpFeedbackDialogPrivate;

G_DEFINE_TYPE_WITH_PRIVATE(TlltCpFeedbackDialog, tllt_cp_feedback_dialog, GTK_TYPE_MESSAGE_DIALOG)

typedef enum TlltCpFeedbackDialogProps
{
	PROP_USER = 1,
	N_PROPS,
} TlltCpFeedbackDialogProps;

static GParamSpec *obj_properties[N_PROPS];

static void
tllt_cp_feedback_dialog_finalize(GObject *obj)
{
	TlltCpFeedbackDialog *self		  = TLLT_CP_FEEDBACK_DIALOG(obj);
	TlltCpFeedbackDialogPrivate *priv = tllt_cp_feedback_dialog_get_instance_private(self);

	g_object_unref(priv->user);

	G_OBJECT_CLASS(tllt_cp_feedback_dialog_parent_class)->finalize(obj);
}

static void
tllt_cp_feedback_dialog_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *pspec)
{
	TlltCpFeedbackDialog *self		  = TLLT_CP_FEEDBACK_DIALOG(obj);
	TlltCpFeedbackDialogPrivate *priv = tllt_cp_feedback_dialog_get_instance_private(self);

	switch (prop_id) {
	case PROP_USER:
		g_value_set_object(val, priv->user);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
	}
}

static void
tllt_cp_feedback_dialog_set_property(GObject *obj, guint prop_id, const GValue *val,
									 GParamSpec *pspec)
{
	TlltCpFeedbackDialog *self		  = TLLT_CP_FEEDBACK_DIALOG(obj);
	TlltCpFeedbackDialogPrivate *priv = tllt_cp_feedback_dialog_get_instance_private(self);

	switch (prop_id) {
	case PROP_USER:
		priv->user = g_value_dup_object(val);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
	}
}

static void
on_less_toasty_clicked(G_GNUC_UNUSED GtkButton *widget, G_GNUC_UNUSED gpointer user_data)
{
	TlltCpFeedbackDialog *self = TLLT_CP_FEEDBACK_DIALOG(user_data);

	g_print("less toasty\n");

	gtk_window_close(GTK_WINDOW(self));
}

static void
on_the_same_clicked(G_GNUC_UNUSED GtkButton *widget, G_GNUC_UNUSED gpointer user_data)
{
	TlltCpFeedbackDialog *self = TLLT_CP_FEEDBACK_DIALOG(user_data);

	g_print("the same\n");

	gtk_window_close(GTK_WINDOW(self));
}

static void
on_more_toasty_clicked(G_GNUC_UNUSED GtkButton *widget, G_GNUC_UNUSED gpointer user_data)
{
	TlltCpFeedbackDialog *self = TLLT_CP_FEEDBACK_DIALOG(user_data);

	g_print("more toasty\n");

	gtk_window_close(GTK_WINDOW(self));
}

static void
tllt_cp_feedback_dialog_class_init(TlltCpFeedbackDialogClass *klass)
{
	GObjectClass *obj_class   = G_OBJECT_CLASS(klass);
	GtkWidgetClass *wid_class = GTK_WIDGET_CLASS(klass);

	obj_class->finalize		= tllt_cp_feedback_dialog_finalize;
	obj_class->get_property = tllt_cp_feedback_dialog_get_property;
	obj_class->set_property = tllt_cp_feedback_dialog_set_property;

	obj_properties[PROP_USER] =
		g_param_spec_object("user", _("User"), _("User providing the feedback"), TLLT_CP_TYPE_USER,
							G_PARAM_PRIVATE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);

	g_object_class_install_properties(obj_class, N_PROPS, obj_properties);

	gtk_widget_class_set_template_from_resource(
		wid_class, "/ht/sr/git/tristan957/tllt-cp/ui/tllt-cp-feedback-dialog.ui");
	gtk_widget_class_bind_template_callback(wid_class, on_less_toasty_clicked);
	gtk_widget_class_bind_template_callback(wid_class, on_the_same_clicked);
	gtk_widget_class_bind_template_callback(wid_class, on_more_toasty_clicked);
}

static void
tllt_cp_feedback_dialog_init(TlltCpFeedbackDialog *self)
{
	gtk_widget_init_template(GTK_WIDGET(self));
}

TlltCpFeedbackDialog *
tllt_cp_feedback_dialog_new(TlltCpUser *user)
{
	return g_object_new(TLLT_CP_TYPE_FEEDBACK_DIALOG, "user", user, NULL);
}

A src/tllt-cp-feedback-dialog.h => src/tllt-cp-feedback-dialog.h +16 -0
@@ 0,0 1,16 @@
#pragma once

#include <glib-object.h>
#include <gtk/gtk.h>

#include "tllt-cp.h"

G_BEGIN_DECLS

#define TLLT_CP_TYPE_FEEDBACK_DIALOG (tllt_cp_feedback_dialog_get_type())
G_DECLARE_FINAL_TYPE(TlltCpFeedbackDialog, tllt_cp_feedback_dialog, TLLT_CP, FEEDBACK_DIALOG,
					 GtkMessageDialog)

TlltCpFeedbackDialog *tllt_cp_feedback_dialog_new(TlltCpUser *user);

G_END_DECLS

M src/tllt-cp-window.c => src/tllt-cp-window.c +3 -1
@@ 3,6 3,7 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>

#include "tllt-cp-feedback-dialog.h"
#include "tllt-cp-login-window.h"
#include "tllt-cp-new-recipe-window.h"
#include "tllt-cp-recipe-list-item.h"


@@ 366,7 367,8 @@ on_toaster_stopped(G_GNUC_UNUSED TlltToaster *toaster, gpointer user_data)
	priv->currently_running_recipe = NULL;

	if (priv->toaster_user != NULL && priv->currently_running_recipe != NULL) {
		g_print("Present user opinion window\n");
		TlltCpFeedbackDialog *dialog = tllt_cp_feedback_dialog_new(priv->toaster_user);
		gtk_dialog_run(GTK_DIALOG(dialog));
	}

	g_object_unref(self);	// Refers to ref when toaster is started