Select a mission
This commit is contained in:
parent
882a645926
commit
654c71f3ee
@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "View.h"
|
||||
#include "events.h"
|
||||
#include "widgets.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
class AMI final : public View {
|
||||
@ -14,6 +16,7 @@ public:
|
||||
~AMI();
|
||||
|
||||
void draw() override;
|
||||
void handle_events(std::queue<Event>& events) override;
|
||||
|
||||
private:
|
||||
TTF_Font* avenir;
|
||||
|
@ -1,13 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "events.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <queue>
|
||||
|
||||
class View {
|
||||
public:
|
||||
View(SDL_Renderer* renderer);
|
||||
virtual ~View();
|
||||
|
||||
virtual void draw() = 0;
|
||||
virtual void handle_events(std::queue<Event>& events) = 0;
|
||||
|
||||
protected:
|
||||
SDL_Renderer* renderer;
|
||||
|
3
include/events.h
Normal file
3
include/events.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
enum class Event { Next, Prev, Confirm };
|
@ -85,10 +85,16 @@ public:
|
||||
|
||||
virtual void draw() override;
|
||||
|
||||
void select_next();
|
||||
void select_prev();
|
||||
size_t get_selection();
|
||||
|
||||
protected:
|
||||
int element_height;
|
||||
Alignment element_alignment;
|
||||
|
||||
size_t selection;
|
||||
|
||||
std::vector<Widget*> elements;
|
||||
|
||||
void place_element(Widget* element, int index);
|
||||
|
25
src/AMI.cpp
25
src/AMI.cpp
@ -1,10 +1,14 @@
|
||||
#include "AMI.h"
|
||||
|
||||
#include "defines.h"
|
||||
#include "events.h"
|
||||
#include "util.h"
|
||||
#include "widgets.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
constexpr const char* FT_LOGO_PATH = "resources/Fasttube_Logo-white.bmp";
|
||||
@ -62,4 +66,25 @@ void AMI::draw() {
|
||||
for (const auto& widget : widgets) {
|
||||
widget->draw();
|
||||
}
|
||||
}
|
||||
|
||||
void AMI::handle_events(std::queue<Event>& events) {
|
||||
while (!events.empty()) {
|
||||
Event e = events.front();
|
||||
events.pop();
|
||||
switch (e) {
|
||||
case Event::Next:
|
||||
missions_widget->select_next();
|
||||
break;
|
||||
case Event::Prev:
|
||||
missions_widget->select_prev();
|
||||
break;
|
||||
case Event::Confirm:
|
||||
std::cout << fmt::format("Selected mission {}\n",
|
||||
missions_widget->get_selection());
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(fmt::format("Unknown event: {}", (int)e));
|
||||
}
|
||||
}
|
||||
}
|
29
src/App.cpp
29
src/App.cpp
@ -1,11 +1,15 @@
|
||||
#include "App.h"
|
||||
|
||||
#include "AMI.h"
|
||||
#include "events.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_events.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_keycode.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <queue>
|
||||
#include <stdexcept>
|
||||
|
||||
App::App() : view{AppView::AMI} { init_sdl(); }
|
||||
@ -48,12 +52,37 @@ int App::run() {
|
||||
}
|
||||
|
||||
void App::handle_events() {
|
||||
std::queue<Event> events;
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e) != 0) {
|
||||
if (e.type == SDL_QUIT) {
|
||||
running = false;
|
||||
} else if (e.type == SDL_KEYUP) {
|
||||
switch (e.key.keysym.sym) {
|
||||
case SDLK_DOWN:
|
||||
case SDLK_RIGHT:
|
||||
events.push(Event::Next);
|
||||
break;
|
||||
case SDLK_UP:
|
||||
case SDLK_LEFT:
|
||||
events.push(Event::Prev);
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
case SDLK_KP_ENTER:
|
||||
events.push(Event::Confirm);
|
||||
break;
|
||||
// We can just ignore other keypresses, so no need for a default clause
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (view) {
|
||||
case AppView::AMI:
|
||||
ami->handle_events(events);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(fmt::format("Unknown view: {}", (int)view));
|
||||
}
|
||||
}
|
||||
|
||||
void App::render() {
|
||||
|
@ -7,8 +7,19 @@
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
constexpr uint8_t LIST_SELECTION_BG_R = 0x77;
|
||||
constexpr uint8_t LIST_SELECTION_BG_G = 0x33;
|
||||
constexpr uint8_t LIST_SELECTION_BG_B = 0x33;
|
||||
constexpr uint8_t LIST_OTHER_BG_R = 0x22;
|
||||
constexpr uint8_t LIST_OTHER_BG_G = 0x22;
|
||||
constexpr uint8_t LIST_OTHER_BG_B = 0x22;
|
||||
constexpr uint8_t LIST_NORMAL_BG_R = 0x00;
|
||||
constexpr uint8_t LIST_NORMAL_BG_G = 0x00;
|
||||
constexpr uint8_t LIST_NORMAL_BG_B = 0x00;
|
||||
|
||||
PositionInfo::PositionInfo() : x{0}, y{0}, align{Alignment::LEFT} {}
|
||||
|
||||
Widget::Widget(SDL_Renderer* renderer) : renderer{renderer}, rect{0, 0, 0, 0} {}
|
||||
@ -144,7 +155,7 @@ SDL_Texture* TextWidget::generate_text(const std::string& text) {
|
||||
ListWidget::ListWidget(SDL_Renderer* renderer, int element_height,
|
||||
Alignment element_alignment)
|
||||
: Widget{renderer}, element_height{element_height},
|
||||
element_alignment{element_alignment} {}
|
||||
element_alignment{element_alignment}, selection{0} {}
|
||||
|
||||
ListWidget::~ListWidget() {}
|
||||
|
||||
@ -163,12 +174,19 @@ void ListWidget::draw() {
|
||||
// Since the elements are sorted, we can stop the loop now.
|
||||
break;
|
||||
}
|
||||
if (i % 2 == 1) {
|
||||
SDL_SetRenderDrawColor(renderer, 0x11, 0x11, 0x11, 0xFF);
|
||||
SDL_Rect fill_rect = {
|
||||
.x = pos.x, .y = element_pos.y, .w = rect.w, .h = element_height};
|
||||
SDL_RenderFillRect(renderer, &fill_rect);
|
||||
if (i == selection) {
|
||||
SDL_SetRenderDrawColor(renderer, LIST_SELECTION_BG_R, LIST_SELECTION_BG_G,
|
||||
LIST_SELECTION_BG_B, 0xFF);
|
||||
} else if (i % 2 == 1) {
|
||||
SDL_SetRenderDrawColor(renderer, LIST_OTHER_BG_R, LIST_OTHER_BG_G,
|
||||
LIST_OTHER_BG_B, 0xFF);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(renderer, LIST_NORMAL_BG_R, LIST_NORMAL_BG_G,
|
||||
LIST_NORMAL_BG_B, 0xFF);
|
||||
}
|
||||
SDL_Rect fill_rect = {
|
||||
.x = pos.x, .y = element_pos.y, .w = rect.w, .h = element_height};
|
||||
SDL_RenderFillRect(renderer, &fill_rect);
|
||||
element->draw();
|
||||
if (i != elements.size() - 1) {
|
||||
int border_y = element_pos.y + element->get_height();
|
||||
@ -178,6 +196,28 @@ void ListWidget::draw() {
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::select_next() {
|
||||
size_t n = elements.size();
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
selection = (selection + 1) % n;
|
||||
}
|
||||
|
||||
void ListWidget::select_prev() {
|
||||
size_t n = elements.size();
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
if (selection == 0) {
|
||||
selection = n - 1;
|
||||
} else {
|
||||
selection = selection - 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ListWidget::get_selection() { return selection; }
|
||||
|
||||
void ListWidget::place_element(Widget* element, int index) {
|
||||
int x = rect.x;
|
||||
switch (element_alignment) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user