[gnome-weather/wip/ewlsh/gtk4] Start work on popover, fix chart layouts
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-weather/wip/ewlsh/gtk4] Start work on popover, fix chart layouts
- Date: Sun, 2 Jan 2022 20:49:54 +0000 (UTC)
commit 600299642070322999173816b61876c08b8fd7a8
Author: Evan Welsh <contact evanwelsh com>
Date: Sun Jan 2 14:49:28 2022 -0600
Start work on popover, fix chart layouts
data/places-popover.ui | 86 ++++-----------------
src/app/entry.js | 20 ++---
src/app/hourlyForecast.js | 65 ++++++++--------
src/app/world.js | 191 ++++++++++++++++++++++++++++------------------
4 files changed, 172 insertions(+), 190 deletions(-)
---
diff --git a/data/places-popover.ui b/data/places-popover.ui
index ea1e846..f1fffaa 100644
--- a/data/places-popover.ui
+++ b/data/places-popover.ui
@@ -18,66 +18,6 @@
</layout>
</object>
</child>
- <child>
- <object class="GtkStack" id="auto-location-stack">
- <property name="vhomogeneous">0</property>
- <property name="hhomogeneous">0</property>
- <property name="transition_type">crossfade</property>
- <child>
- <object class="GtkStackPage">
- <property name="name">auto-location-switch-grid</property>
- <property name="child">
- <object class="GtkGrid" id="auto-location-grid">
- <property name="column_homogeneous">1</property>
- <property name="margin_top">6</property>
- <property name="margin_bottom">6</property>
- <child>
- <object class="GtkLabel" id="auto-location-label">
- <property name="label" translatable="yes">Automatic Location</property>
- <property name="halign">start</property>
- <attributes>
- <attribute name="weight" value="PANGO_WEIGHT_BOLD"></attribute>
- </attributes>
- <style>
- <class name="dim-label"/>
- </style>
- <layout>
- <property name="column">0</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkSwitch" id="auto-location-switch">
- <property name="halign">end</property>
- <layout>
- <property name="column">1</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- </object>
- </property>
- </object>
- </child>
- <child>
- <object class="GtkStackPage">
- <property name="name">locating-label</property>
- <property name="child">
- <object class="GtkLabel" id="locating-label">
- <property name="label" translatable="yes">Locating…</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- </object>
- </property>
- </object>
- </child>
- <layout>
- <property name="column">0</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
<child>
<object class="GtkStack" id="popover-stack">
<property name="vhomogeneous">0</property>
@@ -130,18 +70,22 @@
<property name="orientation">vertical</property>
<property name="row_spacing">10</property>
<child>
- <object class="GtkScrolledWindow" id="city-search-scroll">
- <child>
- <object class="GtkListView" id="city-search-results">
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="hexpand">True</property>
- <layout>
- <property name="column">0</property>
- <property name="row">0</property>
- </layout>
+ <object class="GtkFrame">
+ <property name="name">search-frame</property>
+ <property name="child">
+ <object class="GtkScrolledWindow" id="search-list-scroll-window">
+ <child>
+ <object class="GtkListView" id="search-list-view">
+ <property name="name">search-list-view</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
</object>
- </child>
+ </property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">1</property>
+ </layout>
</object>
</child>
</object>
diff --git a/src/app/entry.js b/src/app/entry.js
index 5380ab1..fff170c 100644
--- a/src/app/entry.js
+++ b/src/app/entry.js
@@ -1,5 +1,7 @@
const { Gio, GLib, GWeather, GObject, Gtk, Gdk } = imports.gi;
+const World = imports.app.world;
+
const LocationItem = GObject.registerClass(
{
Properties: {
@@ -261,6 +263,8 @@ var LocationSearchEntry = GObject.registerClass(
* @param {number} baseline
*/
vfunc_size_allocate(width, height, baseline) {
+ super.vfunc_size_allocate(width, height, baseline);
+
this._entry.size_allocate(new Gdk.Rectangle({
x: 0,
y: 0,
@@ -268,11 +272,7 @@ var LocationSearchEntry = GObject.registerClass(
height
}), baseline);
- if (this._popup) {
- this._popup.set_size_request(this.get_allocation().width, -1);
- this._popup.queue_resize();
- this._popup.present();
- }
+
}
vfunc_grab_focus() {
@@ -332,16 +332,16 @@ var LocationSearchEntry = GObject.registerClass(
_buildFactory() {
let factory = new Gtk.SignalListItemFactory();
this._setupId = factory.connect("setup", (source, item) => {
- const label = new Gtk.Label();
- item.set_child(label);
+
+ item.set_child(new World.LocationRow('--', false));
});
this._bindId = factory.connect("bind", (source, listitem) => {
- const label = listitem.get_child();
+ const row = listitem.get_child();
/** @type {typeof LocationItem.prototype} */
const item = listitem.get_item();
- if (label instanceof Gtk.Label) {
- label.set_label(item.display_name);
+ if (row instanceof World.LocationRow) {
+ row.locationName = item.display_name;
}
});
diff --git a/src/app/hourlyForecast.js b/src/app/hourlyForecast.js
index a360840..81d52e6 100644
--- a/src/app/hourlyForecast.js
+++ b/src/app/hourlyForecast.js
@@ -36,7 +36,7 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
spacing: 0,
name: 'hourly-forecast-box',
});
-
+
this.update_property([Gtk.AccessibleProperty.LABEL], [_('Hourly Forecast')]);
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
@@ -90,9 +90,11 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
this._addSeparator();
}
} else {
- let label = new Gtk.Label({ label: _('Forecast not available'),
- use_markup: true,
- visible: true });
+ let label = new Gtk.Label({
+ label: _('Forecast not available'),
+ use_markup: true,
+ visible: true
+ });
this.prepend(label);
}
@@ -100,7 +102,6 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
}
_addHourEntry(info, tz, timeLabel) {
- let hourEntry = new HourEntry();
if (!timeLabel) {
let [ok, date] = info.get_value_update();
@@ -117,15 +118,8 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
timeLabel = datetime.format(timeFormat);
}
- hourEntry.timeLabel.label = timeLabel;
- hourEntry.image.iconName = info.get_icon_name() + '-small';
- hourEntry.temperatureLabel.label = Util.getTempString(info);
- if (Util.isDarkTheme()) {
- const color = "#f6d32d";
- const label = "<span color=\""+ color + "\">" + hourEntry.temperatureLabel.label + "</span>";
- hourEntry.temperatureLabel.set_markup(label);
- };
+ let hourEntry = new HourEntry({ info, timeLabel });
this.append(hourEntry);
@@ -133,15 +127,17 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
}
_addSeparator() {
- let separator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL,
- visible: true});
+ let separator = new Gtk.Separator({
+ orientation: Gtk.Orientation.VERTICAL,
+ visible: true
+ });
this.prepend(separator);
}
clear() {
- for (const w of Array.from(this)) {
- this.remove(w);
- }
+ for (const w of Array.from(this)) {
+ this.remove(w);
+ }
}
hasForecastInfo() {
@@ -150,10 +146,10 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
vfunc_snapshot(snapshot) {
const allocation = this.get_allocation();
-
+
const rect = new Graphene.Rect();
rect.init(0, 0, allocation.width, allocation.height);
-
+
let cr = snapshot.append_cairo(rect);
const temps = this._hourlyInfo.map(info => Util.getTemp(info));
@@ -170,7 +166,7 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
const width = this.get_allocated_width();
const height = this.get_allocated_height();
- const entryWidth = 75 ;
+ const entryWidth = 75;
const separatorWidth = 1;
const lineWidth = 2;
@@ -188,7 +184,7 @@ var HourlyForecastBox = GObject.registerClass(class HourlyForecastBox extends Gt
Gdk.cairo_set_source_rgba(cr, strokeColor);
let x = 0;
- cr.moveTo (x, graphMinY + ((1 - values[0]) * graphHeight));
+ cr.moveTo(x, graphMinY + ((1 - values[0]) * graphHeight));
x += entryWidth / 2;
cr.lineTo(x, graphMinY + ((1 - values[0]) * graphHeight));
@@ -227,20 +223,23 @@ var HourEntry = GObject.registerClass({
InternalChildren: ['timeLabel', 'image', 'temperatureLabel'],
}, class HourEntry extends Gtk.Widget {
- _init(params) {
- super._init({...params});
- }
+ _init({ timeLabel, info, ...params }) {
+ super._init({ ...params });
- get timeLabel() {
- return this._timeLabel;
- }
+ Object.assign(this.layoutManager, {
+ orientation: Gtk.Orientation.VERTICAL,
+ });
- get image() {
- return this._image;
- }
+ this._timeLabel.label = timeLabel;
+ this._image.iconName = info.get_icon_name() + '-small';
+ this._temperatureLabel.label = Util.getTempString(info);
- get temperatureLabel() {
- return this._temperatureLabel;
+ // TODO:
+ if (Util.isDarkTheme()) {
+ const color = "#f6d32d";
+ const label = "<span color=\"" + color + "\">" + this.temperatureLabel.label + "</span>";
+ this.temperatureLabel.set_markup(label);
+ };
}
});
HourEntry.set_layout_manager_type(Gtk.BoxLayout);
\ No newline at end of file
diff --git a/src/app/world.js b/src/app/world.js
index 36797fd..ecf72e2 100644
--- a/src/app/world.js
+++ b/src/app/world.js
@@ -25,6 +25,112 @@ const GWeather = imports.gi.GWeather;
const CurrentLocationController = imports.app.currentLocationController;
const Util = imports.misc.util;
+// TODO: Finish converting into a proper GObject w/ properties
+const LocationRow = GObject.registerClass(class LocationRow extends Gtk.Widget {
+
+ _init(locationName, isCurrentLocation) {
+ super._init({});
+
+ this._locationName = locationName;
+ this._isCurrentLocation = isCurrentLocation;
+
+ this._build();
+ }
+
+ get locationName() { return this._locationName };
+
+ get isCurrentLocation() { return this._isCurrentLocation; }
+
+ set locationName(value) {
+ this._locationName = value;
+ this._build();
+ }
+
+ set isCurrentLocation(value) {
+ this._isCurrentLocation = value;
+ this._build();
+ }
+
+ _build() {
+
+ if (!this.grid) {
+ this.grid = new Gtk.Grid({
+ orientation: Gtk.Orientation.HORIZONTAL,
+ column_spacing: 12,
+ margin_start: 12,
+ margin_end: 12,
+ margin_top: 12,
+ margin_bottom: 12,
+ visible: true
+ });
+
+ let grid = this.grid;
+ let locationGrid = new Gtk.Grid({
+ orientation: Gtk.Orientation.HORIZONTAL,
+ column_spacing: 12,
+ halign: Gtk.Align.START,
+ hexpand: true,
+ visible: true
+ });
+ this.locationLabel = new Gtk.Label({
+ label: this.locationName,
+ use_markup: true,
+ halign: Gtk.Align.START,
+ visible: true
+ });
+
+ locationGrid.attach(this.locationLabel, 0, 0, 1, 1);
+ grid.attach(locationGrid, 0, 0, 1, 1);
+
+ let tempLabel = new Gtk.Label({
+ use_markup: true,
+ halign: Gtk.Align.END,
+ margin_start: 12,
+ visible: true
+ });
+ this.tempLabel = tempLabel;
+ grid.attach(tempLabel, 1, 0, 1, 1);
+
+ this.image = new Gtk.Image({
+ icon_size: Gtk.IconSize.LARGE,
+ use_fallback: true,
+ halign: Gtk.Align.END
+ });
+ grid.attach(this.image, 2, 0, 1, 1);
+ }
+
+ if (this.isCurrentLocation && !this.currentImage) {
+ this.currentImage = new Gtk.Image({
+ icon_size: Gtk.IconSize.LARGE,
+ icon_name: 'mark-location-symbolic',
+ use_fallback: true,
+ halign: Gtk.Align.START
+ });
+ this.grid.attach(this.currentImage, 1, 0, 1, 1);
+ } else if (!this.isCurrentLocation && this.currentImage) {
+ this.currentImage.unparent();
+ this.currentImage = null;
+ }
+
+ this.locationLabel.label = this.locationName;
+
+ }
+
+ vfunc_root() {
+ super.vfunc_root();
+
+ this.grid.set_parent(this);
+ }
+
+ vfunc_unroot() {
+ this.grid.unparent();
+ this.grid = null;
+
+ super.vfunc_unroot();
+ }
+});
+LocationRow.set_layout_manager_type(Gtk.BoxLayout);
+
class _WorldContentView extends Gtk.Popover {
static [GObject.TypeName] = 'WorldContentView';
@@ -42,11 +148,12 @@ class _WorldContentView extends Gtk.Popover {
let grid = builder.get_object('popover-grid');
this.set_child(grid);
- this._searchResults = builder.get_object('city-search-results');
this._searchGrid = builder.get_object('empty-search-grid');
this._searchResultsGrid = builder.get_object('search-grid');
this._locationsGrid = builder.get_object('locations-grid');
-
+ this._searchListView = builder.get_object('search-list-view');
+ this._searchListScrollWindow = builder.get_object('search-list-scroll-window');
+ this._searchListScrollWindow.set_size_request(-1, 400);
this.model = application.model;
this._window = window;
@@ -63,7 +170,8 @@ class _WorldContentView extends Gtk.Popover {
});
this._locationEntry = builder.get_object('location-entry');
- this._locationEntry.setListView(this._searchResults);
+
+ this._locationEntry.setListView(this._searchListView);
this._locationEntry.connect('search-updated', (_, term) => {
if (term) {
this._stackPopover.set_visible_child(this._searchResultsGrid);
@@ -77,26 +185,11 @@ class _WorldContentView extends Gtk.Popover {
this._locationEntry.grab_focus();
});
- let autoLocStack = builder.get_object('auto-location-stack');
- let autoLocSwitch = builder.get_object('auto-location-switch');
- this._currentLocationController = application.currentLocationController;
- if (this._currentLocationController.autoLocation == CurrentLocationController.AutoLocation.ENABLED) {
- autoLocStack.visible_child_name = 'locating-label';
- } else {
- autoLocStack.visible_child_name = 'auto-location-switch-grid';
- autoLocSwitch.active = false;
- autoLocSwitch.sensitive = (this._currentLocationController.autoLocation !=
CurrentLocationController.AutoLocation.NOT_AVAILABLE);
- }
- let handlerId = autoLocSwitch.connect('notify::active', () => {
- this._currentLocationController.setAutoLocation(autoLocSwitch.active);
+ this._currentLocationController = application.currentLocationController;
- if (autoLocSwitch.active && !this.model.addedCurrentLocation)
- autoLocStack.visible_child_name = 'locating-label';
- this.hide();
- });
this._listbox.connect('row-activated', (listbox, row) => {
this._window.showInfo(row._info, false);
@@ -105,12 +198,6 @@ class _WorldContentView extends Gtk.Popover {
});
this.model.connect('current-location-changed', (model, info) => {
- autoLocStack.visible_child_name = 'auto-location-switch-grid';
- GObject.signal_handler_block(autoLocSwitch, handlerId);
- autoLocSwitch.active = (this._currentLocationController.autoLocation ==
CurrentLocationController.AutoLocation.ENABLED);
- autoLocSwitch.sensitive = (this._currentLocationController.autoLocation !=
CurrentLocationController.AutoLocation.NOT_AVAILABLE);
- GObject.signal_handler_unblock(autoLocSwitch, handlerId);
-
this._window.showInfo(info, true);
});
@@ -165,57 +252,9 @@ class _WorldContentView extends Gtk.Popover {
_onLocationAdded(model, info, isCurrentLocation) {
let location = info.location;
- let grid = new Gtk.Grid({
- orientation: Gtk.Orientation.HORIZONTAL,
- column_spacing: 12,
- margin_start: 12,
- margin_end: 12,
- margin_top: 12,
- margin_bottom: 12,
- visible: true
- });
let name = location.get_city_name();
- let locationGrid = new Gtk.Grid({
- orientation: Gtk.Orientation.HORIZONTAL,
- column_spacing: 12,
- halign: Gtk.Align.START,
- hexpand: true,
- visible: true
- });
- let locationLabel = new Gtk.Label({
- label: name,
- use_markup: true,
- halign: Gtk.Align.START,
- visible: true
- });
- locationGrid.attach(locationLabel, 0, 0, 1, 1);
- grid.attach(locationGrid, 0, 0, 1, 1);
-
- let tempLabel = new Gtk.Label({
- use_markup: true,
- halign: Gtk.Align.END,
- margin_start: 12,
- visible: true
- });
- grid.attach(tempLabel, 1, 0, 1, 1);
-
- if (isCurrentLocation) {
- let image = new Gtk.Image({
- icon_size: Gtk.IconSize.LARGE,
- icon_name: 'mark-location-symbolic',
- use_fallback: true,
- halign: Gtk.Align.START
- });
- locationGrid.attach(image, 1, 0, 1, 1);
- }
-
- let image = new Gtk.Image({
- icon_size: Gtk.IconSize.LARGE,
- use_fallback: true,
- halign: Gtk.Align.END
- });
- grid.attach(image, 2, 0, 1, 1);
+ const grid = new LocationRow(name, isCurrentLocation);
let row = new Gtk.ListBoxRow({ visible: true });
row.set_child(grid);
@@ -245,8 +284,8 @@ class _WorldContentView extends Gtk.Popover {
return;
info._updatedId = info.connect('updated', (info) => {
- tempLabel.label = info.get_temp_summary();
- image.icon_name = info.get_symbolic_icon_name();
+ grid.tempLabel.label = info.get_temp_summary();
+ grid.image.icon_name = info.get_symbolic_icon_name();
});
this._syncStackPopover();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]