mirror of
https://gitee.com/idea4good/GuiLite.git
synced 2026-01-02 04:17:19 +08:00
refactor folder
This commit is contained in:
569
workspace/core/wnd.cpp
Normal file
569
workspace/core/wnd.cpp
Normal file
@@ -0,0 +1,569 @@
|
||||
#include "../core_include/api.h"
|
||||
#include "../core_include/rect.h"
|
||||
#include "../core_include/cmd_target.h"
|
||||
#include "../core_include/resource.h"
|
||||
#include "../core_include/bitmap.h"
|
||||
#include "../core_include/surface.h"
|
||||
#include "../core_include/wnd.h"
|
||||
|
||||
c_wnd::c_wnd(): m_status(STATUS_NORMAL), m_attr(ATTR_VISIBLE), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0),
|
||||
m_str(0), m_font_color(0), m_bg_color(0), m_resource_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0)
|
||||
{
|
||||
m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
|
||||
}
|
||||
|
||||
int c_wnd::connect(c_wnd *parent, unsigned short resource_id, const char* str,
|
||||
short x, short y, short width, short height, WND_TREE* p_child_tree )
|
||||
{
|
||||
if(0 == resource_id)
|
||||
{
|
||||
ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_resource_id = resource_id;
|
||||
set_str(str);
|
||||
m_parent = parent;
|
||||
m_status = STATUS_NORMAL;
|
||||
|
||||
if (parent)
|
||||
{
|
||||
m_z_order = parent->m_z_order;
|
||||
m_surface = parent->m_surface;
|
||||
}
|
||||
if(0 == m_surface)
|
||||
{
|
||||
ASSERT(false);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/
|
||||
m_wnd_rect.m_left = x;
|
||||
m_wnd_rect.m_top = y;
|
||||
m_wnd_rect.m_right = (x + width - 1);
|
||||
m_wnd_rect.m_bottom = (y + height - 1);
|
||||
|
||||
c_rect rect;
|
||||
get_screen_rect(rect);
|
||||
ASSERT(m_surface->is_valid(rect));
|
||||
|
||||
pre_create_wnd();
|
||||
|
||||
if ( 0 != parent )
|
||||
{
|
||||
parent->add_child_2_tail(this);
|
||||
}
|
||||
|
||||
if (load_child_wnd(p_child_tree) >= 0)
|
||||
{
|
||||
load_cmd_msg();
|
||||
on_init_children();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c_wnd::load_child_wnd(WND_TREE *p_child_tree)
|
||||
{
|
||||
if (0 == p_child_tree)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int sum = 0;
|
||||
|
||||
WND_TREE* p_cur = p_child_tree;
|
||||
while(p_cur->p_wnd)
|
||||
{
|
||||
if (0 != p_cur->p_wnd->m_resource_id)
|
||||
{//This wnd has been used! Do not share!
|
||||
ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_cur->p_wnd->connect(this, p_cur->resource_id, p_cur->str,
|
||||
p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree);
|
||||
}
|
||||
p_cur++;
|
||||
sum++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
c_wnd* c_wnd::connect_clone(c_wnd *parent, unsigned short resource_id, const char* str,
|
||||
short x, short y, short width, short height, WND_TREE* p_child_tree )
|
||||
{
|
||||
if(0 == resource_id)
|
||||
{
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c_wnd* wnd = clone();
|
||||
wnd->m_resource_id = resource_id;
|
||||
wnd->set_str(str);
|
||||
wnd->m_parent = parent;
|
||||
wnd->m_status = STATUS_NORMAL;
|
||||
|
||||
if (parent)
|
||||
{
|
||||
wnd->m_z_order = parent->m_z_order;
|
||||
wnd->m_surface = parent->m_surface;
|
||||
}
|
||||
else
|
||||
{
|
||||
wnd->m_surface = m_surface;
|
||||
}
|
||||
if(0 == wnd->m_surface)
|
||||
{
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/
|
||||
wnd->m_wnd_rect.m_left = x;
|
||||
wnd->m_wnd_rect.m_top = y;
|
||||
wnd->m_wnd_rect.m_right = (x + width - 1);
|
||||
wnd->m_wnd_rect.m_bottom = (y + height - 1);
|
||||
|
||||
c_rect rect;
|
||||
wnd->get_screen_rect(rect);
|
||||
ASSERT(wnd->m_surface->is_valid(rect));
|
||||
|
||||
wnd->pre_create_wnd();
|
||||
|
||||
if ( 0 != parent )
|
||||
{
|
||||
parent->add_child_2_tail(wnd);
|
||||
}
|
||||
|
||||
if (wnd->load_clone_child_wnd(p_child_tree) >= 0)
|
||||
{
|
||||
wnd->load_cmd_msg();
|
||||
wnd->on_init_children();
|
||||
}
|
||||
return wnd;
|
||||
}
|
||||
|
||||
int c_wnd::load_clone_child_wnd(WND_TREE *p_child_tree)
|
||||
{
|
||||
if (0 == p_child_tree)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int sum = 0;
|
||||
|
||||
WND_TREE* p_cur = p_child_tree;
|
||||
while(p_cur->p_wnd)
|
||||
{
|
||||
p_cur->p_wnd->connect_clone(this, p_cur->resource_id, p_cur->str,
|
||||
p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree);
|
||||
p_cur++;
|
||||
sum++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void c_wnd::disconnect()
|
||||
{
|
||||
if (0 == m_resource_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != m_top_child)
|
||||
{
|
||||
c_wnd *child = m_top_child;
|
||||
c_wnd *next_child = 0;
|
||||
|
||||
while (child)
|
||||
{
|
||||
next_child = child->m_next_sibling;
|
||||
child->disconnect();
|
||||
child = next_child;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != m_parent)
|
||||
{
|
||||
m_parent->unlink_child(this);
|
||||
}
|
||||
m_focus_child = 0;
|
||||
m_resource_id = 0;
|
||||
}
|
||||
|
||||
c_wnd* c_wnd::get_wnd_ptr(unsigned short id) const
|
||||
{
|
||||
c_wnd *child = m_top_child;
|
||||
|
||||
while ( child )
|
||||
{
|
||||
if ( child->get_id() == id )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
child = child->m_next_sibling;
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
void c_wnd::set_attr(WND_ATTRIBUTION attr)
|
||||
{
|
||||
m_attr = attr;
|
||||
|
||||
if ( ATTR_DISABLED == (attr & ATTR_DISABLED) )
|
||||
{
|
||||
m_status = STATUS_DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_status == STATUS_DISABLED)
|
||||
{
|
||||
m_status = STATUS_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int c_wnd::is_focus_wnd() const
|
||||
{
|
||||
if ( (m_attr & ATTR_VISIBLE)
|
||||
&& !(m_attr & ATTR_DISABLED)
|
||||
&& (m_attr & ATTR_FOCUS))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void c_wnd::set_wnd_pos(short x, short y, short width, short height)
|
||||
{
|
||||
m_wnd_rect.m_left = x;
|
||||
m_wnd_rect.m_top = y;
|
||||
m_wnd_rect.m_right = x + width - 1;
|
||||
m_wnd_rect.m_bottom = y + height - 1;
|
||||
}
|
||||
|
||||
void c_wnd::get_wnd_rect(c_rect &rect) const
|
||||
{
|
||||
rect = m_wnd_rect;
|
||||
}
|
||||
|
||||
void c_wnd::get_screen_rect(c_rect &rect) const
|
||||
{
|
||||
rect.SetRect(0, 0, (m_wnd_rect.Width() - 1), (m_wnd_rect.Height() - 1));
|
||||
wnd2screen(rect);
|
||||
}
|
||||
|
||||
void c_wnd::wnd2screen(int &x, int &y) const
|
||||
{
|
||||
c_wnd *parent = m_parent;
|
||||
c_rect rect;
|
||||
|
||||
x += m_wnd_rect.m_left;
|
||||
y += m_wnd_rect.m_top;
|
||||
|
||||
while ( 0 != parent )
|
||||
{
|
||||
parent->get_wnd_rect(rect);
|
||||
x += rect.m_left;
|
||||
y += rect.m_top;
|
||||
|
||||
parent = parent->m_parent;
|
||||
}
|
||||
}
|
||||
|
||||
void c_wnd::wnd2screen(c_rect &rect) const
|
||||
{
|
||||
int l = rect.m_left;
|
||||
int t = rect.m_top;
|
||||
wnd2screen(l, t);
|
||||
|
||||
int r = (l + rect.Width() - 1);
|
||||
int b = (t + rect.Height() - 1);
|
||||
rect.SetRect(l, t, r, b);
|
||||
}
|
||||
|
||||
c_wnd* c_wnd::set_child_focus(c_wnd * focus_child)
|
||||
{
|
||||
ASSERT(0 != focus_child);
|
||||
ASSERT(focus_child->m_parent == this);
|
||||
|
||||
c_wnd *old_focus_child = m_focus_child;
|
||||
if (focus_child->is_focus_wnd())
|
||||
{
|
||||
if (focus_child != old_focus_child )
|
||||
{
|
||||
if (old_focus_child)
|
||||
{
|
||||
old_focus_child->on_kill_focus();
|
||||
}
|
||||
m_focus_child = focus_child;
|
||||
|
||||
if (m_parent)
|
||||
{
|
||||
m_parent->set_child_focus(this);
|
||||
}
|
||||
m_focus_child->on_focus();
|
||||
}
|
||||
}
|
||||
return m_focus_child;
|
||||
}
|
||||
|
||||
void c_wnd::add_child_2_tail(c_wnd *child)
|
||||
{
|
||||
if( 0 == child )return;
|
||||
if(child == get_wnd_ptr(child->m_resource_id))return;
|
||||
|
||||
if ( 0 == m_top_child )
|
||||
{
|
||||
m_top_child = child;
|
||||
child->m_prev_sibling = 0;
|
||||
child->m_next_sibling = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_wnd *last_child = get_last_child();
|
||||
if (0 == last_child)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
last_child->m_next_sibling = child;
|
||||
child->m_prev_sibling = last_child;
|
||||
child->m_next_sibling = 0;
|
||||
}
|
||||
}
|
||||
|
||||
c_wnd* c_wnd::get_last_child() const
|
||||
{
|
||||
if ( 0 == m_top_child )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
c_wnd *child = m_top_child;
|
||||
|
||||
while ( child->m_next_sibling)
|
||||
{
|
||||
child = child->m_next_sibling;
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
int c_wnd::unlink_child(c_wnd *child)
|
||||
{
|
||||
if ((0 == child)
|
||||
|| (this != child->m_parent))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == m_top_child)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
int find = false;
|
||||
|
||||
c_wnd *tmp_child = m_top_child;
|
||||
if (tmp_child == child)
|
||||
{
|
||||
m_top_child = child->m_next_sibling;
|
||||
if (0 != child->m_next_sibling)
|
||||
{
|
||||
child->m_next_sibling->m_prev_sibling = 0;
|
||||
}
|
||||
|
||||
find = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (tmp_child->m_next_sibling)
|
||||
{
|
||||
if (child == tmp_child->m_next_sibling)
|
||||
{
|
||||
tmp_child->m_next_sibling = child->m_next_sibling;
|
||||
if (0 != child->m_next_sibling)
|
||||
{
|
||||
child->m_next_sibling->m_prev_sibling = tmp_child;
|
||||
}
|
||||
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_child = tmp_child->m_next_sibling;
|
||||
}
|
||||
}
|
||||
|
||||
if (true == find)
|
||||
{
|
||||
if (m_focus_child == child)
|
||||
{
|
||||
m_focus_child = 0;
|
||||
}
|
||||
|
||||
child->m_next_sibling = 0;
|
||||
child->m_prev_sibling = 0;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void c_wnd::show_window()
|
||||
{
|
||||
if (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE))
|
||||
{
|
||||
on_paint();
|
||||
c_wnd *child = m_top_child;
|
||||
if ( 0 != child )
|
||||
{
|
||||
while ( child )
|
||||
{
|
||||
child->show_window();
|
||||
child = child->m_next_sibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool c_wnd::on_touch(int x, int y, TOUCH_ACTION action)
|
||||
{
|
||||
c_rect rect;
|
||||
x -= m_wnd_rect.m_left;
|
||||
y -= m_wnd_rect.m_top;
|
||||
c_wnd* child = m_top_child;
|
||||
|
||||
c_wnd* target_wnd = 0;
|
||||
int target_z_order = Z_ORDER_LEVEL_0;
|
||||
|
||||
while (child)
|
||||
{
|
||||
if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE))
|
||||
{
|
||||
child->get_wnd_rect(rect);
|
||||
if (true == rect.PtInRect(x, y) || child->m_attr & ATTR_MODAL)
|
||||
{
|
||||
if (true == child->is_focus_wnd())
|
||||
{
|
||||
if (child->m_z_order >= target_z_order)
|
||||
{
|
||||
target_wnd = child;
|
||||
target_z_order = child->m_z_order;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
child = child->m_next_sibling;
|
||||
}
|
||||
|
||||
if (target_wnd == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return target_wnd->on_touch(x, y, action);
|
||||
}
|
||||
|
||||
bool c_wnd::on_key(KEY_TYPE key)
|
||||
{
|
||||
ASSERT(key == KEY_FORWARD || key == KEY_BACKWARD || key == KEY_ENTER);
|
||||
|
||||
// Find current focus wnd.
|
||||
c_wnd* old_focus_wnd = m_focus_child;
|
||||
while (m_focus_child && m_focus_child->m_focus_child)
|
||||
{
|
||||
old_focus_wnd = m_focus_child->m_focus_child;
|
||||
}
|
||||
if (old_focus_wnd && !old_focus_wnd->on_key(key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Default moving focus(Default handle KEY_FOWARD/KEY_BACKWARD)
|
||||
if (key == KEY_ENTER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!old_focus_wnd)
|
||||
{// No current focus wnd, new one.
|
||||
c_wnd *child = m_top_child;
|
||||
c_wnd *new_focus_wnd = 0;
|
||||
while (child)
|
||||
{
|
||||
if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE))
|
||||
{
|
||||
if (true == child->is_focus_wnd())
|
||||
{
|
||||
new_focus_wnd = child;
|
||||
new_focus_wnd->m_parent->set_child_focus(new_focus_wnd);
|
||||
child = child->m_top_child;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
child = child->m_next_sibling;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Move focus from old wnd to next wnd
|
||||
c_wnd* next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling;
|
||||
while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))
|
||||
{// Search neighbor of old focus wnd
|
||||
next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;
|
||||
}
|
||||
if (!next_focus_wnd)
|
||||
{// Search whole brother wnd
|
||||
next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child();
|
||||
while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))
|
||||
{
|
||||
next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;
|
||||
}
|
||||
}
|
||||
if (next_focus_wnd)
|
||||
{
|
||||
next_focus_wnd->m_parent->set_child_focus(next_focus_wnd);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void c_wnd::notify_parent(unsigned int msg_id, int param)
|
||||
{
|
||||
if (!m_parent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const GL_MSG_ENTRY* entry = m_parent->FindMsgEntry(m_parent->GetMSgEntries(), MSG_TYPE_WND, msg_id, m_resource_id);
|
||||
if (0 == entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MSGFUNCS msg_funcs;
|
||||
msg_funcs.func = entry->func;
|
||||
|
||||
switch (entry->callbackType)
|
||||
{
|
||||
case MSG_CALLBACK_VV:
|
||||
(m_parent->*msg_funcs.func)();
|
||||
break;
|
||||
case MSG_CALLBACK_VVL:
|
||||
(m_parent->*msg_funcs.func_vvl)(param);
|
||||
break;
|
||||
case MSG_CALLBACK_VWV:
|
||||
(m_parent->*msg_funcs.func_vwv)(m_resource_id);
|
||||
break;
|
||||
case MSG_CALLBACK_VWL:
|
||||
(m_parent->*msg_funcs.func_vwl)(m_resource_id, param);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user