[gnome-weather/wip/ewlsh/gtk4] Design alignment, cleanup



commit c6c2b2fa3091127597d46e0528336d1a80dfbd6d
Author: Evan Welsh <contact evanwelsh com>
Date:   Mon Jan 17 02:21:09 2022 -0800

    Design alignment, cleanup

 data/application.css      | 34 ++++++++++++++++++++++++++++++----
 data/day-entry.ui         | 10 ++++++++++
 data/hour-entry.ui        |  8 +++++---
 data/weather-widget.ui    | 21 ++++++++++++---------
 src/app/city.js           | 13 ++++++++++++-
 src/app/entry.js          | 43 ++++++++++++++++++++++++++++++++++++-------
 src/app/hourlyForecast.js |  2 +-
 src/app/main.js           |  1 -
 src/app/thermometer.js    |  9 ++++++---
 src/app/thermometer.ui    | 12 ++++++++----
 src/app/window.js         | 21 ++++++++-------------
 11 files changed, 128 insertions(+), 46 deletions(-)
---
diff --git a/data/application.css b/data/application.css
index 5bba87b..32570a4 100644
--- a/data/application.css
+++ b/data/application.css
@@ -44,29 +44,55 @@
     border: 1px solid @borders;
 }
 
-#forecast-frame {
-    background-color: @theme_base_color;
+.forecast-frame {
+    transition: border-radius 100ms ease-out;
+    border-radius: 6px;
 }
 
-#forecast-frame > border {
-    border-radius: 8px;
+.forecast-frame.right-cutoff {
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+}
+
+.forecast-frame.left-cutoff {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
 }
 
 .forecast-temperature-label {
     font-weight: bold;
+    font-size: 12pt;
     color: #c89009;
 }
 
 WeatherThermometer > label.high {
     font-weight: bold;
+    font-size: 13pt;
     color: #c89009;
 }
 
 WeatherThermometer > label.low {
     font-weight: bold;
+    font-size: 13pt;
     color: #2174d9;
 }
 
+.day-label {
+    font-size: 13pt;
+}
+
+.date-label {
+    font-size: 9pt;
+}
+
+.forecast-button {
+    margin: 10px;
+}
+
+.forecast-graphic {
+    margin: 20px;
+}
+
 #daily-forecast-box,
 #hourly-forecast-box {
     /* TODO: Pull from theme/elsewhere */
diff --git a/data/day-entry.ui b/data/day-entry.ui
index 2ffdf2e..b20a560 100644
--- a/data/day-entry.ui
+++ b/data/day-entry.ui
@@ -264,12 +264,18 @@
       <object class="GtkLabel" id="nameLabel">
         <property name="margin_top">8</property>
         <property name="label">Tues</property>
+        <style>
+          <class name="day-label"/>
+        </style>
       </object>
     </child>
     <child>
       <object class="GtkLabel" id="dateLabel">
         <property name="margin_top">8</property>
         <property name="label">7 June</property>
+        <style>
+          <class name="date-label"/>
+        </style>
       </object>
     </child>
     <child>
@@ -277,6 +283,9 @@
         <property name="valign">start</property>
         <property name="pixel_size">32</property>
         <property name="icon_name">weather-showers-symbolic</property>
+        <style>
+          <class name="forecast-graphic"/>
+        </style>
       </object>
     </child>
     <child>
@@ -292,6 +301,7 @@
         <property name="valign">center</property>
         <property name="popover">more_menu</property>
         <style>
+          <class name="forecast-button"/>
           <class name="image-button"/>
           <class name="circular"/>
           <class name="flat"/>
diff --git a/data/hour-entry.ui b/data/hour-entry.ui
index be5d9d3..ba16181 100644
--- a/data/hour-entry.ui
+++ b/data/hour-entry.ui
@@ -10,8 +10,8 @@
     <property name="margin_top">18</property>
     <property name="margin_bottom">18</property>
     <layout>
