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 id="main">
<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 -->
<border height="50" width="100%" pad="5" dir="row" color=".2">
<ref id="multi-button"/>
@@ -75,16 +80,16 @@
</border>
</node>
<!-- 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="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"/>
</node>
<image id="check" margin="10 0 0 0" path="data/uvs.jpg" width="100" height="100" region="0 0 100 100"/>
</border>
</node>
<!-- status bar -->
<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="#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>
</node>
</layout>

View File

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

View File

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

View File

@@ -173,13 +173,16 @@ void App::update(float dt)
if (layout.reload())
{
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);
glEnable(GL_SCISSOR_TEST);
for (auto& n : layout[main_id])
{
if (n.m_widget)
if (n.m_display && n.m_widget)
{
auto box = n.m_widget->clip;
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)
{
constexpr auto main_id = const_hash("main");
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)
{

View File

@@ -6,6 +6,39 @@ Plane WidgetBorder::m_plane;
Plane WidgetImage::m_plane;
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)
{
YGNodeStyleSetWidth(y_node, width);
@@ -29,10 +62,10 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
// correct the padding clip
// should not clip the padded area
// useful to draw decorations
float pt = YGNodeLayoutGetPadding(parent->y_node, YGEdgeTop);
float pr = YGNodeLayoutGetPadding(parent->y_node, YGEdgeRight);
float pb = YGNodeLayoutGetPadding(parent->y_node, YGEdgeBottom);
float pl = YGNodeLayoutGetPadding(parent->y_node, YGEdgeLeft);
float pt = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeTop);
float pr = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeRight);
float pb = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeBottom);
float pl = 0;//YGNodeLayoutGetPadding(parent->y_node, YGEdgeLeft);
glm::vec2 off_p(pl, pt);
glm::vec2 off_s(pr, pb);
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)
{
case kAttribute::id:
m_nodeID_s = attr->Value();
m_nodeID = const_hash(attr->Value());
break;
case kAttribute::Width:
if (strcmp(attr->Value(), "auto") == 0)
{

View File

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

View File

@@ -1,3 +1,15 @@
#include "pch.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)
{
return *input ?
static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
5381;
static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
5381;
}
bool point_in_rect(const glm::vec2& point, const glm::vec4& rect);
glm::vec4 rand_color();