[gnome-weather] Redesign the main layout



commit 45d42f487eb0433e555f741eccdbc8508d371a63
Author: Vitaly Dyachkov <obyknovenius me com>
Date:   Fri Jun 12 19:13:38 2020 +0000

    Redesign the main layout

 data/application.css                       |  94 ++-----
 data/day-entry.ui                          | 413 +++++++++++++++++++++++++++++
 data/hour-entry.ui                         |  60 +++++
 data/org.gnome.Weather.data.gresource.xml  |  11 +-
 data/weather-clear-night.jpg               | Bin 1310871 -> 0 bytes
 data/weather-clear.jpg                     | Bin 100291 -> 0 bytes
 data/weather-few-clouds-night.jpg          | Bin 147364 -> 0 bytes
 data/weather-few-clouds.jpg                | Bin 401504 -> 0 bytes
 data/weather-fog.jpg                       | Bin 619902 -> 0 bytes
 data/weather-overcast.jpg                  | Bin 419325 -> 0 bytes
 data/weather-showers.jpg                   | Bin 721902 -> 0 bytes
 data/weather-snow.jpg                      | Bin 1205617 -> 0 bytes
 data/weather-storm.jpg                     | Bin 274077 -> 0 bytes
 data/weather-widget.ui                     | 377 ++++++++++----------------
 data/window.ui                             | 101 +++----
 src/app/city.js                            | 143 ++++------
 src/app/dailyForecast.js                   | 319 ++++++++++++++++++++++
 src/app/forecast.js                        | 164 ------------
 src/app/hourlyForecast.js                  | 198 ++++++++++++++
 src/app/main.js                            |   3 -
 src/app/weeklyForecast.js                  | 152 -----------
 src/app/window.js                          |  58 ++--
 src/misc/util.js                           |  45 ++++
 src/org.gnome.Weather.src.gresource.xml.in |   4 +-
 24 files changed, 1311 insertions(+), 831 deletions(-)
---
diff --git a/data/application.css b/data/application.css
index 32979d3..98236cc 100644
--- a/data/application.css
+++ b/data/application.css
@@ -1,74 +1,23 @@
+#conditions-grid {
+    margin: 20px;
+}
+
+#places-label {
+    font-weight: bold;
+}
+
 #weather-page-placeholder-title {
     font-weight: bold;
     font-size: 1.2em;
 }
 
 #weather-page-content-view {
-    background-color: black;
     background-size: cover;
     background-position: center;
     background-origin: border-box;
     background-clip: border-box;
 }
 
-#weather-page-content-view.weather-clear,
-#weather-page-content-view.weather-clear:backdrop {
-    background-image: url("weather-clear.jpg");
-    color: rgba(0,0,0,0.8);
-}
-
-#weather-page-content-view.weather-clear-night,
-#weather-page-content-view.weather-clear-night:backdrop {
-    background-image: url("weather-clear-night.jpg");
-    color: rgba(255,255,255,0.8);
-}
-
-#weather-page-content-view.weather-few-clouds,
-#weather-page-content-view.weather-few-clouds:backdrop {
-    background-image: url("weather-few-clouds.jpg");
-    color: rgba(0,0,0,0.6);
-}
-
-#weather-page-content-view.weather-few-clouds-night,
-#weather-page-content-view.weather-few-clouds-night:backdrop {
-    background-image: url("weather-few-clouds-night.jpg");
-    color: rgba(255,255,255,0.8);
-}
-
-#weather-page-content-view.weather-fog,
-#weather-page-content-view.weather-fog:backdrop {
-    background-image: url("weather-fog.jpg");
-    background-position: center 20%;
-    color: rgba(255,255,255,0.8);
-}
-
-#weather-page-content-view.weather-overcast,
-#weather-page-content-view.weather-overcast:backdrop {
-    background-image: url("weather-overcast.jpg");
-    color: rgba(255,255,255,0.8);
-}
-
-#weather-page-content-view.weather-showers,
-#weather-page-content-view.weather-showers:backdrop,
-#weather-page-content-view.weather-showers-scattered,
-#weather-page-content-view.weather-showers-scattered:backdrop {
-    background-image: url("weather-showers.jpg");
-    color: rgba(255,255,255,1.0);
-}
-
-#weather-page-content-view.weather-snow,
-#weather-page-content-view.weather-snow:backdrop {
-    background-image: url("weather-snow.jpg");
-    color: rgba(255,255,255,0.8);
-}
-
-#weather-page-content-view.weather-storm,
-#weather-page-content-view.weather-storm:backdrop {
-    background-image: url("weather-storm.jpg");
-    background-position: center 80%;
-    color: rgba(255,255,255,0.8);
-}
-
 #loading-label {
     padding-top: 24px;
     font-size: 1.5em;
@@ -76,15 +25,7 @@
 
 #temperature-label {
     font-size: 4em;
-}
-
-#conditions-label {
-    font-size: 2.5em;
-}
-
-#wind-label {
-    font-size: 1.5em;
-    padding-bottom: 12px; /* keep in sync with conditions-image */
+    margin-left: 16px;
 }
 
 #attribution-label {
@@ -95,15 +36,6 @@
     color: @theme_fg_color;
 }
 
-#conditions-image {
-    padding: 12px;
-}
-
-#weekly-forecast-frame {
-    background-color: rgba(0, 0, 0, 0.5);
-    color: white;
-}
-
 .content-view.cell {
     font-weight: bold;
 }
@@ -111,3 +43,11 @@
 #locations-list-box {
     border: 1px solid @borders;
 }
