Important information: Google announced that, from September 2026, Android devices will require ALL apps to be signed by Google, effectively leading to an iOS situation. Value your right to a computer that does what you want; do not tolerate this monopolistic practice! Contact me if you don't understand why it is bad. Click to learn more.

 main.py

View raw Download
text/x-script.python • 4.27 kiB
Python script, ASCII text executable
        
            
1
import os
2
import sys
3
import json
4
5
import gi
6
7
from pathlib import Path
8
9
gi.require_version("Gtk", "4.0")
10
11
from gi.repository import Gtk, Gio, GLib, Gdk
12
13
14
module_directory = Path(__file__).resolve().parent
15
16
17
custom_css = """
18
.panorama-weather-current-temperature {
19
font-weight: 100;
20
font-size: 5rem;
21
}
22
"""
23
css_provider = Gtk.CssProvider()
24
css_provider.load_from_data(custom_css)
25
Gtk.StyleContext.add_provider_for_display(
26
Gdk.Display.get_default(),
27
css_provider,
28
100
29
)
30
31
32
@Gtk.Template(filename=str(module_directory / "panorama-weather-report.ui"))
33
class WeatherReport(Gtk.Box):
34
__gtype_name__ = "WeatherReport"
35
36
current_details: Gtk.Label = Gtk.Template.Child()
37
current_temperature: Gtk.Label = Gtk.Template.Child()
38
current_weather_icon: Gtk.Image = Gtk.Template.Child()
39
40
def __init__(self, data, **kwargs):
41
super().__init__(**kwargs)
42
43
self.current_weather_icon.set_from_icon_name(data["icon_name"])
44
self.current_temperature.set_text(data["temp"])
45
46
47
@Gtk.Template(filename=str(module_directory / "panorama-weather.ui"))
48
class WeatherWindow(Gtk.Window):
49
__gtype_name__ = "WeatherWindow"
50
51
sidebar_revealer: Gtk.Revealer = Gtk.Template.Child()
52
sidebar: Gtk.Box = Gtk.Template.Child()
53
inner_sidebar: Gtk.Box = Gtk.Template.Child()
54
drag_handle: Gtk.Separator = Gtk.Template.Child()
55
weather_stack: Gtk.Stack = Gtk.Template.Child()
56
57
def sidebar_revealer_change(self, action, state):
58
action.set_state(state)
59
self.sidebar_revealer.set_reveal_child(state.get_boolean())
60
61
def begin_drag(self, gesture, start_x, start_y):
62
x_win, y_win = self.drag_handle.translate_coordinates(self, start_x, start_y)
63
gesture.widget_to_update.start_w = gesture.widget_to_update.get_width()
64
gesture.widget_to_update.start_x = x_win
65
gesture.start_x = start_x
66
67
def update_drag(self, gesture, dx, dy):
68
x_win, y_win = self.drag_handle.translate_coordinates(self, dx + gesture.start_x, 0)
69
gesture.widget_to_update.set_size_request(gesture.widget_to_update.start_w + x_win - gesture.widget_to_update.start_x, -1)
70
71
def set_window_title(self, stack, *args):
72
self.set_title(stack.get_page(stack.get_visible_child()).get_title())
73
74
def __init__(self, **kwargs):
75
super().__init__(**kwargs)
76
self.sidebar_revealer.set_hexpand(False)
77
self.weather_stack.set_hexpand(True)
78
self.weather_stack.set_halign(Gtk.Align.FILL)
79
self.weather_stack.connect("notify::visible-child", self.set_window_title)
80
81
self.action_group = Gio.SimpleActionGroup()
82
self.sidebar_action = Gio.SimpleAction.new_stateful("reveal-sidebar", None, GLib.Variant.new_boolean(True))
83
self.sidebar_action.connect("change-state", self.sidebar_revealer_change)
84
self.action_group.add_action(self.sidebar_action)
85
self.insert_action_group("win", self.action_group)
86
87
drag_controller = Gtk.GestureDrag()
88
drag_controller.widget_to_update = self.sidebar
89
drag_controller.connect("drag-begin", self.begin_drag)
90
drag_controller.connect("drag-update", self.update_drag)
91
self.drag_handle.add_controller(drag_controller)
92
self.drag_handle.set_cursor(Gdk.Cursor.new_from_name("ew-resize"))
93
94
def read_all(self):
95
application: PanoramaWeather = self.get_application()
96
# Read the weather files
97
for file in application.data_directory.iterdir():
98
with open(file, "r") as f:
99
data = json.load(f)
100
self.weather_stack.add_titled(WeatherReport(data), None, data["location"]["name"])
101
102
103
class PanoramaWeather(Gtk.Application):
104
def __init__(self):
105
super().__init__(
106
application_id="com.roundabout_host.roundabout.PanoramaWeather"
107
)
108
self.data_directory = Path(os.environ.get("XDG_DATA_HOME", "~/.local/share")).expanduser() / "weather" / "data" / "locations"
109
110
def do_startup(self):
111
Gtk.Application.do_startup(self)
112
113
def do_shutdown(self):
114
Gtk.Application.do_shutdown(self)
115
116
def do_activate(self):
117
Gtk.Application.do_activate(self)
118
119
window = WeatherWindow()
120
self.add_window(window)
121
window.present()
122
window.read_all()
123
124
125
if __name__ == "__main__":
126
app = PanoramaWeather()
127
app.run(sys.argv)
128