complete left click event handle

This commit is contained in:
2017-02-09 22:08:30 +00:00
parent de1784e932
commit 914fc34331
8 changed files with 140 additions and 11 deletions

View File

@@ -24,6 +24,11 @@
</layout> </layout>
<layout id="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="5">
<border margin="0 0 5 0" pad="0 0 0 5" color=".3" width="100%" height="25" dir="row" align="center">
<text text="File" font-face="arial" font-size="11" margin="0 15 0 0"/>
<text text="Edit" font-face="arial" font-size="11" margin="0 15 0 0"/>
<text text="View" font-face="arial" font-size="11" margin="0 15 0 0"/>
</border>
<!-- toolbar --> <!-- toolbar -->
<border height="50" width="100%" pad="5" dir="row" color=".2"> <border height="50" width="100%" pad="5" dir="row" color=".2">
<ref id="multi-button"/> <ref id="multi-button"/>
@@ -75,16 +80,16 @@
</border> </border>
</node> </node>
<!-- content panel --> <!-- content panel -->
<node width="1" grow="1" height="100%" pad="10" wrap="1" dir="col" justify="center" align="center"> <border margin="10 0 10 10" border-color=".8" width="1" grow="1" pad="10" wrap="1" dir="col" justify="center" align="center">
<text text="hello widget" font-face="arial" font-size="30" color="0 1 1 1"/> <text text="hello widget" font-face="arial" font-size="30" color="0 1 1 1"/>
<text text="this is a small description of the useless big text above" font-face="arial" font-size="11" color="0 1 1 1"/> <text text="this is a small description of the useless big text above" font-face="arial" font-size="11" color="0 1 1 1"/>
<image margin="10 0 0 0" path="data/uvs.jpg" width="100" height="100"/> <image id="check" margin="10 0 0 0" path="data/uvs.jpg" width="100" height="100" region="0 0 100 100"/>
</node> </border>
</node> </node>
<!-- status bar --> <!-- status bar -->
<border height="30" width="100%" color=".15" border-color=".3" dir="row" pad="0 0 0 10" align="center"> <border height="30" width="100%" color=".15" border-color=".3" dir="row" pad="0 0 0 10" align="center">
<text text="Status Bar: nothing to show here." font-face="arial" font-size="11"/> <text text="Status Bar: nothing to show here." font-face="arial" font-size="11"/>
<text text="#opengl #fromscratch" font-face="arial" font-size="11" margin="0 0 0 10" color=".2 .5 1 1"/> <text text="#opengl #fromscratch #not-made-with-unity" font-face="arial" font-size="11" margin="0 0 0 10" color=".2 .5 1 1"/>
</border> </border>
</node> </node>
</layout> </layout>

View File

