datetime: Port to GTK4

Of particular relevance, the timezone map was massively cleaned up.
It is much more pleasant to use now.
This commit is contained in:
Georges Basile Stavracas Neto 2021-10-31 20:49:52 -03:00
parent d7e794e7ab
commit c6dd59f378
5 changed files with 191 additions and 400 deletions

View file

@ -26,7 +26,6 @@
#include <langinfo.h>
#include <sys/time.h>
#include "list-box-helper.h"
#include "cc-timezone-map.h"
#include "timedated.h"
#include "date-endian.h"
@ -85,7 +84,7 @@ struct _CcDateTimePanel
GSettings *datetime_settings;
GSettings *filechooser_settings;
GDesktopClockFormat clock_format;
GtkWidget *aspectmap;
GtkFrame *aspectmap;
GtkWidget *auto_datetime_row;
GtkWidget *auto_timezone_row;
GtkWidget *auto_timezone_switch;
@ -145,7 +144,7 @@ cc_date_time_panel_dispose (GObject *object)
if (panel->toplevels)
{
g_list_free_full (panel->toplevels, (GDestroyNotify) gtk_widget_destroy);
g_list_free_full (panel->toplevels, (GDestroyNotify) gtk_window_destroy);
panel->toplevels = NULL;
}
@ -421,7 +420,7 @@ city_changed_cb (CcDateTimePanel *self,
cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->map), zone);
entry = gtk_entry_completion_get_entry (completion);
gtk_entry_set_text (GTK_ENTRY (entry), "");
gtk_editable_set_text (GTK_EDITABLE (entry), "");
return TRUE;
}
@ -784,7 +783,7 @@ run_dialog (CcDateTimePanel *self,
parent = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)));
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_window_present (GTK_WINDOW (dialog));
}
static gboolean
@ -907,9 +906,7 @@ setup_timezone_dialog (CcDateTimePanel *self)
/* set up timezone map */
self->map = (GtkWidget *) cc_timezone_map_new ();
gtk_widget_show (self->map);
gtk_container_add (GTK_CONTAINER (self->aspectmap),
self->map);
gtk_frame_set_child (self->aspectmap, self->map);
/* Create the completion object */
completion = gtk_entry_completion_new ();
@ -924,7 +921,7 @@ static void
setup_datetime_dialog (CcDateTimePanel *self)
{
GtkAdjustment *adjustment;
GdkScreen *screen;
GdkDisplay *display;
g_autoptr(GtkCssProvider) provider = NULL;
g_autofree char *month = NULL;
guint num_days;
@ -938,9 +935,9 @@ setup_datetime_dialog (CcDateTimePanel *self)
"}\n"
".gnome-control-center-datetime-setup-time>spinbutton>entry {\n"
" padding: 8px 13px;\n"
"}", -1, NULL);
screen = gdk_screen_get_default ();
gtk_style_context_add_provider_for_screen (screen,
"}", -1);
display = gdk_display_get_default ();
gtk_style_context_add_provider_for_display (display,
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

View file

@ -2,8 +2,6 @@
<interface>
<!-- interface-requires gtk+ 3.10 -->
<object class="GtkLockButton" id="lock_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<object class="GtkListStore" id="city_liststore">
<columns>
@ -18,11 +16,12 @@
</object>
<object class="GtkPopover" id="month_popover">
<property name="visible">False</property>
<property name="relative-to">month_icon</property>
<child>
<object class="GtkFlowBox">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="orientation">vertical</property>
<property name="max-children-per-line">6</property>
<property name="min-children-per-line">4</property>
@ -34,7 +33,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">January</property>
<property name="xalign">0.0</property>
</object>
@ -42,7 +40,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">February</property>
<property name="xalign">0.0</property>
</object>
@ -50,7 +47,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">March</property>
<property name="xalign">0.0</property>
</object>
@ -58,7 +54,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">April</property>
<property name="xalign">0.0</property>
</object>
@ -66,7 +61,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">May</property>
<property name="xalign">0.0</property>
</object>
@ -74,7 +68,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">June</property>
<property name="xalign">0.0</property>
</object>
@ -82,7 +75,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">July</property>
<property name="xalign">0.0</property>
</object>
@ -90,7 +82,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">August</property>
<property name="xalign">0.0</property>
</object>
@ -98,7 +89,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">September</property>
<property name="xalign">0.0</property>
</object>
@ -106,7 +96,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">October</property>
<property name="xalign">0.0</property>
</object>
@ -114,7 +103,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">November</property>
<property name="xalign">0.0</property>
</object>
@ -122,7 +110,6 @@
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">December</property>
<property name="xalign">0.0</property>
</object>
@ -132,14 +119,12 @@
</child>
</object>
<object class="GtkDialog" id="datetime_dialog">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Date &amp; Time</property>
<property name="type_hint">dialog</property>
<property name="modal">True</property>
<property name="hide-on-close">True</property>
<property name="use_header_bar">1</property>
<signal name="delete-event" handler="gtk_widget_hide_on_delete"/>
<child internal-child="vbox">
<child>
<object class="GtkBox" id="dialog_vbox2">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<property name="margin_top">28</property>
@ -149,20 +134,17 @@
<property name="spacing">18</property>
<child>
<object class="CcTimeEditor" id="time_editor">
<property name="visible">True</property>
<property name="halign">center</property>
<signal name="time-changed" handler="time_changed_cb" swapped="yes"/>
</object>
</child>
<child>
<object class="HdyClamp">
<property name="visible">True</property>
<object class="AdwClamp">
<property name="maximum-size">600</property>
<child>
<object class="GtkListBox" id="date_box">
<property name="visible">True</property>
<property name="width-request">320</property>
<property name="selection-mode">none</property>
<signal name="row-activated" handler="date_box_row_activated_cb" swapped="yes"/>
@ -173,15 +155,15 @@
<!-- Year row -->
<child>
<object class="GtkListBoxRow" id="year_row">
<property name="visible">True</property>
<property name="activatable">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Year</property>
@ -193,7 +175,6 @@
</child>
<child>
<object class="GtkSpinButton" id="year_spinbutton">
<property name="visible">True</property>
<property name="width-chars">4</property>
<property name="numeric">True</property>
</object>
@ -206,15 +187,15 @@
<!-- Month row -->
<child>
<object class="GtkListBoxRow" id="month_row">
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Month</property>
@ -225,13 +206,11 @@
</child>
<child>
<object class="GtkLabel" id="month_label">
<property name="visible">True</property>
<property name="halign">end</property>
</object>
</child>
<child>
<object class="GtkImage" id="month_icon">
<property name="visible">True</property>
<property name="icon-name">pan-down-symbolic</property>
</object>
</child>
@ -243,15 +222,15 @@
<!-- Day row -->
<child>
<object class="GtkListBoxRow" id="day_row">
<property name="visible">True</property>
<property name="activatable">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Day</property>
@ -263,7 +242,6 @@
</child>
<child>
<object class="GtkSpinButton" id="day_spinbutton">
<property name="visible">True</property>
<property name="width-chars">3</property>
<property name="numeric">True</property>
</object>
@ -282,21 +260,16 @@
</child>
</object>
<object class="GtkDialog" id="timezone_dialog">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Time Zone</property>
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
<property name="modal">True</property>
<property name="use_header_bar">1</property>
<signal name="delete-event" handler="gtk_widget_hide_on_delete"/>
<property name="hide-on-close">True</property>
<child internal-child="headerbar">
<object class="GtkHeaderBar" id="dialog_header_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<property name="show-title-buttons">True</property>
<child type="title">
<object class="GtkSearchEntry" id="timezone_searchentry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="GtkEntry" id="timezone_searchentry">
<property name="halign">center</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
@ -309,44 +282,27 @@
</child>
</object>
</child>
<child internal-child="vbox">
<child>
<object class="GtkBox" id="dialog_vbox7">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkFrame" id="aspectmap">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="label_xalign">0</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<template class="CcDateTimePanel" parent="CcPanel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hscrollbar-policy">never</property>
<child>
<object class="HdyClamp">
<property name="visible">True</property>
<object class="AdwClamp">
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="margin_start">12</property>
@ -354,14 +310,10 @@
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">32</property>
<child>
<object class="GtkListBox" id="listbox2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="list_box_row_activated" object="CcDateTimePanel" swapped="no"/>
<signal name="keynav-failed" handler="keynav_failed" object="CcDateTimePanel" swapped="no"/>
@ -369,37 +321,24 @@
<class name="content"/>
</style>
<child>
<object class="HdyActionRow" id="auto_datetime_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="title" translatable="yes">Automatic _Date &amp; Time</property>
<object class="AdwActionRow" id="auto_datetime_row">
<property name="title" translatable="yes">Automatic _Date &amp;amp; Time</property>
<property name="subtitle" translatable="yes">Requires internet access</property>
<property name="use_underline">True</property>
<child>
<object class="GtkSwitch" id="network_time_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child>
<object class="HdyActionRow" id="datetime_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="title" translatable="yes">Date &amp; _Time</property>
<object class="AdwActionRow" id="datetime_button">
<property name="title" translatable="yes">Date &amp;amp; _Time</property>
<property name="use_underline">True</property>
<property name="activatable">True</property>
<child>
<object class="GtkLabel" id="datetime_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label">20 June 2012, 6:45 AM</property>
</object>
@ -407,16 +346,9 @@
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkListBox" id="listbox1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="list_box_row_activated" object="CcDateTimePanel" swapped="no"/>
<signal name="keynav-failed" handler="keynav_failed" object="CcDateTimePanel" swapped="no"/>
@ -424,32 +356,24 @@
<class name="content"/>
</style>
<child>
<object class="HdyActionRow" id="auto_timezone_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="auto_timezone_row">
<property name="title" translatable="yes">Automatic Time _Zone</property>
<property name="subtitle" translatable="yes">Requires location services enabled and internet access</property>
<property name="use_underline">True</property>
<child>
<object class="GtkSwitch" id="auto_timezone_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow" id="timezone_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="timezone_button">
<property name="title" translatable="yes">Time Z_one</property>
<property name="use_underline">True</property>
<property name="activatable">True</property>
<child>
<object class="GtkLabel" id="timezone_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="label">GMT+1 (London, United Kingdom)</property>
@ -458,16 +382,9 @@
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkListBox" id="listbox3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="list_box_row_activated" object="CcDateTimePanel" swapped="no"/>
<signal name="keynav-failed" handler="keynav_failed" object="CcDateTimePanel" swapped="no"/>
@ -475,15 +392,11 @@
<class name="content"/>
</style>
<child>
<object class="HdyActionRow" id="timeformat_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="timeformat_row">
<property name="title" translatable="yes">Time _Format</property>
<property name="use_underline">True</property>
<child>
<object class="GtkComboBoxText" id="format_combobox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<signal name="notify::active-id" handler="change_clock_settings" object="CcDateTimePanel" swapped="no"/>
<items>
@ -495,11 +408,6 @@
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>

View file

@ -44,16 +44,12 @@ struct _CcTimezoneMap
{
GtkWidget parent_instance;
GdkPixbuf *orig_background;
GdkPixbuf *orig_background_dim;
GdkPixbuf *orig_color_map;
GdkTexture *orig_background;
GdkTexture *orig_background_dim;
GdkPixbuf *background;
GdkPixbuf *color_map;
GdkPixbuf *pin;
guchar *visible_map_pixels;
gint visible_map_rowstride;
GdkTexture *background;
GdkTexture *color_map;
GdkTexture *pin;
gdouble selected_offset;
@ -73,71 +69,29 @@ enum
static guint signals[LAST_SIGNAL];
static CcTimezoneMapOffset color_codes[] =
static GdkTexture *
texture_from_resource (const gchar *resource_path,
GError **error)
{
{-11.0, 43, 0, 0, 255 },
{-10.0, 85, 0, 0, 255 },
{-9.5, 102, 255, 0, 255 },
{-9.0, 128, 0, 0, 255 },
{-8.0, 170, 0, 0, 255 },
{-7.0, 212, 0, 0, 255 },
{-6.0, 255, 0, 1, 255 }, // north
{-6.0, 255, 0, 0, 255 }, // south
{-5.0, 255, 42, 42, 255 },
{-4.5, 192, 255, 0, 255 },
{-4.0, 255, 85, 85, 255 },
{-3.5, 0, 255, 0, 255 },
{-3.0, 255, 128, 128, 255 },
{-2.0, 255, 170, 170, 255 },
{-1.0, 255, 213, 213, 255 },
{0.0, 43, 17, 0, 255 },
{1.0, 85, 34, 0, 255 },
{2.0, 128, 51, 0, 255 },
{3.0, 170, 68, 0, 255 },
{3.5, 0, 255, 102, 255 },
{4.0, 212, 85, 0, 255 },
{4.5, 0, 204, 255, 255 },
{5.0, 255, 102, 0, 255 },
{5.5, 0, 102, 255, 255 },
{5.75, 0, 238, 207, 247 },
{6.0, 255, 127, 42, 255 },
{6.5, 204, 0, 254, 254 },
{7.0, 255, 153, 85, 255 },
{8.0, 255, 179, 128, 255 },
{9.0, 255, 204, 170, 255 },
{9.5, 170, 0, 68, 250 },
{10.0, 255, 230, 213, 255 },
{10.5, 212, 124, 21, 250 },
{11.0, 212, 170, 0, 255 },
{11.5, 249, 25, 87, 253 },
{12.0, 255, 204, 0, 255 },
{12.75, 254, 74, 100, 248 },
{13.0, 255, 85, 153, 250 },
{-100, 0, 0, 0, 0 }
};
g_autofree gchar *full_path = g_strdup_printf ("resource://%s", resource_path);
g_autoptr(GFile) file = g_file_new_for_uri (full_path);
g_autoptr(GdkTexture) texture = gdk_texture_new_from_file (file, error);
return g_steal_pointer (&texture);
}
static void
cc_timezone_map_dispose (GObject *object)
{
CcTimezoneMap *self = CC_TIMEZONE_MAP (object);
g_clear_object (&self->color_map);
g_clear_object (&self->orig_background);
g_clear_object (&self->orig_background_dim);
g_clear_object (&self->orig_color_map);
g_clear_object (&self->background);
g_clear_object (&self->pin);
g_clear_pointer (&self->bubble_text, g_free);
if (self->color_map)
{
g_clear_object (&self->color_map);
self->visible_map_pixels = NULL;
self->visible_map_rowstride = 0;
}
G_OBJECT_CLASS (cc_timezone_map_parent_class)->dispose (object);
}
@ -153,31 +107,28 @@ cc_timezone_map_finalize (GObject *object)
/* GtkWidget functions */
static void
cc_timezone_map_get_preferred_width (GtkWidget *widget,
cc_timezone_map_measure (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural)
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
gint size;
size = gdk_pixbuf_get_width (map->orig_background);
switch (orientation)
{
case GTK_ORIENTATION_HORIZONTAL:
size = gdk_texture_get_width (map->orig_background);
break;
if (minimum != NULL)
*minimum = size;
if (natural != NULL)
*natural = size;
case GTK_ORIENTATION_VERTICAL:
size = gdk_texture_get_height (map->orig_background);
break;
}
static void
cc_timezone_map_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
gint size;
size = gdk_pixbuf_get_height (map->orig_background);
if (minimum != NULL)
*minimum = size;
if (natural != NULL)
@ -186,67 +137,27 @@ cc_timezone_map_get_preferred_height (GtkWidget *widget,
static void
cc_timezone_map_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
gint width,
gint height,
gint baseline)
{
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
GdkPixbuf *pixbuf;
if (map->background)
g_object_unref (map->background);
GdkTexture *texture;
if (!gtk_widget_is_sensitive (widget))
pixbuf = map->orig_background_dim;
texture = map->orig_background_dim;
else
pixbuf = map->orig_background;
texture = map->orig_background;
map->background = gdk_pixbuf_scale_simple (pixbuf,
allocation->width,
allocation->height,
GDK_INTERP_BILINEAR);
if (map->color_map)
g_object_unref (map->color_map);
map->color_map = gdk_pixbuf_scale_simple (map->orig_color_map,
allocation->width,
allocation->height,
GDK_INTERP_BILINEAR);
map->visible_map_pixels = gdk_pixbuf_get_pixels (map->color_map);
map->visible_map_rowstride = gdk_pixbuf_get_rowstride (map->color_map);
g_clear_object (&map->background);
map->background = g_object_ref (texture);
GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_allocate (widget,
allocation);
width,
height,
baseline);
}
static void
cc_timezone_map_realize (GtkWidget *widget)
{
GdkWindowAttr attr = { 0, };
GtkAllocation allocation;
GdkWindow *window;
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_set_realized (widget, TRUE);
attr.window_type = GDK_WINDOW_CHILD;
attr.wclass = GDK_INPUT_OUTPUT;
attr.width = allocation.width;
attr.height = allocation.height;
attr.x = allocation.x;
attr.y = allocation.y;
attr.event_mask = gtk_widget_get_events (widget)
| GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr,
GDK_WA_X | GDK_WA_Y);
gdk_window_set_user_data (window, widget);
gtk_widget_set_window (widget, window);
}
static gdouble
convert_longitude_to_x (gdouble longitude, gint map_width)
{
@ -284,8 +195,10 @@ convert_latitude_to_y (gdouble latitude, gdouble map_height)
}
static void
draw_text_bubble (cairo_t *cr,
GtkWidget *widget,
draw_text_bubble (CcTimezoneMap *map,
GtkSnapshot *snapshot,
gint width,
gint height,
gdouble pointx,
gdouble pointy)
{
@ -295,20 +208,19 @@ draw_text_bubble (cairo_t *cr,
static const double margin_left = 24.0;
static const double margin_right = 24.0;
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
GtkAllocation alloc;
PangoLayout *layout;
GskRoundedRect rounded_rect;
PangoRectangle text_rect;
PangoLayout *layout;
GdkRGBA rgba;
double x;
double y;
double width;
double height;
double bubble_width;
double bubble_height;
if (!map->bubble_text)
return;
gtk_widget_get_allocation (widget, &alloc);
layout = gtk_widget_create_pango_layout (widget, NULL);
layout = gtk_widget_create_pango_layout (GTK_WIDGET (map), NULL);
/* Layout the text */
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
@ -318,62 +230,78 @@ draw_text_bubble (cairo_t *cr,
pango_layout_get_pixel_extents (layout, NULL, &text_rect);
/* Calculate the bubble size based on the text layout size */
width = text_rect.width + margin_left + margin_right;
height = text_rect.height + margin_top + margin_bottom;
bubble_width = text_rect.width + margin_left + margin_right;
bubble_height = text_rect.height + margin_top + margin_bottom;
if (pointx < alloc.width / 2)
if (pointx < width / 2)
x = pointx + 25;
else
x = pointx - width - 25;
x = pointx - bubble_width - 25;
y = pointy - height / 2;
y = pointy - bubble_height / 2;
/* Make sure it fits in the visible area */
x = CLAMP (x, 0, alloc.width - width);
y = CLAMP (y, 0, alloc.height - height);
x = CLAMP (x, 0, width - bubble_width);
y = CLAMP (y, 0, height - bubble_height);
cairo_save (cr);
cairo_translate (cr, x, y);
gtk_snapshot_save (snapshot);
/* Draw the bubble */
cairo_new_sub_path (cr);
cairo_arc (cr, width - corner_radius, corner_radius, corner_radius, radians (-90), radians (0));
cairo_arc (cr, width - corner_radius, height - corner_radius, corner_radius, radians (0), radians (90));
cairo_arc (cr, corner_radius, height - corner_radius, corner_radius, radians (90), radians (180));
cairo_arc (cr, corner_radius, corner_radius, corner_radius, radians (180), radians (270));
cairo_close_path (cr);
gsk_rounded_rect_init (&rounded_rect,
&GRAPHENE_RECT_INIT (x, y, bubble_width, bubble_height),
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius),
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius),
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius),
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius));
cairo_set_source_rgba (cr, 0.2, 0.2, 0.2, 0.7);
cairo_fill (cr);
gtk_snapshot_push_rounded_clip (snapshot, &rounded_rect);
/* And finally draw the text */
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_move_to (cr, margin_left, margin_top);
pango_cairo_show_layout (cr, layout);
rgba = (GdkRGBA) {
.red = 0.2,
.green = 0.2,
.blue = 0.2,
.alpha = 0.7,
};
gtk_snapshot_append_color (snapshot,
&rgba,
&GRAPHENE_RECT_INIT (x, y, bubble_width, bubble_height));
rgba = (GdkRGBA) {
.red = 1.0,
.green = 1.0,
.blue = 1.0,
.alpha = 1.0,
};
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x + margin_left, y + margin_top));
gtk_snapshot_append_layout (snapshot, layout, &rgba);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
g_object_unref (layout);
cairo_restore (cr);
}
static gboolean
cc_timezone_map_draw (GtkWidget *widget,
cairo_t *cr)
static void
cc_timezone_map_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
g_autoptr(GdkPixbuf) orig_hilight = NULL;
GtkAllocation alloc;
g_autoptr(GdkTexture) orig_highlight = NULL;
g_autofree gchar *file = NULL;
g_autoptr(GError) err = NULL;
gdouble pointx, pointy;
gint width, height;
char buf[16];
gtk_widget_get_allocation (widget, &alloc);
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
/* paint background */
gdk_cairo_set_source_pixbuf (cr, map->background, 0, 0);
cairo_paint (cr);
gtk_snapshot_append_texture (snapshot,
map->background,
&GRAPHENE_RECT_INIT (0, 0, width, height));
/* paint hilight */
/* paint highlight */
if (gtk_widget_is_sensitive (widget))
{
file = g_strdup_printf (DATETIME_RESOURCE_PATH "/timezone_%s.png",
@ -388,64 +316,54 @@ cc_timezone_map_draw (GtkWidget *widget,
}
orig_hilight = gdk_pixbuf_new_from_resource (file, &err);
orig_highlight = texture_from_resource (file, &err);
if (!orig_hilight)
if (!orig_highlight)
{
g_warning ("Could not load hilight: %s",
g_warning ("Could not load highlight: %s",
(err) ? err->message : "Unknown Error");
}
else
{
g_autoptr(GdkPixbuf) hilight = NULL;
hilight = gdk_pixbuf_scale_simple (orig_hilight, alloc.width,
alloc.height, GDK_INTERP_BILINEAR);
gdk_cairo_set_source_pixbuf (cr, hilight, 0, 0);
cairo_paint (cr);
gtk_snapshot_append_texture (snapshot,
orig_highlight,
&GRAPHENE_RECT_INIT (0, 0, width, height));
}
if (map->location)
{
pointx = convert_longitude_to_x (map->location->longitude, alloc.width);
pointy = convert_latitude_to_y (map->location->latitude, alloc.height);
pointx = convert_longitude_to_x (map->location->longitude, width);
pointy = convert_latitude_to_y (map->location->latitude, height);
pointx = CLAMP (floor (pointx), 0, alloc.width);
pointy = CLAMP (floor (pointy), 0, alloc.height);
pointx = CLAMP (floor (pointx), 0, width);
pointy = CLAMP (floor (pointy), 0, height);
draw_text_bubble (cr, widget, pointx, pointy);
draw_text_bubble (map, snapshot, width, height, pointx, pointy);
if (map->pin)
{
gdk_cairo_set_source_pixbuf (cr, map->pin,
pointx - PIN_HOT_POINT_X,
pointy - PIN_HOT_POINT_Y);
cairo_paint (cr);
gtk_snapshot_append_texture (snapshot,
map->pin,
&GRAPHENE_RECT_INIT (pointx - PIN_HOT_POINT_X,
pointy - PIN_HOT_POINT_Y,
gdk_texture_get_width (map->pin),
gdk_texture_get_height (map->pin)));
}
}
return TRUE;
}
static void
update_cursor (GtkWidget *widget)
{
GdkWindow *window;
g_autoptr(GdkCursor) cursor = NULL;
const gchar *cursor_name = NULL;
if (!gtk_widget_get_realized (widget))
return;
if (gtk_widget_is_sensitive (widget))
{
GdkDisplay *display;
display = gtk_widget_get_display (widget);
cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
}
cursor_name = "pointer";
window = gtk_widget_get_window (widget);
gdk_window_set_cursor (window, cursor);
gtk_widget_set_cursor_from_name (widget, cursor_name);
}
static void
@ -468,11 +386,9 @@ cc_timezone_map_class_init (CcTimezoneMapClass *klass)
object_class->dispose = cc_timezone_map_dispose;
object_class->finalize = cc_timezone_map_finalize;
widget_class->get_preferred_width = cc_timezone_map_get_preferred_width;
widget_class->get_preferred_height = cc_timezone_map_get_preferred_height;
widget_class->measure = cc_timezone_map_measure;
widget_class->size_allocate = cc_timezone_map_size_allocate;
widget_class->realize = cc_timezone_map_realize;
widget_class->draw = cc_timezone_map_draw;
widget_class->snapshot = cc_timezone_map_snapshot;
widget_class->state_flags_changed = cc_timezone_map_state_flags_changed;
signals[LOCATION_CHANGED] = g_signal_new ("location-changed",
@ -512,56 +428,29 @@ set_location (CcTimezoneMap *map,
map->selected_offset = tz_location_get_utc_offset (map->location)
/ (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
gtk_widget_queue_draw (GTK_WIDGET (map));
g_signal_emit (map, signals[LOCATION_CHANGED], 0, map->location);
}
static gboolean
button_press_event (CcTimezoneMap *map,
GdkEventButton *event)
map_clicked_cb (GtkGestureClick *self,
gint n_press,
gdouble x,
gdouble y,
CcTimezoneMap *map)
{
gint x, y;
guchar r, g, b, a;
guchar *pixels;
gint rowstride;
gint i;
const GPtrArray *array;
gint width, height;
GList *distances = NULL;
GtkAllocation alloc;
gint i;
x = event->x;
y = event->y;
rowstride = map->visible_map_rowstride;
pixels = map->visible_map_pixels;
r = pixels[(rowstride * y + x * 4)];
g = pixels[(rowstride * y + x * 4) + 1];
b = pixels[(rowstride * y + x * 4) + 2];
a = pixels[(rowstride * y + x * 4) + 3];
for (i = 0; color_codes[i].offset != -100; i++)
{
if (color_codes[i].red == r && color_codes[i].green == g
&& color_codes[i].blue == b && color_codes[i].alpha == a)
{
map->selected_offset = color_codes[i].offset;
}
}
gtk_widget_queue_draw (GTK_WIDGET (map));
/* work out the co-ordinates */
/* work out the coordinates */
array = tz_get_locations (map->tzdb);
gtk_widget_get_allocation (GTK_WIDGET (map), &alloc);
width = alloc.width;
height = alloc.height;
width = gtk_widget_get_width (GTK_WIDGET (map));
height = gtk_widget_get_height (GTK_WIDGET (map));
for (i = 0; i < array->len; i++)
{
@ -591,11 +480,10 @@ button_press_event (CcTimezoneMap *map,
static void
cc_timezone_map_init (CcTimezoneMap *map)
{
GtkGesture *click_gesture;
GError *err = NULL;
map->orig_background = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/bg.png",
&err);
map->orig_background = texture_from_resource (DATETIME_RESOURCE_PATH "/bg.png", &err);
if (!map->orig_background)
{
g_warning ("Could not load background image: %s",
@ -603,9 +491,7 @@ cc_timezone_map_init (CcTimezoneMap *map)
g_clear_error (&err);
}
map->orig_background_dim = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/bg_dim.png",
&err);
map->orig_background_dim = texture_from_resource (DATETIME_RESOURCE_PATH "/bg_dim.png", &err);
if (!map->orig_background_dim)
{
g_warning ("Could not load background image: %s",
@ -613,17 +499,15 @@ cc_timezone_map_init (CcTimezoneMap *map)
g_clear_error (&err);
}
map->orig_color_map = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/cc.png",
&err);
if (!map->orig_color_map)
map->color_map = texture_from_resource (DATETIME_RESOURCE_PATH "/cc.png", &err);
if (!map->color_map)
{
g_warning ("Could not load background image: %s",
(err) ? err->message : "Unknown error");
g_clear_error (&err);
}
map->pin = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/pin.png",
&err);
map->pin = texture_from_resource (DATETIME_RESOURCE_PATH "/pin.png", &err);
if (!map->pin)
{
g_warning ("Could not load pin icon: %s",
@ -633,7 +517,9 @@ cc_timezone_map_init (CcTimezoneMap *map)
map->tzdb = tz_load_db ();
g_signal_connect_object (map, "button-press-event", G_CALLBACK (button_press_event), map, G_CONNECT_SWAPPED);
click_gesture = gtk_gesture_click_new ();
g_signal_connect (click_gesture, "pressed", G_CALLBACK (map_clicked_cb), map);
gtk_widget_add_controller (GTK_WIDGET (map), GTK_EVENT_CONTROLLER (click_gesture));
}
CcTimezoneMap *

View file

@ -5,7 +5,7 @@ panels = [
# 'background',
'camera',
# 'color',
# 'datetime',
'datetime',
'default-apps',
'diagnostics',
# 'display',

View file

@ -37,7 +37,7 @@ extern GType cc_applications_panel_get_type (void);
extern GType cc_bluetooth_panel_get_type (void);
#endif /* BUILD_BLUETOOTH */
//extern GType cc_color_panel_get_type (void);
//extern GType cc_date_time_panel_get_type (void);
extern GType cc_date_time_panel_get_type (void);
extern GType cc_default_apps_panel_get_type (void);
//extern GType cc_display_panel_get_type (void);
extern GType cc_info_overview_panel_get_type (void);
@ -104,7 +104,7 @@ static CcPanelLoaderVtable default_panels[] =
#endif
PANEL_TYPE("camera", cc_camera_panel_get_type, NULL),
//PANEL_TYPE("color", cc_color_panel_get_type, NULL),
//PANEL_TYPE("datetime", cc_date_time_panel_get_type, NULL),
PANEL_TYPE("datetime", cc_date_time_panel_get_type, NULL),
PANEL_TYPE("default-apps", cc_default_apps_panel_get_type, NULL),
PANEL_TYPE("diagnostics", cc_diagnostics_panel_get_type, cc_diagnostics_panel_static_init_func),
//PANEL_TYPE("display", cc_display_panel_get_type, NULL),