[bootloader > interfaces] Interface improvement

This commit is contained in:
devdl11
2022-04-08 23:44:24 +02:00
parent 21f08a2d06
commit ff307b8df8
10 changed files with 307 additions and 4 deletions

View File

@@ -6,13 +6,10 @@
#include <escher/image.h>
namespace Bootloader {
class Interface {
private:
static void drawImage(KDContext * ctx, const Image * image, int offset);
public:
static void drawImage(KDContext * ctx, const Image * image, int offset);
static void drawLoading();
static void drawHeader();
static void drawMenu();

View File

@@ -0,0 +1,13 @@
#include "about.h"
Bootloader::AboutMenu::AboutMenu() : Menu(KDColorBlack, KDColorWhite, Messages::aboutMenuTitle, Messages::bootloaderVersion) {
setup();
}
void Bootloader::AboutMenu::setup() {
m_colomns[0] = Colomn("This is the bootloader of", k_small_font, 0, true);
m_colomns[1] = Colomn("the Upsilon Calculator.", k_small_font, 0, true);
m_colomns[2] = Colomn("It is used to install", k_small_font, 0, true);
m_colomns[3] = Colomn("and select the OS", k_small_font, 0, true);
m_colomns[4] = Colomn("to boot.", k_small_font, 0, true);
}

View File

@@ -0,0 +1,17 @@
#ifndef _BOOTLOADER_INTERFACE_ABOUT_ABOUT_H_
#define _BOOTLOADER_INTERFACE_ABOUT_ABOUT_H_
#include <bootloader/interface/src/menu.h>
namespace Bootloader {
class AboutMenu : public Menu {
public:
AboutMenu();
void setup() override;
};
}
#endif

View File

@@ -0,0 +1,62 @@
#include "home.h"
#include <bootloader/slot.h>
#include <bootloader/interface/menus/about/about.h>
Bootloader::AboutMenu * Bootloader::HomeMenu::aboutMenu() {
static AboutMenu * aboutMenu = new AboutMenu();
return aboutMenu;
}
Bootloader::HomeMenu::HomeMenu() : Menu(KDColorBlack, KDColorWhite, Messages::mainMenuTitle, Messages::mainTitle) {
setup();
}
bool slotA_submenu() {
if (Bootloader::Slot::isFullyValid(Bootloader::Slot::A())) {
}
return false;
}
bool slotKhi_submenu() {
if (Bootloader::Slot::isFullyValid(Bootloader::Slot::Khi())) {
}
return false;
}
bool slotB_submenu() {
if (Bootloader::Slot::isFullyValid(Bootloader::Slot::B())) {
}
return false;
}
bool installer_submenu() {
}
bool about_submenu() {
Bootloader::HomeMenu::aboutMenu()->open();
return true;
}
const char * Bootloader::HomeMenu::slotA_text() {
return Slot::isFullyValid(Slot::A()) ? "1 - Slot A" : Messages::invalidSlot;
}
const char * Bootloader::HomeMenu::slotKhi_text() {
return Slot::isFullyValid(Slot::Khi()) ? "2 - Slot Khi" : Messages::invalidSlot;
}
const char * Bootloader::HomeMenu::slotB_text() {
return Slot::isFullyValid(Slot::B()) ? "3 - Slot B" : Messages::invalidSlot;
}
void Bootloader::HomeMenu::setup() {
m_colomns[0] = Colomn(slotA_text(), Ion::Keyboard::Key::One, k_large_font, 10, false, &slotA_submenu);
m_colomns[1] = Colomn(slotKhi_text(), Ion::Keyboard::Key::Two, k_large_font, 10, false, &slotKhi_submenu);
m_colomns[2] = Colomn(slotB_text(), Ion::Keyboard::Key::Three, k_large_font, 10, false, &slotB_submenu);
m_colomns[3] = Colomn("4- installer", Ion::Keyboard::Key::Four, k_large_font, 10, false, &installer_submenu);
m_colomns[4] = Colomn("5- about", Ion::Keyboard::Key::Five, k_large_font, 10, false, &about_submenu);
}

View File

@@ -0,0 +1,23 @@
#ifndef _BOOTLOADER_INTERFACE_HOME_HOME_H_
#define _BOOTLOADER_INTERFACE_HOME_HOME_H_
#include <bootloader/interface/src/menu.h>
#include <bootloader/interface/menus/about/about.h>
namespace Bootloader {
class HomeMenu : public Menu {
public:
HomeMenu();
void setup() override;
static AboutMenu * aboutMenu();
private:
const char * slotA_text();
const char * slotKhi_text();
const char * slotB_text();
};
}
#endif

View File

@@ -0,0 +1,15 @@
#ifndef _BOOTLOADER_INTERFACE_MENUS_INSTALLER_INSTALLER_H_
#define _BOOTLOADER_INTERFACE_MENUS_INSTALLER_INSTALLER_H_
#include <bootloader/interface/src/menu.h>
namespace Bootloader {
class InstallerMenu : public Menu {
public:
InstallerMenu();
void setup() override;
};
}
#endif

View File

@@ -0,0 +1,88 @@
#include <bootloader/interface/src/menu.h>
#include <bootloader/interface.h>
#include <ion.h>
#include <kandinsky/context.h>
#include <string.h>
#include "computer.h"
void Bootloader::Menu::setup() {
// Here we add the colomns to the menu.
}
void Bootloader::Menu::open() {
showMenu();
uint64_t scan = 0;
bool exit = false;
while(!exit) {
scan = Ion::Keyboard::scan();
exit = !handleKey(scan);
}
}
int Bootloader::Menu::calculateCenterX(const char * text, int fontWidth) {
return (k_screen.width() - fontWidth * strlen(text)) / 2;
}
void Bootloader::Menu::showMenu() {
KDContext * ctx = KDIonContext::sharedContext();
ctx->fillRect(k_screen, m_background);
Interface::drawImage(ctx, ImageStore::Computer, 25);
int y = ImageStore::Computer->height() + 25 + 10;
int x = calculateCenterX(m_title, largeFontWidth());
ctx->drawString(m_title, KDPoint(x, y), k_large_font, m_foreground, m_background);
y += largeFontHeight() + 10;
//TODO: center the colomns if m_centerY is true
for (Colomn & colomn : m_colomns) {
if (colomn.isNull()) {
break;
}
y += colomn.draw(ctx, y, m_background, m_foreground) + k_colomns_margin;
}
if (m_bottom != nullptr) {
y = k_screen.height() - smallFontHeight() - 10;
x = calculateCenterX(m_bottom, smallFontWidth());
ctx->drawString(m_bottom, KDPoint(x, y), k_small_font, m_foreground, m_background);
}
}
bool Bootloader::Menu::handleKey(uint64_t key) {
for (Ion::Keyboard::Key breaking : this->k_breaking_keys) {
if (Ion::Keyboard::State(breaking) == key) {
return false;
}
}
if (key == Ion::Keyboard::State(Ion::Keyboard::Key::Power)) {
Ion::Power::standby();
return false;
}
for (Colomn & colomn : this->m_colomns) {
if (colomn.isNull() || !colomn.isClickable()) {
continue;
} else {
colomn.didHandledEvent(key);
}
}
return true;
}
bool Bootloader::Menu::Colomn::didHandledEvent(uint64_t key) {
if (isMyKey(key) && isClickable()) {
return m_callback();
}
return false;
}
int Bootloader::Menu::Colomn::draw(KDContext * ctx, int y, KDColor background, KDColor foreground) {
int x = m_extraX;
if (m_center) {
x += Bootloader::Menu::calculateCenterX(m_text, m_font->glyphSize().width());
}
ctx->drawString(m_text, KDPoint(x, y), m_font, foreground, background);
return m_font->glyphSize().height();
}

View File

@@ -0,0 +1,83 @@
#ifndef _BOOTLOADER_MENU_H_
#define _BOOTLOADER_MENU_H_
#include <ion/keyboard.h>
#include <bootloader/messages.h>
#include <kandinsky/context.h>
namespace Bootloader {
class Menu {
public:
Menu() : m_colomns(), m_background(KDColorWhite), m_title(Messages::mainTitle), m_foreground(KDColorBlack), m_bottom(nullptr), m_centerY(false) {
setup();
};
Menu(KDColor forground, KDColor background, const char * title) : m_colomns(), m_background(background), m_title(title), m_foreground(forground), m_bottom(nullptr), m_centerY(false) {
setup();
};
Menu(KDColor forground, KDColor background, const char * title, const char * bottom) : m_colomns(), m_background(background), m_title(title), m_foreground(forground), m_bottom(bottom), m_centerY(false) {
setup();
};
Menu(KDColor forground, KDColor background, const char * title, const char * bottom, bool centerY) : m_colomns(), m_background(background), m_title(title), m_foreground(forground), m_bottom(bottom), m_centerY(centerY) {
setup();
}
virtual void setup() = 0;
class Colomn {
public:
Colomn() : m_text(nullptr), m_key(Ion::Keyboard::Key::None), m_font(KDFont::SmallFont), m_extraX(0), m_center(false), m_callback(nullptr) {};
Colomn(const char * t, Ion::Keyboard::Key k, const KDFont * font, int extraX, bool center, bool(*pointer)()) : m_text(t), m_key(k), m_font(font), m_extraX(extraX), m_center(center), m_callback(pointer), m_clickable(true) {};
Colomn(const char * t, const KDFont * font, int extraX, bool center) : m_text(t), m_key(Ion::Keyboard::Key::None), m_font(font), m_extraX(extraX), m_center(center), m_callback(nullptr), m_clickable(false) {};
bool isNull() const { return m_text == nullptr; };
bool isClickable() const { return m_clickable; };
bool didHandledEvent(uint64_t key);
int draw(KDContext * ctx, int y, KDColor background, KDColor foreground);
private:
bool isMyKey(uint64_t key) const { return Ion::Keyboard::State(m_key) == key; };
const char * m_text;
Ion::Keyboard::Key m_key;
const KDFont * m_font;
int m_extraX;
bool m_center;
bool m_clickable;
bool (*m_callback)();
};
void open();
void redraw() { showMenu(); };
static int calculateCenterX(const char * text, int fontWidth);
static constexpr const KDFont * k_small_font = KDFont::SmallFont;
static constexpr const KDFont * k_large_font = KDFont::LargeFont;
private:
static const int k_max_colomns = 5;
static const int k_colomns_margin = 5;
static constexpr Ion::Keyboard::Key k_breaking_keys[] = {Ion::Keyboard::Key::Back, Ion::Keyboard::Key::Home};
static constexpr KDRect k_screen = KDRect(0, 0, 320, 240);
int smallFontHeight() const { return k_small_font->glyphSize().height(); };
int largeFontHeight() const { return k_large_font->glyphSize().height(); };
int smallFontWidth() const { return k_small_font->glyphSize().width(); };
int largeFontWidth() const { return k_large_font->glyphSize().width(); };
bool handleKey(uint64_t key);
void showMenu();
protected:
Colomn m_colomns[k_max_colomns];
KDColor m_background;
KDColor m_foreground;
const char * m_title;
const char * m_bottom;
bool m_centerY;
};
}
#endif // _BOOTLOADER_MENU_H_

View File

@@ -45,6 +45,7 @@ public:
constexpr static const char * epsilonWarningText5 = "EXE - Yes";
constexpr static const char * epsilonWarningText6 = "BACK - No";
constexpr static const char * bootloaderVersion = "Version 1.0.0 - FREEDOM";
constexpr static const char * aboutMenuTitle = "About";
//USB NAMES

View File

@@ -24,6 +24,10 @@ public:
static const Slot B();
static const Slot Khi();
static bool isFullyValid(const Slot& slot) {
return slot.kernelHeader()->isValid() && slot.userlandHeader()->isValid();
}
private:
const KernelHeader* m_kernelHeader;
const UserlandHeader* m_userlandHeader;