[gnome-weather/wip/ewlsh/gtk4: 2/2] Initial thermometer port
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-weather/wip/ewlsh/gtk4: 2/2] Initial thermometer port
- Date: Fri, 31 Dec 2021 21:37:13 +0000 (UTC)
commit 9217560bdab53c6f7d8eb5d4bad2662138dfc0e0
Author: Evan Welsh <contact evanwelsh com>
Date: Fri Dec 31 13:36:47 2021 -0800
Initial thermometer port
data/application.css | 4 +-
src/app/dailyForecast.js | 7 +-
src/app/thermometer.js | 189 +++++++++++++++++++++++------------------------
3 files changed, 97 insertions(+), 103 deletions(-)
---
diff --git a/data/application.css b/data/application.css
index 12dde99..6aaf9a3 100644
--- a/data/application.css
+++ b/data/application.css
@@ -51,12 +51,12 @@
color: #c89009;
}
-thermometer > high {
+WeatherThermometer > label.high {
font-weight: bold;
color: #c89009;
}
-thermometer > low {
+WeatherThermometer > label.low {
font-weight: bold;
color: #2174d9;
}
diff --git a/src/app/dailyForecast.js b/src/app/dailyForecast.js
index 3ac5ad9..a0e3280 100644
--- a/src/app/dailyForecast.js
+++ b/src/app/dailyForecast.js
@@ -194,12 +194,8 @@ var DailyForecastBox = GObject.registerClass(class DailyForecastBox extends Gtk.
dayEntry.image.iconName = `${dayInfo.get_icon_name()}-small`;
- const adjustment = Gtk.Adjustment.new(minTemp,
- weekLowestTemp, weekHighestTemp,
- 0, 0,
- maxTemp - minTemp);
- dayEntry.thermometer.adjustment = adjustment;
+ dayEntry.thermometer.setTemperatureRange(weekLowestTemp, weekHighestTemp, minTemp, maxTemp);
dayEntry.nightTemperatureLabel.label = Util.getTempString(nightInfo);
dayEntry.nightImage.iconName = nightInfo.get_icon_name() + '-small';
dayEntry.nightHumidity.label = nightInfo.get_humidity();
@@ -350,4 +346,3 @@ var DayEntry = GObject.registerClass({
});
DayEntry.set_layout_manager_type(Gtk.BoxLayout);
-
\ No newline at end of file
diff --git a/src/app/thermometer.js b/src/app/thermometer.js
index 8356ea4..59a531c 100644
--- a/src/app/thermometer.js
+++ b/src/app/thermometer.js
@@ -21,10 +21,13 @@
const GObject = imports.gi.GObject;
const Gdk = imports.gi.Gdk;
const Gtk = imports.gi.Gtk;
+const Gsk = imports.gi.Gsk;
const Pango = imports.gi.Pango;
const Cairo = imports.cairo;
+const Graphene = imports.gi.Graphene;
-const Thermometer = GObject.registerClass({
+const ThermometerScale = GObject.registerClass({
+ CssName: 'WeatherThermometerScale',
Properties: {
'adjustment': GObject.ParamSpec.object(
'adjustment',
@@ -34,91 +37,42 @@ const Thermometer = GObject.registerClass({
Gtk.Adjustment,
),
},
- CssName: 'thermometer',
-},class Thermometer extends Gtk.DrawingArea {
+}, class ThermometerScale extends Gtk.Widget {
- _init(params) {
+ _init({ adjustment, radius = 12, margin = 12, ...params }) {
super._init(params);
- const styleContext = this.get_style_context();
-
- const createStyleContext = (selector) => {
- const path = styleContext.get_path().copy();
-
- const pos = path.append_type(GObject.TYPE_NONE);
- path.iter_set_object_name(pos, selector);
-
- const context = Gtk.StyleContext.new();
- context.set_parent(styleContext);
- context.set_path(path);
-
- return context;
- }
-
- this._highStyleContext = createStyleContext('high');
- this._lowStyleContext = createStyleContext('low');
-
- this._radius = 12;
- this._margin = 12;
- }
-
- get adjustment() {
- return this._adjustment;
- }
-
- set adjustment(adjustment) {
this._adjustment = adjustment;
+ this._adjustment.connect('changed', () => {
+ this.queue_draw();
+ });
- this._updatePangoLayouts(adjustment);
- }
-
- vfunc_get_preferred_width() {
- const [highWidth] = this._highLayout.get_pixel_size();
- const [lowWidth] = this._lowLayout.get_pixel_size();
+ this.vexpand = true;
- const width = Math.max(this._radius, highWidth, lowWidth);
- return [width, width];
+ this._radius = radius;
+ this._margin = margin;
}
- vfunc_get_preferred_height() {
- const [, highHeight] = this._highLayout.get_pixel_size();
- const [, lowHeight] = this._lowLayout.get_pixel_size();
+ vfunc_measure(orientation /*, for_size */) {
+ let minimum = this._radius + this._margin, minimum_baseline = -1, natural_baseline = - 1;
- const height = highHeight + this._maring + lowHeight;
- return [height, height];
- }
-
- _updatePangoLayouts(adjustment) {
- const value = adjustment.get_value();
- const pageSize = adjustment.get_page_size();
-
- const highLabel = Math.round(value + pageSize) + "°";
- this._highLayout = this._createPangoLayout(this._highStyleContext, highLabel);
-
- const lowLabel = Math.round(value) + "°";
- this._lowLayout = this._createPangoLayout(this._lowStyleContext, lowLabel);
- }
-
- _createPangoLayout(styleContext, text) {
- const context = this._createPangoContext(styleContext);
- const layout = Pango.Layout.new(context);
-
- layout.set_text(text, -1);
-
- return layout;
+ if (orientation === Gtk.Orientation.HORIZONTAL) {
+ return [minimum, minimum, minimum_baseline, natural_baseline];
+ } else {
+ return [minimum, minimum, minimum_baseline, natural_baseline];
+ }
}
- _createPangoContext(styleContext) {
- const display = this.get_display();
- const context = Gdk.pango_context_get_for_display(display);
+ vfunc_snapshot(snapshot) {
+ if (!this._adjustment)
+ return super.vfunc_snapshot(snapshot);
- const font = styleContext.get_property('font', styleContext.get_state());
- context.set_font_description (font);
+ const allocation = this.get_allocation();
- return context;
- }
+ const rect = new Graphene.Rect();
+ rect.init(0, 0, allocation.width, allocation.height);
- vfunc_draw(cr) {
+ let cr = snapshot.append_cairo(rect);
const lower = this._adjustment.get_lower();
const upper = this._adjustment.get_upper();
const value = this._adjustment.get_value();
@@ -127,41 +81,22 @@ const Thermometer = GObject.registerClass({
const width = this.get_allocated_width();
const height = this.get_allocated_height();
- const [highWidth, highHeight] = this._highLayout.get_pixel_size();
- const [lowWidth, lowHeight] = this._lowLayout.get_pixel_size();
-
const radius = this._radius;
const margin = this._margin;
- const maxScaleHeight = height - highHeight - lowHeight - 2 * radius - 2 * margin;
+ const maxScaleHeight = height - 2 * radius - 2 * margin;
const factor = maxScaleHeight / (upper - lower);
- const scaleY = highHeight + radius + margin + (upper - value - pageSize) * factor;
+ const scaleY = radius + margin + (upper - value - pageSize) * factor;
const scaleHeight = pageSize * factor;
- let highY = 0;
- let lowY = height - lowHeight;
-
- cr.save();
-
if (maxScaleHeight > 0) {
this._renderScale(cr, width / 2 - radius, scaleY, radius, scaleHeight);
-
- highY = scaleY - radius - margin - highHeight;
- lowY = scaleY + scaleHeight + radius + margin;
}
- Gtk.render_layout(this._highStyleContext, cr,
- width / 2 - highWidth / 2, highY,
- this._highLayout);
-
- Gtk.render_layout(this._lowStyleContext, cr,
- width / 2 - lowWidth / 2, lowY,
- this._lowLayout);
+ super.vfunc_snapshot(snapshot);
- cr.restore();
-
- return false;
+ cr.$dispose();
}
_renderScale(cr, x, y, radius, height) {
@@ -188,5 +123,69 @@ const Thermometer = GObject.registerClass({
return pattern;
}
+})
+
+var Thermometer = GObject.registerClass({
+
+ CssName: 'WeatherThermometer',
+}, class Thermometer extends Gtk.Widget {
+
+ _init({ ...params }) {
+ super._init(params);
+
+ this._adjustment = Gtk.Adjustment.new(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ );
+
+ this.layoutManager.orientation = Gtk.Orientation.VERTICAL;
+
+ this._scale = new ThermometerScale({ adjustment: this._adjustment });
+ this._highLabel = new Gtk.Label();
+ this._highLabel.add_css_class('high');
+ this._lowLabel = new Gtk.Label();
+ this._lowLabel.add_css_class('low');
+
+ this._highLabel.set_parent(this);
+ this._scale.set_parent(this);
+ this._lowLabel.set_parent(this);
+
+ this._updateLabels();
+
+ this._radius = 12;
+ this._margin = 12;
+
+ }
+
+ setTemperatureRange(weekLowestTemp, weekHighestTemp, minTemp, maxTemp) {
+ this._adjustment.configure(
+ minTemp,
+ weekLowestTemp,
+ weekHighestTemp,
+ 0, 0,
+ maxTemp - minTemp
+ );
+
+ this._updateLabels();
+
+ }
+ _updateLabels() {
+ if (!this._adjustment) return;
+
+ const value = this._adjustment.get_value();
+ const pageSize = this._adjustment.get_page_size();
+
+ const highLabel = Math.round(value + pageSize) + "°";
+ this._highLabel.label = highLabel;
+
+ const lowLabel = Math.round(value) + "°";
+ this._lowLabel.label = lowLabel;
+ }
});
+
+Thermometer.set_layout_manager_type(Gtk.BoxLayout);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]