-        <property name="orientation">vertical</property>
-    <property name="spacing">18</property>
+      <property name="orientation">vertical</property>
+      <property name="spacing">18</property>
     </layout>
     <child>
       <object class="GtkLabel" id="timeLabel">
@@ -20,11 +20,13 @@
     </child>
     <child>
       <object class="GtkImage" id="image">
-
         <property name="valign">1</property>
         <property name="vexpand">1</property>
         <property name="pixel_size">32</property>
         <property name="icon_name">weather-showers-symbolic</property>
+        <style>
+          <class name="forecast-graphic"/>
+        </style>
       </object>
     </child>
     <child>
diff --git a/data/weather-widget.ui b/data/weather-widget.ui
index 650b247..401a592 100644
--- a/data/weather-widget.ui
+++ b/data/weather-widget.ui
@@ -9,7 +9,7 @@
         <property name="margin-end">0</property>
         <property name="margin-top">18</property>
         <property name="margin-bottom">18</property>
-        <!-- <property name="spacing">18</property> -->
+        <property name="spacing">20</property>
         <child>
           <object class="GtkGrid">
             <property name="name">conditions-grid</property>
@@ -94,9 +94,6 @@
         <child>
           <object class="GtkOverlay">
             <property name="child">
-              <!-- <object class="GtkFrame" id="forecastFrame">
-                        <property name="name">forecast-frame</property>
-                        <property name="child"> -->
               <object class="AdwViewStack" id="forecastStack">
                 <child>
                   <object class="AdwViewStackPage">
@@ -104,9 +101,12 @@
                     <property name="title" translatable="yes">Hourly</property>
                     <property name="icon-name">preferences-system-time-symbolic</property>
                     <property name="child">
-                      <object class="GtkScrolledWindow">
+                      <object class="GtkScrolledWindow" id="forecastHourlyScrollWindow">
+                        <style>
+                          <class name="forecast-frame"/>
+                          <class name="frame"/>
+                        </style>
                         <property name="focusable">1</property>
-                        <property name="has-frame">true</property>
                         <property name="vscrollbar_policy">never</property>
                         <property name="hscrollbar_policy">external</property>
                         <property name="overflow">hidden</property>
@@ -133,9 +133,12 @@
                     <property name="title" translatable="yes">Daily</property>
                     <property name="icon-name">x-office-calendar-symbolic</property>
                     <property name="child">
-                      <object class="GtkScrolledWindow">
+                      <object class="GtkScrolledWindow" id="forecastDailyScrollWindow">
+                        <style>
+                          <class name="forecast-frame"/>
+                          <class name="frame"/>
+                        </style>
                         <property name="focusable">1</property>
-                        <property name="has-frame">true</property>
                         <property name="vscrollbar_policy">never</property>
                         <property name="hscrollbar_policy">external</property>
                         <property name="overflow">hidden</property>
@@ -148,7 +151,7 @@
                             <property name="hscroll_policy">natural</property>
                             <property name="vscroll_policy">natural</property>
                             <child>
-                              <object class="Gjs_DailyForecastBox" id="forecastDaily" />
+                              <object class="Gjs_DailyForecastBox" id="forecastDaily"/>
                             </child>
                           </object>
                         </property>