+
+.forecast-temperature-label {
+    font-weight: bold;
+    color: #c89009;
+}
+
+@define-color temp_graph_border_color rgba(246, 211, 45, 1.0);
+@define-color temp_graph_background_color rgba(248, 228, 92, 0.5);
diff --git a/data/day-entry.ui b/data/day-entry.ui
new file mode 100644
index 0000000..8eb2b58
--- /dev/null
+++ b/data/day-entry.ui
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkPopoverMenu" id="more_menu">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkAlignment">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="top_padding">16</property>
+        <property name="bottom_padding">16</property>
+        <property name="left_padding">16</property>
+        <property name="right_padding">16</property>
+        <child>
+          <object class="GtkGrid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="row_spacing">8</property>
+            <property name="column_spacing">16</property>
+            <property name="row_homogeneous">True</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Night</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Morning</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Afternoon</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="label" translatable="yes">Evening</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">4</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkImage" id="nightImage">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="icon_name">weather-showers-symbolic</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkImage" id="morningImage">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="icon_name">weather-showers-symbolic</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkImage" id="afternoonImage">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="icon_name">weather-showers-symbolic</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkImage" id="eveningImage">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="icon_name">weather-showers-symbolic</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">4</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="vexpand">True</property>
+                <property name="row_spacing">8</property>
+                <property name="row_homogeneous">True</property>
+                <property name="column_homogeneous">True</property>
+                <child>
+                  <object class="GtkLabel" id="nightTemperatureLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">16°</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="morningTemperatureLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">16°</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="afternoonTemperatureLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">16°</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="eveningTemperatureLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">16°</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">weather-windy</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">weather-windy</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">weather-windy</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="nightHumidity">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">2.1 mm</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="morningHumidity">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">2.1 mm</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="afternoonHumidity">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">2.1 mm</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="eveningHumidity">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">2.1 mm</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="nightWind">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">5 m/s</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="morningWind">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">5 m/s</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="afternoonWind">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">5 m/s</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="eveningWind">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">5 m/s</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">4</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">0</property>
+                <property name="height">5</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="submenu">main</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+  </object>
+  <template class="Gjs_DayEntry" parent="GtkBox">
+    <property name="width_request">75</property>
+    <property name="height_request">200</property>
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">8</property>
+    <child>
+      <object class="GtkLabel" id="nameLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">8</property>
+        <property name="label" translatable="yes">Tues</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="dateLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">8</property>
+        <property name="label" translatable="yes">7 June</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkImage" id="image">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="valign">start</property>
+        <property name="vexpand">True</property>
+        <property name="pixel_size">32</property>
+        <property name="icon_name">weather-showers-symbolic</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="maxTemperatureLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">8</property>
+        <property name="label" translatable="yes">18°</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="minTemperatureLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">8</property>
+        <property name="label" translatable="yes">9°</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkMenuButton">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="popover">more_menu</property>
+        <child>
+          <object class="GtkImage">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="icon_name">view-more-symbolic</property>
+          </object>
+        </child>
+        <style>
+          <class name="image-button"/>
+          <class name="circular"/>
+          <class name="flat"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">5</property>
+      </packing>
+    </child>
+  </template>
+</interface>
diff --git a/data/hour-entry.ui b/data/hour-entry.ui
new file mode 100644
index 0000000..df5d94e
--- /dev/null
+++ b/data/hour-entry.ui
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="Gjs_HourEntry" parent="GtkBox">
+    <property name="width_request">75</property>
+    <property name="height_request">200</property>
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">8</property>
+    <child>
+      <object class="GtkLabel" id="timeLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">8</property>
+        <property name="label" translatable="yes">Now</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkImage" id="image">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="valign">start</property>
+        <property name="vexpand">True</property>
+        <property name="pixel_size">32</property>
+        <property name="icon_name">weather-showers-symbolic</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="temperatureLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="valign">end</property>
+        <property name="margin_bottom">16</property>
+        <property name="label" translatable="yes">13°</property>
+        <style>
+          <class name="forecast-temperature-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+  </template>
+</interface>
diff --git a/data/org.gnome.Weather.data.gresource.xml b/data/org.gnome.Weather.data.gresource.xml
index 9913ed5..eb357d3 100644
--- a/data/org.gnome.Weather.data.gresource.xml
+++ b/data/org.gnome.Weather.data.gresource.xml
@@ -6,16 +6,9 @@
     <file preprocess="xml-stripblanks">primary-menu.ui</file>
     <file preprocess="xml-stripblanks">weather-widget.ui</file>
     <file preprocess="xml-stripblanks">window.ui</file>
+    <file preprocess="xml-stripblanks">hour-entry.ui</file>
+    <file preprocess="xml-stripblanks">day-entry.ui</file>
     <file>application.css</file>
-    <file>weather-clear.jpg</file>
-    <file>weather-clear-night.jpg</file>
-    <file>weather-few-clouds.jpg</file>
-    <file>weather-few-clouds-night.jpg</file>
-    <file>weather-fog.jpg</file>
-    <file>weather-overcast.jpg</file>
-    <file>weather-showers.jpg</file>
-    <file>weather-snow.jpg</file>
-    <file>weather-storm.jpg</file>
   </gresource>
   <gresource prefix="/org/gnome/shell">
     <file>ShellWeatherIntegration.xml</file>
diff --git a/data/weather-widget.ui b/data/weather-widget.ui
index 6e6940a..9bfb198 100644
--- a/data/weather-widget.ui
+++ b/data/weather-widget.ui
@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.1 -->
+<!-- Generated with glade 3.22.0 -->
 <interface>
   <requires lib="gtk+" version="3.0"/>
   <template class="Gjs_WeatherWidget" parent="GtkFrame">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
+    <property name="label_xalign">0</property>
     <child>
       <object class="GtkFrame" id="contentFrame">
         <property name="name">weather-page-content-view</property>
@@ -16,314 +17,230 @@
           <object class="GtkGrid" id="outerGrid">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="vexpand">True</property>
             <child>
-              <object class="GtkGrid" id="alignment">
+              <object class="GtkOverlay" id="forecast-overlay">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="halign">center</property>
-                <property name="valign">start</property>
-                <property name="hexpand">True</property>
-                <property name="vexpand">True</property>
-                <property name="margin-top">50</property>
-                <property name="margin-start">50</property>
-                <property name="margin-end">20</property>
-                <property name="row_spacing">32</property>
+                <property name="margin_bottom">50</property>
                 <child>
-                  <object class="GtkGrid" id="inner-grid">
-                    <property name="name">conditions-grid</property>
+                  <object class="GtkStack" id="forecastStack">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="column_spacing">20</property>
-                    <child internal-child="accessible">
-                      <object class="AtkObject" id="conditions-grid-a11y">
-                        <property name="accessible-name" translatable="yes">Current conditions</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImage" id="conditionsImage">
-                        <property name="name">conditions-image</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="pixel_size">172</property>
-                        <property name="icon-size">2</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="temperatureLabel">
-                        <property name="name">temperature-label</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="valign">start</property>
-                        <property name="halign">start</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="conditionsLabel">
-                        <property name="name">conditions-label</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="valign">start</property>
-                        <property name="vexpand">True</property>
-                        <property name="halign">start</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">1</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
                     <child>
-                      <object class="GtkBox" id="windBox">
-                        <property name="name">wind-box</property>
+                      <object class="GtkScrolledWindow" id="forecast-hourly">
                         <property name="visible">True</property>
-                        <property name="orientation">horizontal</property>
-                        <property name="halign">start</property>
-                        <property name="valign">start</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <object class="GtkImage" id="windIcon">
-                            <property name="name">wind-icon</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="halign">start</property>
-                            <property name="icon-name">weather-windy-symbolic</property>
-                          </object>
-                        </child>
+                        <property name="can_focus">True</property>
+                        <property name="vscrollbar_policy">never</property>
+                        <property name="min_content_width">332</property>
                         <child>
-                          <object class="GtkLabel" id="windLabel">
-                            <property name="name">wind-label</property>
+                          <object class="GtkViewport" id="forecast-hourly-viewport">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="vexpand">True</property>
-                            <property name="halign">start</property>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">2</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkGrid" id="stack-grid">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkStackSwitcher" id="day-stack-switcher">
-                        <property name="visible">True</property>
-                        <property name="stack">forecastStack</property>
-                        <style>
-                          <class name="osd"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkGrid" id="forecast-parent-grid">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkStack" id="forecastStack">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <child>
-                          <object class="GtkScrolledWindow" id="forecast-today">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="vscrollbar_policy">never</property>
-                            <property name="min_content_width">332</property>
-                            <property name="margin-start">32</property>
-                            <property name="margin-end">32</property>
+                            <property name="hscroll_policy">natural</property>
+                            <property name="vscroll_policy">natural</property>
                             <child>
