mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-26 18:00:41 +00:00
UI: Break out the hierarchy functions into ui/root.cpp/h
This commit is contained in:
parent
3e6050beac
commit
271f79ea63
@ -1040,6 +1040,8 @@ add_library(native STATIC
|
||||
ext/native/thread/threadutil.h
|
||||
ext/native/thread/threadpool.cpp
|
||||
ext/native/thread/threadpool.h
|
||||
ext/native/ui/root.cpp
|
||||
ext/native/ui/root.h
|
||||
ext/native/ui/screen.cpp
|
||||
ext/native/ui/screen.h
|
||||
ext/native/ui/ui.cpp
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "input/input_state.h"
|
||||
#include "math/curves.h"
|
||||
#include "ui/root.h"
|
||||
#include "ui/ui.h"
|
||||
#include "ui/ui_context.h"
|
||||
#include "ui/ui_tween.h"
|
||||
|
@ -455,6 +455,7 @@
|
||||
<ClInclude Include="..\..\ext\native\thread\prioritizedworkqueue.h" />
|
||||
<ClInclude Include="..\..\ext\native\thread\threadpool.h" />
|
||||
<ClInclude Include="..\..\ext\native\thread\threadutil.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\root.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\screen.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\ui.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\ui_context.h" />
|
||||
@ -1608,6 +1609,7 @@
|
||||
<ClCompile Include="..\..\ext\native\thread\prioritizedworkqueue.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\thread\threadpool.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\thread\threadutil.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\root.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\screen.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\ui.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\ui_context.cpp" />
|
||||
|
@ -145,6 +145,9 @@
|
||||
<ClCompile Include="..\..\ext\native\input\input_state.cpp">
|
||||
<Filter>input</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\native\ui\root.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\native\ui\screen.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
@ -583,6 +586,9 @@
|
||||
<ClInclude Include="..\..\ext\native\input\keycodes.h">
|
||||
<Filter>input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ext\native\ui\root.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ext\native\ui\screen.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
|
@ -89,6 +89,7 @@ LOCAL_SRC_FILES :=\
|
||||
thin3d/VulkanRenderManager.cpp \
|
||||
thin3d/VulkanQueueRunner.cpp \
|
||||
thin3d/DataFormatGL.cpp \
|
||||
ui/root.cpp \
|
||||
ui/view.cpp \
|
||||
ui/viewgroup.cpp \
|
||||
ui/ui.cpp \
|
||||
|
@ -438,6 +438,7 @@
|
||||
<ClInclude Include="thin3d\thin3d_create.h" />
|
||||
<ClInclude Include="thin3d\VulkanQueueRunner.h" />
|
||||
<ClInclude Include="thin3d\VulkanRenderManager.h" />
|
||||
<ClInclude Include="ui\root.h" />
|
||||
<ClInclude Include="util\text\wrap_text.h" />
|
||||
<ClInclude Include="gfx_es2\draw_buffer.h" />
|
||||
<ClInclude Include="gfx_es2\draw_text.h" />
|
||||
@ -1147,6 +1148,7 @@
|
||||
<ClCompile Include="thin3d\thin3d_d3d11.cpp" />
|
||||
<ClCompile Include="thin3d\VulkanQueueRunner.cpp" />
|
||||
<ClCompile Include="thin3d\VulkanRenderManager.cpp" />
|
||||
<ClCompile Include="ui\root.cpp" />
|
||||
<ClCompile Include="util\text\wrap_text.cpp" />
|
||||
<ClCompile Include="gfx_es2\draw_buffer.cpp" />
|
||||
<ClCompile Include="gfx_es2\draw_text.cpp" />
|
||||
|
@ -347,6 +347,9 @@
|
||||
<ClInclude Include="thin3d\d3d9_d3dcompiler_loader.h">
|
||||
<Filter>thin3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ui\root.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="gfx\gl_debug_log.cpp">
|
||||
@ -826,6 +829,9 @@
|
||||
<ClCompile Include="thin3d\d3d9_d3dcompiler_loader.cpp">
|
||||
<Filter>thin3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ui\root.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="gfx">
|
||||
|
@ -1,9 +1,10 @@
|
||||
set(SRCS
|
||||
ui.cpp
|
||||
ui_context.cpp
|
||||
view.cpp
|
||||
viewgroup.cpp
|
||||
view.cpp
|
||||
viewgroup.cpp
|
||||
screen.cpp
|
||||
root.cpp
|
||||
)
|
||||
|
||||
set(SRCS ${SRCS})
|
||||
|
202
ext/native/ui/root.cpp
Normal file
202
ext/native/ui/root.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "base/timeutil.h"
|
||||
#include "ui/root.h"
|
||||
#include "ui/viewgroup.h"
|
||||
|
||||
namespace UI {
|
||||
|
||||
static std::mutex focusLock;
|
||||
static std::vector<int> focusMoves;
|
||||
extern bool focusForced;
|
||||
|
||||
void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root) {
|
||||
if (!root) {
|
||||
ELOG("Tried to layout a view hierarchy from a zero pointer root");
|
||||
return;
|
||||
}
|
||||
const Bounds &rootBounds = dc.GetBounds();
|
||||
|
||||
MeasureSpec horiz(EXACTLY, rootBounds.w);
|
||||
MeasureSpec vert(EXACTLY, rootBounds.h);
|
||||
|
||||
// Two phases - measure contents, layout.
|
||||
root->Measure(dc, horiz, vert);
|
||||
// Root has a specified size. Set it, then let root layout all its children.
|
||||
root->SetBounds(rootBounds);
|
||||
root->Layout();
|
||||
}
|
||||
|
||||
void MoveFocus(ViewGroup *root, FocusDirection direction) {
|
||||
if (!GetFocusedView()) {
|
||||
// Nothing was focused when we got in here. Focus the first non-group in the hierarchy.
|
||||
root->SetFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
NeighborResult neigh(0, 0);
|
||||
neigh = root->FindNeighbor(GetFocusedView(), direction, neigh);
|
||||
|
||||
if (neigh.view) {
|
||||
neigh.view->SetFocus();
|
||||
root->SubviewFocused(neigh.view);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Figure out where this should really live.
|
||||
// Simple simulation of key repeat on platforms and for gamepads where we don't
|
||||
// automatically get it.
|
||||
|
||||
static int frameCount;
|
||||
|
||||
// Ignore deviceId when checking for matches. Turns out that Ouya for example sends
|
||||
// completely broken input where the original keypresses have deviceId = 10 and the repeats
|
||||
// have deviceId = 0.
|
||||
struct HeldKey {
|
||||
int key;
|
||||
int deviceId;
|
||||
double triggerTime;
|
||||
|
||||
// Ignores startTime
|
||||
bool operator <(const HeldKey &other) const {
|
||||
if (key < other.key) return true;
|
||||
return false;
|
||||
}
|
||||
bool operator ==(const HeldKey &other) const { return key == other.key; }
|
||||
};
|
||||
|
||||
static std::set<HeldKey> heldKeys;
|
||||
|
||||
const double repeatDelay = 15 * (1.0 / 60.0f); // 15 frames like before.
|
||||
const double repeatInterval = 5 * (1.0 / 60.0f); // 5 frames like before.
|
||||
|
||||
bool KeyEvent(const KeyInput &key, ViewGroup *root) {
|
||||
bool retval = false;
|
||||
// Ignore repeats for focus moves.
|
||||
if ((key.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) {
|
||||
if (IsDPadKey(key)) {
|
||||
// Let's only repeat DPAD initially.
|
||||
HeldKey hk;
|
||||
hk.key = key.keyCode;
|
||||
hk.deviceId = key.deviceId;
|
||||
hk.triggerTime = time_now_d() + repeatDelay;
|
||||
|
||||
// Check if the key is already held. If it is, ignore it. This is to avoid
|
||||
// multiple key repeat mechanisms colliding.
|
||||
if (heldKeys.find(hk) != heldKeys.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
heldKeys.insert(hk);
|
||||
std::lock_guard<std::mutex> lock(focusLock);
|
||||
focusMoves.push_back(key.keyCode);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
if (key.flags & KEY_UP) {
|
||||
// We ignore the device ID here (in the comparator for HeldKey), due to the Ouya quirk mentioned above.
|
||||
if (!heldKeys.empty()) {
|
||||
HeldKey hk;
|
||||
hk.key = key.keyCode;
|
||||
hk.deviceId = key.deviceId;
|
||||
hk.triggerTime = 0.0; // irrelevant
|
||||
if (heldKeys.find(hk) != heldKeys.end()) {
|
||||
heldKeys.erase(hk);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retval = root->Key(key);
|
||||
|
||||
// Ignore volume keys and stuff here. Not elegant but need to propagate bools through the view hierarchy as well...
|
||||
switch (key.keyCode) {
|
||||
case NKCODE_VOLUME_DOWN:
|
||||
case NKCODE_VOLUME_UP:
|
||||
case NKCODE_VOLUME_MUTE:
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ProcessHeldKeys(ViewGroup *root) {
|
||||
double now = time_now_d();
|
||||
|
||||
restart:
|
||||
|
||||
for (std::set<HeldKey>::iterator iter = heldKeys.begin(); iter != heldKeys.end(); ++iter) {
|
||||
if (iter->triggerTime < now) {
|
||||
KeyInput key;
|
||||
key.keyCode = iter->key;
|
||||
key.deviceId = iter->deviceId;
|
||||
key.flags = KEY_DOWN;
|
||||
KeyEvent(key, root);
|
||||
|
||||
std::lock_guard<std::mutex> lock(focusLock);
|
||||
focusMoves.push_back(key.keyCode);
|
||||
|
||||
// Cannot modify the current item when looping over a set, so let's do this instead.
|
||||
HeldKey hk = *iter;
|
||||
heldKeys.erase(hk);
|
||||
hk.triggerTime = now + repeatInterval;
|
||||
heldKeys.insert(hk);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TouchEvent(const TouchInput &touch, ViewGroup *root) {
|
||||
focusForced = false;
|
||||
root->Touch(touch);
|
||||
if ((touch.flags & TOUCH_DOWN) && !focusForced) {
|
||||
EnableFocusMovement(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AxisEvent(const AxisInput &axis, ViewGroup *root) {
|
||||
root->Axis(axis);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateViewHierarchy(ViewGroup *root) {
|
||||
ProcessHeldKeys(root);
|
||||
frameCount++;
|
||||
|
||||
if (!root) {
|
||||
ELOG("Tried to update a view hierarchy from a zero pointer root");
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusMoves.size()) {
|
||||
std::lock_guard<std::mutex> lock(focusLock);
|
||||
EnableFocusMovement(true);
|
||||
if (!GetFocusedView()) {
|
||||
View *defaultView = root->GetDefaultFocusView();
|
||||
// Can't focus what you can't see.
|
||||
if (defaultView && defaultView->GetVisibility() == V_VISIBLE) {
|
||||
root->GetDefaultFocusView()->SetFocus();
|
||||
} else {
|
||||
root->SetFocus();
|
||||
}
|
||||
root->SubviewFocused(GetFocusedView());
|
||||
} else {
|
||||
for (size_t i = 0; i < focusMoves.size(); i++) {
|
||||
switch (focusMoves[i]) {
|
||||
case NKCODE_DPAD_LEFT: MoveFocus(root, FOCUS_LEFT); break;
|
||||
case NKCODE_DPAD_RIGHT: MoveFocus(root, FOCUS_RIGHT); break;
|
||||
case NKCODE_DPAD_UP: MoveFocus(root, FOCUS_UP); break;
|
||||
case NKCODE_DPAD_DOWN: MoveFocus(root, FOCUS_DOWN); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
focusMoves.clear();
|
||||
}
|
||||
|
||||
root->Update();
|
||||
DispatchEvents();
|
||||
}
|
||||
|
||||
}
|
17
ext/native/ui/root.h
Normal file
17
ext/native/ui/root.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/ui_context.h"
|
||||
#include "input/input_state.h"
|
||||
|
||||
namespace UI {
|
||||
|
||||
class ViewGroup;
|
||||
|
||||
void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root);
|
||||
void UpdateViewHierarchy(ViewGroup *root);
|
||||
// Hooks arrow keys for navigation
|
||||
bool KeyEvent(const KeyInput &key, ViewGroup *root);
|
||||
bool TouchEvent(const TouchInput &touch, ViewGroup *root);
|
||||
bool AxisEvent(const AxisInput &axis, ViewGroup *root);
|
||||
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
#include "ui/ui_screen.h"
|
||||
#include "ui/ui_context.h"
|
||||
#include "ui/screen.h"
|
||||
#include "ui/root.h"
|
||||
#include "i18n/i18n.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
|
||||
|
@ -19,10 +19,6 @@ namespace UI {
|
||||
|
||||
const float ITEM_HEIGHT = 64.f;
|
||||
|
||||
static std::mutex focusLock;
|
||||
static std::vector<int> focusMoves;
|
||||
extern bool focusForced;
|
||||
|
||||
void ApplyGravity(const Bounds outer, const Margins &margins, float w, float h, int gravity, Bounds &inner) {
|
||||
inner.w = w;
|
||||
inner.h = h;
|
||||
@ -375,22 +371,6 @@ NeighborResult ViewGroup::FindNeighbor(View *view, FocusDirection direction, Nei
|
||||
}
|
||||
}
|
||||
|
||||
void MoveFocus(ViewGroup *root, FocusDirection direction) {
|
||||
if (!GetFocusedView()) {
|
||||
// Nothing was focused when we got in here. Focus the first non-group in the hierarchy.
|
||||
root->SetFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
NeighborResult neigh(0, 0);
|
||||
neigh = root->FindNeighbor(GetFocusedView(), direction, neigh);
|
||||
|
||||
if (neigh.view) {
|
||||
neigh.view->SetFocus();
|
||||
root->SubviewFocused(neigh.view);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This code needs some cleanup/restructuring...
|
||||
void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) {
|
||||
MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_);
|
||||
@ -1421,177 +1401,4 @@ bool StringVectorListAdaptor::AddEventCallback(View *view, std::function<EventRe
|
||||
return EVENT_DONE;
|
||||
}
|
||||
|
||||
void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root) {
|
||||
if (!root) {
|
||||
ELOG("Tried to layout a view hierarchy from a zero pointer root");
|
||||
return;
|
||||
}
|
||||
const Bounds &rootBounds = dc.GetBounds();
|
||||
|
||||
MeasureSpec horiz(EXACTLY, rootBounds.w);
|
||||
MeasureSpec vert(EXACTLY, rootBounds.h);
|
||||
|
||||
// Two phases - measure contents, layout.
|
||||
root->Measure(dc, horiz, vert);
|
||||
// Root has a specified size. Set it, then let root layout all its children.
|
||||
root->SetBounds(rootBounds);
|
||||
root->Layout();
|
||||
}
|
||||
|
||||
// TODO: Figure out where this should really live.
|
||||
// Simple simulation of key repeat on platforms and for gamepads where we don't
|
||||
// automatically get it.
|
||||
|
||||
static int frameCount;
|
||||
|
||||
// Ignore deviceId when checking for matches. Turns out that Ouya for example sends
|
||||
// completely broken input where the original keypresses have deviceId = 10 and the repeats
|
||||
// have deviceId = 0.
|
||||
struct HeldKey {
|
||||
int key;
|
||||
int deviceId;
|
||||
double triggerTime;
|
||||
|
||||
// Ignores startTime
|
||||
bool operator <(const HeldKey &other) const {
|
||||
if (key < other.key) return true;
|
||||
return false;
|
||||
}
|
||||
bool operator ==(const HeldKey &other) const { return key == other.key; }
|
||||
};
|
||||
|
||||
static std::set<HeldKey> heldKeys;
|
||||
|
||||
const double repeatDelay = 15 * (1.0 / 60.0f); // 15 frames like before.
|
||||
const double repeatInterval = 5 * (1.0 / 60.0f); // 5 frames like before.
|
||||
|
||||
bool KeyEvent(const KeyInput &key, ViewGroup *root) {
|
||||
bool retval = false;
|
||||
// Ignore repeats for focus moves.
|
||||
if ((key.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) {
|
||||
if (IsDPadKey(key)) {
|
||||
// Let's only repeat DPAD initially.
|
||||
HeldKey hk;
|
||||
hk.key = key.keyCode;
|
||||
hk.deviceId = key.deviceId;
|
||||
hk.triggerTime = time_now_d() + repeatDelay;
|
||||
|
||||
// Check if the key is already held. If it is, ignore it. This is to avoid
|
||||
// multiple key repeat mechanisms colliding.
|
||||
if (heldKeys.find(hk) != heldKeys.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
heldKeys.insert(hk);
|
||||
std::lock_guard<std::mutex> lock(focusLock);
|
||||
focusMoves.push_back(key.keyCode);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
if (key.flags & KEY_UP) {
|
||||
// We ignore the device ID here (in the comparator for HeldKey), due to the Ouya quirk mentioned above.
|
||||
if (!heldKeys.empty()) {
|
||||
HeldKey hk;
|
||||
hk.key = key.keyCode;
|
||||
hk.deviceId = key.deviceId;
|
||||
hk.triggerTime = 0.0; // irrelevant
|
||||
if (heldKeys.find(hk) != heldKeys.end()) {
|
||||
heldKeys.erase(hk);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retval = root->Key(key);
|
||||
|
||||
// Ignore volume keys and stuff here. Not elegant but need to propagate bools through the view hierarchy as well...
|
||||
switch (key.keyCode) {
|
||||
case NKCODE_VOLUME_DOWN:
|
||||
case NKCODE_VOLUME_UP:
|
||||
case NKCODE_VOLUME_MUTE:
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ProcessHeldKeys(ViewGroup *root) {
|
||||
double now = time_now_d();
|
||||
|
||||
restart:
|
||||
|
||||
for (std::set<HeldKey>::iterator iter = heldKeys.begin(); iter != heldKeys.end(); ++iter) {
|
||||
if (iter->triggerTime < now) {
|
||||
KeyInput key;
|
||||
key.keyCode = iter->key;
|
||||
key.deviceId = iter->deviceId;
|
||||
key.flags = KEY_DOWN;
|
||||
KeyEvent(key, root);
|
||||
|
||||
std::lock_guard<std::mutex> lock(focusLock);
|
||||
focusMoves.push_back(key.keyCode);
|
||||
|
||||
// Cannot modify the current item when looping over a set, so let's do this instead.
|
||||
HeldKey hk = *iter;
|
||||
heldKeys.erase(hk);
|
||||
hk.triggerTime = now + repeatInterval;
|
||||
heldKeys.insert(hk);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TouchEvent(const TouchInput &touch, ViewGroup *root) {
|
||||
focusForced = false;
|
||||
root->Touch(touch);
|
||||
if ((touch.flags & TOUCH_DOWN) && !focusForced) {
|
||||
EnableFocusMovement(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AxisEvent(const AxisInput &axis, ViewGroup *root) {
|
||||
root->Axis(axis);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateViewHierarchy(ViewGroup *root) {
|
||||
ProcessHeldKeys(root);
|
||||
frameCount++;
|
||||
|
||||
if (!root) {
|
||||
ELOG("Tried to update a view hierarchy from a zero pointer root");
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusMoves.size()) {
|
||||
std::lock_guard<std::mutex> lock(focusLock);
|
||||
EnableFocusMovement(true);
|
||||
if (!GetFocusedView()) {
|
||||
View *defaultView = root->GetDefaultFocusView();
|
||||
// Can't focus what you can't see.
|
||||
if (defaultView && defaultView->GetVisibility() == V_VISIBLE) {
|
||||
root->GetDefaultFocusView()->SetFocus();
|
||||
} else {
|
||||
root->SetFocus();
|
||||
}
|
||||
root->SubviewFocused(GetFocusedView());
|
||||
} else {
|
||||
for (size_t i = 0; i < focusMoves.size(); i++) {
|
||||
switch (focusMoves[i]) {
|
||||
case NKCODE_DPAD_LEFT: MoveFocus(root, FOCUS_LEFT); break;
|
||||
case NKCODE_DPAD_RIGHT: MoveFocus(root, FOCUS_RIGHT); break;
|
||||
case NKCODE_DPAD_UP: MoveFocus(root, FOCUS_UP); break;
|
||||
case NKCODE_DPAD_DOWN: MoveFocus(root, FOCUS_DOWN); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
focusMoves.clear();
|
||||
}
|
||||
|
||||
root->Update();
|
||||
DispatchEvents();
|
||||
}
|
||||
|
||||
} // namespace UI
|
||||
|
@ -397,11 +397,4 @@ private:
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root);
|
||||
void UpdateViewHierarchy(ViewGroup *root);
|
||||
// Hooks arrow keys for navigation
|
||||
bool KeyEvent(const KeyInput &key, ViewGroup *root);
|
||||
bool TouchEvent(const TouchInput &touch, ViewGroup *root);
|
||||
bool AxisEvent(const AxisInput &axis, ViewGroup *root);
|
||||
|
||||
} // namespace UI
|
||||
|
@ -305,6 +305,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \
|
||||
$(NATIVEDIR)/thin3d/DataFormatGL.cpp \
|
||||
$(NATIVEDIR)/thread/threadutil.cpp \
|
||||
$(NATIVEDIR)/thread/threadpool.cpp \
|
||||
$(NATIVEDIR)/ui/root.cpp \
|
||||
$(NATIVEDIR)/ui/screen.cpp \
|
||||
$(NATIVEDIR)/ui/ui.cpp \
|
||||
$(NATIVEDIR)/ui/ui_context.cpp \
|
||||
|
Loading…
Reference in New Issue
Block a user