Files
MuditaOS/module-gui/gui/widgets/TopBar.cpp
Michał Kamoń eec4370cdc [EGD-5703] Fix SimCard topBar icon on Desktop
In initial design a `TobBar`'s SimCard icon with number is supposed
to display on the home screen only if there are two cards inserted.
Because of the hardware limitations (there is no way of telling if
there is a single or two cards inserted) the established consensus is
that home screen should not display SimCard widget unless it's
indication error state.

Although in the task description there is only home screen mentioned,
the behaviour was established for all `ApplicationDesktop`'s windows.
2021-04-27 08:14:17 +02:00

324 lines
10 KiB
C++

// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <iomanip>
#include "Label.hpp"
#include "Image.hpp"
#include "BoxLayout.hpp"
#include "TopBar.hpp"
#include "TopBar/Style.hpp"
#include "TopBar/BatteryBar.hpp"
#include "TopBar/BatteryText.hpp"
#include "TopBar/SignalStrengthBar.hpp"
#include "TopBar/SignalStrengthText.hpp"
#include "TopBar/NetworkAccessTechnology.hpp"
#include "TopBar/PhoneMode.hpp"
#include "TopBar/SIM.hpp"
#include "TopBar/Time.hpp"
#include "TopBar/Lock.hpp"
#include "common_data/EventStore.hpp"
namespace gui::top_bar
{
using namespace style::header::status_bar;
constexpr auto batteryWidgetAsText = true;
using BatteryType = std::conditional<batteryWidgetAsText, BatteryText, BatteryBar>::type;
constexpr auto signalWidgetAsText = true;
using SignalType = std::conditional<signalWidgetAsText, SignalStrengthText, SignalStrengthBar>::type;
constexpr auto simWidgetInDevelopersMode = false;
using SimType = std::conditional<simWidgetInDevelopersMode, SIMDevelopersMode, SIM>::type;
void Configuration::enable(Indicator indicator)
{
setIndicator(indicator, true);
}
void Configuration::enable(const Indicators &indicators)
{
for (auto indicator : indicators) {
enable(indicator);
}
}
void Configuration::disable(Indicator indicator)
{
setIndicator(indicator, false);
}
void Configuration::setIndicator(Indicator indicator, bool enabled)
{
indicatorStatuses[indicator] = enabled;
}
auto Configuration::getPhoneMode() const noexcept -> sys::phone_modes::PhoneMode
{
return mPhoneMode;
}
void Configuration::setPhoneMode(sys::phone_modes::PhoneMode phoneMode)
{
mPhoneMode = phoneMode;
}
auto Configuration::isEnabled(Indicator indicator) const -> bool
{
return indicatorStatuses.at(indicator);
}
auto Configuration::getIndicatorsConfiguration() const noexcept -> const IndicatorStatuses &
{
return indicatorStatuses;
}
auto Configuration::getIndicatorsModifiers() const noexcept -> const IndicatorsModifiers &
{
return indicatorsModifiers;
}
void Configuration::setIndicatorModifier(Indicator indicator, std::shared_ptr<StatusBarVisitor> config)
{
indicatorsModifiers[indicator] = std::move(config);
}
TopBar::TopBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) : HBox{parent, x, y, w, h}
{
prepareWidget();
setEdges(RectangleEdge::None);
setAlignment(Alignment(Alignment::Horizontal::Center));
updateDrawArea();
preBuildDrawListHook = [this](std::list<Command> &) { updateTime(); };
}
void TopBar::prepareWidget()
{
// left
leftBox = new HBox(this, 0, 0, 0, 0);
leftBox->setMinimumSize(boxes::left::minX, this->drawArea.h);
leftBox->setMaximumSize(boxes::left::maxX, this->drawArea.h);
leftBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
leftBox->setEdges(RectangleEdge::None);
signal = new SignalType(leftBox, 0, 0, 0, 0);
signal->setMargins(gui::Margins(margins::between, 0, 0, margins::iconBottom));
networkAccessTechnology = new NetworkAccessTechnology(leftBox, 0, 0, 0, 0);
networkAccessTechnology->setMaximumSize(nat::maxX, this->drawArea.h);
networkAccessTechnology->setMargins(gui::Margins(margins::between, 0, 0, margins::textBottom));
phoneMode = new PhoneMode(leftBox, 0, 0, 0, 0);
phoneMode->setMaximumSize(phonemode::maxX, this->drawArea.h);
phoneMode->setMargins(gui::Margins(margins::between, 0, 0, margins::textBottom));
phoneMode->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
// center
centralBox = new HBox(this, 0, 0, 0, 0);
centralBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Bottom));
centralBox->setEdges(RectangleEdge::None);
lock = new Lock(centralBox, 0, 0);
lock->setMargins(Margins(0, 0, 0, margins::iconBottom));
time = new Time(centralBox, 0, 0, 0, 0);
time->setMaximumSize(time::maxX, this->drawArea.h);
// right
rightBox = new HBox(this, 0, 0, 0, 0);
rightBox->setMinimumSize(boxes::right::minX, this->drawArea.h);
rightBox->setMaximumSize(boxes::right::maxX, this->drawArea.h);
rightBox->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Bottom));
rightBox->setEdges(RectangleEdge::None);
rightBox->setReverseOrder(true);
battery = new BatteryType(rightBox, 0, 0, 0, 0);
battery->setMargins(gui::Margins(0, 0, margins::between, margins::iconBottom));
sim = new SimType(rightBox, 0, 0);
sim->setMargins(gui::Margins(0, 0, margins::between, margins::iconBottom));
updateSignalStrength();
updateNetworkAccessTechnology();
updatePhoneMode();
}
auto TopBar::getConfiguration() const noexcept -> const Configuration &
{
return configuration;
}
void TopBar::configure(Configuration &&config)
{
if (config.isEnabled(Indicator::Lock)) {
// In current implementation, lock and time indicators are mutually exclusive.
// I.e. enabling the lock indicator disables the time indicator.
config.disable(Indicator::Time);
}
// phone mode and NAT are mutually exclusive.
if (config.isEnabled(Indicator::NetworkAccessTechnology)) {
config.disable(Indicator::PhoneMode);
}
if (config.isEnabled(Indicator::PhoneMode)) {
phoneMode->setPhoneMode(config.getPhoneMode());
}
for (auto &[indicator, modifier] : config.getIndicatorsModifiers()) {
setIndicatorModifier(indicator, *modifier);
}
for (auto [indicator, enabled] : config.getIndicatorsConfiguration()) {
setIndicatorStatus(indicator, enabled);
}
configuration = std::move(config);
leftBox->resizeItems();
resizeItems();
}
void TopBar::setIndicatorStatus(Indicator indicator, bool enabled)
{
switch (indicator) {
case Indicator::Signal:
showSignalStrength(enabled);
break;
case Indicator::Time:
showTime(enabled);
break;
case Indicator::Lock:
showLock(enabled);
break;
case Indicator::Battery:
showBattery(enabled);
break;
case Indicator::SimCard:
showSim(enabled);
break;
case Indicator::NetworkAccessTechnology:
showNetworkAccessTechnology(enabled);
break;
case Indicator::PhoneMode:
showPhoneMode(enabled);
break;
}
}
void TopBar::setIndicatorModifier(Indicator indicator, StatusBarVisitor &modifier)
{
if (indicator == Indicator::SimCard && sim != nullptr) {
sim->acceptStatusBarVisitor(modifier);
}
else if (indicator == Indicator::Time && time != nullptr) {
time->acceptStatusBarVisitor(modifier);
}
}
bool TopBar::updateBattery()
{
if (battery == nullptr) {
return false;
}
showBattery(configuration.isEnabled(Indicator::Battery));
return true;
}
void TopBar::showBattery(bool enabled)
{
battery->update(Store::Battery::get());
enabled ? battery->show() : battery->hide();
}
void TopBar::showSim(bool enabled)
{
sim->update(Store::GSM::get()->sim);
enabled ? sim->show() : sim->hide();
}
bool TopBar::updateSim()
{
if (sim == nullptr) {
return false;
}
showSim(configuration.isEnabled(Indicator::SimCard));
return true;
}
void TopBar::showSignalStrength(bool enabled)
{
auto signalStrength = Store::GSM::get()->getSignalStrength();
signal->update(signalStrength);
enabled ? signal->show() : signal->hide();
}
bool TopBar::updateSignalStrength()
{
if (signal == nullptr) {
return false;
}
showSignalStrength(configuration.isEnabled(Indicator::Signal));
return true;
}
bool TopBar::updatePhoneMode()
{
if (phoneMode == nullptr) {
return false;
}
showPhoneMode(configuration.isEnabled(Indicator::PhoneMode));
return true;
}
void TopBar::showPhoneMode(bool enabled)
{
enabled ? phoneMode->show() : phoneMode->hide();
}
bool TopBar::updateNetworkAccessTechnology()
{
if (networkAccessTechnology == nullptr) {
return false;
}
showNetworkAccessTechnology(configuration.isEnabled(Indicator::NetworkAccessTechnology));
return true;
}
void TopBar::showNetworkAccessTechnology(bool enabled)
{
networkAccessTechnology->update(Store::GSM::get()->getNetwork().accessTechnology);
enabled ? networkAccessTechnology->show() : networkAccessTechnology->hide();
}
void TopBar::showTime(bool enabled)
{
time->update();
if (enabled) {
centralBox->setMinimumSize(boxes::center::maxX, this->drawArea.h);
time->show();
lock->hide();
centralBox->resizeItems();
return;
}
time->hide();
}
void TopBar::showLock(bool enabled)
{
if (enabled) {
centralBox->setMinimumSize(boxes::center::minX, this->drawArea.h);
lock->show();
time->hide();
return;
}
lock->hide();
}
bool TopBar::updateTime()
{
if (time == nullptr) {
return false;
}
showTime(configuration.isEnabled(Indicator::Time));
return true;
}
void TopBar::accept(GuiVisitor &visitor)
{
visitor.visit(*this);
}
} // namespace gui::top_bar