mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-26 07:49:36 -05:00
Scrollable menuview
This commit is contained in:
parent
b4afdad7e6
commit
94b27ec45c
@ -27,24 +27,28 @@
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
/*
|
static constexpr uint8_t bitmap_more_data[] = {
|
||||||
00000000 00000000 00000000
|
0x00, 0x00,
|
||||||
11110001 11100111 10111110
|
0xC0, 0x03,
|
||||||
10001010 00001000 00001000
|
0xC0, 0x03,
|
||||||
10001010 00001000 00001000
|
0xC0, 0x03,
|
||||||
11110001 11000111 00001000
|
0xC0, 0x03,
|
||||||
10010000 00100000 10001000
|
0xC0, 0x03,
|
||||||
10001000 00100000 10001000
|
0xC0, 0x03,
|
||||||
10001011 11001111 00111110
|
0xC0, 0x03,
|
||||||
00000000 00000000 00000000
|
0xC6, 0x63,
|
||||||
11111100 01111000 01111000
|
0xCF, 0xF3,
|
||||||
10000100 01001000 01001000
|
0xDE, 0x7B,
|
||||||
10000100 01001000 01001000
|
0xFC, 0x3F,
|
||||||
10000100 01001000 01001000
|
0xF8, 0x1F,
|
||||||
10000100 01001000 01001000
|
0xF0, 0x0F,
|
||||||
10000100 01001000 01001000
|
0xE0, 0x07,
|
||||||
10000111 11001111 11001110
|
0xC0, 0x03
|
||||||
*/
|
};
|
||||||
|
|
||||||
|
static constexpr Bitmap bitmap_more {
|
||||||
|
{ 16, 16 }, bitmap_more_data
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr uint8_t bitmap_rssipwm_data[] = {
|
static constexpr uint8_t bitmap_rssipwm_data[] = {
|
||||||
0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00,
|
||||||
|
@ -26,31 +26,37 @@
|
|||||||
//BUG: No audio in about when shown second time
|
//BUG: No audio in about when shown second time
|
||||||
//BUG: Description doesn't show up first time going to system>module info (UI drawn on top)
|
//BUG: Description doesn't show up first time going to system>module info (UI drawn on top)
|
||||||
|
|
||||||
|
//TODO: Check AFSK transmit end, skips last bits ?
|
||||||
//TODO: Weird LCR AFSK scrambling ?
|
//TODO: Weird LCR AFSK scrambling ?
|
||||||
|
//TODO: Use msgpack !
|
||||||
//TODO: Frequency manager
|
//TODO: Frequency manager
|
||||||
//TODO: SD card wiper
|
|
||||||
//TODO: Draw on touchscreen and transmit as spectrum paint
|
|
||||||
//TODO: Use progressbars
|
|
||||||
//TODO: LCR receiver
|
|
||||||
//TODO: Xylos receiver
|
|
||||||
//TODO: Morse coder
|
//TODO: Morse coder
|
||||||
//TODO: Playdead amnesia and login
|
|
||||||
//TODO: Touch screen calibration
|
//Multimon-style stuff:
|
||||||
//TODO: Check jammer bandwidths
|
|
||||||
//TODO: GSM channel detector
|
|
||||||
//TODO: AFSK receiver
|
//TODO: AFSK receiver
|
||||||
|
//TODO: Xylos receiver
|
||||||
|
|
||||||
|
//TODO: Check jammer bandwidths
|
||||||
|
//TODO: Closecall wide range fix
|
||||||
|
//TODO: SD card wiper
|
||||||
|
//TODO: Use progressbars
|
||||||
|
//TODO: GSM channel detector
|
||||||
//TODO: SIGFOX RX/TX
|
//TODO: SIGFOX RX/TX
|
||||||
//TODO: Show MD5 mismatches for modules not found, etc...
|
|
||||||
//TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule
|
|
||||||
//TODO: Check bw setting in LCR TX
|
|
||||||
//TODO: Bodet :)
|
//TODO: Bodet :)
|
||||||
//TODO: Whistler
|
//TODO: Whistler
|
||||||
|
|
||||||
|
//TODO: LCR full message former (see norm)
|
||||||
|
//TODO: AFSK NRZI, parity and format
|
||||||
|
//TODO: TX power setting
|
||||||
|
|
||||||
|
//TODO: Playdead amnesia and login
|
||||||
//TODO: Setup: Play dead by default ? Enable/disable ?
|
//TODO: Setup: Play dead by default ? Enable/disable ?
|
||||||
//TODO: Hide statusview when playing dead
|
//TODO: Hide statusview when playing dead
|
||||||
//TODO: Persistent playdead !
|
//TODO: Persistent playdead !
|
||||||
//TODO: LCR full message former (see norm)
|
//TODO: Show MD5 mismatches for modules not found, etc...
|
||||||
//TODO: AFSK NRZI
|
//TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule
|
||||||
//TODO: TX power setting
|
|
||||||
|
//TODO: Draw on touchscreen and transmit as spectrum paint
|
||||||
//TODO: Two players tic-tac-toe
|
//TODO: Two players tic-tac-toe
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2016 Furrtek
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
@ -20,10 +21,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ui_menu.hpp"
|
#include "ui_menu.hpp"
|
||||||
|
#include "time.hpp"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
/* MenuViewItem **********************************************************/
|
/* MenuItemView **********************************************************/
|
||||||
|
|
||||||
void MenuItemView::select() {
|
void MenuItemView::select() {
|
||||||
if( item.on_select ) {
|
if( item.on_select ) {
|
||||||
@ -72,27 +74,67 @@ void MenuItemView::paint(Painter& painter) {
|
|||||||
|
|
||||||
/* MenuView **************************************************************/
|
/* MenuView **************************************************************/
|
||||||
|
|
||||||
|
MenuView::MenuView() {
|
||||||
|
set_focusable(true);
|
||||||
|
|
||||||
|
add_child(&arrow_more);
|
||||||
|
signal_token_tick_second = time::signal_tick_second += [this]() {
|
||||||
|
this->on_tick_second();
|
||||||
|
};
|
||||||
|
|
||||||
|
arrow_more.set_parent_rect( { 216, 320 - 16 - 24, 16, 16 } );
|
||||||
|
arrow_more.set_focusable(false);
|
||||||
|
}
|
||||||
|
|
||||||
MenuView::~MenuView() {
|
MenuView::~MenuView() {
|
||||||
/* TODO: Double-check this */
|
/* TODO: Double-check this */
|
||||||
for(auto child : children_) {
|
for (auto child : children_) {
|
||||||
delete child;
|
delete child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuView::on_tick_second() {
|
||||||
|
if (more_ && blink_)
|
||||||
|
arrow_more.set_foreground(Color::white());
|
||||||
|
else
|
||||||
|
arrow_more.set_foreground(Color::black());
|
||||||
|
|
||||||
|
blink_ = !blink_;
|
||||||
|
|
||||||
|
arrow_more.set_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
void MenuView::add_item(const MenuItem item) {
|
void MenuView::add_item(const MenuItem item) {
|
||||||
add_child(new MenuItemView { item });
|
add_child(new MenuItemView { item });
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuView::set_parent_rect(const Rect new_parent_rect) {
|
void MenuView::set_parent_rect(const Rect new_parent_rect) {
|
||||||
View::set_parent_rect(new_parent_rect);
|
View::set_parent_rect(new_parent_rect);
|
||||||
|
update_items();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuView::update_items() {
|
||||||
constexpr size_t item_height = 24;
|
constexpr size_t item_height = 24;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for(auto child : children_) {
|
Coord y_pos;
|
||||||
child->set_parent_rect({
|
|
||||||
{ 0, static_cast<ui::Coord>(i * item_height) },
|
if (MENU_MAX + offset_ < (children_.size() - 1))
|
||||||
{ size().w, item_height }
|
more_ = true;
|
||||||
});
|
else
|
||||||
|
more_ = false;
|
||||||
|
|
||||||
|
for (auto child : children_) {
|
||||||
|
if (i) { // Skip arrow widget
|
||||||
|
y_pos = (i - 1 - offset_) * item_height;
|
||||||
|
child->set_parent_rect({
|
||||||
|
{ 0, y_pos },
|
||||||
|
{ size().w, item_height }
|
||||||
|
});
|
||||||
|
if ((y_pos < 0) || (y_pos >= (320 - 16 - 24 - 16)))
|
||||||
|
child->hidden(true);
|
||||||
|
else
|
||||||
|
child->hidden(false);
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +143,7 @@ MenuItemView* MenuView::item_view(size_t index) const {
|
|||||||
/* TODO: Terrible cast! Take it as a sign I must be doing something
|
/* TODO: Terrible cast! Take it as a sign I must be doing something
|
||||||
* shamefully wrong here, right?
|
* shamefully wrong here, right?
|
||||||
*/
|
*/
|
||||||
return static_cast<MenuItemView*>(children_[index]);
|
return static_cast<MenuItemView*>(children_[index + 1]); // Skip arrow widget
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MenuView::highlighted() const {
|
size_t MenuView::highlighted() const {
|
||||||
@ -109,10 +151,20 @@ size_t MenuView::highlighted() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MenuView::set_highlighted(const size_t new_value) {
|
bool MenuView::set_highlighted(const size_t new_value) {
|
||||||
if( new_value >= children_.size() ) {
|
if( new_value >= (children_.size() - 1) ) { // Skip arrow widget
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((new_value - offset_ + 1) >= MENU_MAX) {
|
||||||
|
// Shift MenuView up
|
||||||
|
offset_ = new_value - MENU_MAX + 1;
|
||||||
|
update_items();
|
||||||
|
} else if (new_value < offset_) {
|
||||||
|
// Shift MenuView down
|
||||||
|
offset_ = new_value;
|
||||||
|
update_items();
|
||||||
|
}
|
||||||
|
|
||||||
item_view(highlighted())->unhighlight();
|
item_view(highlighted())->unhighlight();
|
||||||
highlighted_ = new_value;
|
highlighted_ = new_value;
|
||||||
item_view(highlighted())->highlight();
|
item_view(highlighted())->highlight();
|
||||||
|
@ -25,11 +25,15 @@
|
|||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
#include "ui_painter.hpp"
|
#include "ui_painter.hpp"
|
||||||
|
#include "bitmap.hpp"
|
||||||
|
#include "signal.hpp"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#define MENU_MAX 11
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
struct MenuItem {
|
struct MenuItem {
|
||||||
@ -64,17 +68,14 @@ class MenuView : public View {
|
|||||||
public:
|
public:
|
||||||
std::function<void(void)> on_left;
|
std::function<void(void)> on_left;
|
||||||
|
|
||||||
MenuView() {
|
MenuView();
|
||||||
set_focusable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
~MenuView();
|
~MenuView();
|
||||||
|
|
||||||
void add_item(const MenuItem item);
|
void add_item(const MenuItem item);
|
||||||
|
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
void add_items(const std::array<MenuItem, N>& items) {
|
void add_items(const std::array<MenuItem, N>& items) {
|
||||||
for(const auto& item : items) {
|
for (const auto& item : items) {
|
||||||
add_item(item);
|
add_item(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +94,22 @@ public:
|
|||||||
//bool on_touch(const TouchEvent event) override;
|
//bool on_touch(const TouchEvent event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void update_items();
|
||||||
|
void on_tick_second();
|
||||||
|
|
||||||
|
SignalToken signal_token_tick_second;
|
||||||
|
|
||||||
|
Image arrow_more {
|
||||||
|
{ 216, 320 - 16 - 24, 16, 16 },
|
||||||
|
&bitmap_more,
|
||||||
|
Color::white(),
|
||||||
|
Color::black()
|
||||||
|
};
|
||||||
|
|
||||||
|
bool blink_ = false;
|
||||||
|
bool more_ = false;
|
||||||
size_t highlighted_ { 0 };
|
size_t highlighted_ { 0 };
|
||||||
|
size_t offset_ { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2016 Furrtek
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
@ -33,7 +34,6 @@
|
|||||||
#include "ui_setup.hpp"
|
#include "ui_setup.hpp"
|
||||||
#include "ui_debug.hpp"
|
#include "ui_debug.hpp"
|
||||||
|
|
||||||
#include "ui_handwrite.hpp" // DEBUG
|
|
||||||
#include "ui_soundboard.hpp" // DEBUG
|
#include "ui_soundboard.hpp" // DEBUG
|
||||||
#include "ui_closecall.hpp" // DEBUG
|
#include "ui_closecall.hpp" // DEBUG
|
||||||
#include "ui_freqman.hpp" // DEBUG
|
#include "ui_freqman.hpp" // DEBUG
|
||||||
@ -238,36 +238,35 @@ ReceiverMenuView::ReceiverMenuView(NavigationView& nav) {
|
|||||||
/* SystemMenuView ********************************************************/
|
/* SystemMenuView ********************************************************/
|
||||||
|
|
||||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||||
add_items<11>({ {
|
add_items<14>({ {
|
||||||
{ "Play dead", ui::Color::red(), [&nav](){ nav.push<PlayDeadView>(false); } },
|
{ "Play dead", ui::Color::red(), [&nav](){ nav.push<PlayDeadView>(false); } },
|
||||||
{ "Receiver RX", ui::Color::cyan(), [&nav](){ nav.push<ReceiverMenuView>(); } },
|
{ "Receiver RX", ui::Color::cyan(), [&nav](){ nav.push<ReceiverMenuView>(); } },
|
||||||
{ "Capture RX", ui::Color::orange(), [&nav](){ nav.push<CaptureAppView>(); } },
|
{ "Capture RX", ui::Color::cyan(), [&nav](){ nav.push<CaptureAppView>(); } },
|
||||||
{ "Close Call RX", ui::Color::cyan(), [&nav](){ nav.push<CloseCallView>(); } },
|
{ "Close Call RX", ui::Color::cyan(), [&nav](){ nav.push<CloseCallView>(); } },
|
||||||
//{ "Pokemon GO Away TX", ui::Color::blue(), [&nav](){ nav.push<JammerView>(); } },
|
{ "Numbers station TX", ui::Color::purple(), [&nav](){ nav.push<NotImplementedView>(); } }, //nav.push<NumbersStationView>();
|
||||||
|
{ "Pokemon GO Away TX", ui::Color::blue(), [&nav](){ nav.push<JammerView>(); } },
|
||||||
//{ "Soundboard TX", ui::Color::yellow(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, SoundBoard); } },
|
//{ "Soundboard TX", ui::Color::yellow(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, SoundBoard); } },
|
||||||
//{ "Audio TX", ui::Color::yellow(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, AudioTX); } },
|
//{ "Audio TX", ui::Color::yellow(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, AudioTX); } },
|
||||||
//{ "Frequency manager", ui::Color::white(), [&nav](){ nav.push<FreqManView>(); } },
|
//{ "Frequency manager", ui::Color::white(), [&nav](){ nav.push<FreqManView>(); } },
|
||||||
//{ "EPAR TX", ui::Color::green(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, EPAR); } },
|
//{ "EPAR TX", ui::Color::green(), [&nav](){ nav.push<LoadModuleView>(md5_baseband_tx, EPAR); } },
|
||||||
{ "Xylos TX", ui::Color::green(), [&nav](){ nav.push<XylosView>(); } },
|
{ "Xylos TX", ui::Color::green(), [&nav](){ nav.push<XylosView>(); } },
|
||||||
{ "TEDI/LCR TX", ui::Color::orange(), [&nav](){ nav.push<LCRView>(); } },
|
{ "TEDI/LCR TX", ui::Color::yellow(), [&nav](){ nav.push<LCRView>(); } },
|
||||||
{ "RDS TX", ui::Color::yellow(), [&nav](){ nav.push<RDSView>(); } },
|
{ "OOK encoder TX", ui::Color::orange(), [&nav](){ nav.push<NotImplementedView>(); } },
|
||||||
//{ "Capture", ui::Color::white(), [&nav](){ nav.push<NotImplementedView>(); } },
|
{ "RDS TX", ui::Color::red(), [&nav](){ nav.push<RDSView>(); } },
|
||||||
//{ "Analyze", ui::Color::white(), [&nav](){ nav.push<NotImplementedView>(); } },
|
//{ "Analyze", ui::Color::white(), [&nav](){ nav.push<NotImplementedView>(); } },
|
||||||
{ "Setup", ui::Color::white(), [&nav](){ nav.push<SetupMenuView>(); } },
|
{ "Setup", ui::Color::white(), [&nav](){ nav.push<SetupMenuView>(); } },
|
||||||
{ "Debug", ui::Color::white(), [&nav](){ nav.push<DebugMenuView>(); } },
|
{ "Debug", ui::Color::white(), [&nav](){ nav.push<DebugMenuView>(); } },
|
||||||
{ "HackRF", ui::Color::white(), [&nav](){ nav.push<HackRFFirmwareView>(); } },
|
{ "HackRF", ui::Color::white(), [&nav](){ nav.push<HackRFFirmwareView>(); } },
|
||||||
{ "About", ui::Color::white(), [&nav](){ nav.push<AboutView>(); } }
|
{ "About", ui::Color::white(), [&nav](){ nav.push<AboutView>(); } }
|
||||||
} });
|
} });
|
||||||
|
|
||||||
//{ "Nordic/BTLE RX", ui::Color::cyan(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
//{ "Nordic/BTLE RX", ui::Color::cyan(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||||
//{ "Jammer", ui::Color::white(), [&nav](){ nav.push<LoadModuleView>(md5_baseband, new JammerView(nav)); } },
|
//{ "Jammer", ui::Color::white(), [&nav](){ nav.push<LoadModuleView>(md5_baseband, new JammerView(nav)); } },
|
||||||
//{ "Audio file TX", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
//{ "Audio file TX", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||||
//{ "Encoder TX", ui::Color::green(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
|
||||||
//{ "Whistle", ui::Color::purple(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband, new WhistleView { nav, transmitter_model }}); } },
|
//{ "Whistle", ui::Color::purple(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband, new WhistleView { nav, transmitter_model }}); } },
|
||||||
//{ "SIGFOX RX", ui::Color::orange(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband, new SIGFRXView { nav, receiver_model }}); } },
|
//{ "SIGFOX RX", ui::Color::orange(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband, new SIGFRXView { nav, receiver_model }}); } },
|
||||||
//{ "Xylos RX", ui::Color::green(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband_tx, new XylosRXView { nav, receiver_model }}); } },
|
//{ "Xylos RX", ui::Color::green(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband_tx, new XylosRXView { nav, receiver_model }}); } },
|
||||||
//{ "AFSK RX", ui::Color::cyan(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband, new AFSKRXView { nav, receiver_model }}); } },
|
//{ "AFSK RX", ui::Color::cyan(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband, new AFSKRXView { nav, receiver_model }}); } },
|
||||||
//{ "Numbers station", ui::Color::purple(), [&nav](){ nav.push(new LoadModuleView { nav, md5_baseband_tx, new NumbersStationView { nav, transmitter_model }}); } },
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user