Skip to content

Commit

Permalink
Display alerts
Browse files Browse the repository at this point in the history
Refs: #24
  • Loading branch information
orontee committed Sep 12, 2023
1 parent 5a92d7b commit 4e15cd2
Show file tree
Hide file tree
Showing 18 changed files with 282 additions and 41 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Display alerts [#24](https://github.com/orontee/argos/issues/24)

- Polish translations [#22](https://github.com/orontee/argos/issues/22)

### Changed
Expand Down
Binary file added icons/icon_warning.bmp
Binary file not shown.
3 changes: 2 additions & 1 deletion icons/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ icons = files(
'icon_11n_2x.bmp',
'icon_13n_2x.bmp',
'icon_50n_2x.bmp',
'icon_menu.bmp'
'icon_menu.bmp',
'icon_warning.bmp'
)
72 changes: 72 additions & 0 deletions src/alerts.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "alerts.h"

#include <iomanip>
#include <sstream>

#include "events.h"
#include "util.h"

#define T(x) GetLangText(x)

#define OK_BUTTON_INDEX 0
#define NEXT_ALERT_BUTTON_INDEX 1

static size_t alert_index{0};
static size_t alert_count{0};

inline bool is_next_alert_button_at(int button_index) {
return (alert_index + 1 < alert_count) ? button_index == 1 : false;
}

void taranis::alert_dialog_handler(int button_index) {
if (is_next_alert_button_at(button_index)) {
const auto event_handler = GetEventHandler();
++alert_index;
SendEvent(event_handler, EVT_CUSTOM, CustomEvent::display_alert, 0);
} else {
alert_index = 0;
}
CloseDialog();
}

void taranis::AlertsButton::open_dialog_maybe() {
alert_count = this->model->alerts.size();

if (alert_count == 0) {
return;
}
if (alert_index >= alert_count) {
return;
}

const auto &alert = this->model->alerts.at(alert_index);

const auto dialog_title = not alert.event.empty() ? alert.event : T("Alert");
// 😕 Looks like dialog title isn't displayed at all!

std::stringstream alert_text;
if (not alert.event.empty()) {
alert_text << alert.event << std::endl << std::endl;
}
alert_text << alert.description << std::endl << std::endl;
if (alert.start_date) {
alert_text << T("Start") << " " << format_time(alert.start_date, true)
<< std::endl;
if (alert.end_date) {
alert_text << T("Duration") << " "
<< format_duration(alert.start_date, alert.end_date)
<< std::endl;
}
}
if (not alert.sender.empty()) {
alert_text << T("Source") << " " << alert.sender;
}

const auto first_button_text =
alert_index + 1 < alert_count ? T("Next alert") : T("Ok");
const auto second_button_text =
alert_index + 1 < alert_count ? T("Ok") : nullptr;

Dialog(ICON_WARNING, dialog_title.c_str(), alert_text.str().c_str(),
first_button_text, second_button_text, &alert_dialog_handler);
}
57 changes: 57 additions & 0 deletions src/alerts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <experimental/optional>
#include <inkview.h>
#include <memory>

#include "button.h"
#include "fonts.h"
#include "icons.h"
#include "model.h"

namespace std {
template <class T> using optional = std::experimental::optional<T>;
}

namespace taranis {

void alert_dialog_handler(int button_index);

class AlertsButton : public Button {
public:
AlertsButton(std::shared_ptr<Model> model, std::shared_ptr<Icons> icons,
std::shared_ptr<Fonts> fonts)
: Button{AlertsButton::icon_size + 2 * AlertsButton::padding,
AlertsButton::icon_size + 2 * AlertsButton::padding,
BitmapStretchProportionally(icons->get("warning"),
AlertsButton::icon_size,
AlertsButton::icon_size)},
model{model}, font{fonts->get_normal_font()} {}

void show() override {
if (this->model->alerts.empty()) {
this->fill_bounding_box();
} else {
Button::show();
}
}

void open_dialog_maybe();

static const int padding{50};
static const int icon_size{70};

protected:
void on_clicked() override {
if (this->model->alerts.empty()) {
return;
}

this->open_dialog_maybe();
}

private:
std::shared_ptr<Model> model;
std::shared_ptr<ifont> font;
};
} // namespace taranis
8 changes: 8 additions & 0 deletions src/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ class App {
this->ui->show();
return 1;
}
} else if (param_one == CustomEvent::display_alert) {
if (this->ui) {
this->ui->display_alert();
return 1;
}
} else if (param_one == CustomEvent::new_location_requested) {
auto *const raw_location =
reinterpret_cast<std::array<char, 256> *>(GetCurrentEventExData());
Expand Down Expand Up @@ -198,6 +203,9 @@ class App {
++it;
}

const auto alerts = this->service->get_alerts();
this->model->alerts = alerts;

const auto event_handler = GetEventHandler();
SendEvent(event_handler, EVT_CUSTOM, CustomEvent::model_updated, 0);
} catch (const ConnectionError &error) {
Expand Down
17 changes: 5 additions & 12 deletions src/currentconditionbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "fonts.h"
#include "model.h"
#include "units.h"
#include "util.h"
#include "widget.h"

#define T(x) GetLangText(x)
Expand Down Expand Up @@ -108,19 +109,11 @@ class CurrentConditionBox : public Widget {
const auto condition = *(this->model->current_condition);
const Units units{this->model};

const char *const time_format = "%H:%M";
std::string sunrise_text{"?????"};
std::strftime(const_cast<char *>(sunrise_text.c_str()), 6, time_format,
std::localtime(&condition.sunrise));
std::string sunset_text{"?????"};
std::strftime(const_cast<char *>(sunset_text.c_str()), 6, time_format,
std::localtime(&condition.sunset));

std::stringstream content;
content << T("Sunrise") << std::right << std::setw(10) << sunrise_text
<< std::endl
<< T("Sunset") << std::right << std::setw(10) << sunset_text
<< std::endl
content << T("Sunrise") << std::right << std::setw(10)
<< format_time(condition.sunrise) << std::endl
<< T("Sunset") << std::right << std::setw(10)
<< format_time(condition.sunset) << std::endl
<< T("Pressure") << std::right << std::setw(10)
<< units.format_pressure(condition.pressure) << std::endl
<< T("Humidity") << std::right << std::setw(10)
Expand Down
1 change: 1 addition & 0 deletions src/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
enum CustomEvent {
about_dialog_requested,
change_unit_system,
display_alert,
model_updated,
new_location_requested,
refresh_requested,
Expand Down
5 changes: 1 addition & 4 deletions src/hourlyforecastbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,7 @@ class HourlyForecastBox : public Widget {

SetFont(tiny_font.get(), BLACK);

std::string time_text{"?????"};
const char *const time_format = "%H:%M";
std::strftime(const_cast<char *>(time_text.c_str()), 6, time_format,
std::localtime(&forecast.date));
const auto time_text = format_time(forecast.date);
DrawString(bar_center_x - StringWidth(time_text.c_str()) / 2.0,
this->time_y, time_text.c_str());

Expand Down
9 changes: 8 additions & 1 deletion src/icons.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ extern const ibitmap icon_11n_2x;
extern const ibitmap icon_13n_2x;
extern const ibitmap icon_50n_2x;
extern const ibitmap icon_menu;
extern const ibitmap icon_warning;
;

namespace taranis {
class Icons {
Expand All @@ -22,7 +24,8 @@ class Icons {
icon_03n{&::icon_03n_2x}, icon_04n{&::icon_04n_2x},
icon_09n{&::icon_09n_2x}, icon_10n{&::icon_10n_2x},
icon_11n{&::icon_11n_2x}, icon_13n{&::icon_13n_2x},
icon_50n{&::icon_50n_2x}, icon_menu{&::icon_menu} {}
icon_50n{&::icon_50n_2x}, icon_menu{&::icon_menu},
icon_warning{&::icon_warning} {}

ibitmap *get(const std::string &name) {
if (name == "01d" or name == "01n") {
Expand Down Expand Up @@ -55,6 +58,9 @@ class Icons {
if (name == "menu") {
return const_cast<ibitmap *>(this->icon_menu);
}
if (name == "warning") {
return const_cast<ibitmap *>(this->icon_warning);
}
return nullptr;
}

Expand All @@ -69,5 +75,6 @@ class Icons {
const ibitmap *const icon_13n;
const ibitmap *const icon_50n;
const ibitmap *const icon_menu;
const ibitmap *const icon_warning;
};
} // namespace taranis
14 changes: 14 additions & 0 deletions src/l10n.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ inline void initialize_translations() {
"Ce programme est fourni sans aucune garantie. Pour plus de détails, "
"lisez la License publique générale GNU, version 3 ou ultérieure.");

// alerts.h
AddTranslation("Alert", "Alerte");
AddTranslation("Start", "Début");
AddTranslation("Duration", "Durée");
AddTranslation("Source", "Source");
AddTranslation("Next alert", "Alerte suivante");

// app.h
AddTranslation("Unsupported software version", "Logiciel incompatible");
AddTranslation("The application isn't compatible with the software version "
Expand Down Expand Up @@ -96,6 +103,13 @@ inline void initialize_translations() {
"zapoznaj się z warunkami GNU General Public License w wersji 3 lub "
"nowszej.");

// alerts.h
AddTranslation("Alert", "Alert");
AddTranslation("Start", "Zacznij o");
AddTranslation("Duration", "Przez");
AddTranslation("Source", "Źródło");
AddTranslation("Next alert", "Następne powiadomienie");

// app.h
AddTranslation("Unsupported software version",
"Nieobsługiwana wersja oprogramowania");
Expand Down
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ about_cc = configure_file(


sources = [about_cc] + files(
'alerts.cc',
'app.cc',
'config.cc',
'currentconditionbox.cc',
Expand Down
10 changes: 10 additions & 0 deletions src/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ struct Condition {
long double snow;
};

struct Alert {
std::string sender;
std::string event;
std::time_t start_date;
std::time_t end_date;
std::string description;
};

struct Model {
std::string source;
UnitSystem unit_system{standard};
Expand All @@ -120,5 +128,7 @@ struct Model {

std::optional<Condition> current_condition;
std::vector<Condition> hourly_forecast;

std::vector<Alert> alerts;
};
} // namespace taranis
Loading

0 comments on commit 4e15cd2

Please sign in to comment.