added checkbox, slider, layer panel, brushes panel
This commit is contained in:
165
data/layout.xml
165
data/layout.xml
@@ -5,11 +5,13 @@
|
||||
<text text="A" font-face="arial" font-size="11"/>
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<layout id="multi-button-item">
|
||||
<button-custom height="50%" width="50%" justify="center" align="center">
|
||||
<text text="A" font-face="arial" font-size="11"/>
|
||||
</button-custom>
|
||||
</layout>
|
||||
|
||||
<layout id="multi-button">
|
||||
<node width="50" margin="0 5 0 0" dir="row" wrap="1" flood-events="1">
|
||||
<ref id="multi-button-item"/>
|
||||
@@ -18,10 +20,81 @@
|
||||
<ref id="multi-button-item"/>
|
||||
</node>
|
||||
</layout>
|
||||
|
||||
<layout id="rounded-inside">
|
||||
<border thickness="1" border-color=".9" color=".4" height="100%" pad="10">
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<!--brush icon-->
|
||||
<layout id="tpl-brush-icon">
|
||||
<button-custom width="50" height="50" margin="1" pad="2" align="center" justify="center">
|
||||
<image width="100%" height="100%"/>
|
||||
</button-custom>
|
||||
</layout>
|
||||
|
||||
<!--slider control-->
|
||||
<layout id="tpl-slider">
|
||||
<border pad="1" grow="1" height="100%" color="1" dir="row">
|
||||
<node height="100%" grow="1">
|
||||
<slider-cursor id="cursor" width="10" height="100%" positioning="absolute" />
|
||||
</node>
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<!--layer template-->
|
||||
<layout id="tpl-layer">
|
||||
<border height="30" border-color="1" thickness="1" color=".4" dir="row" margin="1 0 1 0">
|
||||
<node width="30" pad="1">
|
||||
<checkbox id="cb"></checkbox>
|
||||
</node>
|
||||
<node width="1" grow="1" justify="center" pad="5">
|
||||
<text id="label" text="Layer0" font-face="arial" font-size="11"/>
|
||||
</node>
|
||||
<node color=".4" width="100" pad="5">
|
||||
<slider></slider>
|
||||
</node>
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<!--layers panel template-->
|
||||
<layout id="tpl-panel-layers">
|
||||
<node width="220" margin="0 0 10 0">
|
||||
<border height="30" color=".5" align="center" justify="center" margin="0 0 0 0">
|
||||
<text text="Layers" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||
</border>
|
||||
<border id="layers-container" pad="5" color=".4" dir="col" flood-events="1">
|
||||
<!--layers list-->
|
||||
</border>
|
||||
<border height="40" color=".5" dir="row" align="center" flood-events="1">
|
||||
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
||||
<icon width="30" icon="add"/>
|
||||
</button-custom>
|
||||
<button-custom id="btn-up" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 0">
|
||||
<icon width="30" icon="bullet_arrow_up"/>
|
||||
</button-custom>
|
||||
<button-custom id="btn-down" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 0">
|
||||
<icon width="30" icon="bullet_arrow_down"/>
|
||||
</button-custom>
|
||||
<node grow="1"></node>
|
||||
<button-custom id="btn-remove" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 10 0 0">
|
||||
<icon width="30" icon="bin_closed"/>
|
||||
</button-custom>
|
||||
</border>
|
||||
</node>
|
||||
</layout>
|
||||
|
||||
<!--brushes panel-->
|
||||
<layout id="tpl-panel-brushes">
|
||||
<node width="220" margin="0 0 10 0">
|
||||
<border height="30" color=".5" align="center" justify="center">
|
||||
<text text="Brushes" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||
</border>
|
||||
<border id="brushes" color=".4" pad="5" dir="row" wrap="1" flood-events="1">
|
||||
</border>
|
||||
</node>
|
||||
</layout>
|
||||
|
||||
<layout id="message-box">
|
||||
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center">
|
||||
<border thickness="1" border-color=".2" pad="3">
|
||||
@@ -38,6 +111,7 @@
|
||||
</border>
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<!--settings window-->
|
||||
<layout id="settings">
|
||||
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center">
|
||||
@@ -75,6 +149,7 @@
|
||||
</border>
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<!--popup menu-->
|
||||
<layout id="popup-menu">
|
||||
<popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
|
||||
@@ -100,9 +175,22 @@
|
||||
</button-custom>
|
||||
</popup-menu>
|
||||
</layout>
|
||||
<!--popup menu-->
|
||||
|
||||
<!--file menu-->
|
||||
<layout id="file-menu">
|
||||
<popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
|
||||
<button-custom height="30" align="center" color=".2" pad="0 20 0 10" dir="row">
|
||||
<checkbox width="20" height="20"/>
|
||||
<node pad="5" width="100%">
|
||||
<slider></slider>
|
||||
</node>
|
||||
</button-custom>
|
||||
<button-custom height="30" align="center" color=".2" pad="0 20 0 10" dir="row">
|
||||
<icon icon="page_add" width="20"/>
|
||||
<node pad="5" width="100%">
|
||||
<slider></slider>
|
||||
</node>
|
||||
</button-custom>
|
||||
<button-custom text="Menu" height="30" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||
<icon icon="page_add" width="20"/>
|
||||
<text text="New Panodoc" margin="0 0 0 5" font-face="arial" font-size="11"/>
|
||||
@@ -125,6 +213,7 @@
|
||||
</button-custom>
|
||||
</popup-menu>
|
||||
</layout>
|
||||
|
||||
<!--edit menu-->
|
||||
<layout id="edit-menu">
|
||||
<popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
|
||||
@@ -142,6 +231,7 @@
|
||||
</button-custom>
|
||||
</popup-menu>
|
||||
</layout>
|
||||
|
||||
<!--layers menu-->
|
||||
<layout id="layers-menu">
|
||||
<popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
|
||||
@@ -163,25 +253,12 @@
|
||||
</button-custom>
|
||||
</popup-menu>
|
||||
</layout>
|
||||
<!--brush icon-->
|
||||
<layout id="tpl-brush-icon">
|
||||
<button-custom width="50" height="50" margin="1" thickness="1" border-color=".0" pad="4" align="center" justify="center">
|
||||
<image width="100%" height="100%"/>
|
||||
</button-custom>
|
||||
</layout>
|
||||
<!--slider control-->
|
||||
<layout id="tpl-slider">
|
||||
<border pad="1" grow="1" height="100%" color="1">
|
||||
<node width="100%" height="100%">
|
||||
<slider-cursor width="10" height="100%" positioning="absolute" />
|
||||
</node>
|
||||
</border>
|
||||
</layout>
|
||||
|
||||
<!--main-->
|
||||
<layout id="main">
|
||||
<node dir="col" wrap="0" width="100%" height="100%" pad="5">
|
||||
<node dir="col" wrap="0" width="100%" height="100%" pad="0">
|
||||
<!-- menu bar -->
|
||||
<border flood-events="1" margin="0 0 5 0" pad="0 0 0 0" color=".1" width="100%" height="25" dir="row" align="center">
|
||||
<border flood-events="1" margin="0 0 0 0" pad="0 0 0 0" color=".1" width="100%" height="30" dir="row" align="center">
|
||||
<button-custom id="menu-file" height="100%" margin="0 0 0 0" justify="center" align="center" pad="8">
|
||||
<text text="File" font-face="arial" font-size="11"/>
|
||||
</button-custom>
|
||||
@@ -219,29 +296,10 @@
|
||||
<button-custom width="50" margin="0 5 0 0" thickness="1" border-color=".0" pad="8" align="center" justify="center">
|
||||
<icon width="100%" height="100%" icon="accept"/>
|
||||
</button-custom>
|
||||
<!--<border width="50" margin="0 5 0 0" color=".1" thickness="2" border-color=".7" pad="4">
|
||||
<image path="data/uvs.jpg" region="0 0 50 50" width="100%" height="100%" align="center" justify="flex-end">
|
||||
<text text="atlas" font-face="arial" font-size="11"/>
|
||||
</image>
|
||||
</border>
|
||||
<border width="60" pad="2" margin="0 5 0 0" color=".2" thickness="2" border-color=".7">
|
||||
<image path="data/social.png" region="0 0 230 230" width="100%" height="100%" pad="5" align="center" justify="flex-end">
|
||||
<text text="Facebook" font-face="arial" font-size="11"/>
|
||||
</image>
|
||||
</border>
|
||||
<border width="50" margin="0 5 0 0" color=".3" thickness="2" border-color=".7">
|
||||
<image path="data/social.png" region="250 0 480 230" width="100%" height="100%" pad="5" align="center" justify="flex-end">
|
||||
<text text="Twitter" font-face="arial" font-size="11"/>
|
||||
</image>
|
||||
</border>
|
||||
<separator width="10"/>
|
||||
<border width="50" margin="0 5 0 0"></border>
|
||||
<border width="50" margin="0 5 0 0"></border>
|
||||
<border width="50" margin="0 5 0 0"></border>-->
|
||||
</border>
|
||||
<!-- central row -->
|
||||
<node grow="1" dir="row" wrap="1" height="0">
|
||||
<border width="60" color=".2" margin="0 10 0 0" dir="col" pad="4">
|
||||
<!--<border width="60" color=".2 .2 .2 .6" margin="0 0 0 0" dir="col" pad="4">
|
||||
<border height="4" margin="-4 0 0 0"/>
|
||||
<button-custom width="50" height="50" margin="5 5 0 0" thickness="1" border-color=".0" pad="12" align="center" justify="center">
|
||||
<icon width="100%" height="100%" icon="accept"/>
|
||||
@@ -255,33 +313,20 @@
|
||||
<button-custom width="50" height="50" margin="5 5 0 0" thickness="1" border-color=".0" pad="12" align="center" justify="center">
|
||||
<icon width="100%" height="100%" icon="disk"/>
|
||||
</button-custom>
|
||||
</border>
|
||||
</border>-->
|
||||
<!-- side bar -->
|
||||
<node width="250" height="100%" dir="col" color=".2">
|
||||
<border pad="15" margin="10 0 10 0" color=".3" width="100%" height="auto">
|
||||
<border id="slider-space" color="0" height="30" margin="0 0 10 0">
|
||||
<ref id="tpl-slider" />
|
||||
</border>
|
||||
<border height="30" color=".5" align="center" justify="center">
|
||||
<text text="Brushes" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||
</border>
|
||||
<border id="brushes" color=".4" pad="5" dir="row" wrap="1">
|
||||
</border>
|
||||
</border>
|
||||
<border pad="15" margin="0 0 10 0" color=".3" width="100%" height="auto">
|
||||
<border height="30" color=".5" align="center" justify="center">
|
||||
<text text="Statistics" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||
</border>
|
||||
<border height="30" color=".4" />
|
||||
<border height="30" color=".5" />
|
||||
<border height="30" color=".4" />
|
||||
<border height="30" color=".5" />
|
||||
<node height="100%" dir="row" shrink="1">
|
||||
<border pad="5 5 5 5" margin="0 0 0 0" color=".3 .3 .3 .4" height="100%" dir="col" wrap="1" shrink="1">
|
||||
<!--Brushes-->
|
||||
<panel-brushes id="panel-brushes"></panel-brushes>
|
||||
<!--Layers-->
|
||||
<panel-layers></panel-layers>
|
||||
</border>
|
||||
</node>
|
||||
<!-- content panel -->
|
||||
<border grow="1" color=".1" pad="10">
|
||||
<viewport grow="1"></viewport>
|
||||
</border>
|
||||
<node grow="1" color=".1" pad="10">
|
||||
<!--<viewport grow="1"></viewport>-->
|
||||
</node>
|
||||
</node>
|
||||
<!-- status bar -->
|
||||
<border height="30" width="100%" color=".15" border-color=".3" dir="row" pad="0 0 0 10" align="center">
|
||||
|
||||
@@ -13,26 +13,6 @@ App App::I; // singleton
|
||||
#define SHADER_VERSION "#version 150\n"
|
||||
#endif
|
||||
|
||||
static std::vector<std::string> FindAllBrushes(std::string folder)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
std::string search_path = folder + "*.png";
|
||||
WIN32_FIND_DATAA fd;
|
||||
HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
// read all (real) files in current folder
|
||||
// , delete '!' read other 2 default folder . and ..
|
||||
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
names.push_back(fd.cFileName);
|
||||
}
|
||||
} while (::FindNextFileA(hFind, &fd));
|
||||
::FindClose(hFind);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
void App::create()
|
||||
{
|
||||
width = 800;
|
||||
@@ -169,33 +149,18 @@ void App::initLayout()
|
||||
|
||||
layout.on_loaded = [&] {
|
||||
LOG("initializing layout updating after load");
|
||||
static auto icons = FindAllBrushes("data\\Icons\\");
|
||||
if (auto* container = layout[main_id]->find<NodeBorder>("brushes"))
|
||||
{
|
||||
if (auto* tpl = layout[const_hash("tpl-brush-icon")])
|
||||
{
|
||||
for (auto& i : icons)
|
||||
{
|
||||
NodeButtonCustom* btn = (NodeButtonCustom*)tpl->m_children[0]->clone();
|
||||
NodeImage* img = (NodeImage*)btn->m_children[0].get();
|
||||
img->m_path = "data\\Icons\\" + i;
|
||||
img->m_tex_id = const_hash(img->m_path.c_str());
|
||||
img->create();
|
||||
container->add_child(btn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layout[main_id]->update(width, height, zoom);
|
||||
LOG("initializing layout components");
|
||||
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
||||
brushes = layout[main_id]->find<NodePanelBrushes>("panel-brushes");
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
||||
{
|
||||
button->on_click = [] { exit(0); };
|
||||
button->on_click = [](Node*) { exit(0); };
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-popup"))
|
||||
{
|
||||
button->on_click = [this] {
|
||||
button->on_click = [this](Node*) {
|
||||
msgbox = new NodeMessageBox();
|
||||
msgbox->m_manager = &layout;
|
||||
msgbox->init();
|
||||
@@ -205,7 +170,7 @@ void App::initLayout()
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-settings"))
|
||||
{
|
||||
button->on_click = [this] {
|
||||
button->on_click = [this](Node*) {
|
||||
settings = new NodeSettings();
|
||||
settings->m_manager = &layout;
|
||||
settings->init();
|
||||
@@ -215,35 +180,41 @@ void App::initLayout()
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-file"))
|
||||
{
|
||||
menu_file->on_click = [=] {
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("file-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-edit"))
|
||||
{
|
||||
menu_file->on_click = [=] {
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("edit-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-layers"))
|
||||
{
|
||||
menu_file->on_click = [=] {
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("layers-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
};
|
||||
}
|
||||
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
||||
@@ -252,7 +223,11 @@ void App::initLayout()
|
||||
}
|
||||
};
|
||||
LOG("initializing layout xml");
|
||||
#ifdef _WIN32
|
||||
layout.load("C:\\Users\\omar\\Desktop\\new_engine\\data\\layout.xml");
|
||||
#else
|
||||
layout.load("data/layout.xml");
|
||||
#endif
|
||||
LOG("initializing layout completed");
|
||||
}
|
||||
|
||||
@@ -344,41 +319,45 @@ void App::resize(float w, float h)
|
||||
main->update(w , h, zoom);
|
||||
}
|
||||
|
||||
void App::mouse_down(int button, float x, float y)
|
||||
bool App::mouse_down(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
layout[main_id]->on_event(&e);
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
LOG("mouse click button%d pos %f %f\n", button, x, y);
|
||||
|
||||
if (popup)
|
||||
{
|
||||
layout[main_id]->remove_child(popup);
|
||||
popup = nullptr;
|
||||
}
|
||||
if (button == 1)
|
||||
{
|
||||
popup = (NodePopupMenu*)layout[const_hash("popup-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(x / zoom, y / zoom);
|
||||
layout[main_id]->add_child(popup);
|
||||
}
|
||||
// if (popup)
|
||||
// {
|
||||
// layout[main_id]->remove_child(popup);
|
||||
// popup = nullptr;
|
||||
// }
|
||||
// if (button == 1)
|
||||
// {
|
||||
// popup = (NodePopupMenu*)layout[const_hash("popup-menu")]->m_children[0]->clone();
|
||||
// popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
// popup->SetPosition(x / zoom, y / zoom);
|
||||
// layout[main_id]->add_child(popup);
|
||||
// }
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
void App::mouse_move(float x, float y)
|
||||
bool App::mouse_move(float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseMove;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
kEventResult ret = kEventResult::Available;
|
||||
if (auto* main = layout[main_id])
|
||||
main->on_event(&e);
|
||||
ret = main->on_event(&e);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
void App::mouse_up(int button, float x, float y)
|
||||
bool App::mouse_up(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseUpR : kEventType::MouseUpL;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
layout[main_id]->on_event(&e);
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
NodePopupMenu* menu_edit = nullptr;
|
||||
NodePopupMenu* menu_layers = nullptr;
|
||||
NodeBorder* sidebar = nullptr;
|
||||
NodePanelBrushes* brushes;
|
||||
const uint16_t main_id = const_hash("main");
|
||||
float width;
|
||||
float height;
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
void clear();
|
||||
void update(float dt);
|
||||
void resize(float w, float h);
|
||||
void mouse_down(int button, float x, float y);
|
||||
void mouse_move(float x, float y);
|
||||
void mouse_up(int button, float x, float y);
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -36,9 +36,12 @@ kEventResult Node::on_event(Event* e)
|
||||
{
|
||||
case kEventCategory::MouseEvent:
|
||||
{
|
||||
if (m_mouse_ignore)
|
||||
break;
|
||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||
bool inside = point_in_rect(me->m_pos, m_clip);
|
||||
bool inside_old = m_mouse_inside;
|
||||
m_mouse_inside = inside;
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
@@ -55,7 +58,6 @@ kEventResult Node::on_event(Event* e)
|
||||
e2.m_type = kEventType::MouseEnter;
|
||||
handle_event(&e2);
|
||||
}
|
||||
m_mouse_inside = inside;
|
||||
if (inside || m_mouse_captured)
|
||||
ret = handle_event(e);
|
||||
if (inside_old == true && inside == false)
|
||||
@@ -78,6 +80,21 @@ kEventResult Node::on_event(Event* e)
|
||||
return ret;
|
||||
}
|
||||
|
||||
const Node* Node::init_template(const char* id)
|
||||
{
|
||||
const auto& m_template = static_cast<Node*>((*m_manager)[const_hash(id)]->m_children[0].get());
|
||||
for (auto& c : m_template->m_children)
|
||||
{
|
||||
auto node = c->clone();
|
||||
add_child(node);
|
||||
node->init();
|
||||
node->create();
|
||||
node->loaded();
|
||||
}
|
||||
YGNodeCopyStyle(y_node, m_template->y_node);
|
||||
return m_template;
|
||||
}
|
||||
|
||||
void Node::add_child(Node* n)
|
||||
{
|
||||
m_children.emplace_back(n);
|
||||
@@ -86,16 +103,58 @@ void Node::add_child(Node* n)
|
||||
YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node));
|
||||
}
|
||||
|
||||
void Node::add_child(Node* n, int index)
|
||||
{
|
||||
m_children.emplace_back(n);
|
||||
n->parent = this;
|
||||
n->m_manager = m_manager;
|
||||
YGNodeInsertChild(y_node, n->y_node, index);
|
||||
}
|
||||
|
||||
void Node::remove_child(Node* n)
|
||||
{
|
||||
auto i = std::find_if(m_children.begin(), m_children.end(), [=](std::unique_ptr<Node>& ptr) { return ptr.get() == n; });
|
||||
if (i != m_children.end())
|
||||
{
|
||||
m_children.erase(i);
|
||||
YGNodeRemoveChild(y_node, n->y_node);
|
||||
m_children.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::move_child(Node* n, int index)
|
||||
{
|
||||
YGNodeRemoveChild(y_node, n->y_node);
|
||||
YGNodeInsertChild(y_node, n->y_node, index);
|
||||
}
|
||||
|
||||
void Node::move_child_offset(Node* n, int offset)
|
||||
{
|
||||
int count = YGNodeGetChildCount(y_node);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (YGNodeGetChild(y_node, i) == n->y_node)
|
||||
{
|
||||
int new_index = glm::clamp<int>(i + offset, 0, count - 1);
|
||||
YGNodeRemoveChild(y_node, n->y_node);
|
||||
YGNodeInsertChild(y_node, n->y_node, new_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Node::get_child_index(Node* n)
|
||||
{
|
||||
int count = YGNodeGetChildCount(y_node);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (YGNodeGetChild(y_node, i) == n->y_node)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Node::update(float width, float height, float zoom)
|
||||
{
|
||||
m_zoom = zoom;
|
||||
@@ -358,71 +417,22 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
||||
kWidget child_id = (kWidget)const_hash(x_child->Name());
|
||||
switch (child_id)
|
||||
{
|
||||
case kWidget::Border:
|
||||
{
|
||||
auto n = new NodeBorder();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
// case kWidget::Shape:
|
||||
// break;
|
||||
case kWidget::Image:
|
||||
{
|
||||
auto n = new NodeImage();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::Icon:
|
||||
{
|
||||
auto n = new NodeIcon();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::Text:
|
||||
{
|
||||
auto n = new NodeText();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::Button:
|
||||
{
|
||||
auto n = new NodeButton();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::ButtonCustom:
|
||||
{
|
||||
auto n = new NodeButtonCustom();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::SliderCursor:
|
||||
{
|
||||
auto n = new NodeSliderCursor();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::PopupMenu:
|
||||
{
|
||||
auto n = new NodePopupMenu();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::Viewport:
|
||||
{
|
||||
auto n = new NodeViewport();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
#define CASE(W,C) case W: { auto n = new C(); add_child(n); n->load_internal(x_child); break; }
|
||||
CASE(kWidget::Border, NodeBorder);
|
||||
CASE(kWidget::Image, NodeImage);
|
||||
CASE(kWidget::Icon, NodeIcon);
|
||||
CASE(kWidget::Text, NodeText);
|
||||
CASE(kWidget::Button , NodeButton);
|
||||
CASE(kWidget::ButtonCustom, NodeButtonCustom);
|
||||
CASE(kWidget::SliderCursor, NodeSliderCursor);
|
||||
CASE(kWidget::Slider, NodeSlider);
|
||||
CASE(kWidget::PopupMenu, NodePopupMenu);
|
||||
CASE(kWidget::Viewport, NodeViewport);
|
||||
CASE(kWidget::CheckBox, NodeCheckBox);
|
||||
CASE(kWidget::Layer, NodeLayer);
|
||||
CASE(kWidget::PanelLayers, NodePanelLayers);
|
||||
CASE(kWidget::PanelBrushes, NodePanelBrushes);
|
||||
#undef CASE
|
||||
case kWidget::Ref:
|
||||
{
|
||||
auto ids = x_child->Attribute("id");
|
||||
|
||||
412
engine/layout.h
412
engine/layout.h
@@ -40,6 +40,7 @@ enum class kAttribute : uint16_t
|
||||
Positioning = const_hash("positioning"),
|
||||
FloodEvents = const_hash("flood-events"),
|
||||
Icon = const_hash("icon"),
|
||||
Selected = const_hash("selected"),
|
||||
};
|
||||
|
||||
enum class kWidget : uint16_t
|
||||
@@ -52,9 +53,14 @@ enum class kWidget : uint16_t
|
||||
Button = const_hash("button"),
|
||||
ButtonCustom = const_hash("button-custom"),
|
||||
SliderCursor = const_hash("slider-cursor"),
|
||||
Slider = const_hash("slider"),
|
||||
PopupMenu = const_hash("popup-menu"),
|
||||
Viewport = const_hash("viewport"),
|
||||
Ref = const_hash("ref"),
|
||||
CheckBox = const_hash("checkbox"),
|
||||
Layer = const_hash("layer"),
|
||||
PanelLayers = const_hash("panel-layers"),
|
||||
PanelBrushes = const_hash("panel-brushes"),
|
||||
};
|
||||
|
||||
enum class kShapeType : uint16_t
|
||||
@@ -136,6 +142,7 @@ public:
|
||||
bool m_flood_events = false;
|
||||
bool m_destroyed = false;
|
||||
|
||||
bool m_mouse_ignore = true;
|
||||
float m_zoom = 1.f;
|
||||
glm::vec2 m_scale{ 1.f };
|
||||
glm::vec2 m_pos;
|
||||
@@ -161,6 +168,7 @@ public:
|
||||
m_size = o.m_size;
|
||||
m_clip = o.m_clip;
|
||||
m_zoom = o.m_zoom;
|
||||
m_mouse_ignore = o.m_mouse_ignore;
|
||||
o.y_node = nullptr;
|
||||
o.parent = nullptr;
|
||||
}
|
||||
@@ -263,8 +271,13 @@ public:
|
||||
virtual void create() { }
|
||||
virtual void init() { }
|
||||
virtual void loaded() { }
|
||||
const Node* init_template(const char* id);
|
||||
void add_child(Node* n);
|
||||
void add_child(Node* n, int index);
|
||||
void remove_child(Node* n);
|
||||
void move_child(Node* n, int index);
|
||||
void move_child_offset(Node* n, int offset);
|
||||
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; }
|
||||
|
||||
@@ -309,6 +322,7 @@ public:
|
||||
glm::vec4 m_color{ 0, 0, 0, 1 };
|
||||
glm::vec4 m_border_color{ 1, 1, 1, 1 };
|
||||
float m_thinkness{ 0 };
|
||||
NodeBorder() { m_mouse_ignore = false; }
|
||||
static void static_init()
|
||||
{
|
||||
m_plane.create<1>(1, 1);
|
||||
@@ -321,6 +335,7 @@ public:
|
||||
n->m_color = m_color;
|
||||
n->m_border_color = m_border_color;
|
||||
n->m_thinkness = m_thinkness;
|
||||
n->m_mouse_ignore = false;
|
||||
}
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
|
||||
{
|
||||
@@ -386,22 +401,25 @@ public:
|
||||
std::string m_font;
|
||||
glm::vec4 m_color{ 1, 1, 1, 1 };
|
||||
int m_font_size;
|
||||
kFont font_id;
|
||||
virtual Node* clone_instantiate() const override { return new NodeText(); }
|
||||
virtual void clone_copy(Node* dest) const override
|
||||
{
|
||||
Node::clone_copy(dest);
|
||||
NodeText* n = static_cast<NodeText*>(dest);
|
||||
n->m_text_mesh = m_text_mesh;
|
||||
n->m_text_mesh.create();
|
||||
n->m_text_mesh.update(font_id, m_text.c_str());
|
||||
n->m_text = m_text;
|
||||
n->m_font = m_font;
|
||||
n->m_color = m_color;
|
||||
n->m_font_size = m_font_size;
|
||||
n->font_id = font_id;
|
||||
}
|
||||
virtual void create() override
|
||||
{
|
||||
char font[64];
|
||||
sprintf(font, "%s-%d", m_font.c_str(), m_font_size);
|
||||
kFont font_id = (kFont)const_hash(font);
|
||||
font_id = (kFont)const_hash(font);
|
||||
m_text_mesh.create();
|
||||
m_text_mesh.update(font_id, m_text.c_str());
|
||||
SetSize(m_text_mesh.bb);
|
||||
@@ -434,6 +452,12 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void set_text(const char* s)
|
||||
{
|
||||
m_text = s;
|
||||
m_text_mesh.update(font_id, s);
|
||||
SetSize(m_text_mesh.bb);
|
||||
}
|
||||
virtual void draw() override
|
||||
{
|
||||
using namespace ui;
|
||||
@@ -543,7 +567,7 @@ public:
|
||||
glm::vec4 color_normal{ .1, .1, .1, 1 };
|
||||
glm::vec4 color_hover{ .2, .2, .2, 1 };
|
||||
glm::vec4 color_down{ .3, .3, .3, 1 };
|
||||
std::function<void()> on_click;
|
||||
std::function<void(Node* target)> on_click;
|
||||
virtual Node* clone_instantiate() const override { return new NodeButton(); }
|
||||
virtual void clone_children(Node* dest) const override
|
||||
{
|
||||
@@ -562,6 +586,7 @@ public:
|
||||
n->color_hover = color_hover;
|
||||
n->color_down = color_down;
|
||||
//n->on_click = on_click;
|
||||
n->m_mouse_ignore = false;
|
||||
}
|
||||
virtual void init() override
|
||||
{
|
||||
@@ -576,17 +601,23 @@ public:
|
||||
m_text->m_font_size = 11;
|
||||
m_border->SetAlign(YGAlignCenter);
|
||||
m_border->SetJustify(YGJustifyCenter);
|
||||
m_border->m_mouse_ignore = false;
|
||||
m_mouse_ignore = false;
|
||||
}
|
||||
virtual void create() override
|
||||
{
|
||||
m_border->create();
|
||||
m_text->create();
|
||||
m_border->m_mouse_ignore = false;
|
||||
m_mouse_ignore = false;
|
||||
}
|
||||
virtual void loaded() override
|
||||
{
|
||||
m_border->m_thinkness = 1;
|
||||
m_border->m_border_color = glm::vec4(0, 0, 0, 1);
|
||||
m_border->m_color = color_normal;
|
||||
m_border->m_mouse_ignore = false;
|
||||
m_mouse_ignore = false;
|
||||
}
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
|
||||
{
|
||||
@@ -614,6 +645,7 @@ public:
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
Node::handle_event(e);
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseEnter:
|
||||
@@ -628,7 +660,7 @@ public:
|
||||
case kEventType::MouseUpL:
|
||||
m_border->m_color = color_normal;
|
||||
if (m_mouse_inside && on_click != nullptr)
|
||||
on_click();
|
||||
on_click(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -652,7 +684,7 @@ public:
|
||||
m_template = (*m_manager)[const_hash("message-box")]->m_children[0]->clone();
|
||||
add_child(m_template);
|
||||
btnOk = m_template->find<NodeButton>("btn-ok");
|
||||
btnOk->on_click = [&] { destroy(); };
|
||||
btnOk->on_click = [&](Node*) { destroy(); };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -670,6 +702,20 @@ public:
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
if (!m_mouse_inside)
|
||||
{
|
||||
mouse_release();
|
||||
destroy();
|
||||
}
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
};
|
||||
@@ -677,10 +723,10 @@ public:
|
||||
class NodeButtonCustom : public NodeBorder
|
||||
{
|
||||
public:
|
||||
glm::vec4 color_normal{ .1, .1, .1, 1 };
|
||||
glm::vec4 color_hover{ .2, .2, .2, 1 };
|
||||
glm::vec4 color_down{ .3, .3, .3, 1 };
|
||||
std::function<void()> on_click;
|
||||
glm::vec4 color_normal{ .2, .2, .2, 1 };
|
||||
glm::vec4 color_hover{ .3, .3, .3, 1 };
|
||||
glm::vec4 color_down{ .4, .4, .4, 1 };
|
||||
std::function<void(Node* target)> on_click;
|
||||
virtual Node* clone_instantiate() const override { return new NodeButtonCustom(); }
|
||||
virtual void clone_copy(Node* dest) const override
|
||||
{
|
||||
@@ -689,6 +735,8 @@ public:
|
||||
n->color_normal = color_normal;
|
||||
n->color_hover = color_hover;
|
||||
n->color_down = color_down;
|
||||
n->m_mouse_ignore = false;
|
||||
n->m_color = color_normal;
|
||||
}
|
||||
virtual void loaded() override
|
||||
{
|
||||
@@ -696,6 +744,7 @@ public:
|
||||
//m_thinkness = 1;
|
||||
//m_border_color = glm::vec4(0, 0, 0, 1);
|
||||
m_color = color_normal;
|
||||
m_mouse_ignore = false;
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
@@ -712,15 +761,27 @@ public:
|
||||
m_color = color_down;
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
m_color = color_normal;
|
||||
m_color = m_mouse_inside ? color_hover : color_normal;
|
||||
if (m_mouse_inside && on_click != nullptr)
|
||||
on_click();
|
||||
on_click(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
|
||||
{
|
||||
NodeBorder::parse_attributes(ka, attr);
|
||||
switch (ka)
|
||||
{
|
||||
case kAttribute::Color:
|
||||
color_normal = m_color;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class NodeSettings : public Node
|
||||
@@ -738,7 +799,7 @@ public:
|
||||
m_template = (*m_manager)[const_hash("settings")]->m_children[0]->clone();
|
||||
add_child(m_template);
|
||||
btnOk = m_template->find<NodeButton>("btn-ok");
|
||||
btnOk->on_click = [&] { destroy(); };
|
||||
btnOk->on_click = [&](Node*) { destroy(); };
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
@@ -906,6 +967,7 @@ public:
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
old_pos = GetPosition();
|
||||
drag_start = ((MouseEvent*)e)->m_pos;
|
||||
dragging = true;
|
||||
mouse_capture();
|
||||
@@ -919,7 +981,7 @@ public:
|
||||
{
|
||||
float pw = parent->GetWidth();
|
||||
float w = GetWidth();
|
||||
drag_diff = ((MouseEvent*)e)->m_pos - drag_start;
|
||||
drag_diff = old_pos + ((MouseEvent*)e)->m_pos - drag_start;
|
||||
float x = glm::clamp<float>(drag_diff.x, 0, pw - w);
|
||||
SetPosition(x, 0);
|
||||
}
|
||||
@@ -930,3 +992,327 @@ public:
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
};
|
||||
|
||||
class NodeSlider : public NodeBorder
|
||||
{
|
||||
public:
|
||||
NodeSliderCursor* m_cursor;
|
||||
virtual Node* clone_instantiate() const override { return new NodeSlider(); }
|
||||
virtual void init() override
|
||||
{
|
||||
const auto& m_template = (NodeBorder*)init_template("tpl-slider");
|
||||
m_color = m_template->m_color;
|
||||
m_border_color = m_template->m_border_color;
|
||||
m_thinkness = m_thinkness;
|
||||
m_cursor = find<NodeSliderCursor>("cursor");
|
||||
}
|
||||
};
|
||||
|
||||
class NodeCheckBox : public Node
|
||||
{
|
||||
public:
|
||||
NodeBorder* m_outer;
|
||||
NodeBorder* m_inner;
|
||||
bool checked = false;
|
||||
virtual Node* clone_instantiate() const override { return new NodeCheckBox(); }
|
||||
virtual void clone_children(Node* dest) const override
|
||||
{
|
||||
Node::clone_children(dest);
|
||||
NodeCheckBox* n = static_cast<NodeCheckBox*>(dest);
|
||||
n->m_outer = (NodeBorder*)n->m_children[0].get();
|
||||
n->m_inner = (NodeBorder*)n->m_outer->m_children[0].get();
|
||||
n->m_mouse_ignore = false;
|
||||
}
|
||||
virtual void init() override
|
||||
{
|
||||
m_outer = new NodeBorder();
|
||||
m_inner = new NodeBorder();
|
||||
add_child(m_outer);
|
||||
m_outer->add_child(m_inner);
|
||||
m_outer->init();
|
||||
m_outer->m_color = { .3, .3, .3, 1 };
|
||||
m_outer->SetAlign(YGAlignCenter);
|
||||
m_outer->SetJustify(YGJustifyCenter);
|
||||
m_outer->SetPadding(5, 5, 5, 5);
|
||||
m_outer->SetWidthP(100);
|
||||
m_outer->SetHeightP(100);
|
||||
m_outer->m_mouse_ignore = false;
|
||||
m_inner->init();
|
||||
m_inner->SetWidthP(100);
|
||||
m_inner->SetHeightP(100);
|
||||
m_inner->m_border_color = glm::vec4(.8, .8, .8, 1);
|
||||
m_inner->m_thinkness = 1;
|
||||
m_inner->m_color = glm::vec4(.8, .8, .8, 1);
|
||||
m_mouse_ignore = false;
|
||||
}
|
||||
virtual void create() override
|
||||
{
|
||||
m_outer->create();
|
||||
m_inner->create();
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
Node::handle_event(e);
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseEnter:
|
||||
break;
|
||||
case kEventType::MouseLeave:
|
||||
break;
|
||||
case kEventType::MouseDownL:
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
checked = !checked;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
virtual void draw() override
|
||||
{
|
||||
m_inner->m_color = checked ? glm::vec4(.4, .4, .4, 1) : glm::vec4(.8, .8, .8, 1);
|
||||
Node::draw();
|
||||
}
|
||||
};
|
||||
|
||||
class NodeLayer : public NodeBorder
|
||||
{
|
||||
public:
|
||||
std::function<void(NodeLayer* target)> on_selected;
|
||||
bool m_selected = false;
|
||||
glm::vec4 m_color_normal = glm::vec4(.4, .4, .4, 1);
|
||||
glm::vec4 m_color_selected = glm::vec4(.3, .3, .3, 1);
|
||||
glm::vec4 m_color_hover = glm::vec4(.5, .5, .5, 1);
|
||||
std::string m_label_text;
|
||||
NodeText* m_label;
|
||||
NodeCheckBox* m_visibility;
|
||||
virtual Node* clone_instantiate() const override { return new NodeLayer(); }
|
||||
virtual void clone_children(Node* dest) const override
|
||||
{
|
||||
NodeBorder::clone_children(dest);
|
||||
NodeLayer* n = static_cast<NodeLayer*>(dest);
|
||||
n->m_label = n->find<NodeText>("label");
|
||||
n->m_visibility = n->find<NodeCheckBox>("cb");
|
||||
}
|
||||
virtual void clone_copy(Node* dest) const override
|
||||
{
|
||||
NodeBorder::clone_copy(dest);
|
||||
NodeLayer* n = (NodeLayer*)dest;
|
||||
n->m_selected = m_selected;
|
||||
n->m_label_text = m_label_text;
|
||||
}
|
||||
virtual void init() override
|
||||
{
|
||||
const auto& m_template = (NodeBorder*)init_template("tpl-layer");
|
||||
m_color = m_template->m_color;
|
||||
m_border_color = m_template->m_border_color;
|
||||
m_thinkness = m_template->m_thinkness;
|
||||
m_label = find<NodeText>("label");
|
||||
m_visibility = find<NodeCheckBox>("cb");
|
||||
}
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
|
||||
{
|
||||
NodeBorder::parse_attributes(ka, attr);
|
||||
switch (ka)
|
||||
{
|
||||
case kAttribute::Text:
|
||||
m_label_text = attr->Value();
|
||||
break;
|
||||
case kAttribute::Selected:
|
||||
m_selected = attr->BoolValue();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
virtual void loaded() override
|
||||
{
|
||||
NodeBorder::loaded();
|
||||
if (!m_label_text.empty())
|
||||
m_label->set_text(m_label_text.c_str());
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
NodeBorder::handle_event(e);
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseEnter:
|
||||
break;
|
||||
case kEventType::MouseLeave:
|
||||
break;
|
||||
case kEventType::MouseDownL:
|
||||
m_selected = true;
|
||||
if (on_selected)
|
||||
on_selected(this);
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
virtual void draw() override
|
||||
{
|
||||
auto c = m_selected ? m_color_selected : m_color_normal;
|
||||
m_thinkness = m_selected ? 1 : 0;
|
||||
m_color = m_mouse_inside ? m_color_hover : c;
|
||||
NodeBorder::draw();
|
||||
}
|
||||
void set_name(const char* s)
|
||||
{
|
||||
m_label_text = s;
|
||||
m_label->set_text(s);
|
||||
}
|
||||
};
|
||||
|
||||
class NodePanelLayers : public Node
|
||||
{
|
||||
NodeButtonCustom* btn_add;
|
||||
NodeButtonCustom* btn_remove;
|
||||
NodeButtonCustom* btn_up;
|
||||
NodeButtonCustom* btn_down;
|
||||
public:
|
||||
NodeLayer* m_current_layer = nullptr;
|
||||
std::vector<NodeLayer*> m_layers;
|
||||
NodeBorder* m_layers_container;
|
||||
virtual Node* clone_instantiate() const override { return new NodePanelLayers(); }
|
||||
virtual void init() override
|
||||
{
|
||||
init_template("tpl-panel-layers");
|
||||
m_layers_container = find<NodeBorder>("layers-container");
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
static char s[64];
|
||||
sprintf(s, "Layer-%d", i);
|
||||
add_layer(s);
|
||||
}
|
||||
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");
|
||||
btn_add->on_click = [this](Node*) { add_layer("New Layer"); };
|
||||
btn_remove->on_click = [this](Node*) {
|
||||
if (m_layers.size() == 1)
|
||||
return; // dont' delete the last layer
|
||||
auto it = std::find(m_layers.begin(), m_layers.end(), m_current_layer);
|
||||
auto i = m_layers_container->get_child_index(m_current_layer);
|
||||
m_layers_container->remove_child(m_current_layer);
|
||||
m_layers.erase(it);
|
||||
i = std::min<int>(i, m_layers.size() - 1);
|
||||
m_current_layer = m_layers[i];
|
||||
m_current_layer->m_selected = true;
|
||||
};
|
||||
btn_up->on_click = [this](Node*) { m_layers_container->move_child_offset(m_current_layer, -1); };
|
||||
btn_down->on_click = [this](Node*) { m_layers_container->move_child_offset(m_current_layer, +1); };
|
||||
}
|
||||
void add_layer(const char* name)
|
||||
{
|
||||
NodeLayer* l = new NodeLayer;
|
||||
m_layers_container->add_child(l);
|
||||
l->init();
|
||||
l->create();
|
||||
l->loaded();
|
||||
l->set_name(name);
|
||||
l->on_selected = std::bind(&NodePanelLayers::handle_layer_selected, this, std::placeholders::_1);
|
||||
m_layers.push_back(l);
|
||||
}
|
||||
void handle_layer_selected(NodeLayer* target)
|
||||
{
|
||||
if (m_current_layer)
|
||||
m_current_layer->m_selected = false;
|
||||
m_current_layer = target;
|
||||
m_current_layer->m_selected = true;
|
||||
}
|
||||
};
|
||||
|
||||
class NodeButtonBrush : public NodeButtonCustom
|
||||
{
|
||||
public:
|
||||
int m_brushID;
|
||||
bool m_selected = false;
|
||||
NodeImage* img;
|
||||
virtual Node* clone_instantiate() const override { return new NodeButtonBrush(); }
|
||||
virtual void init() override
|
||||
{
|
||||
init_template("tpl-brush-icon");
|
||||
color_hover = glm::vec4(.7, .7, .7, 1);
|
||||
color_normal = glm::vec4(.3, .3, .3, 1);
|
||||
m_color = color_normal;
|
||||
img = (NodeImage*)m_children[0].get();
|
||||
}
|
||||
void set_icon(const char* path)
|
||||
{
|
||||
img->m_path = path;
|
||||
img->m_tex_id = const_hash(img->m_path.c_str());
|
||||
img->create();
|
||||
}
|
||||
virtual void draw() override
|
||||
{
|
||||
m_color = m_selected ? glm::vec4(1, 0, 0, 1) : color_normal;
|
||||
NodeButtonCustom::draw();
|
||||
}
|
||||
};
|
||||
|
||||
class NodePanelBrushes : public Node
|
||||
{
|
||||
std::vector<NodeButtonBrush*> m_brushes;
|
||||
NodeButtonBrush* m_current = nullptr;
|
||||
Node* m_container;
|
||||
public:
|
||||
std::function<void(Node* target, int id)> on_brush_changed;
|
||||
virtual Node* clone_instantiate() const override { return new NodePanelLayers(); }
|
||||
virtual void init() override
|
||||
{
|
||||
init_template("tpl-panel-brushes");
|
||||
//m_layers_container = find<NodeBorder>("layers-container");
|
||||
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;
|
||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||
m_container->add_child(brush);
|
||||
brush->init();
|
||||
brush->create();
|
||||
brush->loaded();
|
||||
brush->set_icon(path.c_str());
|
||||
brush->m_brushID = count++;
|
||||
m_brushes.push_back(brush);
|
||||
brush->on_click = std::bind(&NodePanelBrushes::handle_click, this, std::placeholders::_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
void handle_click(Node* target)
|
||||
{
|
||||
if (target == m_current)
|
||||
return;
|
||||
if (m_current)
|
||||
m_current->m_selected = false;
|
||||
m_current = (NodeButtonBrush*)target;
|
||||
m_current->m_selected = true;
|
||||
on_brush_changed(this, m_current->m_brushID);
|
||||
}
|
||||
std::vector<std::string> FindAllBrushes(std::string folder)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
std::string search_path = folder + "*.png";
|
||||
WIN32_FIND_DATAA fd;
|
||||
HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
// read all (real) files in current folder
|
||||
// , delete '!' read other 2 default folder . and ..
|
||||
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
names.push_back(fd.cFileName);
|
||||
}
|
||||
} while (::FindNextFileA(hFind, &fd));
|
||||
::FindClose(hFind);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user