-                              <object class="GtkViewport" id="forecast-today-viewport">
+                              <object class="GtkAlignment" id="forecast-hourly-alignment">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="hscroll_policy">natural</property>
-                                <property name="vscroll_policy">natural</property>
+                                <property name="halign">center</property>
+                                <property name="left_padding">20</property>
+                                <property name="right_padding">20</property>
                                 <child>
-                                  <object class="GtkGrid" id="forecast-today-grid">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="halign">center</property>
-                                  </object>
+                                  <placeholder/>
                                 </child>
                               </object>
                             </child>
                           </object>
-                          <packing>
-                            <property name="name">today</property>
-                            <property name="title" translatable="yes">Today</property>
-                          </packing>
                         </child>
+                      </object>
+                      <packing>
+                        <property name="name">hourly</property>
+                        <property name="title" translatable="yes">Hourly</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkScrolledWindow" id="forecast-daily">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="vscrollbar_policy">never</property>
+                        <property name="min_content_width">332</property>
                         <child>
-                          <object class="GtkScrolledWindow" id="forecast-tomorrow">
+                          <object class="GtkViewport" id="forecast-daily-viewport">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="vscrollbar_policy">never</property>
-                            <property name="min_content_width">332</property>
-                            <property name="margin-start">32</property>
-                            <property name="margin-end">32</property>
+                            <property name="can_focus">False</property>
+                            <property name="hscroll_policy">natural</property>
+                            <property name="vscroll_policy">natural</property>
                             <child>
-                              <object class="GtkViewport" id="forecast-tomorrow-viewport">
+                              <object class="GtkAlignment" id="forecast-daily-alignment">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="hscroll_policy">natural</property>
-                                <property name="vscroll_policy">natural</property>
+                                <property name="halign">center</property>
+                                <property name="left_padding">20</property>
+                                <property name="right_padding">20</property>
                                 <child>
-                                  <object class="GtkGrid" id="forecast-tomorrow-grid">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="halign">center</property>
-                                  </object>
+                                  <placeholder/>
                                 </child>
                               </object>
                             </child>
                           </object>
-                          <packing>
-                            <property name="name">tomorrow</property>
-                            <property name="title" translatable="yes">Tomorrow</property>
-                          </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
+                        <property name="name">daily</property>
+                        <property name="title" translatable="yes">Daily</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
+                  </object>
+                  <packing>
+                    <property name="index">-1</property>
+                  </packing>
+                </child>
+                <child type="overlay">
+                  <object class="GtkButton" id="rightButton">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">end</property>
+                    <property name="valign">center</property>
+                    <property name="margin_right">28</property>
                     <child>
-                      <object class="GtkButton" id="leftButton">
+                      <object class="GtkImage" id="right-image">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="valign">center</property>
-                        <style>
-                          <class name="osd"/>
-                        </style>
-                        <child>
-                          <object class="GtkImage" id="left-image">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="icon-name">go-previous-symbolic</property>
-                            <property name="icon_size">1</property>
-                          </object>
-                        </child>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">go-next-symbolic</property>
                       </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
+                    <style>
+                      <class name="osd"/>
+                    </style>
+                  </object>
+                </child>
+                <child type="overlay">
+                  <object class="GtkButton" id="leftButton">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">start</property>
+                    <property name="valign">center</property>
+                    <property name="margin_left">28</property>
                     <child>
-                      <object class="GtkButton" id="rightButton">
+                      <object class="GtkImage" id="left-image">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="valign">center</property>
-                        <style>
-                          <class name="osd"/>
-                        </style>
-                        <child>
-                          <object class="GtkImage" id="right-image">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="icon-name">go-next-symbolic</property>
-                          </object>
-                        </child>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">go-previous-symbolic</property>
+                        <property name="icon_size">1</property>
                       </object>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
+                    <style>
+                      <class name="osd"/>
+                    </style>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">2</property>
+                    <property name="index">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
-              <object class="GtkGrid" id="timeGrid">
+              <object class="GtkGrid" id="inner-grid">
+                <property name="name">conditions-grid</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="halign">end</property>
-                <property name="margin-end">20</property>
+                <property name="column_spacing">10</property>
                 <child>
-                  <object class="GtkImage" id="clock-image">
+                  <object class="GtkImage" id="conditionsImage">
+                    <property name="name">conditions-image</property>
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="margin-start">10</property>
-                    <property name="margin-end">10</property>
-                    <property name="margin-top">15</property>
-                    <property name="margin-bottom">15</property>
-                    <property name="icon_name">document-open-recent-symbolic</property>
+                    <property name="valign">start</property>
+                    <property name="pixel_size">96</property>
+                    <property name="icon_size">2</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="height">2</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="timeLabel">
+                  <object class="GtkLabel" id="temperatureLabel">
+                    <property name="name">temperature-label</property>
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin-top">15</property>
-                    <property name="margin-bottom">15</property>
-                    <property name="label">label</property>
+                    <property name="halign">start</property>
+                    <property name="valign">start</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkMenuButton" id="placesButton">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="focus_on_click">False</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">start</property>
+                    <property name="valign">start</property>
+                    <child>
+                      <object class="GtkBox" id="placesBox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">12</property>
+                        <child>
+                          <object class="GtkLabel" id="placesLabel">
+                            <property name="name">places-label</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">Places</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkImage" id="placesImage">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">pan-down-symbolic</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                    <style>
+                      <class name="text-button"/>
+                      <class name="flat"/>
+                    </style>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="inner-grid-atkobject">
+                    <property name="AtkObject::accessible-name" translatable="yes">Current 
conditions</property>
+                  </object>
+                </child>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
           </object>
diff --git a/data/window.ui b/data/window.ui
index ff650d9..14307a0 100644
--- a/data/window.ui
+++ b/data/window.ui
@@ -1,71 +1,61 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
 <interface>
-  <!-- interface-requires gtk+ 3.10 -->
+  <requires lib="gtk+" version="3.10"/>
   <object class="GtkHeaderBar" id="header-bar">
     <property name="visible">True</property>
+    <property name="can_focus">False</property>
     <property name="vexpand">False</property>
-    <property name="show-close-button">True</property>
+    <property name="show_close_button">True</property>
     <child>
       <object class="GtkMenuButton" id="primary-menu-button">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
-        <property name="use-popover">True</property>
+        <property name="receives_default">False</property>
         <property name="valign">center</property>
-        <style>
-          <class name="image-button"/>
-        </style>
         <child>
           <object class="GtkImage" id="primary-menu-img">
             <property name="visible">True</property>
-            <property name="icon-name">open-menu-symbolic</property>
-            <property name="icon-size">1</property>
+            <property name="can_focus">False</property>
+            <property name="icon_name">open-menu-symbolic</property>
+            <property name="icon_size">1</property>
           </object>
         </child>