@@ -164,6 +164,7 @@
<ClCompile Include="engine\shader.cpp" /> <ClCompile Include="engine\shader.cpp" />
<ClCompile Include="engine\shape.cpp" /> <ClCompile Include="engine\shape.cpp" />
<ClCompile Include="engine\texture.cpp" /> <ClCompile Include="engine\texture.cpp" />
<ClCompile Include="engine\util.cpp" />
<ClCompile Include="libs\tinyxml2\tinyxml2.cpp"> <ClCompile Include="libs\tinyxml2\tinyxml2.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
@@ -192,6 +193,7 @@
<ClInclude Include="engine\shader.h" /> <ClInclude Include="engine\shader.h" />
<ClInclude Include="engine\shape.h" /> <ClInclude Include="engine\shape.h" />
<ClInclude Include="engine\texture.h" /> <ClInclude Include="engine\texture.h" />
<ClInclude Include="engine\util.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@@ -51,6 +51,9 @@
<ClCompile Include="engine\font.cpp"> <ClCompile Include="engine\font.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="engine\util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="engine\app.h"> <ClInclude Include="engine\app.h">
@@ -77,5 +80,8 @@
<ClInclude Include="engine\font.h"> <ClInclude Include="engine\font.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="engine\util.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -173,13 +173,16 @@ void App::update(float dt)
if (layout.reload()) if (layout.reload())
{ {
layout[main_id].update(width, height); layout[main_id].update(width, height);
//Node* check = layout[main_id].find("check");
//if (check)
// check->m_display = false;
} }
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
for (auto& n : layout[main_id]) for (auto& n : layout[main_id])
{ {
if (n.m_widget) if (n.m_display && n.m_widget)
{ {
auto box = n.m_widget->clip; auto box = n.m_widget->clip;
glScissor((int)box.x, (int)(height - box.y - box.w), (int)box.z, (int)box.w); glScissor((int)box.x, (int)(height - box.y - box.w), (int)box.z, (int)box.w);
@@ -225,7 +228,11 @@ void App::resize(float w, float h)
void App::mouse_down(int button, float x, float y) void App::mouse_down(int button, float x, float y)
{ {
constexpr auto main_id = const_hash("main");
printf("mouse click %f %f\n", x, y); printf("mouse click %f %f\n", x, y);
MouseEvent e;
e.m_pos = { x, y };
layout[main_id].on_event(&e);
} }
void App::mouse_move(float x, float y) void App::mouse_move(float x, float y)
{ {

View File

@@ -6,6 +6,39 @@ Plane WidgetBorder::m_plane;
Plane WidgetImage::m_plane; Plane WidgetImage::m_plane;
Sampler WidgetImage::m_sampler; Sampler WidgetImage::m_sampler;
Node* Node::find(const char* ids)
{
uint16_t id = const_hash(ids);
if (id == m_nodeID)
return this;
for (auto& c : *this)
if (c.m_nodeID == id)
return &c;
return nullptr;
}
kEventResult Node::on_event(Event* e)
{
for (auto& c : m_children)
if (c.on_event(e) == kEventResult::Handled)
return kEventResult::Handled;
if (m_widget)
{
switch (e->m_cat)
{
case kEventCategory::MouseEvent:
if (point_in_rect(((MouseEvent*)e)->m_pos, m_clip) && m_widget->on_event(e) == kEventResult::Handled)
return kEventResult::Handled;
break;
default:
if (m_widget->on_event(e) == kEventResult::Handled)
return kEventResult::Handled;
break;
}
}
return kEventResult::UnHandled;
}
void Node::update(float width, float height) void Node::update(float width, float height)
{ {
YGNodeStyleSetWidth(y_node, width); YGNodeStyleSetWidth(y_node, width);
@@ -29,10 +62,10 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
// correct the padding clip // correct the padding clip
// should not clip the padded area // should not clip the padded area
// useful to draw decorations // useful to draw decorations
float pt = YGNodeLayoutGetPadding(parent->y_node, YGEdgeTop); float pt = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeTop);
float pr = YGNodeLayoutGetPadding(parent->y_node, YGEdgeRight); float pr = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeRight);
float pb = YGNodeLayoutGetPadding(parent->y_node, YGEdgeBottom); float pb = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeBottom);
float pl = YGNodeLayoutGetPadding(parent->y_node, YGEdgeLeft); float pl = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeLeft);
glm::vec2 off_p(pl, pt); glm::vec2 off_p(pl, pt);
glm::vec2 off_s(pr, pb); glm::vec2 off_s(pr, pb);
m_clip = glm::vec4(m_pos - off_p, m_size + off_p + off_s); m_clip = glm::vec4(m_pos - off_p, m_size + off_p + off_s);
@@ -63,6 +96,10 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
{ {
switch (ka) switch (ka)
{ {
case kAttribute::id:
m_nodeID_s = attr->Value();
m_nodeID = const_hash(attr->Value());
break;
case kAttribute::Width: case kAttribute::Width:
if (strcmp(attr->Value(), "auto") == 0) if (strcmp(attr->Value(), "auto") == 0)
{ {

View File

@@ -52,6 +52,39 @@ enum class kShapeType : uint16_t
Slice9 = const_hash("slice9"), Slice9 = const_hash("slice9"),
}; };
enum class kEventResult : uint8_t
{
Handled,
UnHandled,
};
enum class kEventCategory : uint8_t
{
MouseEvent,
};
enum class kEventType : uint8_t
{
MouseDownL,
MouseDownR,
MouseMove,
MouseUpL,
MouseUpR,
};
class Event
{
public:
kEventCategory m_cat;
kEventType m_type;
};
class MouseEvent : public Event
{
public:
MouseEvent() { m_cat = kEventCategory::MouseEvent; }
glm::vec2 m_pos;
};
class Widget class Widget
{ {
public: public:
@@ -65,6 +98,7 @@ public:
virtual void draw() { } virtual void draw() { }
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { } virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { }
virtual void update() { } virtual void update() { }
virtual kEventResult on_event(Event* e) { return kEventResult::UnHandled; }
}; };
class WidgetRef : public Widget class WidgetRef : public Widget
@@ -136,6 +170,11 @@ public:
break; break;
} }
} }
virtual kEventResult on_event(Event* e)
{
m_color = rand_color();
return kEventResult::Handled;
}
}; };
class WidgetShape : public Widget class WidgetShape : public Widget
@@ -288,6 +327,11 @@ public:
{ {
mvp = proj * pos; mvp = proj * pos;
} }
virtual kEventResult on_event(Event* e)
{
m_color = rand_color();
return kEventResult::Handled;
}
}; };
class WidgetImage : public Widget class WidgetImage : public Widget
@@ -366,6 +410,11 @@ public:
break; break;
} }
} }
virtual kEventResult on_event(Event* e)
{
MouseEvent* me = static_cast<MouseEvent*>(e);
return kEventResult::UnHandled;
}
}; };
class Node class Node
@@ -377,22 +426,28 @@ class Node
class LayoutManager* m_manager; class LayoutManager* m_manager;
public: public:
uint16_t m_nodeID;
std::string m_nodeID_s;
std::vector<Node> m_children; std::vector<Node> m_children;
std::unique_ptr<Widget> m_widget; std::unique_ptr<Widget> m_widget;
glm::vec2 m_pos; glm::vec2 m_pos;
glm::vec2 m_size; glm::vec2 m_size;
glm::vec4 m_clip; glm::vec4 m_clip;
std::string m_name; std::string m_name;
bool m_display = true;
Node(const Node&) = delete; Node(const Node&) = delete;
Node& operator=(const Node&) = delete; Node& operator=(const Node&) = delete;
Node&& operator=(Node&& o) { return std::forward<Node>(o); } Node&& operator=(Node&& o) { return std::forward<Node>(o); }
Node(Node&& o) Node(Node&& o)
{ {
m_name = std::move(o.m_name); m_name = std::move(o.m_name);
m_nodeID_s = std::move(o.m_nodeID_s);
m_widget = std::move(o.m_widget); m_widget = std::move(o.m_widget);
m_children = std::move(o.m_children); m_children = std::move(o.m_children);
for (auto& c : m_children) for (auto& c : m_children)
c.parent = this; c.parent = this;
m_nodeID = o.m_nodeID;
m_display = o.m_display;
parent = o.parent; parent = o.parent;
y_node = o.y_node; y_node = o.y_node;
m_pos = o.m_pos; m_pos = o.m_pos;
@@ -444,6 +499,8 @@ public:
void load_internal(const tinyxml2::XMLElement* x_node); void load_internal(const tinyxml2::XMLElement* x_node);
void draw(); void draw();
Node clone(); Node clone();
Node* find(const char* ids);
kEventResult on_event(Event* e);
class iterator class iterator
{ {

View File

@@ -1,3 +1,15 @@
#include "pch.h" #include "pch.h"
#include "util.h" #include "util.h"
bool point_in_rect(const glm::vec2& p, const glm::vec4& r)
{
return p.x > r.x && p.x < r.x+r.z && p.y > r.y && p.y < r.y+r.w;
}
glm::vec4 rand_color()
{
float r = (rand() % 256) / 256.f;
float g = (rand() % 256) / 256.f;
float b = (rand() % 256) / 256.f;
return { r, g, b, 1.f };
}

View File

@@ -3,6 +3,9 @@
uint16_t constexpr const_hash(const char* input) uint16_t constexpr const_hash(const char* input)
{ {
return *input ? return *input ?
static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) : static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
5381; 5381;
} }
bool point_in_rect(const glm::vec2& point, const glm::vec4& rect);
glm::vec4 rand_color();