construct the inline widget for listbox

This commit is contained in:
Jinhao
2015-06-14 21:48:35 +08:00
parent 36b3e6e6cc
commit 1822fafd79
15 changed files with 472 additions and 179 deletions

View File

@@ -298,6 +298,15 @@ namespace nana
return false;
}
basic_window * basic_window::seek_non_lite_widget_ancestor() const
{
auto anc = this->parent;
while (anc && (category::flags::lite_widget == anc->other.category))
anc = anc->parent;
return anc;
}
void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r)
{
pos_owner = pos_root = r;

View File

@@ -64,6 +64,26 @@ namespace nana
bedrock::instance().evt_operation.cancel(evt);
}
class bedrock::flag_guard
{
public:
flag_guard(bedrock* brock, core_window_t * wd)
: brock_{ brock }, wd_(wd)
{
wd_->flags.refreshing = true;
}
~flag_guard()
{
if (brock_->wd_manager.available((wd_)))
wd_->flags.refreshing = false;
}
private:
bedrock *const brock_;
core_window_t *const wd_;
};
void bedrock::event_expose(core_window_t * wd, bool exposed)
{
if (nullptr == wd) return;
@@ -79,11 +99,8 @@ namespace nana
{
if (category::flags::root != wd->other.category)
{
//If the wd->parent is a lite_widget then find a parent until it is not a lite_widget
wd = wd->parent;
while (category::flags::lite_widget == wd->other.category)
wd = wd->parent;
//find an ancestor until it is not a lite_widget
wd = wd->seek_non_lite_widget_ancestor();
}
else if (category::flags::frame == wd->other.category)
wd = wd_manager.find_window(wd->root, wd->pos_root.x, wd->pos_root.y);
@@ -162,6 +179,9 @@ namespace nana
auto retain = wd->together.events_ptr;
auto evts_ptr = retain.get();
//enable refreshing flag, this is a RAII class for exception-safe
flag_guard fguard(this, wd);
switch (evt_code)
{
case event_code::click:
@@ -214,9 +234,9 @@ namespace nana
}
(wd->drawer.*drawer_event_fn)(*arg);
if (!draw_only)
evt_addr->emit(*arg);
break;
}
case event_code::mouse_wheel:

View File

@@ -1473,9 +1473,7 @@ namespace detail
brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared
}
brock.wd_manager.destroy(msgwnd);
nana::detail::platform_spec::instance().release_window_icon(msgwnd->root);
break;
case WM_NCDESTROY:

View File

@@ -1,7 +1,7 @@
/*
* Window Layout Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,12 +24,14 @@ namespace nana
//class window_layout
void window_layout::paint(core_window_t* wd, bool is_redraw, bool is_child_refreshed)
{
if (wd->flags.refreshing)
return;
if (nullptr == wd->effect.bground)
{
if (is_redraw)
{
if (wd->flags.refreshing) return;
wd->flags.refreshing = true;
wd->drawer.refresh();
wd->flags.refreshing = false;
@@ -42,6 +44,10 @@ namespace nana
bool window_layout::maproot(core_window_t* wd, bool have_refreshed, bool is_child_refreshed)
{
auto check_opaque = wd->seek_non_lite_widget_ancestor();
if (check_opaque && check_opaque->flags.refreshing)
return true;
nana::rectangle vr;
if (read_visual_rectangle(wd, vr))
{

View File

@@ -1333,14 +1333,16 @@ namespace detail
delete wd->together.caret;
wd->together.caret = nullptr;
}
arg_destroy arg;
arg.window_handle = reinterpret_cast<window>(wd);
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
//Delete the children widgets.
for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end; ++i)
_m_destroy(*i);
wd->children.clear();
arg_destroy arg;
arg.window_handle = reinterpret_cast<window>(wd);
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
_m_disengage(wd, nullptr);
wndlayout_type::enable_effects_bground(wd, false);