-      </object>
-      <packing>
-        <property name="pack_type">end</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkMenuButton" id="places-button">
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="label" translatable="yes">Places</property>
-        <property name="use-popover">True</property>
-        <property name="valign">center</property>
         <style>
-          <class name="text-button"/>
+          <class name="image-button"/>
         </style>
       </object>
       <packing>
-        <property name="pack_type">start</property>
+        <property name="pack_type">end</property>
       </packing>
     </child>
     <child>
       <object class="GtkButton" id="refresh-button">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
-        <property name="action-name">win.refresh</property>
+        <property name="receives_default">False</property>
         <property name="valign">center</property>
-        <style>
-          <class name="image-button"/>
-        </style>
-        <child internal-child="accessible">
-          <object class="AtkObject" id="refresh-button-a11y">
-            <property name="accessible-name" translatable="yes">Refresh</property>
-          </object>
-        </child>
+        <property name="action_name">win.refresh</property>
         <child>
           <object class="GtkImage" id="refresh-button-image">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="icon-name">view-refresh-symbolic</property>
-            <property name="icon-size">1</property>
+            <property name="icon_name">view-refresh-symbolic</property>
+            <property name="icon_size">1</property>
+          </object>
+        </child>
+        <child internal-child="accessible">
+          <object class="AtkObject" id="refresh-button-atkobject">
+            <property name="AtkObject::accessible-name" translatable="yes">Refresh</property>
           </object>
         </child>
+        <style>
+          <class name="image-button"/>
+        </style>
       </object>
       <packing>
         <property name="pack_type">end</property>
+        <property name="position">2</property>
       </packing>
     </child>
   </object>
@@ -75,67 +65,62 @@
     <property name="orientation">vertical</property>
     <child>
       <object class="GtkStack" id="main-stack">
-        <property name="transition-type">crossfade</property>
+        <property name="can_focus">False</property>
+        <property name="transition_type">crossfade</property>
         <child>
           <object class="GtkGrid" id="initial-grid">
-            <property name="visible">True</property>
             <property name="name">initial-grid</property>
+            <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="margin_top">25</property>
-            <property name="margin_bottom">25</property>
             <property name="halign">center</property>
             <property name="valign">center</property>
-            <property name="row_homogeneous">True</property>
+            <property name="margin_top">25</property>
+            <property name="margin_bottom">25</property>
             <property name="vexpand">False</property>
+            <property name="orientation">vertical</property>
+            <property name="row_homogeneous">True</property>
             <child>
               <object class="GtkImage" id="mark-location-image">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="icon_name">mark-location-symbolic</property>
-                <property name="icon_size">6</property>
-                <property name="use_fallback">True</property>
                 <property name="halign">center</property>
                 <property name="valign">center</property>
                 <property name="vexpand">False</property>
+                <property name="icon_name">mark-location-symbolic</property>
+                <property name="use_fallback">True</property>
+                <property name="icon_size">6</property>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
               <object class="GtkLabel" id="search-location-label">
                 <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Search for a location</property>
+                <property name="can_focus">False</property>
                 <property name="halign">center</property>
                 <property name="valign">center</property>
                 <property name="vexpand">False</property>
+                <property name="label" translatable="yes">Search for a location</property>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
               <object class="GtkLabel" id="search-nereby-location-label">
                 <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">To see weather information, enter the name of a 
city.</property>
+                <property name="can_focus">False</property>
                 <property name="halign">center</property>
                 <property name="valign">center</property>
                 <property name="vexpand">False</property>
+                <property name="label" translatable="yes">To see weather information, enter the name of a 
city.</property>
               </object>
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">2</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
             <child>
@@ -147,23 +132,15 @@
               <packing>
                 <property name="left_attach">0</property>
                 <property name="top_attach">3</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
               </packing>
             </child>
           </object>
         </child>
-        <child>
-          <placeholder/> <!-- city view -->
-        </child>
       </object>
       <packing>
-        <property name="left-attach">0</property>
-        <property name="top-attach">0</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
       </packing>
     </child>
   </object>
 </interface>
-
diff --git a/src/app/city.js b/src/app/city.js
index 86726ee..c187561 100644
--- a/src/app/city.js
+++ b/src/app/city.js
@@ -21,9 +21,11 @@ const GLib = imports.gi.GLib;
 const Gnome = imports.gi.GnomeDesktop;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
+const GWeather = imports.gi.GWeather;
 
-const Forecast = imports.app.forecast;
-const WForecast = imports.app.weeklyForecast;
+const WorldView = imports.app.world;
+const HourlyForecast = imports.app.hourlyForecast;
+const DailyForecast = imports.app.dailyForecast;
 const Util = imports.misc.util;
 
 const SPINNER_SIZE = 128;