diff --git a/src/app/city.js b/src/app/city.js
index 9e937d9..cce8519 100644
--- a/src/app/city.js
+++ b/src/app/city.js
@@ -44,8 +44,10 @@ export const WeatherWidget = GObject.registerClass({
         'leftButton',
         'rightButton',
         'forecastHourly',
+        'forecastHourlyScrollWindow',
         'forecastHourlyAdjustment',
         'forecastDaily',
+        'forecastDailyScrollWindow',
         'forecastDailyAdjustment',
         'updatedTimeLabel',
         'attributionLabel'
@@ -124,19 +126,28 @@ export const WeatherWidget = GObject.registerClass({
     }
 
     _syncLeftRightButtons() {
-        let hadjustment = this._forecastStack.visible_child.get_hadjustment();
+        const visible_child = this._forecastStack.visible_child;
+        let hadjustment = visible_child.get_hadjustment();
         if ((hadjustment.get_upper() - hadjustment.get_lower()) == hadjustment.page_size) {
             this._leftButton.hide();
             this._rightButton.hide();
+            visible_child.remove_css_class('left-cutoff');
+            visible_child.remove_css_class('right-cutoff');
         } else if (hadjustment.value == hadjustment.get_lower()) {
             this._leftButton.hide();
             this._rightButton.show();
+            visible_child.remove_css_class('left-cutoff');
+            visible_child.add_css_class('right-cutoff');
         } else if (hadjustment.value >= (hadjustment.get_upper() - hadjustment.page_size)) {
             this._leftButton.show();
             this._rightButton.hide();
+            visible_child.remove_css_class('right-cutoff');
+            visible_child.add_css_class('left-cutoff');
         } else {
             this._leftButton.show();
             this._rightButton.show();
+            visible_child.add_css_class('left-cutoff');
+            visible_child.add_css_class('right-cutoff');
         }
     }
 
diff --git a/src/app/entry.js b/src/app/entry.js
index 698bb93..199b6e5 100644
--- a/src/app/entry.js
+++ b/src/app/entry.js
@@ -84,6 +84,39 @@ const LocationListModel = GObject.registerClass(
     }
 );
 
+// Avoid the overhead of closures and Gtk.StringFilter
+
+const LocationFilter = GObject.registerClass(
+    class LocationFilter extends Gtk.Filter {
+        _init() {
+            super._init();
+
+            /** @type {WeakMap<GWeather.Location, string>} */
+            this._itemMap = new WeakMap();
+            this._filter = null;
+            this._filterLowerCase = null;
+        }
+        setFilterString(filter) {
+            if (filter !== this._filter) {
+                this._filter = filter;
+                this._filterLowerCase = this._filter.toLowerCase();
+                this.changed(Gtk.FilterChange.DIFFERENT);
+            }
+        }
+
+        vfunc_match(item) {
+            if (!this._filter) return false;
+
+            const cached = this._itemMap.get(item);
+            const string = cached ?? item.get_name().toLowerCase();
+            if (!cached)
+                this._itemMap.set(item, string);
+
+            return string.includes(this._filterLowerCase);
+        }
+    }
+);
+
 export const LocationSearchEntry = GObject.registerClass(
     {
         Properties: {
@@ -111,7 +144,7 @@ export const LocationSearchEntry = GObject.registerClass(
                 const text = source.get_text();
 
                 if (text === null || text === '') {
-                    this._filter?.set_search(null);
+                    this._filter?.setFilterString(text);
                     this.emit('search-updated', null);
 
                     if (this._popup && this._popup.visible) {
@@ -125,7 +158,7 @@ export const LocationSearchEntry = GObject.registerClass(
                     this._entry?.grab_focus();
                 }
 
-                this._filter?.set_search(text);
+                this._filter?.setFilterString(text);
                 this.emit('search-updated', text);
             });
 
@@ -168,12 +201,8 @@ export const LocationSearchEntry = GObject.registerClass(
         }
 
         _populateModel() {
-            let filter = new Gtk.StringFilter();
+            let filter = new LocationFilter();
             this._filter = filter;
-            const expr = Gtk.ClosureExpression.new(GObject.TYPE_STRING, (location) => {
-                return location._cachedName ?? (location._cachedName = location.get_name());
-            }, []);
-            filter.set_expression(expr);
 
             let filter_model = new Gtk.FilterListModel({
                 model: this._model,
diff --git a/src/app/hourlyForecast.js b/src/app/hourlyForecast.js
index 1393281..c251fd7 100644
--- a/src/app/hourlyForecast.js
+++ b/src/app/hourlyForecast.js
@@ -131,7 +131,7 @@ export const HourlyForecastBox = GObject.registerClass(class HourlyForecastBox e
             orientation: Gtk.Orientation.VERTICAL,
             visible: true
         });
-        this.prepend(separator);
+        this.append(separator);
     }
 
     clear() {
diff --git a/src/app/main.js b/src/app/main.js
index b7fb91a..a373e86 100644
--- a/src/app/main.js
+++ b/src/app/main.js
@@ -234,7 +234,6 @@ console.log('created...')
         }
 
         vfunc_activate() {
-            console.log('activated')
             let win = this._createWindow();
             win.showDefault();
             this._showWindowWhenReady(win);
diff --git a/src/app/thermometer.js b/src/app/thermometer.js
index 31853c5..632d88b 100644
--- a/src/app/thermometer.js
+++ b/src/app/thermometer.js
@@ -82,10 +82,10 @@ const ThermometerScale = GObject.registerClass({
     super.vfunc_snapshot(snapshot);
 
     if (!this.range) return;
- 
+
     const { width, height } = this.get_allocation();
 
-    const { dailyHigh, dailyLow, weeklyHigh, weeklyLow } = this.range;  
+    const { dailyHigh, dailyLow, weeklyHigh, weeklyLow } = this.range;
 
     const scaleFactor = height / (weeklyHigh - weeklyLow);
 
@@ -137,7 +137,10 @@ export const Thermometer = GObject.registerClass({
   _init({ ...params }) {
     super._init(params);
 
-    this.layoutManager.orientation = Gtk.Orientation.VERTICAL;
+    Object.assign(this.layoutManager, {
+      orientation: Gtk.Orientation.VERTICAL,
+      spacing: 20
+    });
   }
 
   vfunc_root() {
diff --git a/src/app/thermometer.ui b/src/app/thermometer.ui
index 69cd6e0..81af798 100644
--- a/src/app/thermometer.ui
+++ b/src/app/thermometer.ui
@@ -3,17 +3,21 @@
     <requires lib="gtk" version="4.0"/>
     <template class="Gjs_Thermometer">
         <child>
-            <object class="GtkLabel" id="highLabel">
-                <property name="css-classes">high</property>
+            <object class="Gjs_ThermometerScale" id="scale">
             </object>
         </child>
         <child>
-            <object class="Gjs_ThermometerScale" id="scale">
+            <object class="GtkLabel" id="highLabel">
+                <style>
+                    <class name="high" />
+                </style>
             </object>
         </child>
         <child>
             <object class="GtkLabel" id="lowLabel">
-                <property name="css-classes">low</property>
+                <style>
+                    <class name="low" />
+                </style>
             </object>
         </child>
     </template>
diff --git a/src/app/window.js b/src/app/window.js
index 21ba1dc..e1c4db2 100644
--- a/src/app/window.js
+++ b/src/app/window.js
@@ -16,24 +16,20 @@
 // with Gnome Weather; if not, write to the Free Software Foundation,
 // Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-const Adw = imports.gi.Adw;
-const Gio = imports.gi.Gio;
-const GObject = imports.gi.GObject;
-const Gtk = imports.gi.Gtk;
-const GWeather = imports.gi.GWeather;
-
-const City = imports.app.city;
-const CurrentLocationController = imports.app.currentLocationController;
-const World = imports.shared.world;
-const WorldView = imports.app.world;
-const Util = imports.misc.util;
+import Adw from 'gi://Adw';
+import Gio from 'gi://Gio';
+import GObject from 'gi://GObject';
+import Gtk from 'gi://Gtk';
+
+import * as City from './city.js';
+import * as CurrentLocationController from './currentLocationController.js';
 
 const Page = {
     SEARCH: 0,
     CITY: 1
 };
 
-var MainWindow = GObject.registerClass({
+export const MainWindow = GObject.registerClass({
     Template: 'resource:///org/gnome/Weather/window.ui',
     InternalChildren: ['header', 'refreshRevealer', 'refresh', 'forecastStackSwitcher', 'stack',
         'titleStack', 'searchEntry', 'searchView', 'forecastStackSwitcherBar']
@@ -89,7 +85,6 @@ var MainWindow = GObject.registerClass({
         }
 
         this._showingDefault = false;
-        // this.show_all();
     }
 
     vfunc_unroot() {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]