initial work on touch support
list of things not done: - no scrolling - only some menus - no widgets - no buttons
This commit is contained in:
@@ -196,39 +196,19 @@ struct Theme {
|
|||||||
fs::FsPath path;
|
fs::FsPath path;
|
||||||
PLSR_BFSTM music;
|
PLSR_BFSTM music;
|
||||||
ElementEntry elements[ThemeEntryID_MAX];
|
ElementEntry elements[ThemeEntryID_MAX];
|
||||||
|
|
||||||
// NVGcolor background; // bg
|
|
||||||
// NVGcolor lines; // grid lines
|
|
||||||
// NVGcolor spacer; // lines in popup box
|
|
||||||
// NVGcolor text; // text colour
|
|
||||||
// NVGcolor text_info; // description text
|
|
||||||
NVGcolor selected; // selected colours
|
|
||||||
// NVGcolor overlay; // popup overlay colour
|
|
||||||
|
|
||||||
// void DrawElement(float x, float y, float w, float h, ThemeEntryID id);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TouchState {
|
|
||||||
Start, // set when touch has started
|
|
||||||
Touching, // set when touch is held longer than 1 frame
|
|
||||||
Stop, // set after touch is released
|
|
||||||
None, // set when there is no touch
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TouchInfo {
|
struct TouchInfo {
|
||||||
s32 initial_x;
|
HidTouchState initial;
|
||||||
s32 initial_y;
|
HidTouchState cur;
|
||||||
|
|
||||||
s32 cur_x;
|
auto in_range(s32 x, s32 y, s32 w, s32 h) const -> bool {
|
||||||
s32 cur_y;
|
return cur.x >= x && cur.x <= x + w && cur.y >= y && cur.y <= y + h;
|
||||||
|
}
|
||||||
s32 prev_x;
|
|
||||||
s32 prev_y;
|
|
||||||
|
|
||||||
u32 finger_id;
|
|
||||||
|
|
||||||
bool is_touching;
|
bool is_touching;
|
||||||
bool is_tap;
|
bool is_tap;
|
||||||
|
bool is_clicked;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Button : u64 {
|
enum class Button : u64 {
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ struct Widget : public Object {
|
|||||||
m_actions.clear();
|
m_actions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto FireAction(Button button, u8 type = ActionType::DOWN) -> bool;
|
||||||
|
|
||||||
void SetPop(bool pop = true) {
|
void SetPop(bool pop = true) {
|
||||||
m_pop = pop;
|
m_pop = pop;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -707,34 +707,27 @@ void App::Poll() {
|
|||||||
m_controller.m_kup = padGetButtonsUp(&m_pad);
|
m_controller.m_kup = padGetButtonsUp(&m_pad);
|
||||||
m_controller.UpdateButtonHeld(static_cast<u64>(Button::ANY_DIRECTION));
|
m_controller.UpdateButtonHeld(static_cast<u64>(Button::ANY_DIRECTION));
|
||||||
|
|
||||||
HidTouchScreenState touch_state{};
|
HidTouchScreenState state{};
|
||||||
hidGetTouchScreenStates(&touch_state, 1);
|
hidGetTouchScreenStates(&state, 1);
|
||||||
|
m_touch_info.is_clicked = false;
|
||||||
|
|
||||||
if (touch_state.count == 1 && !m_touch_info.is_touching) {
|
if (state.count == 1 && !m_touch_info.is_touching) {
|
||||||
m_touch_info.initial_x = m_touch_info.prev_x = m_touch_info.cur_x = touch_state.touches[0].x;
|
m_touch_info.initial = m_touch_info.cur = state.touches[0];
|
||||||
m_touch_info.initial_y = m_touch_info.prev_y = m_touch_info.cur_y = touch_state.touches[0].y;
|
|
||||||
m_touch_info.finger_id = touch_state.touches[0].finger_id;
|
|
||||||
m_touch_info.is_touching = true;
|
m_touch_info.is_touching = true;
|
||||||
m_touch_info.is_tap = true;
|
m_touch_info.is_tap = true;
|
||||||
// PlaySoundEffect(SoundEffect_Limit);
|
// PlaySoundEffect(SoundEffect_Limit);
|
||||||
} else if (touch_state.count >= 1 && m_touch_info.is_touching && m_touch_info.finger_id == touch_state.touches[0].finger_id) {
|
} else if (state.count >= 1 && m_touch_info.is_touching) {
|
||||||
m_touch_info.prev_x = m_touch_info.cur_x;
|
m_touch_info.cur = state.touches[0];
|
||||||
m_touch_info.prev_y = m_touch_info.cur_y;
|
|
||||||
|
|
||||||
m_touch_info.cur_x = touch_state.touches[0].x;
|
|
||||||
m_touch_info.cur_y = touch_state.touches[0].y;
|
|
||||||
|
|
||||||
if (m_touch_info.is_tap &&
|
if (m_touch_info.is_tap &&
|
||||||
(std::abs(m_touch_info.initial_x - m_touch_info.cur_x) > 20 ||
|
(std::abs((s32)m_touch_info.initial.x - (s32)m_touch_info.cur.x) > 20 ||
|
||||||
std::abs(m_touch_info.initial_y - m_touch_info.cur_y) > 20)) {
|
std::abs((s32)m_touch_info.initial.y - (s32)m_touch_info.cur.y) > 20)) {
|
||||||
m_touch_info.is_tap = false;
|
m_touch_info.is_tap = false;
|
||||||
}
|
}
|
||||||
} else if (m_touch_info.is_touching) {
|
} else if (m_touch_info.is_touching) {
|
||||||
m_touch_info.is_touching = false;
|
m_touch_info.is_touching = false;
|
||||||
|
|
||||||
// check if we clicked on anything, if so, handle it
|
|
||||||
if (m_touch_info.is_tap) {
|
if (m_touch_info.is_tap) {
|
||||||
// todo:
|
m_touch_info.is_clicked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1014,6 +1014,27 @@ Menu::~Menu() {
|
|||||||
|
|
||||||
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
||||||
MenuBase::Update(controller, touch);
|
MenuBase::Update(controller, touch);
|
||||||
|
|
||||||
|
const u64 SCROLL = m_start;
|
||||||
|
const u64 max_entry_display = 9;
|
||||||
|
const u64 nro_total = m_entries.size();
|
||||||
|
const u64 cursor_pos = m_index;
|
||||||
|
|
||||||
|
if (touch->is_clicked) {
|
||||||
|
for (u64 i = 0, pos = SCROLL, y = 110, w = 370, h = 155; pos < nro_total && i < max_entry_display; y += h + 10) {
|
||||||
|
for (u64 j = 0, x = 75; j < 3 && pos < nro_total && i < max_entry_display; j++, i++, pos++, x += w + 10) {
|
||||||
|
if (touch->in_range(x, y, w, h)) {
|
||||||
|
if (pos == m_index) {
|
||||||
|
FireAction(Button::A);
|
||||||
|
} else {
|
||||||
|
App::PlaySoundEffect(SoundEffect_Focus);
|
||||||
|
SetIndex(pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
||||||
|
|||||||
@@ -153,6 +153,27 @@ Menu::~Menu() {
|
|||||||
|
|
||||||
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
||||||
MenuBase::Update(controller, touch);
|
MenuBase::Update(controller, touch);
|
||||||
|
|
||||||
|
const u64 SCROLL = m_start;
|
||||||
|
const u64 max_entry_display = 9;
|
||||||
|
const u64 nro_total = m_entries.size();
|
||||||
|
const u64 cursor_pos = m_index;
|
||||||
|
|
||||||
|
if (touch->is_clicked) {
|
||||||
|
for (u64 i = 0, pos = SCROLL, y = 110, w = 370, h = 155; pos < nro_total && i < max_entry_display; y += h + 10) {
|
||||||
|
for (u64 j = 0, x = 75; j < 3 && pos < nro_total && i < max_entry_display; j++, i++, pos++, x += w + 10) {
|
||||||
|
if (touch->in_range(x, y, w, h)) {
|
||||||
|
if (pos == m_index) {
|
||||||
|
FireAction(Button::A);
|
||||||
|
} else {
|
||||||
|
App::PlaySoundEffect(SoundEffect_Focus);
|
||||||
|
SetIndex(pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
||||||
|
|||||||
@@ -553,6 +553,36 @@ Menu::~Menu() {
|
|||||||
|
|
||||||
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
||||||
MenuBase::Update(controller, touch);
|
MenuBase::Update(controller, touch);
|
||||||
|
|
||||||
|
if (m_pages.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& page = m_pages[m_page_index];
|
||||||
|
if (page.m_ready != PageLoadState::Done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 SCROLL = m_start;
|
||||||
|
const u64 max_entry_display = 9;
|
||||||
|
const u64 nro_total = page.m_packList.size();// m_entries_current.size();
|
||||||
|
const u64 cursor_pos = m_index;
|
||||||
|
|
||||||
|
if (touch->is_clicked) {
|
||||||
|
for (u64 i = 0, pos = SCROLL, y = 110, w = 350, h = 250; pos < nro_total && i < max_entry_display; y += h + 10) {
|
||||||
|
for (u64 j = 0, x = 75; j < 3 && pos < nro_total && i < max_entry_display; j++, i++, pos++, x += w + 10) {
|
||||||
|
if (touch->in_range(x, y, w, h)) {
|
||||||
|
if (pos == m_index) {
|
||||||
|
FireAction(Button::A);
|
||||||
|
} else {
|
||||||
|
App::PlaySoundEffect(SoundEffect_Focus);
|
||||||
|
SetIndex(pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
||||||
|
|||||||
@@ -47,4 +47,15 @@ void Widget::RemoveAction(Button button) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Widget::FireAction(Button b, u8 type) -> bool {
|
||||||
|
for (const auto& [button, action] : m_actions) {
|
||||||
|
if (button == b && (action.m_type & type)) {
|
||||||
|
App::PlaySoundEffect(SoundEffect_Focus);
|
||||||
|
action.Invoke(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sphaira::ui
|
} // namespace sphaira::ui
|
||||||
|
|||||||
Reference in New Issue
Block a user