Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • SuborbitalPigeon/rugby
  • webpigeon/rugby
2 results
Show changes
Showing
with 463 additions and 287 deletions
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 2020 Bruce Cowan <bruce@bcowan.me.uk>
SPDX-FileCopyrightText: 2020-2023 Bruce Cowan <bruce@bcowan.me.uk>
SPDX-License-Identifier: GPL-3.0-or-later
-->
......@@ -22,4 +22,16 @@
<description>Number of points for a kick (drop goal or penalty)</description>
</key>
</schema>
<schema id="uk.me.bcowan.Rugby.window" path="/uk/me/bcowan/Rugby/window/">
<key name="height" type="i">
<default>600</default>
<summary>Window height</summary>
<description>The height of the window</description>
</key>
<key name="width" type="i">
<default>400</default>
<summary>Window width</summary>
<description>The width of the window</description>
</key>
</schema>
</schemalist>
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 2023-2024 Bruce Cowan
SPDX-License-Identifier: CC0-1.0
-->
<component type="desktop-application">
<id>uk.me.bcowan.Rugby</id>
<name>Rugby</name>
<developer_name>Bruce Cowan</developer_name>
<summary>Find possibilities for rugby scores</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<supports>
<control>pointing</control>
<control>keyboard</control>
<control>touch</control>
</supports>
<description>
<p>
A program to determine possible combinations of scoring for rugby matches.
</p>
</description>
<launchable type="desktop-id">uk.me.bcowan.Rugby.desktop</launchable>
<icon type="stock">rugby</icon>
<categories>
<category>Utility</category>
<category>GNOME</category>
</categories>
<provides>
<binary>rugby</binary>
</provides>
</component>
// SPDX-FileCopyrightText: 2022 Bruce Cowan <bruce@bcowan.me.uk>
//
// SPDX-License-Identifier: GPL-3.0-or-later
using Gtk 4.0;
using Adw 1;
template RugbyAppWindow : Adw.ApplicationWindow {
title: "Rugby";
default-height: 600;
default-width: 400;
Box {
orientation: vertical;
Adw.HeaderBar {
SpinButton scorespin {
adjustment: Adjustment {
step-increment: 1;
upper: 200;
};
focusable: true;
tooltip-text: "Score";
}
[end]
MenuButton menu_button {
direction: none;
menu-model: app_menu;
tooltip-text: "Main Menu";
}
}
ScrolledWindow {
vexpand: true;
Adw.ClampScrollable {
maximum-size: 600;
ListView listview {
styles ["rich-list"]
model: NoSelection {
model: .RugbyListStore {
score: bind scorespin.value;
};
};
factory: BuilderListItemFactory {
resource: "/uk/me/bcowan/Rugby/score-item.ui";
};
}
}
}
}
}
menu app_menu {
section {
item ("_Preferences", "app.prefs")
item ("_Keyboard Shortcuts", "win.show-help-overlay")
item ("_About Rugby", "app.about")
}
}
# SPDX-FileCopyrightText: 2016-2022 Bruce Cowan <bruce@bcowan.me.uk>
# SPDX-FileCopyrightText: 2016-2024 Bruce Cowan <bruce@bcowan.me.uk>
#
# SPDX-License-Identifier: GPL-3.0-or-later
project('rugby', 'c',
version: '0.4.alpha',
license:'GPLv3+',
meson_version: '>= 0.57.0',
meson_version: '>= 1.1.0',
default_options: [
'buildtype=debugoptimized',
'c_std=gnu11',
......@@ -18,36 +18,25 @@ desktopdir = datadir / 'applications'
gnome = import('gnome')
gio_dep = dependency('gio-2.0', version: '>= 2.66')
gtk_dep = dependency('gtk4', version: '>= 4.0')
libadwaita_dep = dependency('libadwaita-1')
gio_dep = dependency('gio-2.0', version: '>= 2.76')
gtk_dep = dependency('gtk4', version: '>= 4.12')
libadwaita_dep = dependency('libadwaita-1', version: '>=1.5.beta')
conf = configuration_data()
conf.set_quoted('VERSION','@VCS_TAG@')
devel = get_option('development')
conf.set10('DEVELOPMENT', devel)
profile = get_option('profile')
conf.set_quoted('PROFILE', profile)
if devel
if profile == 'development'
conf.set_quoted('VERSION', '@0@-@VCS_TAG@'.format(meson.project_version()))
else
conf.set_quoted('VERSION', meson.project_version())
endif
config_h = vcs_tag(
input: configure_file(
output: 'config.h.in',
configuration: conf
),
output: 'config.h',
command: ['git', 'rev-parse', '--short', 'HEAD'],
fallback: devel ? 'devel' : '',
)
cflags = ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_66',
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_66',
'-DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_4_0',
'-DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_4_0',
cflags = ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_70',
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_70',
'-DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_4_12',
'-DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_4_12',
'-Wno-overlength-strings',
]
......@@ -59,4 +48,7 @@ add_project_arguments(cc.get_supported_arguments(cflags),
subdir('data')
subdir('src')
gnome.post_install(glib_compile_schemas: true)
gnome.post_install(
glib_compile_schemas: true,
update_desktop_database: true,
)
......@@ -2,4 +2,10 @@
#
# SPDX-License-Identifier: CC0-1.0
option('development', type: 'boolean', value: true, description: 'Is this a development build?')
option(
'profile',
type: 'combo',
choices: ['default', 'development'],
value: 'default',
description: 'What sort of build is this?'
)
/*
* SPDX-FileCopyrightText: 2012-2022 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2012-2024 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <config.h>
#include "rugby-app-window.h"
#include "rugby-pref-window.h"
static GtkWidget *window = NULL;
#include "rugby-pref-dialog.h"
static void
on_activate ( GApplication *app,
G_GNUC_UNUSED gpointer user_data)
G_GNUC_UNUSED void *user_data)
{
g_assert (GTK_IS_APPLICATION (app));
GtkWindow *window = gtk_application_get_active_window (GTK_APPLICATION (app));
if (!window)
window = GTK_WIDGET (rugby_app_window_new (GTK_APPLICATION (app)));
window = GTK_WINDOW (rugby_app_window_new (GTK_APPLICATION (app)));
if (DEVELOPMENT)
if (g_strcmp0 (PROFILE, "development") == 0)
gtk_widget_add_css_class (GTK_WIDGET (window), "devel");
gtk_window_present (GTK_WINDOW (window));
......@@ -26,37 +27,34 @@ on_activate ( GApplication *app,
static void
about_activated (G_GNUC_UNUSED GSimpleAction *simple,
G_GNUC_UNUSED GVariant *parameter,
gpointer user_data)
void *user_data)
{
GtkApplication *app = GTK_APPLICATION (user_data);
GtkWindow *window = gtk_application_get_active_window (app);
adw_show_about_window (window,
"application-icon", "face-wink",
"application-name", "Rugby",
"copyright", "Copyright 2012–2022 Bruce Cowan",
"license-type", GTK_LICENSE_GPL_3_0,
"developer-name", "Bruce Cowan",
"comments", "Rugby scores possibilities program",
"version", VERSION,
NULL);
adw_show_about_dialog_from_appdata (GTK_WIDGET (window),
"uk/me/bcowan/Rugby/uk.me.bcowan.Rugby.metainfo.xml",
NULL,
"application-icon", "football-american",
"version", VERSION,
NULL);
}
static void
preferences_activated (G_GNUC_UNUSED GSimpleAction *simple,
G_GNUC_UNUSED GVariant *parameter,
gpointer user_data)
void *user_data)
{
GtkApplication *app = GTK_APPLICATION (user_data);
GtkWindow *window = gtk_application_get_active_window (app);
RugbyPrefWindow *pref_window = rugby_pref_window_new (RUGBY_APP_WINDOW (window));
gtk_window_present (GTK_WINDOW (pref_window));
RugbyPrefDialog *pref_window = rugby_pref_dialog_new ();
adw_dialog_present (ADW_DIALOG (pref_window), GTK_WIDGET (window));
}
static void
on_startup (GApplication *app,
G_GNUC_UNUSED gpointer user_data)
on_startup ( GApplication *app,
G_GNUC_UNUSED void *user_data)
{
const GActionEntry app_entries[] =
{
......@@ -68,18 +66,9 @@ on_startup (GApplication *app,
app_entries,
G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"win.show-primary-menu",
(const char*[]) { "F10", NULL });
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.prefs",
(const char*[]) { "<Ctrl>comma", NULL });
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"win.score-changed::up",
(const char*[]) { "<Ctrl>Up", "<Ctrl>Right", NULL });
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"win.score-changed::down",
(const char*[]) { "<Ctrl>Down", "<Ctrl>Left", NULL });
}
int
......@@ -87,7 +76,7 @@ main (int argc,
char **argv)
{
g_autoptr (AdwApplication) app = adw_application_new ("uk.me.bcowan.Rugby",
G_APPLICATION_FLAGS_NONE);
G_APPLICATION_NON_UNIQUE);
g_signal_connect (app, "startup",
G_CALLBACK (on_startup), NULL);
......
# SPDX-FileCopyrightText: 2016-2022 Bruce Cowan <bruce@bcowan.me.uk>
# SPDX-FileCopyrightText: 2016-2024 Bruce Cowan <bruce@bcowan.me.uk>
#
# SPDX-License-Identifier: GPL-3.0-or-later
sources = [
......@@ -7,11 +7,21 @@ sources = [
'rugby-list-store.c',
'rugby-possibility.c',
'rugby-possibility-widget.c',
'rugby-pref-window.c',
'rugby-pref-dialog.c',
]
config_h = vcs_tag(
input: configure_file(
output: 'config.h.in',
configuration: conf,
),
output: 'config.h',
command: ['git', 'rev-parse', '--short', 'HEAD'],
fallback: (profile == 'development') ? 'devel' : '',
)
executable('rugby',
sources, config_h, resources, compiled_schemas,
sources, config_h, resources,
dependencies: [gio_dep, gtk_dep, libadwaita_dep],
install_dir: get_option('bindir'),
install: true)
/*
* SPDX-FileCopyrightText: 2017-2022 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2017-2024 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <config.h>
#include "config.h"
#include "rugby-app-window.h"
#include "rugby-list-store.h"
#include "rugby-possibility.h"
#include "rugby-possibility-widget.h"
#include <glib/gi18n.h>
......@@ -17,10 +18,26 @@ struct _RugbyAppWindow
AdwApplicationWindow parent;
GtkWidget *scorespin;
GtkWidget *menu_button;
GtkWidget *stack;
GSettings *win_settings;
};
G_DEFINE_TYPE (RugbyAppWindow, rugby_app_window, ADW_TYPE_APPLICATION_WINDOW)
G_DEFINE_FINAL_TYPE (RugbyAppWindow, rugby_app_window, ADW_TYPE_APPLICATION_WINDOW)
static void
list_store_items_changed_cb ( GListModel *model,
G_GNUC_UNUSED unsigned position,
G_GNUC_UNUSED unsigned removed,
G_GNUC_UNUSED unsigned added,
RugbyAppWindow *self)
{
unsigned n_items = g_list_model_get_n_items (model);
if (n_items == 0)
gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "empty_page");
else
gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "list_page");
}
static char *
item_tooltip_cb (GtkListItem *item)
......@@ -29,54 +46,59 @@ item_tooltip_cb (GtkListItem *item)
if (!possibility)
return NULL;
int tries, utries, kicks;
GString *tooltip = g_string_new (NULL);
g_object_get (possibility,
"tries", &tries,
"utries", &utries,
"kicks", &kicks,
NULL);
int tries = rugby_possibility_get_tries (possibility);
int utries = rugby_possibility_get_utries (possibility);
int kicks = rugby_possibility_get_kicks (possibility);
if (tries > 0 && utries == 0)
if (tries > 0)
{
g_string_printf (tooltip, ngettext ("%d converted try",
"%d converted tries",
tries),
tries);
}
else if (utries > 0 && tries == 0)
{
g_string_printf (tooltip, ngettext ("%d unconverted try",
"%d unconverted tries",
utries),
utries);
}
else if (tries + utries > 0)
if (utries > 0)
{
g_string_printf (tooltip, ngettext ("%d try, %d converted",
"%d tries, %d converted",
tries + utries),
tries + utries, tries);
}
if (tooltip->len > 0)
g_string_append (tooltip, ", ");
g_string_append_printf (tooltip, ngettext ("%d unconverted try",
"%d unconverted tries",
utries),
utries);
}
if (kicks > 0)
{
if (tries > 0 || utries > 0)
g_string_append_printf (tooltip, ", ");
if (tooltip->len > 0)
g_string_append (tooltip, ", ");
g_string_append_printf (tooltip,
ngettext ("%d kick", "%d kicks", kicks),
kicks);
g_string_append_printf (tooltip, ngettext ("%d kick",
"%d kicks",
kicks),
kicks);
}
return g_string_free (tooltip, FALSE);
}
static char *
header_label_cb (GtkListItem *item)
{
RugbyPossibility *possibility = gtk_list_header_get_item (GTK_LIST_HEADER (item));
if (!possibility)
return NULL;
int total_tries = rugby_possibility_total_tries (possibility);
return g_strdup_printf (ngettext ("%d try", "%d tries", total_tries), total_tries);
}
static void
activate_score_changed (G_GNUC_UNUSED GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
void *user_data)
{
RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data);
......@@ -92,45 +114,57 @@ activate_score_changed (G_GNUC_UNUSED GSimpleAction *action,
}
static void
activate_show_primary_menu (G_GNUC_UNUSED GSimpleAction *action,
G_GNUC_UNUSED GVariant *parameter,
gpointer user_data)
rugby_app_window_dispose (GObject *object)
{
RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data);
gtk_menu_button_popup (GTK_MENU_BUTTON (self->menu_button));
}
gtk_widget_dispose_template (GTK_WIDGET (object), RUGBY_TYPE_APP_WINDOW);
g_clear_object (&RUGBY_APP_WINDOW (object)->win_settings);
const GActionEntry win_entries[] = {
{ .name = "score-changed", .activate = activate_score_changed, .parameter_type = "s" },
{ .name = "show-primary-menu", .activate = activate_show_primary_menu },
};
G_OBJECT_CLASS (rugby_app_window_parent_class)->dispose (object);
}
static void
rugby_app_window_init (RugbyAppWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
const GActionEntry win_entries[] = {
{ .name = "score-changed", .activate = activate_score_changed, .parameter_type = "s" },
};
g_action_map_add_action_entries (G_ACTION_MAP (self),
win_entries,
G_N_ELEMENTS (win_entries),
self);
self->win_settings = g_settings_new ("uk.me.bcowan.Rugby.window");
g_settings_bind (self->win_settings, "height",
self, "default-height",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (self->win_settings, "width",
self, "default-width",
G_SETTINGS_BIND_DEFAULT);
}
static void
rugby_app_window_class_init (RugbyAppWindowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
g_type_ensure (RUGBY_TYPE_POSSIBILITY_WIDGET);
g_type_ensure (RUGBY_TYPE_LIST_STORE);
object_class->dispose = rugby_app_window_dispose;
gtk_widget_class_set_template_from_resource (widget_class,
"/uk/me/bcowan/Rugby/window.ui");
"/uk/me/bcowan/Rugby/gtk/window.ui");
gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, scorespin);
gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, menu_button);
gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, stack);
gtk_widget_class_bind_template_callback (widget_class, header_label_cb);
gtk_widget_class_bind_template_callback (widget_class, item_tooltip_cb);
gtk_widget_class_bind_template_callback (widget_class, list_store_items_changed_cb);
}
RugbyAppWindow *
......
......@@ -14,6 +14,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (RugbyAppWindow, rugby_app_window, RUGBY, APP_WINDOW, AdwApplicationWindow)
RugbyAppWindow * rugby_app_window_new (GtkApplication *app);
RugbyAppWindow *rugby_app_window_new (GtkApplication *app);
G_END_DECLS
/*
* SPDX-FileCopyrightText: 2018-2022 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2018-2024 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
......@@ -9,6 +9,7 @@
#include "rugby-possibility.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
struct _RugbyListStore
{
......@@ -21,10 +22,14 @@ struct _RugbyListStore
};
static void rugby_list_store_list_model_iface_init (GListModelInterface *iface);
static void rugby_list_store_section_model_iface_init (GtkSectionModelInterface *iface);
G_DEFINE_FINAL_TYPE_WITH_CODE (RugbyListStore, rugby_list_store, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
rugby_list_store_list_model_iface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SECTION_MODEL,
rugby_list_store_section_model_iface_init))
G_DEFINE_TYPE_WITH_CODE (RugbyListStore, rugby_list_store, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
rugby_list_store_list_model_iface_init))
enum
{
......@@ -37,21 +42,14 @@ static GParamSpec *properties[N_PROPS];
// Helper functions
static int
sort_func ( gconstpointer a,
gconstpointer b,
G_GNUC_UNUSED gpointer user_data)
sort_func ( gconstpointer a,
gconstpointer b,
G_GNUC_UNUSED void *user_data)
{
int atries, autries;
int btries, butries;
g_object_get ((gpointer) a,
"tries", &atries,
"utries", &autries,
NULL);
g_object_get ((gpointer) b,
"tries", &btries,
"utries", &butries,
NULL);
int atries = rugby_possibility_get_tries ((void *) a);
int autries = rugby_possibility_get_utries ((void *) a);
int btries = rugby_possibility_get_tries ((void *) b);
int butries = rugby_possibility_get_utries ((void *) b);
int trydiff = (btries + butries) - (atries + autries);
......@@ -72,6 +70,12 @@ process_data (RugbyListStore *self)
unsigned old_length = g_list_model_get_n_items (G_LIST_MODEL (self->items));
g_list_store_remove_all (self->items);
if (self->score == 0)
{
g_list_model_items_changed (G_LIST_MODEL (self), 0, old_length, 0);
return;
}
int max_tries = self->score / try_points;
int max_utries = self->score / utry_points;
......@@ -118,7 +122,7 @@ rugby_list_store_get_n_items (GListModel *list)
return g_list_model_get_n_items (G_LIST_MODEL (self->items));
}
static gpointer
static void *
rugby_list_store_get_item (GListModel *list,
unsigned position)
{
......@@ -135,6 +139,63 @@ rugby_list_store_list_model_iface_init (GListModelInterface *iface)
iface->get_item = rugby_list_store_get_item;
}
// SectionModel implementation
static void
rugby_list_store_get_section (GtkSectionModel *model,
unsigned position,
unsigned *out_start,
unsigned *out_end)
{
RugbyListStore *self = RUGBY_LIST_STORE (model);
unsigned n_items = g_list_model_get_n_items (G_LIST_MODEL (self->items));
RugbyPossibility *possibility = g_list_model_get_item (G_LIST_MODEL (self->items),
position);
if (!possibility)
{
*out_start = n_items;
*out_end = G_MAXUINT;
return;
}
int target_tries = rugby_possibility_total_tries (possibility);
// Find start
for (unsigned i = 0; i < n_items; i++)
{
possibility = g_list_model_get_item (G_LIST_MODEL (self->items), i);
int total = rugby_possibility_total_tries (possibility);
if (total == target_tries)
{
*out_start = i;
break;
}
}
// Find end
for (unsigned i = *out_start + 1; i < n_items; i++)
{
possibility = g_list_model_get_item (G_LIST_MODEL (self->items), i);
int total = rugby_possibility_total_tries (possibility);
if (total != target_tries)
{
*out_end = i;
return;
}
}
*out_end = n_items;
}
static void
rugby_list_store_section_model_iface_init (GtkSectionModelInterface *iface)
{
iface->get_section = rugby_list_store_get_section;
}
// Class functions
static void
......@@ -159,7 +220,7 @@ rugby_list_store_get_property (GObject *object,
switch (prop_id)
{
case PROP_SCORE:
g_value_set_int (value, rugby_list_store_get_score (self));
g_value_set_int (value, self->score);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -176,8 +237,15 @@ rugby_list_store_set_property (GObject *object,
switch (prop_id)
{
int score;
case PROP_SCORE:
rugby_list_store_set_score (self, g_value_get_int (value));
score = g_value_get_int (value);
if (score != self->score)
{
self->score = score;
process_data (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SCORE]);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -195,7 +263,7 @@ rugby_list_store_class_init (RugbyListStoreClass *klass)
properties[PROP_SCORE] = g_param_spec_int ("score", "", "",
0, 200, 0,
G_PARAM_READWRITE);
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class,
N_PROPS,
......@@ -218,26 +286,3 @@ rugby_list_store_init (RugbyListStore *self)
self->items = g_list_store_new (RUGBY_TYPE_POSSIBILITY);
}
// Public functions
int
rugby_list_store_get_score (RugbyListStore *self)
{
g_assert (RUGBY_IS_LIST_STORE (self));
return self->score;
}
void
rugby_list_store_set_score (RugbyListStore *self,
int score)
{
g_assert (RUGBY_IS_LIST_STORE (self));
if (score != self->score)
{
self->score = score;
process_data (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SCORE]);
}
}
/*
* SPDX-FileCopyrightText: 2018-2022 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
......@@ -10,10 +11,7 @@
G_BEGIN_DECLS
#define RUGBY_TYPE_LIST_STORE (rugby_list_store_get_type())
G_DECLARE_FINAL_TYPE (RugbyListStore, rugby_list_store, RUGBY, LIST_STORE, GObject)
int rugby_list_store_get_score (RugbyListStore *self);
void rugby_list_store_set_score (RugbyListStore *self,
int score);
G_DECLARE_FINAL_TYPE (RugbyListStore, rugby_list_store, RUGBY, LIST_STORE, GObject)
G_END_DECLS
/*
* SPDX-FileCopyrightText: 2018-2022 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2018-2024 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <config.h>
#include "config.h"
#include "rugby-possibility-widget.h"
#include <adwaita.h>
#include "rugby-possibility.h"
#include "rugby-possibility-widget.h"
#include <adwaita.h>
struct _RugbyPossibilityWidget
{
......@@ -18,7 +19,7 @@ struct _RugbyPossibilityWidget
RugbyPossibility *possibility;
};
G_DEFINE_TYPE (RugbyPossibilityWidget, rugby_possibility_widget, GTK_TYPE_WIDGET)
G_DEFINE_FINAL_TYPE (RugbyPossibilityWidget, rugby_possibility_widget, GTK_TYPE_WIDGET)
enum
{
......@@ -76,12 +77,12 @@ rugby_possibility_widget_set_property (GObject *object,
}
static void
render_bar (GtkWidget *widget,
GtkSnapshot *snapshot,
float x,
float w,
float h,
const GdkRGBA rgba)
render_bar (GtkSnapshot *snapshot,
float x,
float w,
float h,
const GdkRGBA fill,
const GdkRGBA border)
{
graphene_rect_t area = GRAPHENE_RECT_INIT (x, 0.0, w, h);
......@@ -92,21 +93,17 @@ render_bar (GtkWidget *widget,
gtk_snapshot_push_rounded_clip (snapshot, &rounded);
gtk_snapshot_append_color (snapshot,
&rgba,
&fill,
&area);
gtk_snapshot_pop (snapshot);
GtkStyleContext *ctx = gtk_widget_get_style_context (widget);
GdkRGBA border_colour;
gtk_style_context_lookup_color (ctx, "card_fg_color", &border_colour);
gtk_snapshot_append_border (snapshot,
&rounded,
(float[]) { 2.0, 2.0, 2.0, 2.0 },
(GdkRGBA[]) { border_colour,
border_colour,
border_colour,
border_colour });
(GdkRGBA[]) { border,
border,
border,
border });
}
static void
......@@ -123,41 +120,46 @@ rugby_possibility_widget_snapshot (GtkWidget *widget,
int height = gtk_widget_get_height (widget);
float x = 0.0;
int tries, utries, kicks;
g_object_get (self->possibility,
"tries", &tries,
"utries", &utries,
"kicks", &kicks,
NULL);
int tries = rugby_possibility_get_tries (self->possibility);
int utries = rugby_possibility_get_utries (self->possibility);
int kicks = rugby_possibility_get_kicks (self->possibility);
int score = tries * try_points + utries * utry_points + kicks * kick_points;
GtkStyleContext *ctx = gtk_widget_get_style_context (widget);
GdkRGBA rgba;
GdkRGBA fill;
GdkRGBA border;
AdwStyleManager *manager = adw_style_manager_get_default ();
if (adw_style_manager_get_dark (manager))
gdk_rgba_parse (&border, "white");
else
gdk_rgba_parse (&border, "black");
// Tries
float w = width / (score / (float) try_points);
gdk_rgba_parse (&fill, "#33d17a"); // Green 3
for (int i = 0; i < tries; i++)
{
gtk_style_context_lookup_color (ctx, "green_3", &rgba);
render_bar (widget, snapshot, x, w, height, rgba);
render_bar (snapshot, x, w, height, fill, border);
x += w;
}
// Unconverted tries
w = width / (score / (float) utry_points);
gdk_rgba_parse (&fill, "#f6d32d"); // Yellow 3
for (int i = 0; i < utries; i++)
{
gtk_style_context_lookup_color (ctx, "red_3", &rgba);
render_bar (widget, snapshot, x, w, height, rgba);
render_bar (snapshot, x, w, height, fill, border);
x += w;
}
// Unconverted kicks
// Kicks
w = width / (score / (float) kick_points);
gdk_rgba_parse (&fill, "#e01b24"); // Red 3
for (int i = 0; i < kicks; i++)
{
gtk_style_context_lookup_color (ctx, "yellow_3", &rgba);
render_bar (widget, snapshot, x, w, height, rgba);
render_bar (snapshot, x, w, height, fill, border);
x += w;
}
}
......@@ -177,7 +179,7 @@ rugby_possibility_widget_class_init (RugbyPossibilityWidgetClass *klass)
properties[PROP_POSSIBILITY] =
g_param_spec_object ("possibility", "", "",
RUGBY_TYPE_POSSIBILITY,
G_PARAM_READWRITE);
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class,
N_PROPS,
......
......@@ -8,8 +8,6 @@
#include <gtk/gtk.h>
#include "rugby-possibility.h"
G_BEGIN_DECLS
#define RUGBY_TYPE_POSSIBILITY_WIDGET (rugby_possibility_widget_get_type())
......
/*
* SPDX-FileCopyrightText: 2018-2021 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2018-2024 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
......@@ -16,7 +16,7 @@ struct _RugbyPossibility
int kicks;
};
G_DEFINE_TYPE (RugbyPossibility, rugby_possibility, G_TYPE_OBJECT)
G_DEFINE_FINAL_TYPE (RugbyPossibility, rugby_possibility, G_TYPE_OBJECT)
enum
{
......@@ -39,13 +39,13 @@ rugby_possibility_get_property (GObject *object,
switch (prop_id)
{
case PROP_TRIES:
g_value_set_int (value, self->tries);
g_value_set_int (value, rugby_possibility_get_tries (self));
break;
case PROP_UTRIES:
g_value_set_int (value, self->utries);
g_value_set_int (value, rugby_possibility_get_utries (self));
break;
case PROP_KICKS:
g_value_set_int (value, self->kicks);
g_value_set_int (value, rugby_possibility_get_kicks (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -87,15 +87,15 @@ rugby_possibility_class_init (RugbyPossibilityClass *klass)
properties[PROP_TRIES] =
g_param_spec_int ("tries", "", "",
0, 200, 0,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_UTRIES] =
g_param_spec_int ("utries", "", "",
0, 200, 0,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_KICKS] =
g_param_spec_int ("kicks", "", "",
0, 200, 0,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class,
N_PROPS,
......@@ -119,3 +119,35 @@ rugby_possibility_new (int tries,
"kicks", kicks,
NULL);
}
int
rugby_possibility_get_tries (RugbyPossibility *self)
{
g_assert (RUGBY_IS_POSSIBILITY (self));
return self->tries;
}
int
rugby_possibility_get_utries (RugbyPossibility *self)
{
g_assert (RUGBY_IS_POSSIBILITY (self));
return self->utries;
}
int
rugby_possibility_get_kicks (RugbyPossibility *self)
{
g_assert (RUGBY_IS_POSSIBILITY (self));
return self->kicks;
}
int
rugby_possibility_total_tries (RugbyPossibility *self)
{
g_assert (RUGBY_IS_POSSIBILITY (self));
return self->tries + self->utries;
}
/*
* SPDX-FileCopyrightText: 2018 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2018-2024 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
......@@ -13,8 +14,14 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (RugbyPossibility, rugby_possibility, RUGBY, POSSIBILITY, GObject)
RugbyPossibility * rugby_possibility_new (int tries,
int utries,
int kicks);
RugbyPossibility *rugby_possibility_new (int tries,
int utries,
int kicks);
int rugby_possibility_get_tries (RugbyPossibility *self);
int rugby_possibility_get_utries (RugbyPossibility *self);
int rugby_possibility_get_kicks (RugbyPossibility *self);
int rugby_possibility_total_tries (RugbyPossibility *self);
G_END_DECLS
......@@ -4,11 +4,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "rugby-pref-window.h"
#include "rugby-pref-dialog.h"
struct _RugbyPrefWindow
struct _RugbyPrefDialog
{
AdwPreferencesWindow parent_instance;
AdwPreferencesDialog parent_instance;
GtkWidget *try_spin;
GtkWidget *utry_spin;
......@@ -17,37 +17,37 @@ struct _RugbyPrefWindow
GSettings *settings;
};
G_DEFINE_TYPE (RugbyPrefWindow, rugby_pref_window, ADW_TYPE_PREFERENCES_WINDOW)
G_DEFINE_FINAL_TYPE (RugbyPrefDialog, rugby_pref_dialog, ADW_TYPE_PREFERENCES_DIALOG)
static void
rugby_pref_window_dispose (GObject *object)
rugby_pref_dialog_dispose (GObject *object)
{
RugbyPrefWindow *self = RUGBY_PREF_WINDOW (object);
RugbyPrefDialog *self = RUGBY_PREF_DIALOG (object);
g_clear_object (&self->settings);
gtk_widget_dispose_template (GTK_WIDGET (object), RUGBY_TYPE_PREF_DIALOG);
G_OBJECT_CLASS (rugby_pref_window_parent_class)->dispose (object);
G_OBJECT_CLASS (rugby_pref_dialog_parent_class)->dispose (object);
}
static void
rugby_pref_window_class_init (RugbyPrefWindowClass *klass)
rugby_pref_dialog_class_init (RugbyPrefDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = rugby_pref_window_dispose;
object_class->dispose = rugby_pref_dialog_dispose;
gtk_widget_class_set_template_from_resource (widget_class,
"/uk/me/bcowan/Rugby/prefs.ui");
gtk_widget_class_bind_template_child (widget_class, RugbyPrefWindow, try_spin);
gtk_widget_class_bind_template_child (widget_class, RugbyPrefWindow, utry_spin);
gtk_widget_class_bind_template_child (widget_class, RugbyPrefWindow, kick_spin);
"/uk/me/bcowan/Rugby/gtk/prefs.ui");
gtk_widget_class_bind_template_child (widget_class, RugbyPrefDialog, try_spin);
gtk_widget_class_bind_template_child (widget_class, RugbyPrefDialog, utry_spin);
gtk_widget_class_bind_template_child (widget_class, RugbyPrefDialog, kick_spin);
}
static void
rugby_pref_window_init (RugbyPrefWindow *self)
rugby_pref_dialog_init (RugbyPrefDialog *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
......@@ -64,10 +64,9 @@ rugby_pref_window_init (RugbyPrefWindow *self)
G_SETTINGS_BIND_DEFAULT);
}
RugbyPrefWindow *
rugby_pref_window_new (RugbyAppWindow *window)
RugbyPrefDialog *
rugby_pref_dialog_new (void)
{
return g_object_new (RUGBY_TYPE_PREF_WINDOW,
"transient-for", window,
return g_object_new (RUGBY_TYPE_PREF_DIALOG,
NULL);
}
/*
* SPDX-FileCopyrightText: 2020-2021 Bruce Cowan <bruce@bcowan.me.uk>
* SPDX-FileCopyrightText: 2020-2024 Bruce Cowan <bruce@bcowan.me.uk>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
......@@ -8,15 +8,14 @@
#include "rugby-app-window.h"
#include <gtk/gtk.h>
#include <adwaita.h>
G_BEGIN_DECLS
#define RUGBY_TYPE_PREF_WINDOW (rugby_pref_window_get_type())
#define RUGBY_TYPE_PREF_DIALOG (rugby_pref_dialog_get_type())
G_DECLARE_FINAL_TYPE (RugbyPrefWindow, rugby_pref_window, RUGBY, PREF_WINDOW, AdwPreferencesWindow)
G_DECLARE_FINAL_TYPE (RugbyPrefDialog, rugby_pref_dialog, RUGBY, PREF_DIALOG, AdwPreferencesDialog)
RugbyPrefWindow *rugby_pref_window_new (RugbyAppWindow *window);
RugbyPrefDialog *rugby_pref_dialog_new (void);
G_END_DECLS
# SPDX-FileCopyrightText: 2022-2024 Bruce Cowan
#
# SPDX-License-Identifier: CC0-1.0
[wrap-git]
directory = blueprint-compiler
url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git
revision = v0.4.0
revision = v0.14.0
depth = 1
[provide]
......
{
"app-id": "uk.me.bcowan.Rugby",
"runtime": "org.gnome.Platform",
"runtime-version": "47",
"sdk": "org.gnome.Sdk",
"command": "rugby",
"finish-args": [
"--share=ipc",
"--device=dri",
"--socket=fallback-x11",
"--socket=wayland"
],
"modules": [
{
"name": "blueprint-compiler",
"buildsystem": "meson",
"sources": [
{
"type": "git",
"url": "https://gitlab.gnome.org/jwestman/blueprint-compiler",
"tag": "v0.14.0"
}
]
},
{
"name": "rugby",
"buildsystem": "meson",
"builddir": true,
"sources": [
{
"type": "dir",
"path": "."
}
],
"config-opts": [
"-Dprofile=development"
]
}
]
}
SPDX-FileCopyrightText: 2024 Bruce Cowan <bruce@bcowan.me.uk>
SPDX-License-Identifier: GPL-3.0-or-later