compile for Android, add initial TextInput support
This commit is contained in:
@@ -27,6 +27,8 @@ add_library(
|
||||
src/main/cpp/main.cpp
|
||||
../engine/pch.cpp
|
||||
../engine/util.cpp
|
||||
../engine/rtt.cpp
|
||||
../engine/bezier.cpp
|
||||
../engine/asset.cpp
|
||||
../engine/image.cpp
|
||||
../engine/texture.cpp
|
||||
|
||||
@@ -54,8 +54,6 @@ struct engine {
|
||||
struct saved_state state;
|
||||
};
|
||||
|
||||
Plane plane;
|
||||
|
||||
/**
|
||||
* Initialize an EGL context for the current display.
|
||||
*/
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<text text="Colors" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||
</border>
|
||||
<border color=".3" pad="5" dir="row" height="150">
|
||||
<color-quad id="quad" color=".2" height="100%" grow="1"/>
|
||||
<color-quad id="quad" color="1 0 0 1" height="100%" grow="1"/>
|
||||
<node width="30" dir="col" pad="0 0 0 5"><slider-hue id="hue"/></node>
|
||||
</border>
|
||||
</node>
|
||||
@@ -410,6 +410,7 @@
|
||||
</node>
|
||||
<!-- status bar -->
|
||||
<border height="30" width="100%" color=".15" border-color=".3" dir="row" pad="0 0 0 10" align="center">
|
||||
<text-input width="100" height="100%" color=".3"/>
|
||||
<text text="Status Bar: nothing to show here." font-face="arial" font-size="11"/>
|
||||
<text text="#opengl #fromscratch #c++" font-face="arial" font-size="11" margin="0 0 0 10" color=".2 .5 1 1"/>
|
||||
</border>
|
||||
|
||||
@@ -28,7 +28,7 @@ void App::initShaders()
|
||||
"out vec3 uv;"
|
||||
"void main(){"
|
||||
" uv = vec3(uvs, pos.w);"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.f);"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
||||
"}";
|
||||
static const char* shader_f =
|
||||
SHADER_VERSION
|
||||
@@ -45,7 +45,7 @@ void App::initShaders()
|
||||
"in vec3 uv;"
|
||||
"out vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = vec4(uv.xy,0,1);"
|
||||
" frag = vec4(uv.xy, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_atlas_v =
|
||||
SHADER_VERSION
|
||||
@@ -57,7 +57,7 @@ void App::initShaders()
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = tof + uvs * tsz;"
|
||||
" gl_Position = mvp * vec4(pos, 0, 1);"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_atlas_f =
|
||||
SHADER_VERSION
|
||||
@@ -97,8 +97,8 @@ void App::initShaders()
|
||||
"in vec3 uv;"
|
||||
"out vec4 frag;"
|
||||
"void main(){"
|
||||
" vec4 gradient_x = mix(col, vec4(1, 1, 1, 1), uv.x);"
|
||||
" frag = mix(gradient_x, vec4(0, 0, 0, 1), uv.y);"
|
||||
" vec4 gradient_x = mix(col, vec4(1.0, 1.0, 1.0, 1.0), uv.x);"
|
||||
" frag = mix(gradient_x, vec4(0.0, 0.0, 0.0, 1.0), uv.y);"
|
||||
"}";
|
||||
static const char* shader_color_hue_v =
|
||||
SHADER_VERSION
|
||||
@@ -121,7 +121,7 @@ void App::initShaders()
|
||||
" return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);"
|
||||
"}"
|
||||
"void main(){"
|
||||
" frag = vec4(hsv2rgb(vec3(uv.y, 1, 1)), 1);"
|
||||
" frag = vec4(hsv2rgb(vec3(uv.y, 1.0, 1.0)), 1.0);"
|
||||
"}";
|
||||
static const char* shader_font_v =
|
||||
SHADER_VERSION
|
||||
@@ -131,7 +131,7 @@ void App::initShaders()
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = uvs;"
|
||||
" gl_Position = mvp * vec4(pos, 0, 1);"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_font_f =
|
||||
SHADER_VERSION
|
||||
@@ -201,11 +201,20 @@ void App::initLayout()
|
||||
auto tid = brushes->get_texture_id(index);
|
||||
stroke->m_canvas->m_tex_id = tid;
|
||||
stroke->m_canvas->draw_stroke();
|
||||
if (on_brush_select)
|
||||
on_brush_select(index);
|
||||
};
|
||||
|
||||
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
||||
stroke->m_canvas->m_tip_color = color;
|
||||
stroke->m_canvas->draw_stroke();
|
||||
if (on_color_change)
|
||||
on_color_change(color);
|
||||
};
|
||||
|
||||
stroke->on_stroke_change = [this](Node*target) {
|
||||
if (on_stroke_change)
|
||||
on_stroke_change();
|
||||
};
|
||||
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
||||
@@ -338,13 +347,13 @@ void App::init()
|
||||
|
||||
void App::update(float dt)
|
||||
{
|
||||
//glClearColor(.1f, .1f, .1f, 1.f);
|
||||
//glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||
//glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(.1f, .1f, .1f, 1.f);
|
||||
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// layout.reload();
|
||||
// if (auto* main = layout[main_id])
|
||||
// main->update(width, height, zoom);
|
||||
//layout.reload();
|
||||
if (auto* main = layout[main_id])
|
||||
main->update(width, height, zoom);
|
||||
|
||||
auto observer = [this](Node* n)
|
||||
{
|
||||
@@ -412,5 +421,36 @@ bool App::mouse_up(int button, float x, float y)
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
LOG("mouse up button%d pos %f %f\n", button, x, y);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_down(int key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyDown;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
LOG("key down %d '%c'", key, key);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_up(int key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyUp;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
LOG("key up %d '%c'", key, key);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_char(int key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyChar;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
LOG("key up %d '%c'", key, key);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
@@ -24,11 +24,14 @@ public:
|
||||
NodePanelLayer* layers;
|
||||
NodePanelColor* color;
|
||||
NodePanelStroke* stroke;
|
||||
std::function<void(int)> on_brush_select;
|
||||
std::function<void(glm::vec4 color)> on_color_change;
|
||||
std::function<void()> on_stroke_change;
|
||||
const uint16_t main_id = const_hash("main");
|
||||
float width;
|
||||
float height;
|
||||
#ifdef __ANDROID__
|
||||
float zoom = 4.0;
|
||||
float zoom = 3.0;
|
||||
#else
|
||||
float zoom = 1.0;
|
||||
#endif // __ANDROID__
|
||||
@@ -43,4 +46,7 @@ public:
|
||||
bool mouse_down(int button, float x, float y);
|
||||
bool mouse_move(float x, float y);
|
||||
bool mouse_up(int button, float x, float y);
|
||||
bool key_down(int key);
|
||||
bool key_up(int key);
|
||||
bool key_char(int key);
|
||||
};
|
||||
|
||||
@@ -428,6 +428,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
||||
CASE(kWidget::Image, NodeImage);
|
||||
CASE(kWidget::Icon, NodeIcon);
|
||||
CASE(kWidget::Text, NodeText);
|
||||
CASE(kWidget::TextInput, NodeTextInput);
|
||||
CASE(kWidget::Button , NodeButton);
|
||||
CASE(kWidget::ButtonCustom, NodeButtonCustom);
|
||||
CASE(kWidget::SliderCursor, NodeSliderCursor);
|
||||
|
||||
100
engine/layout.h
100
engine/layout.h
@@ -51,6 +51,7 @@ enum class kWidget : uint16_t
|
||||
Border = const_hash("border"),
|
||||
Shape = const_hash("shape"),
|
||||
Text = const_hash("text"),
|
||||
TextInput = const_hash("text-input"),
|
||||
Image = const_hash("image"),
|
||||
Icon = const_hash("icon"),
|
||||
Button = const_hash("button"),
|
||||
@@ -89,6 +90,7 @@ enum class kEventResult : uint8_t
|
||||
enum class kEventCategory : uint8_t
|
||||
{
|
||||
MouseEvent,
|
||||
KeyEvent,
|
||||
};
|
||||
enum class kEventType : uint8_t
|
||||
{
|
||||
@@ -99,6 +101,9 @@ enum class kEventType : uint8_t
|
||||
MouseUpR,
|
||||
MouseEnter,
|
||||
MouseLeave,
|
||||
KeyDown,
|
||||
KeyUp,
|
||||
KeyChar,
|
||||
};
|
||||
|
||||
class Event
|
||||
@@ -115,6 +120,13 @@ public:
|
||||
glm::vec2 m_pos;
|
||||
};
|
||||
|
||||
class KeyEvent : public Event
|
||||
{
|
||||
public:
|
||||
KeyEvent() { m_cat = kEventCategory::KeyEvent; }
|
||||
int m_key;
|
||||
};
|
||||
|
||||
class LayoutManager
|
||||
{
|
||||
std::map<uint16_t, std::unique_ptr<class Node>> m_layouts;
|
||||
@@ -143,7 +155,9 @@ public:
|
||||
std::string m_nodeID_s;
|
||||
std::vector<std::unique_ptr<Node>> m_children;
|
||||
Node* current_mouse_capture = nullptr;
|
||||
Node* current_key_capture = nullptr;
|
||||
bool m_mouse_captured = false;
|
||||
bool m_key_captured = false;
|
||||
|
||||
glm::mat4 m_proj;
|
||||
glm::mat4 m_mvp;
|
||||
@@ -291,6 +305,8 @@ public:
|
||||
int get_child_index(Node* n);
|
||||
void mouse_capture() { root()->current_mouse_capture = this; m_mouse_captured = true; }
|
||||
void mouse_release() { root()->current_mouse_capture = nullptr; m_mouse_captured = false; }
|
||||
void key_capture() { root()->current_key_capture = this; m_key_captured = true; }
|
||||
void key_release() { root()->current_key_capture = nullptr; m_key_captured = false; }
|
||||
|
||||
// class iterator
|
||||
// {
|
||||
@@ -682,6 +698,60 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class NodeTextInput : public NodeBorder
|
||||
{
|
||||
public:
|
||||
NodeText* m_text;
|
||||
std::string m_string;
|
||||
virtual Node* clone_instantiate() const override { return new NodeTextInput(); }
|
||||
virtual void init() override
|
||||
{
|
||||
init_controls();
|
||||
}
|
||||
void init_controls()
|
||||
{
|
||||
m_text = new NodeText;
|
||||
add_child(m_text);
|
||||
m_text->m_font = "arial";
|
||||
m_text->m_font_size = 11;
|
||||
m_text->m_text = "TextInput";
|
||||
m_text->create();
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
KeyEvent* ke = (KeyEvent*)e;
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
key_capture();
|
||||
break;
|
||||
case kEventType::KeyDown:
|
||||
switch (ke->m_key)
|
||||
{
|
||||
case VK_BACK:
|
||||
m_string.erase(m_string.end() - 1);
|
||||
m_text->set_text(m_string.c_str());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kEventType::KeyChar:
|
||||
if (ke->m_key >= 32 && ke->m_key < 32+96)
|
||||
{
|
||||
m_string += (char)ke->m_key;
|
||||
m_text->set_text(m_string.c_str());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
};
|
||||
|
||||
class NodeMessageBox : public Node
|
||||
{
|
||||
public:
|
||||
@@ -1306,18 +1376,24 @@ public:
|
||||
virtual Node* clone_instantiate() const override { return new NodePanelLayer(); }
|
||||
virtual void init() override
|
||||
{
|
||||
LOG("NodePanelLayer::init");
|
||||
init_template("tpl-panel-layers");
|
||||
LOG("template initted");
|
||||
m_layers_container = find<NodeBorder>("layers-container");
|
||||
LOG("template container found");
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
LOG("add layer");
|
||||
add_layer();
|
||||
}
|
||||
LOG("find components");
|
||||
m_current_layer = m_layers[0];
|
||||
m_layers[0]->m_selected = true;
|
||||
btn_add = find<NodeButtonCustom>("btn-add");
|
||||
btn_remove = find<NodeButtonCustom>("btn-remove");
|
||||
btn_up = find<NodeButtonCustom>("btn-up");
|
||||
btn_down = find<NodeButtonCustom>("btn-down");
|
||||
LOG("attach events");
|
||||
btn_add->on_click = [this](Node*) {
|
||||
add_layer();
|
||||
};
|
||||
@@ -1332,6 +1408,7 @@ public:
|
||||
btn_down->on_click = [this](Node*) {
|
||||
m_layers_container->move_child_offset(m_current_layer, +1);
|
||||
};
|
||||
LOG("done init");
|
||||
}
|
||||
void add_layer()
|
||||
{
|
||||
@@ -1418,13 +1495,13 @@ public:
|
||||
{
|
||||
init_template("tpl-panel-brushes");
|
||||
//m_layers_container = find<NodeBorder>("layers-container");
|
||||
static auto icons = FindAllBrushes("data\\Icons\\");
|
||||
static auto icons = FindAllBrushes("data/Icons/");
|
||||
if (m_container = find<NodeBorder>("brushes"))
|
||||
{
|
||||
int count = 0;
|
||||
for (auto& i : icons)
|
||||
{
|
||||
std::string path = "data\\Icons\\" + i;
|
||||
std::string path = "data/Icons/" + i;
|
||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||
m_container->add_child(brush);
|
||||
brush->init();
|
||||
@@ -1452,6 +1529,7 @@ public:
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
std::string search_path = folder + "*.png";
|
||||
#ifdef _WIN32
|
||||
WIN32_FIND_DATAA fd;
|
||||
HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
@@ -1464,6 +1542,17 @@ public:
|
||||
} while (::FindNextFileA(hFind, &fd));
|
||||
::FindClose(hFind);
|
||||
}
|
||||
#elif __ANDROID__
|
||||
LOG("listing brushes");
|
||||
AAssetDir* dir = AAssetManager_openDir(Asset::m_am, "data/Icons");
|
||||
while (const char* name = AAssetDir_getNextFileName(dir))
|
||||
{
|
||||
LOG("asset: %s", name);
|
||||
names.push_back(name);
|
||||
}
|
||||
AAssetDir_close(dir);
|
||||
#else
|
||||
#endif
|
||||
return names;
|
||||
}
|
||||
uint16_t get_texture_id(int index) const
|
||||
@@ -1606,7 +1695,7 @@ public:
|
||||
"out vec3 uv;"
|
||||
"void main(){"
|
||||
" uv = vec3(uvs, pos.w);"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.f);"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
||||
"}";
|
||||
static const char* shader_f =
|
||||
SHADER_VERSION
|
||||
@@ -1616,7 +1705,7 @@ public:
|
||||
"in vec3 uv;"
|
||||
"out vec4 frag;"
|
||||
"void main(){"
|
||||
" float a = (1 - texture(tex, uv.xy).r) * alpha;"
|
||||
" float a = (1.0 - texture(tex, uv.xy).r) * alpha;"
|
||||
" frag = vec4(col.rgb, a);"
|
||||
"}";
|
||||
m_shader.create(shader_v, shader_f);
|
||||
@@ -1732,6 +1821,7 @@ public:
|
||||
NodeSliderH* m_jitter_angle;
|
||||
NodeSliderH* m_jitter_spread;
|
||||
NodeSliderH* m_jitter_flow;
|
||||
std::function<void(Node* target)> on_stroke_change;
|
||||
virtual Node* clone_instantiate() const override { return new NodePanelStroke(); }
|
||||
virtual void clone_finalize(Node* dest) const override
|
||||
{
|
||||
@@ -1766,6 +1856,8 @@ public:
|
||||
{
|
||||
m_canvas->*prop = value;
|
||||
m_canvas->draw_stroke();
|
||||
if (on_stroke_change)
|
||||
on_stroke_change(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -459,9 +459,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
keys[wp] = true;
|
||||
App::I.key_down((int)wp);
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
keys[wp] = false;
|
||||
App::I.key_up((int)wp);
|
||||
break;
|
||||
case WM_CHAR:
|
||||
App::I.key_char((int)wp);
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
App::I.mouse_move(LOWORD(lp), HIWORD(lp));
|
||||
|
||||
@@ -112,7 +112,7 @@ void RTT::clear(glm::vec4 color)
|
||||
void RTT::readTextureData(uint8_t* buffer)
|
||||
{
|
||||
bindTexture();
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
|
||||
//glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
|
||||
unbindTexture();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user