@@ -33,32 +35,37 @@ const SCROLLING_ANIMATION_TIME = 400000; //us
 var WeatherWidget = GObject.registerClass({
     Template: 'resource:///org/gnome/Weather/weather-widget.ui',
     InternalChildren: ['contentFrame', 'outerGrid', 'conditionsImage',
-                       'temperatureLabel', 'conditionsLabel', 'windLabel',
-                       'timeLabel', 'timeGrid', 'forecastStack',
-                       'leftButton', 'rightButton',
-                       'forecast-today-grid', 'forecast-tomorrow-grid',
-                       'forecast-today', 'forecast-tomorrow'],
+                       'placesButton', 'placesLabel','temperatureLabel',
+                       'forecastStack','leftButton', 'rightButton',
+                       'forecast-hourly', 'forecast-hourly-alignment',
+                       'forecast-daily', 'forecast-daily-alignment'],
 }, class WeatherWidget extends Gtk.Frame {
 
-    _init(params) {
+    _init(application, window, params) {
         super._init(Object.assign({
             shadow_type: Gtk.ShadowType.NONE,
             name: 'weather-page'
         }, params));
 
-        this._currentStyle = null;
         this._info = null;
 
-        this._weeklyForecasts = new WForecast.WeeklyForecastFrame();
-        this._outerGrid.attach(this._weeklyForecasts, 1, 0, 1, 2);
+        this._worldView = new WorldView.WorldContentView(application, window);
+        this._placesButton.set_popover(this._worldView);
+
+        this._dailyForecasts = new DailyForecast.DailyForecastFrame();
 
         this._forecasts = { };
 
-        for (let t of ['today', 'tomorrow']) {
-            let box = new Forecast.ForecastBox({ hexpand: false });
+        for (let t of ['hourly', 'daily']) {
+            let box;
+            if (t == 'hourly') {
+                box = new HourlyForecast.HourlyForecastFrame();
+            } else {
+                box = new DailyForecast.DailyForecastFrame();
+            }
 
             this._forecasts[t] = box;
-            this['_forecast_' + t + '_grid'].add(box);
+            this['_forecast_' + t + '_alignment'].add(box);
 
             let fsw = this['_forecast_' + t];
             let hscrollbar = fsw.get_hscrollbar();
@@ -104,17 +111,17 @@ var WeatherWidget = GObject.registerClass({
     _syncLeftRightButtons() {
         let hadjustment = this._forecastStack.visible_child.get_hadjustment();
         if ((hadjustment.get_upper() - hadjustment.get_lower()) == hadjustment.page_size) {
-            this._leftButton.set_sensitive(false);
-            this._rightButton.set_sensitive(false);
+            this._leftButton.hide();
+            this._rightButton.hide();
         } else if (hadjustment.value == hadjustment.get_lower()){
-            this._leftButton.set_sensitive(false);
-            this._rightButton.set_sensitive(true);
+            this._leftButton.hide();
+            this._rightButton.show();
         } else if (hadjustment.value >= (hadjustment.get_upper() - hadjustment.page_size)){
-            this._leftButton.set_sensitive(true);
-            this._rightButton.set_sensitive(false);
+            this._leftButton.show();
+            this._rightButton.hide();
         } else {
-            this._leftButton.set_sensitive(true);
-            this._rightButton.set_sensitive(true);
+            this._leftButton.show();
+            this._rightButton.show();
         }
     }
 
@@ -147,7 +154,7 @@ var WeatherWidget = GObject.registerClass({
     }
 
     clear() {
-        for (let t of ['today', 'tomorrow'])
+        for (let t of ['hourly', 'daily'])
             this._forecasts[t].clear();
 
         if (this._tickId) {
@@ -156,49 +163,36 @@ var WeatherWidget = GObject.registerClass({
         }
     }
 
-    _getStyleClass(info) {
-        let icon = info.get_icon_name();
-        let name = icon.replace(/(-\d{3})/, "");
-        return name;
-    }
-
-    setTimeVisible(visible) {
-        this._timeGrid.visible = visible;
-    }
-
-    setTime(time) {
-        this._timeLabel.label = time;
+    getForecastStack() {
+        return this._forecastStack;
     }
 
     update(info) {
         this._info = info;
 
-        this._conditionsLabel.label = Util.getWeatherConditions(info);
-        this._temperatureLabel.label = info.get_temp_summary();
-        this._windLabel.label = info.get_wind();
+        let location = info.location;
+        let city = location;
+        if (location.get_level() == GWeather.LocationLevel.WEATHER_STATION)
+            city = location.get_parent();
+
+        let country = city.get_parent();
+        while (country && country.get_level() > GWeather.LocationLevel.COUNTRY)
+            country = country.get_parent();
+
+        if (country)
+            this._placesLabel.set_text(city.get_name() + ', ' + country.get_name());
+        else
+            this._placesLabel.set_text(city.get_name());
+
+        this._worldView.refilter();
 
         this._conditionsImage.icon_name = info.get_symbolic_icon_name();
-        let context = this._contentFrame.get_style_context();
-        if (this._currentStyle)
-            context.remove_class(this._currentStyle);
-        this._currentStyle = this._getStyleClass(info);
-        context.add_class(this._currentStyle);
+        this._temperatureLabel.label = info.get_temp_summary();
 
         let forecasts = info.get_forecast_list();
         let tz = GLib.TimeZone.new(info.location.get_timezone().get_tzid());
-        for (let t of ['today', 'tomorrow'])
-            this._forecasts[t].update(forecasts, tz, t);
-
-        if (!this._forecasts['today'].hasForecastInfo() && this._forecasts['tomorrow'].hasForecastInfo())
-            this._forecastStack.set_visible_child_name('tomorrow');
-
-        // FIXME: This doesn't make sense, since the above code assumes forecasts.length != 0.
-        if (forecasts.length == 0) {
-            this._weeklyForecasts.hide();
-        } else {
-            this._weeklyForecasts.show();
-            this._weeklyForecasts.update(forecasts);
-        }
+        for (let t of ['hourly', 'daily'])
+            this._forecasts[t].update(forecasts, tz);
     }
 });
 
@@ -207,10 +201,10 @@ var WeatherView = GObject.registerClass({
     InternalChildren: ['spinner']
 }, class WeatherView extends Gtk.Stack {
 
-    _init(params) {
+    _init(application, window, params) {
         super._init(params);
 
-        this._infoPage = new WeatherWidget();
+        this._infoPage = new WeatherWidget(application, window);
         this.add_named(this._infoPage, 'info');
 
         this._info = null;
@@ -265,40 +259,11 @@ var WeatherView = GObject.registerClass({
     _onUpdate(info) {
         this._infoPage.clear();
         this._infoPage.update(info);
-        this._updateTime();
         this._spinner.stop();
         this.visible_child_name = 'info';
     }
 
-    setTimeVisible(visible) {
-        if (this._clockHandlerId && !visible) {
-            this._wallClock.disconnect(this._clockHandlerId);
-            this._clockHandlerId = 0;
-        }
-
-        if (!this._clockHandlerId && visible) {
-            this._clockHandlerId = this._wallClock.connect('notify::clock',  () => {
-                this._updateTime();
-            });
-        }
-
-        this._infoPage.setTimeVisible(visible);
-    }
-
-    _updateTime() {
-        this._infoPage.setTime(this._getTime());
-    }
-
-    _getTime() {
-        if (this._info != null) {
-            let location = this._info.location;
-            let tz = GLib.TimeZone.new(location.get_timezone().get_tzid());
-            let dt = GLib.DateTime.new_now(tz);
-
-            return this._wallClock.string_for_datetime (dt,
-                                                        this._desktopSettings.get_enum('clock-format'),
-                                                        false, false, false);
-        }
-        return null;
+    getInfoPage() {
+        return this._infoPage;
     }
 });
diff --git a/src/app/dailyForecast.js b/src/app/dailyForecast.js
new file mode 100644
index 0000000..5819c7e
--- /dev/null
+++ b/src/app/dailyForecast.js
@@ -0,0 +1,319 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2014 Saurabh Patel <srp201201051 gmail com>
+//
+// Gnome Weather is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2 of the License, or (at your
+// option) any later version.
+//
+// Gnome Weather is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with Gnome Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+
+const Util = imports.misc.util;
+
+var DailyForecastFrame = GObject.registerClass(class DailyForecastFrame extends Gtk.Frame {
+
+    _init(params) {
+        super._init(Object.assign({
+            shadow_type: Gtk.ShadowType.IN,
+            name: 'daily-forecast-frame',
+        }, params));
+        this.get_accessible().accessible_name = _('Daily Forecast');
+
+        this._box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
+                                  spacing: 0});
+        this.add(this._box);
+    }
+
+    // get infos for the correct day
+    _preprocess(infos) {
+        let i;
+
+        let day = GLib.DateTime.new_now_local();
+        day = day.add_days(1);
+
+        // First ignore all infos that are on a different
+        // older than day.
+        // infos are ordered by time, and it's assumed at some point
+        // there is an info for the day (otherwise, nothing
+        // is shown)
+        for (i = 0; i < infos.length; i++) {
+            let info = infos[i];
+
+            let datetime = Util.getDateTime(info);
+            if (Util.arrayEqual(day.get_ymd(), datetime.get_ymd()))
+                break;
+        }
+
+        let weekInfos = [];
+        while (i < infos.length) {
+            let dayInfos = {day: day, infos: []};
+            for ( ; i < infos.length; i++) {
+                let info = infos[i];
+
+                let datetime = Util.getDateTime(info);
+                if (!Util.arrayEqual(day.get_ymd(), datetime.get_ymd()))
+                    break;
+
+                dayInfos.infos.push(info);
+            }
+            weekInfos.push(dayInfos);
+            day = day.add_days(1);
+        }
+        return weekInfos;
+    }
+
+    update(infos) {
+        let weekInfos = this._preprocess(infos);
+
+        if (weekInfos.length > 0) {
+            for (let i = 0; i < weekInfos.length; i++) {
+                let dayInfos = weekInfos[i];
+                this._addDayEntry(dayInfos);
+
+                if (i < weekInfos.length - 1)
+                    this._addSeparator();
+            }
+        } else {
+            let label = new Gtk.Label({ label: _('Forecast not available'),
+                                        use_markup: true,
+                                        visible: true });
+            this._box.pack_start(label, true, false, 0);
+        }
+    }
+
+    _addDayEntry({day, infos}) {
+        let maxInfo;
+        let maxTemp = -Infinity;
+
+        let minInfo;
+        let minTemp = Infinity;
+
+        day = Util.getDay(day);
+        let dayInfo;
+        let dayDiff = Infinity;
+
+        let night = Util.getNight(day);
+        let nightInfo;
+        let nightDiff = Infinity;
+
+        let morning = Util.getMorning(day);
+        let morningInfo;
+        let morningDiff = Infinity;
+
+        let afternoon = Util.getAfternoon(day);
+        let afternoonInfo;
+        let afternoonDiff = Infinity;
+
+        let evening = Util.getEvening(day);
+        let eveningInfo;
+        let eveningDiff = Infinity;
+
+        for (let i = 0; i < infos.length; i++) {
+            let info = infos[i];
+
+            let temp = Util.getTemp(info);
+            if (temp > maxTemp) {
+                maxInfo = info;
+                maxTemp = temp;
+            }
+            if (temp < minTemp) {
+                minInfo = info;
+                minTemp = minTemp;
+            }
+
+            let datetime = Util.getDateTime(info);
+
+            let diff = Math.abs(datetime.difference(day));
+            if (diff < dayDiff) {
+                dayInfo = info;
+                dayDiff = diff;
+            }
+
+            diff = Math.abs(datetime.difference(night));
+            if (diff < nightDiff) {
+                nightInfo = info;
+                nightDiff = diff;
+            }
+
+            diff = Math.abs(datetime.difference(morning));
+            if (diff < morningDiff) {
+                morningInfo = info;
+                morningDiff = diff;
+            }
+
+            diff = Math.abs(datetime.difference(afternoon));
+            if (diff < afternoonDiff) {
+                afternoonInfo = info;
+                afternoonDiff = diff;
+            }
+
+            diff = Math.abs(datetime.difference(evening));
+            if (diff < eveningDiff) {
+                eveningInfo = info;
+                eveningDiff = diff;
+            }
+        }
+
+        let dayEntry = new DayEntry();
+
+        let nameFormat = '%a';
+        dayEntry.nameLabel.label = day.format(nameFormat);
+
+        /* Translators: this is the time format for day and month name according to the current locale */
+        let dateFormat = _('%e %b');
+        dayEntry.dateLabel.label = day.format(dateFormat);
+
+        dayEntry.image.iconName = dayInfo.get_symbolic_icon_name();
+
+        dayEntry.maxTemperatureLabel.label = maxInfo.get_temp_summary();
+        dayEntry.minTemperatureLabel.label = minInfo.get_temp_summary();
+
+        dayEntry.nightTemperatureLabel.label = nightInfo.get_temp_summary();
+        dayEntry.nightImage.iconName = nightInfo.get_symbolic_icon_name();
+        dayEntry.nightHumidity.label = nightInfo.get_humidity();
+        dayEntry.nightWind.label = nightInfo.get_wind();
+
+        dayEntry.morningTemperatureLabel.label = morningInfo.get_temp_summary();
+        dayEntry.morningImage.iconName = morningInfo.get_symbolic_icon_name();
+        dayEntry.morningHumidity.label = morningInfo.get_humidity();
+        dayEntry.morningWind.label = morningInfo.get_wind();
+
+        dayEntry.afternoonTemperatureLabel.label = afternoonInfo.get_temp_summary();
+        dayEntry.afternoonImage.iconName = afternoonInfo.get_symbolic_icon_name();
+        dayEntry.afternoonHumidity.label = afternoonInfo.get_humidity();
+        dayEntry.afternoonWind.label = afternoonInfo.get_wind();
+
+        dayEntry.eveningTemperatureLabel.label = eveningInfo.get_temp_summary();
+        dayEntry.eveningImage.iconName = eveningInfo.get_symbolic_icon_name();
+        dayEntry.eveningHumidity.label = eveningInfo.get_humidity();
+        dayEntry.eveningWind.label = eveningInfo.get_wind();
+
+        this._box.pack_start(dayEntry, false, false, 0);
+    }
+
+    _addSeparator() {
+        let separator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL,
+                                            visible: true});
+        this._box.pack_start(separator, false, false, 0);
+    }
+
+    clear() {
+        this._box.foreach(function(w) { w.destroy(); });
+    }
+});
+
+var DayEntry = GObject.registerClass({
+    Template: 'resource:///org/gnome/Weather/day-entry.ui',
+    InternalChildren: ['nameLabel', 'dateLabel', 'image',
+                       'maxTemperatureLabel', 'minTemperatureLabel',
+                       'nightTemperatureLabel', 'nightImage',
+                       'nightHumidity', 'nightWind',
+                       'morningTemperatureLabel', 'morningImage',
+                       'morningHumidity', 'morningWind',
+                       'afternoonTemperatureLabel', 'afternoonImage',
+                       'afternoonHumidity', 'afternoonWind',
+                       'eveningTemperatureLabel', 'eveningImage',
+                       'eveningHumidity', 'eveningWind'],
+}, class DayEntry extends Gtk.Box {
+
+    _init(params) {
+        super._init(params);
+    }
+
+    get nameLabel() {
+        return this._nameLabel;
+    }
+
+    get dateLabel() {
+        return this._dateLabel;
+    }
+
+    get image() {
+        return this._image;
+    }
+
+    get maxTemperatureLabel() {
+        return this._maxTemperatureLabel;
+    }
+
+    get minTemperatureLabel() {
+        return this._minTemperatureLabel;
+    }
+
+    get nightTemperatureLabel() {
+        return this._nightTemperatureLabel;
+    }
+
+    get nightImage() {
+        return this._nightImage;
+    }
+
+    get nightHumidity() {
+        return this._nightHumidity;
+    }
+
+    get nightWind() {
+        return this._nightWind;
+    }
+
+    get morningTemperatureLabel() {
+        return this._morningTemperatureLabel;
+    }
+
+    get morningImage() {
+        return this._morningImage;
+    }
+
+    get morningHumidity() {
+        return this._morningHumidity;
+    }
+
+    get morningWind() {
+        return this._morningWind;
+    }
+
+    get afternoonTemperatureLabel() {
+        return this._afternoonTemperatureLabel;
+    }
+
+    get afternoonImage() {
+        return this._afternoonImage;
+    }
+
+    get afternoonHumidity() {
+        return this._afternoonHumidity;
+    }
+
+    get afternoonWind() {
+        return this._afternoonWind;
+    }
+
+    get eveningTemperatureLabel() {
+        return this._eveningTemperatureLabel;
+    }
+
+    get eveningImage() {
+        return this._eveningImage;
+    }
+
+    get eveningHumidity() {
+        return this._eveningHumidity;
+    }
+
+    get eveningWind() {
+        return this._eveningWind;
+    }
+});
diff --git a/src/app/hourlyForecast.js b/src/app/hourlyForecast.js
new file mode 100644
index 0000000..c3f378d
--- /dev/null
+++ b/src/app/hourlyForecast.js
@@ -0,0 +1,198 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2 of the License, or (at your
+// option) any later version.
+//
+// Gnome Weather is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with Gnome Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Gdk = imports.gi.Gdk;
+const Gtk = imports.gi.Gtk;
+const GWeather = imports.gi.GWeather;
+
+const Util = imports.misc.util;
+
+// In microseconds
+const TWENTY_FOUR_HOURS = 24 * 3600 * 1000 * 1000;
+
+var HourlyForecastFrame = GObject.registerClass(class ForecastFrame extends Gtk.Frame {
+
+    _init(params) {
+        super._init(Object.assign({
+            shadow_type: Gtk.ShadowType.IN,
+            name: 'hourly-forecast-frame',
+        }, params));
+        this.get_accessible().accessible_name = _('Hourly Forecast');
+
+        this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
+
+        this._box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
+                                  spacing: 0});
+        this.add(this._box);
+
+        this._hourlyInfo = [];
+
+        this._hasForecastInfo = false;
+    }
+
+    // Ensure that infos are sufficiently spaced, and
+    // remove infos for the wrong day
+    _preprocess(now, infos) {
+        let ret = [];
+
+        for (let i = 0; i < infos.length; i++) {
+            let info = infos[i];
+
+            let [ok, date] = info.get_value_update();
+            let datetime = GLib.DateTime.new_from_unix_utc(date).to_timezone(now.get_timezone());
+
+            if (datetime.difference(now) <= 0)
+                continue;
+
+            if (datetime.difference(now) >= TWENTY_FOUR_HOURS)
+                break;
+
+            ret.push(info);
+        }
+
+        return ret;
+    }
+
+    update(infos, tz) {
+        let now = GLib.DateTime.new_now(tz);
+        let hourlyInfo = this._preprocess(now, infos);
+
+        if (hourlyInfo.length > 0) {
+            for (let i = 0; i < hourlyInfo.length; i++) {
+                let info = hourlyInfo[i];
+                this._addHourEntry(info, tz);
+
+                if (i < hourlyInfo.length - 1)
+                    this._addSeparator();
+            }
+        } else {
+            let label = new Gtk.Label({ label: _('Forecast not available'),
+                                        use_markup: true,
+                                        visible: true });
+            this._box.pack_start(label, true, false, 0);
+        }
+
+        this._hourlyInfo = hourlyInfo;
+    }
+
+    _addHourEntry(info, tz) {
+        let [ok, date] = info.get_value_update();
+        let datetime = GLib.DateTime.new_from_unix_utc(date).to_timezone(tz);
+
+        let timeSetting = this._settings.get_string('clock-format');
+        let timeFormat = null;
+
+        if (timeSetting == '12h')
+            /* Translators: this is a time format without date used for AM/PM */
+            timeFormat = _('%l∶%M %p');
+        else
+            timeFormat = '%R';
+
+        let hourEntry = new HourEntry();
+        hourEntry.timeLabel.label = datetime.format(timeFormat);
+        hourEntry.image.iconName = info.get_symbolic_icon_name();
+        hourEntry.temperatureLabel.label = info.get_temp_summary();
+
+        this._box.pack_start(hourEntry, false, false, 0);
+
+        this._hasForecastInfo = true;
+    }
+
+    _addSeparator() {
+        let separator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL,
+                                            visible: true});
+        this._box.pack_start(separator, false, false, 0);
+    }
+
+    clear() {
+        this._box.foreach(function(w) { w.destroy(); });
+    }
+
+    hasForecastInfo() {
+        return this._hasForecastInfo;
+    }
+
+    vfunc_draw(cr) {
+        let hourlyInfo = this._hourlyInfo;
+
+        let temps = hourlyInfo.map(info => {
+            let [ok, t] = info.get_value_temp(GWeather.TemperatureUnit.DEFAULT);
+            return t;
+        });
+        let maxTemp = Math.max(...temps);
+        temps = temps.map(t => t / maxTemp);
+        let n = temps.length;
+
+        let width = this.get_allocated_width();
+        let height = this.get_allocated_height();
+
+        let top_padding = 80;
+        let bottom_padding = 40;
+
+        let canvas_height = height - top_padding - bottom_padding;
+        let step = (width - (n - 1)) / n;
+
+        let [, borderColor] = this.get_style_context().lookup_color('temp_graph_border_color');
+        Gdk.cairo_set_source_rgba(cr, borderColor);
+        cr.setLineWidth(2);
+
+        cr.moveTo (0, top_padding + ((1 - temps[0]) * canvas_height));
+        for (let i = 0; i < n; i++)
+            cr.lineTo((i * step) + step / 2, top_padding + ((1 - temps[i]) * canvas_height));
+        cr.lineTo(width, top_padding + ((1 - temps[n - 1]) * canvas_height));
+        cr.strokePreserve();
+
+        cr.lineTo(width, height);
+        cr.lineTo(0, height);
+
+        let [, backgroundColor] = this.get_style_context().lookup_color('temp_graph_background_color');
+        Gdk.cairo_set_source_rgba(cr, backgroundColor);
+
+        cr.fill();
+
+        super.vfunc_draw(cr);
+        cr.$dispose();
+
+        return Gdk.EVENT_PROPAGATE;
+    }
+});
+
+var HourEntry = GObject.registerClass({
+    Template: 'resource:///org/gnome/Weather/hour-entry.ui',
+    InternalChildren: ['timeLabel', 'image', 'temperatureLabel'],
+}, class HourEntry extends Gtk.Box {
+
+    _init(params) {
+        super._init(params);
+    }
+
+    get timeLabel() {
+        return this._timeLabel;
+    }
+
+    get image() {
+        return this._image;
+    }
+
+    get temperatureLabel() {
+        return this._temperatureLabel;
+    }
+});
diff --git a/src/app/main.js b/src/app/main.js
index 158254b..6e93fa9 100644
--- a/src/app/main.js
+++ b/src/app/main.js
@@ -90,9 +90,6 @@ const Application = GObject.registerClass(
 
         Util.loadStyleSheet('/org/gnome/Weather/application.css');
 
-        let settings = Gtk.Settings.get_for_screen(Gdk.Screen.get_default());
-        settings.gtk_application_prefer_dark_theme = true;
-
         this.world = GWeather.Location.get_world();
         this.model = new World.WorldModel(this.world, true);
         this.model.load();
diff --git a/src/app/window.js b/src/app/window.js
index c1bde7c..201b457 100644
--- a/src/app/window.js
+++ b/src/app/window.js
@@ -43,6 +43,8 @@ var MainWindow = GObject.registerClass(
         this._currentPage = Page.SEARCH;
         this._pageWidgets = [[],[]];
 
+        this.set_default_size(650, 520);
+
         let aboutAction = new Gio.SimpleAction({
             enabled: true,
             name: 'about'
@@ -71,14 +73,9 @@ var MainWindow = GObject.registerClass(
         let grid = builder.get_object('main-panel');
         this._header = builder.get_object('header-bar');
         this.set_titlebar(this._header);
-        let [title, subtitle] = this._getTitle();
-        this._header.title = title;
-        this._header.subtitle = subtitle;
-
-        this._worldView = new WorldView.WorldContentView(this.application, this, { visible: true });
-        this._worldView.hide();
+        this._header.set_title(_('Select Location'));
 
-        this._model = this._worldView.model;
+        this._model = this.application.model;
 
         this._searchView = builder.get_object('initial-grid');
 
@@ -87,11 +84,6 @@ var MainWindow = GObject.registerClass(
             this._searchLocationChanged(entry);
         });
 
-        let placesButton = builder.get_object('places-button');
-        this._pageWidgets[Page.CITY].push(placesButton);
-
-        placesButton.set_popover(this._worldView);
-
         let refresh = builder.get_object('refresh-button');
         this._pageWidgets[Page.CITY].push(refresh);
 
@@ -103,10 +95,13 @@ var MainWindow = GObject.registerClass(
 
         this._stack = builder.get_object('main-stack');
 
-        this._cityView = new City.WeatherView({ hexpand: true,
-                                                vexpand: true });
+        this._cityView = new City.WeatherView(this.application, this,
+                                              { hexpand: true, vexpand: true });
         this._stack.add(this._cityView);
 
+        this._forecastStackSwitcher = new Gtk.StackSwitcher({visible: true});
+        this._forecastStackSwitcher.set_stack(this._cityView.getInfoPage().getForecastStack());
+
         this._stack.set_visible_child(this._searchView);
 
         this.add(grid);
@@ -134,24 +129,11 @@ var MainWindow = GObject.registerClass(
         }
     }
 
-    _getTitle() {
-        if (this._currentPage == Page.SEARCH)
-            return [_("Select Location"), null];
-
-        let location = this._cityView.info.location;
-        let city = location;
-        if (location.get_level() == GWeather.LocationLevel.WEATHER_STATION)
-            city = location.get_parent();
-
-        let country = city.get_parent();
-        while (country &&
-               country.get_level() > GWeather.LocationLevel.COUNTRY)
-            country = country.get_parent();
-
-        if (country)
-            return [city.get_name(), country.get_name()];
+    _setTitle(page) {
+        if (page == Page.CITY)
+            this._header.set_custom_title(this._forecastStackSwitcher);
         else
-            return [city.get_name(), null];
+            this._header.set_custom_title(null);
     }
 
     _goToPage(page) {
@@ -164,11 +146,9 @@ var MainWindow = GObject.registerClass(
                 this._pageWidgets[page][i].show();
         }
 
-        this._currentPage = page;
+        this._setTitle(page);
 
-        let [title, subtitle] = this._getTitle();
-        this._header.title = title;
-        this._header.subtitle = subtitle;
+        this._currentPage = page;
     }
 
     showDefault() {
@@ -218,14 +198,6 @@ var MainWindow = GObject.registerClass(
         this.currentInfo = info;
         this._cityView.info = info;
 
-        let isCurrentTimezone = false;
-        let currentLocation = this.application.currentLocationController.currentLocation;
-        if (currentLocation) {
-            isCurrentTimezone = currentLocation.get_timezone().get_tzid() == 
info.location.get_timezone().get_tzid();
-        }
-        this._cityView.setTimeVisible(!isCurrentTimezone);
-
-        this._worldView.refilter();
         this._stack.set_visible_child(this._cityView);
         this._goToPage(Page.CITY);
     }
diff --git a/src/misc/util.js b/src/misc/util.js
index f63cbd8..0494e5e 100644
--- a/src/misc/util.js
+++ b/src/misc/util.js
@@ -156,3 +156,48 @@ function easeOutCubic(value) {
     let t = value - 1;
     return t * t * t + 1;
 }
+
+function getNight(date) {
+    return GLib.DateTime.new_local(date.get_year(),
+                                   date.get_month(),
+                                   date.get_day_of_month(),
+                                   2, 0, 0);
+}
+
+function getMorning(date) {
+    return GLib.DateTime.new_local(date.get_year(),
+                                   date.get_month(),
+                                   date.get_day_of_month(),
+                                   7, 0, 0);
+}
+
+function getDay(date) {
+    return GLib.DateTime.new_local(date.get_year(),
+                                   date.get_month(),
+                                   date.get_day_of_month(),
+                                   12, 0, 0);
+}
+
+function getAfternoon(date) {
+    return GLib.DateTime.new_local(date.get_year(),
+                                   date.get_month(),
+                                   date.get_day_of_month(),
+                                   17, 0, 0);
+}
+
+function getEvening(date) {
+    return GLib.DateTime.new_local(date.get_year(),
+                                   date.get_month(),
+                                   date.get_day_of_month(),
+                                   22, 0, 0);
+}
+
+function getDateTime(info) {
+    let [ok, date] = info.get_value_update();
+    return GLib.DateTime.new_from_unix_local(date);
+}
+
+function getTemp(info) {
+    let [ok, temp] = info.get_value_temp(GWeather.TemperatureUnit.DEFAULT);
+    return temp;
+}
diff --git a/src/org.gnome.Weather.src.gresource.xml.in b/src/org.gnome.Weather.src.gresource.xml.in
index 7234183..17b7432 100644
--- a/src/org.gnome.Weather.src.gresource.xml.in
+++ b/src/org.gnome.Weather.src.gresource.xml.in
@@ -3,8 +3,8 @@
   <gresource prefix="/org/gnome/Weather@profile@/js">
     <file>app/city.js</file>
     <file>app/currentLocationController.js</file>
-    <file>app/forecast.js</file>
-    <file>app/weeklyForecast.js</file>
+    <file>app/hourlyForecast.js</file>
+    <file>app/dailyForecast.js</file>
     <file>app/main.js</file>
     <file>app/window.js</file>
     <file>app/world.js</file>



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