Merge branch 'hotfix-1.3' into develop

This commit is contained in:
Jinhao
2016-04-18 15:16:03 +08:00
116 changed files with 2343 additions and 1004 deletions

View File

@@ -207,10 +207,10 @@ namespace nana
{
switch(categ)
{
case category::root_tag::value:
case category::flags::root:
attribute.root = new attr_root_tag;
break;
case category::frame_tag::value:
case category::flags::frame:
attribute.frame = new attr_frame_tag;
break;
default:
@@ -222,10 +222,10 @@ namespace nana
{
switch(category)
{
case category::root_tag::value:
case category::flags::root:
delete attribute.root;
break;
case category::frame_tag::value:
case category::flags::frame:
delete attribute.frame;
break;
default: break;
@@ -236,7 +236,7 @@ namespace nana
//basic_window
//@brief: constructor for the root window
basic_window::basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&& wdg_notifier, category::root_tag**)
: widget_notifier(std::move(wdg_notifier)), other(category::root_tag::value)
: widget_notifier(std::move(wdg_notifier)), other(category::flags::root)
{
drawer.bind(this);
_m_init_pos_and_size(nullptr, rectangle());
@@ -256,7 +256,7 @@ namespace nana
//@brief: bind a native window and baisc_window
void basic_window::bind_native_window(native_window_type wd, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, nana::paint::graphics& graphics)
{
if(category::root_tag::value == this->other.category)
if(category::flags::root == this->other.category)
{
this->root = wd;
dimension.width = width;
@@ -270,7 +270,7 @@ namespace nana
void basic_window::frame_window(native_window_type wd)
{
if(category::frame_tag::value == this->other.category)
if(category::flags::frame == this->other.category)
other.attribute.frame->container = wd;
}
@@ -357,12 +357,12 @@ namespace nana
void basic_window::_m_initialize(basic_window* agrparent)
{
if(other.category == category::root_tag::value)
if(category::flags::root == other.category)
{
if(agrparent && (nana::system::this_thread_id() != agrparent->thread_id))
agrparent = nullptr;
while(agrparent && (agrparent->other.category != category::root_tag::value))
while(agrparent && (category::flags::root != agrparent->other.category))
agrparent = agrparent->parent;
owner = agrparent;

View File

@@ -36,6 +36,18 @@ namespace nana
detail::bedrock::instance().wd_manager().internal_lock().unlock();
}
//end class internal_scope_guard
//class internal_revert_guard
internal_revert_guard::internal_revert_guard()
{
detail::bedrock::instance().wd_manager().internal_lock().revert();
}
internal_revert_guard::~internal_revert_guard()
{
detail::bedrock::instance().wd_manager().internal_lock().forward();
}
//end class internal_revert_guard
//class event_arg
void event_arg::stop_propagation() const

View File

@@ -227,7 +227,7 @@ namespace detail
return impl_->estore;
}
void bedrock::map_through_widgets(core_window_t* wd, native_drawable_type drawable)
void bedrock::map_through_widgets(core_window_t*, native_drawable_type)
{
//No implementation for Linux
}
@@ -250,9 +250,13 @@ namespace detail
_m_emit_core(evt_code, wd, false, arg);
if(ask_update)
wd_manager().do_lazy_refresh(wd, false);
else
//A child of wd may not be drawn if it was out of wd's range before wd resized,
//so refresh all children of wd when a resized occurs.
if(ask_update || (event_code::resized == evt_code))
{
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code));
}
else if(wd_manager().available(wd))
wd->other.upd_state = core_window_t::update_state::none;
if(thrd) thrd->event_window = prev_wd;
@@ -358,7 +362,7 @@ namespace detail
}
}
void window_proc_for_packet(Display * display, nana::detail::msg_packet_tag& msg)
void window_proc_for_packet(Display * /*display*/, nana::detail::msg_packet_tag& msg)
{
static auto& brock = detail::bedrock::instance();
@@ -477,7 +481,7 @@ namespace detail
return wchar_t(keysym);
}
void window_proc_for_xevent(Display* display, XEvent& xevent)
void window_proc_for_xevent(Display* /*display*/, XEvent& xevent)
{
typedef detail::bedrock::core_window_t core_window_t;
@@ -486,7 +490,8 @@ namespace detail
static core_window_t* last_mouse_down_window;
auto native_window = reinterpret_cast<native_window_type>(event_window(xevent));
auto root_runtime = brock.wd_manager().root_runtime(native_window);
auto & wd_manager = brock.wd_manager();
auto root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime)
{
@@ -506,7 +511,7 @@ namespace detail
if(pressed_wd_space)
break;
msgwnd = brock.wd_manager().find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y);
msgwnd = wd_manager.find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y);
if(msgwnd)
{
if (mouse_action::pressed != msgwnd->flags.action)
@@ -520,7 +525,7 @@ namespace detail
arg.evt_code = event_code::mouse_move;
brock.emit(event_code::mouse_move, msgwnd, arg, true, &context);
if (!brock.wd_manager().available(hovered_wd))
if (!wd_manager.available(hovered_wd))
hovered_wd = nullptr;
}
break;
@@ -544,7 +549,7 @@ namespace detail
if(msgwnd->dimension.width != static_cast<unsigned>(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast<unsigned>(xevent.xconfigure.height))
{
auto & cf = xevent.xconfigure;
brock.wd_manager().size(msgwnd, nana::size{static_cast<unsigned>(cf.width), static_cast<unsigned>(cf.height)}, true, true);
wd_manager.size(msgwnd, nana::size{static_cast<unsigned>(cf.width), static_cast<unsigned>(cf.height)}, true, true);
}
if(msgwnd->pos_native.x != xevent.xconfigure.x || msgwnd->pos_native.y != xevent.xconfigure.y)
@@ -562,7 +567,7 @@ namespace detail
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
break;
msgwnd = brock.wd_manager().find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
if(nullptr == msgwnd) break;
if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true))
@@ -584,7 +589,7 @@ namespace detail
context.event_window = new_focus;
auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press);
if (kill_focus != new_focus)
brock.wd_manager().do_lazy_refresh(kill_focus, false);
wd_manager.do_lazy_refresh(kill_focus, false);
}
}
@@ -598,7 +603,7 @@ namespace detail
arg.evt_code = dbl_click ? event_code::dbl_click : event_code::mouse_down;
if(brock.emit(arg.evt_code, msgwnd, arg, true, &context))
{
if (brock.wd_manager().available(msgwnd))
if (wd_manager.available(msgwnd))
{
pressed_wd = msgwnd;
//If a root window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event.
@@ -606,8 +611,9 @@ namespace detail
{
//call the drawer mouse up event for restoring the surface graphics
msgwnd->flags.action = mouse_action::normal;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
}
}
@@ -638,7 +644,7 @@ namespace detail
}
else
{
msgwnd = brock.wd_manager().find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
if(nullptr == msgwnd)
break;
@@ -669,7 +675,7 @@ namespace detail
}
//Do mouse_up, this handle may be closed by click handler.
if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled)
if(wd_manager.available(msgwnd) && msgwnd->flags.enabled)
{
if(hit)
msgwnd->flags.action = mouse_action::over;
@@ -683,7 +689,7 @@ namespace detail
if(click_arg.window_handle)
evt_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
if (brock.wd_manager().available(msgwnd))
if (wd_manager.available(msgwnd))
{
arg.evt_code = event_code::mouse_up;
evt_ptr->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd));
@@ -692,29 +698,27 @@ namespace detail
else if(click_arg.window_handle)
msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
pressed_wd = nullptr;
}
break;
case DestroyNotify:
if(wd_manager.available(msgwnd))
{
auto & spec = nana::detail::platform_spec::instance();
if(brock.wd_manager().available(msgwnd))
//The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window().
if (msgwnd->root == brock.get_menu())
{
//The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window().
if (msgwnd->root == brock.get_menu())
{
brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared
}
spec.remove(native_window);
brock.wd_manager().destroy(msgwnd);
brock.manage_form_loader(msgwnd, false);
brock.wd_manager().destroy_handle(msgwnd);
brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared
}
auto & spec = ::nana::detail::platform_spec::instance();
spec.remove(native_window);
wd_manager.destroy(msgwnd);
brock.manage_form_loader(msgwnd, false);
wd_manager.destroy_handle(msgwnd);
}
break;
case MotionNotify:
@@ -732,8 +736,8 @@ namespace detail
if(pressed_wd_space)
break;
msgwnd = brock.wd_manager().find_window(native_window, xevent.xmotion.x, xevent.xmotion.y);
if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd))
msgwnd = wd_manager.find_window(native_window, xevent.xmotion.x, xevent.xmotion.y);
if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
{
brock.event_msleave(hovered_wd);
hovered_wd->flags.action = mouse_action::normal;
@@ -741,14 +745,14 @@ namespace detail
//if msgwnd is neither a captured window nor a child of captured window,
//redirect the msgwnd to the captured window.
auto cap_wd = brock.wd_manager().capture_redirect(msgwnd);
auto cap_wd = wd_manager.capture_redirect(msgwnd);
if(cap_wd)
msgwnd = cap_wd;
}
else if(msgwnd)
{
bool prev_captured_inside;
if(brock.wd_manager().capture_window_entered(xevent.xmotion.x, xevent.xmotion.y, prev_captured_inside))
if(wd_manager.capture_window_entered(xevent.xmotion.x, xevent.xmotion.y, prev_captured_inside))
{
event_code evt_code;
if(prev_captured_inside)
@@ -787,7 +791,7 @@ namespace detail
arg.evt_code = event_code::mouse_move;
brock.emit(event_code::mouse_move, msgwnd, arg, true, &context);
}
if (!brock.wd_manager().available(hovered_wd))
if (!wd_manager.available(hovered_wd))
hovered_wd = nullptr;
break;
case MapNotify:
@@ -852,7 +856,6 @@ namespace detail
keybuf[len] = 0;
wchar_t os_code = 0;
auto & wd_manager = brock.wd_manager();
switch(status)
{
case XLookupKeySym:
@@ -934,7 +937,7 @@ namespace detail
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
if(brock.wd_manager().available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd))
if(wd_manager.available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd))
{
int cmd = (menu_wd && (keyboard::escape == static_cast<wchar_t>(arg.key)) ? 1 : 0 );
brock.delay_restore(cmd);
@@ -1041,7 +1044,7 @@ namespace detail
arg.window_handle = reinterpret_cast<window>(msgwnd);
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
pressed_wd_space = nullptr;
}
@@ -1072,7 +1075,7 @@ namespace detail
{
bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus);
if (set_focus)
brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::general);
wd_manager.set_focus(msgwnd, false, arg_focus::reason::general);
arg_keyboard arg;
arg.evt_code = event_code::key_release;
@@ -1111,7 +1114,7 @@ namespace detail
}
}
root_runtime = brock.wd_manager().root_runtime(native_window);
root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime)
{
context.event_window = pre_event_window;
@@ -1126,14 +1129,14 @@ namespace detail
}
auto thread_id = ::nana::system::this_thread_id();
brock.wd_manager().call_safe_place(thread_id);
wd_manager.call_safe_place(thread_id);
if(msgwnd)
brock.wd_manager().remove_trash_handle(thread_id);
wd_manager.remove_trash_handle(thread_id);
}
}
void bedrock::pump_event(window modal_window, bool is_modal)
void bedrock::pump_event(window modal_window, bool /*is_modal*/)
{
thread_context * context = open_thread_context();
if(0 == context->window_count)

View File

@@ -1,4 +1,4 @@
/*
/**
* A Bedrock Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
@@ -7,7 +7,8 @@
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/detail/win32/bedrock.cpp
* @file nana/gui/detail/win32/bedrock.cpp
* @brief A Bedrock Implementation
* @contributors: Ariel Vina-Rodriguez
*/
@@ -25,6 +26,8 @@
#include <nana/gui/detail/element_store.hpp>
#include <nana/gui/detail/color_schemes.hpp>
#include <iostream>
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
@@ -232,6 +235,7 @@ namespace detail
if(wd_manager().number_of_core_window())
{
std::string msg = "Nana.GUI detects a memory leaks in window_manager, " + std::to_string(wd_manager().number_of_core_window()) + " window(s) are not uninstalled.";
std::cerr << msg; /// \todo add list of cations of open windows and if aut testin GUI do auto Ok after 2 sec.
::MessageBoxA(0, msg.c_str(), ("Nana C++ Library"), MB_OK);
}
@@ -239,8 +243,8 @@ namespace detail
delete pi_data_;
}
//inc_window
//@brief: increament the number of windows
/// @brief increament the number of windows in the thread id
int bedrock::inc_window(unsigned tid)
{
//impl refers to the object of private_impl, the object is created when bedrock is creating.
@@ -453,6 +457,7 @@ namespace detail
{
(msgbox(modal_window, "An exception during message pumping!").icon(msgbox::icon_information)
<<"An uncaptured non-std exception during message pumping!"
<< "\n in form: " << API::window_caption(modal_window)
).show();
internal_scope_guard lock;
_m_except_handler();
@@ -650,6 +655,14 @@ namespace detail
case nana::detail::messages::tray:
notifications_window_proc(wd, wParam, lParam);
return true;
case nana::detail::messages::affinity_execute:
if (wParam)
{
auto arg = reinterpret_cast<detail::messages::arg_affinity_execute*>(wParam);
if (arg->function_ptr)
(*arg->function_ptr)();
}
break;
default:
break;
}
@@ -772,7 +785,9 @@ namespace detail
static restrict::TRACKMOUSEEVENT track = {sizeof track, 0x00000002};
auto native_window = reinterpret_cast<native_window_type>(root_window);
auto* root_runtime = brock.wd_manager().root_runtime(native_window);
auto & wd_manager = brock.wd_manager();
auto* root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime)
{
@@ -817,7 +832,7 @@ namespace detail
bool take_over = false;
auto mmi = reinterpret_cast<MINMAXINFO*>(lParam);
if(msgwnd->min_track_size.width && msgwnd->min_track_size.height)
if(!msgwnd->min_track_size.empty())
{
mmi->ptMinTrackSize.x = static_cast<LONG>(msgwnd->min_track_size.width + msgwnd->extra_width);
mmi->ptMinTrackSize.y = static_cast<LONG>(msgwnd->min_track_size.height + msgwnd->extra_height);
@@ -878,14 +893,14 @@ namespace detail
break;
pressed_wd = nullptr;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if(msgwnd && msgwnd->flags.enabled)
{
if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus)
{
auto killed = brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::mouse_press);
if (killed != msgwnd)
brock.wd_manager().do_lazy_refresh(killed, false);
wd_manager.do_lazy_refresh(killed, false);
}
arg_mouse arg;
@@ -903,7 +918,7 @@ namespace detail
if (pressed_wd_space)
break;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if ((nullptr == msgwnd) || (pressed_wd && (msgwnd != pressed_wd)))
break;
@@ -924,7 +939,7 @@ namespace detail
{
auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press);
if (kill_focus != new_focus)
brock.wd_manager().do_lazy_refresh(kill_focus, false);
wd_manager.do_lazy_refresh(kill_focus, false);
}
}
@@ -941,14 +956,14 @@ namespace detail
auto pos = native_interface::cursor_position();
auto rootwd = native_interface::find_window(pos.x, pos.y);
native_interface::calc_window_point(rootwd, pos);
if(msgwnd != brock.wd_manager().find_window(rootwd, pos.x, pos.y))
if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y))
{
//call the drawer mouse up event for restoring the surface graphics
msgwnd->flags.action = mouse_action::normal;
arg.evt_code = event_code::mouse_up;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
}
}
@@ -964,7 +979,7 @@ namespace detail
if (pressed_wd_space)
break;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if(nullptr == msgwnd)
break;
@@ -993,7 +1008,7 @@ namespace detail
}
//Do mouse_up, this handle may be closed by click handler.
if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled)
if(wd_manager.available(msgwnd) && msgwnd->flags.enabled)
{
arg.evt_code = event_code::mouse_up;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
@@ -1001,7 +1016,7 @@ namespace detail
if (click_arg.window_handle)
retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
if (brock.wd_manager().available(msgwnd))
if (wd_manager.available(msgwnd))
{
arg.evt_code = event_code::mouse_up;
retain->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd));
@@ -1010,7 +1025,7 @@ namespace detail
else if (click_arg.window_handle)
retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
pressed_wd = nullptr;
break;
@@ -1019,8 +1034,8 @@ namespace detail
if (pressed_wd_space)
break;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd))
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
{
brock.event_msleave(hovered_wd);
hovered_wd->flags.action = mouse_action::normal;
@@ -1028,7 +1043,7 @@ namespace detail
//if msgwnd is neither captured window nor the child of captured window,
//redirect the msgwnd to the captured window.
auto wd = brock.wd_manager().capture_redirect(msgwnd);
auto wd = wd_manager.capture_redirect(msgwnd);
if(wd)
msgwnd = wd;
}
@@ -1036,7 +1051,7 @@ namespace detail
else if(msgwnd)
{
bool prev_captured_inside;
if(brock.wd_manager().capture_window_entered(pmdec.mouse.x, pmdec.mouse.y, prev_captured_inside))
if(wd_manager.capture_window_entered(pmdec.mouse.x, pmdec.mouse.y, prev_captured_inside))
{
event_code evt_code;
if(prev_captured_inside)
@@ -1084,7 +1099,7 @@ namespace detail
track.hwndTrack = native_window;
restrict::track_mouse_event(&track);
}
if (!brock.wd_manager().available(hovered_wd))
if (!wd_manager.available(hovered_wd))
hovered_wd = nullptr;
break;
case WM_MOUSELEAVE:
@@ -1100,7 +1115,7 @@ namespace detail
if (pointer_wd == root_window)
{
::ScreenToClient(pointer_wd, &scr_pos);
auto scrolled_wd = brock.wd_manager().find_window(reinterpret_cast<native_window_type>(pointer_wd), scr_pos.x, scr_pos.y);
auto scrolled_wd = wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), scr_pos.x, scr_pos.y);
def_window_proc = true;
auto evt_wd = scrolled_wd;
@@ -1110,7 +1125,7 @@ namespace detail
{
def_window_proc = false;
nana::point mspos{ scr_pos.x, scr_pos.y };
brock.wd_manager().calc_window_point(evt_wd, mspos);
wd_manager.calc_window_point(evt_wd, mspos);
arg_wheel arg;
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
@@ -1124,14 +1139,14 @@ namespace detail
if (scrolled_wd && (nullptr == evt_wd))
{
nana::point mspos{ scr_pos.x, scr_pos.y };
brock.wd_manager().calc_window_point(scrolled_wd, mspos);
wd_manager.calc_window_point(scrolled_wd, mspos);
arg_wheel arg;
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
assign_arg(arg, scrolled_wd, pmdec);
draw_invoker(&drawer::mouse_wheel, scrolled_wd, arg, &context);
brock.wd_manager().do_lazy_refresh(scrolled_wd, false);
wd_manager.do_lazy_refresh(scrolled_wd, false);
}
}
else
@@ -1149,7 +1164,7 @@ namespace detail
POINT pos;
::DragQueryPoint(drop, &pos);
msgwnd = brock.wd_manager().find_window(native_window, pos.x, pos.y);
msgwnd = wd_manager.find_window(native_window, pos.x, pos.y);
if(msgwnd)
{
arg_dropfiles dropfiles;
@@ -1180,11 +1195,11 @@ namespace detail
dropfiles.pos.x = pos.x;
dropfiles.pos.y = pos.y;
brock.wd_manager().calc_window_point(msgwnd, dropfiles.pos);
wd_manager.calc_window_point(msgwnd, dropfiles.pos);
dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast<window>(msgwnd));
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
}
@@ -1272,7 +1287,7 @@ namespace detail
break;
case WM_SIZE:
if(wParam != SIZE_MINIMIZED)
brock.wd_manager().size(msgwnd, size(pmdec.size.width, pmdec.size.height), true, true);
wd_manager.size(msgwnd, size(pmdec.size.width, pmdec.size.height), true, true);
break;
case WM_MOVE:
brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
@@ -1298,7 +1313,7 @@ namespace detail
case WM_SYSCHAR:
def_window_proc = true;
brock.shortkey_occurred(true);
msgwnd = brock.wd_manager().find_shortkey(native_window, static_cast<unsigned long>(wParam));
msgwnd = wd_manager.find_shortkey(native_window, static_cast<unsigned long>(wParam));
if(msgwnd)
{
arg_keyboard arg;
@@ -1345,7 +1360,7 @@ namespace detail
bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus);
if (set_focus)
brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::general);
wd_manager.set_focus(msgwnd, false, arg_focus::reason::general);
arg_keyboard arg;
arg.evt_code = event_code::key_release;
@@ -1375,9 +1390,7 @@ namespace detail
if(msgwnd)
{
auto & wd_manager = brock.wd_manager();
if ((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab
if((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab
{
bool is_forward = (::GetKeyState(VK_SHIFT) >= 0);
@@ -1498,7 +1511,7 @@ namespace detail
arg.window_handle = reinterpret_cast<window>(msgwnd);
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false);
wd_manager.do_lazy_refresh(msgwnd, false);
}
pressed_wd_space = nullptr;
}
@@ -1544,12 +1557,12 @@ namespace detail
brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared
}
brock.wd_manager().destroy(msgwnd);
wd_manager.destroy(msgwnd);
nana::detail::platform_spec::instance().release_window_icon(msgwnd->root);
break;
case WM_NCDESTROY:
brock.manage_form_loader(msgwnd, false);
brock.wd_manager().destroy_handle(msgwnd);
wd_manager.destroy_handle(msgwnd);
if(--context.window_count <= 0)
{
@@ -1561,7 +1574,7 @@ namespace detail
def_window_proc = true;
}
root_runtime = brock.wd_manager().root_runtime(native_window);
root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime)
{
root_runtime->condition.pressed = pressed_wd;

View File

@@ -1,7 +1,7 @@
/*
* Platform Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,9 @@
#include <nana/detail/platform_spec_selector.hpp>
#include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/screen.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/window_manager.hpp>
#if defined(NANA_WINDOWS)
#if defined(STD_THREAD_NOT_SUPPORTED)
#include <nana/std_mutex.hpp>
@@ -23,8 +26,6 @@
#include "../../paint/detail/image_ico.hpp"
#elif defined(NANA_X11)
#include <nana/system/platform.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/window_manager.hpp>
#endif
namespace nana{
@@ -131,9 +132,13 @@ namespace nana{
}
}
if (async)
{
::ShowWindowAsync(wd, cmd);
else
::ShowWindow(wd, cmd);
return;
}
internal_revert_guard revert;
::ShowWindow(wd, cmd);
}
#elif defined(NANA_X11)
namespace restrict
@@ -143,6 +148,33 @@ namespace nana{
#endif
//struct native_interface
void native_interface::affinity_execute(native_window_type native_handle, const std::function<void()>& fn)
{
if (!fn)
return;
#if defined(NANA_WINDOWS)
auto mswin = reinterpret_cast<HWND>(native_handle);
if (::IsWindow(mswin))
{
if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(mswin, nullptr))
{
detail::messages::arg_affinity_execute arg;
arg.function_ptr = &fn;
internal_revert_guard revert;
::SendMessage(mswin, detail::messages::affinity_execute, reinterpret_cast<WPARAM>(&arg), 0);
return;
}
}
fn();
#else
fn();
#endif
}
nana::size native_interface::primary_monitor_size()
{
#if defined(NANA_WINDOWS)
@@ -173,6 +205,8 @@ namespace nana{
mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top);
}
}
#else
static_cast<void>(pos); //eliminate unused parameter compiler warning.
#endif
return rectangle{ primary_monitor_size() };
}
@@ -547,6 +581,8 @@ namespace nana{
activate_window(reinterpret_cast<native_window_type>(
::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER)
));
#else
static_cast<void>(wd); //eliminate unused parameter compiler warning.
#endif
}
@@ -565,6 +601,8 @@ namespace nana{
else
::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0);
}
#else
static_cast<void>(wd); //eliminate unused parameter compiler warning.
#endif
}
@@ -640,6 +678,7 @@ namespace nana{
::XFlush(disp);
}
static_cast<void>(active); //eliminate unused parameter compiler warning.
#endif
}
@@ -715,6 +754,7 @@ namespace nana{
#if defined(NANA_WINDOWS)
::InvalidateRect(reinterpret_cast<HWND>(wd), nullptr, true);
#elif defined(NANA_X11)
static_cast<void>(wd); //eliminate unused parameter compiler warning.
#endif
}
@@ -963,6 +1003,7 @@ namespace nana{
::SetWindowPos(native_wd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::AttachThreadInput(::GetCurrentThreadId(), fg_tid, FALSE);
#else
static_cast<void>(activated); //eliminate unused parameter compiler warning.
set_window_z_order(wd, nullptr, z_order_action::top);
#endif
}
@@ -1110,11 +1151,18 @@ namespace nana{
auto native_interface::window_caption(native_window_type wd) -> native_string_type
{
native_string_type str;
#if defined(NANA_WINDOWS)
auto & lock = bedrock::instance().wd_manager().internal_lock();
bool is_current_thread = (::GetCurrentThreadId() == ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr));
if (!is_current_thread)
lock.revert();
int length = ::GetWindowTextLength(reinterpret_cast<HWND>(wd));
if(length > 0)
{
native_string_type str;
//One for NULL terminator which GetWindowText will write.
str.resize(length+1);
@@ -1122,9 +1170,11 @@ namespace nana{
//Remove the null terminator writtien by GetWindowText
str.resize(length);
return str;
}
if (!is_current_thread)
lock.forward();
#elif defined(NANA_X11)
nana::detail::platform_scope_guard psg;
::XTextProperty txtpro;
@@ -1136,14 +1186,13 @@ namespace nana{
{
if(size > 1)
{
std::string text = *strlist;
str = *strlist;
::XFreeStringList(strlist);
return text;
}
}
}
#endif
return native_string_type();
return str;
}
void native_interface::capture_window(native_window_type wd, bool cap)
@@ -1305,7 +1354,10 @@ namespace nana{
if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr))
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::async_set_focus, 0, 0);
else
{
internal_revert_guard revert;
::SetFocus(reinterpret_cast<HWND>(wd));
}
}
#elif defined(NANA_X11)
nana::detail::platform_scope_guard lock;
@@ -1414,6 +1466,11 @@ namespace nana{
if(static_cast<unsigned>(y) > sz.height + ext_height)
sz.height = static_cast<unsigned>(y);
}
#else
//eliminate unused parameter compiler warning.
static_cast<void>(ext_width);
static_cast<void>(ext_height);
static_cast<void>(true_for_max);
#endif
return sz;
}

View File

@@ -53,7 +53,7 @@ namespace nana
//get the root graphics
auto& graph = *(wd->root_graph);
if (wd->other.category != category::lite_widget_tag::value)
if (category::flags::lite_widget != wd->other.category)
graph.bitblt(vr, wd->drawer.graphics, nana::point(vr.x - wd->pos_root.x, vr.y - wd->pos_root.y));
_m_paste_children(wd, is_child_refreshed, have_refreshed, vr, graph, nana::point());
@@ -66,7 +66,7 @@ namespace nana
nana::point p_src;
for (auto & el : blocks)
{
if (el.window->other.category == category::frame_tag::value)
if (category::flags::frame == el.window->other.category)
{
native_window_type container = el.window->other.attribute.frame->container;
native_interface::refresh_window(container);
@@ -95,9 +95,9 @@ namespace nana
}
//read_visual_rectangle
//@brief: Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget,
// the visual rectangle is a rectangular block that a window should be displayed on screen.
// The result is a rectangle that is a visible area for its ancesters.
///@brief Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget,
/// the visual rectangle is a rectangular block that a window should be displayed on screen.
/// The result is a rectangle that is a visible area for its ancesters.
bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual)
{
if (! wd->displayed()) return false;
@@ -158,7 +158,7 @@ namespace nana
bool window_layout::enable_effects_bground(core_window_t * wd, bool enabled)
{
if (wd->other.category != category::widget_tag::value)
if (category::flags::widget != wd->other.category)
return false;
if (false == enabled)
@@ -199,11 +199,11 @@ namespace nana
nana::point rpos{ wd->pos_root };
auto & glass_buffer = wd->other.glass_buffer;
if (wd->parent->other.category == category::lite_widget_tag::value)
if (category::flags::lite_widget == wd->parent->other.category)
{
std::vector<core_window_t*> layers;
core_window_t * beg = wd->parent;
while (beg && (beg->other.category == category::lite_widget_tag::value))
while (beg && (category::flags::lite_widget == beg->other.category))
{
layers.push_back(beg);
beg = beg->parent;
@@ -229,7 +229,7 @@ namespace nana
nana::rectangle ovlp;
if (child->visible && overlap(r, rectangle(child->pos_owner, child->dimension), ovlp))
{
if (child->other.category != category::lite_widget_tag::value)
if (category::flags::lite_widget != child->other.category)
glass_buffer.bitblt(nana::rectangle(ovlp.x - pre->pos_owner.x, ovlp.y - pre->pos_owner.y, ovlp.width, ovlp.height), child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y));
ovlp.x += pre->pos_root.x;
ovlp.y += pre->pos_root.y;
@@ -250,7 +250,7 @@ namespace nana
nana::rectangle ovlp;
if (child->visible && overlap(r_of_wd, rectangle{ child->pos_owner, child->dimension }, ovlp))
{
if (child->other.category != category::lite_widget_tag::value)
if (category::flags::lite_widget != child->other.category)
glass_buffer.bitblt(nana::rectangle{ ovlp.x - wd->pos_owner.x, ovlp.y - wd->pos_owner.y, ovlp.width, ovlp.height }, child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y));
ovlp.x += wd->pos_root.x;
@@ -285,7 +285,7 @@ namespace nana
if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect))
{
bool have_child_refreshed = false;
if (child->other.category != category::lite_widget_tag::value)
if (category::flags::lite_widget != child->other.category)
{
if (is_child_refreshed && (false == child->flags.refreshing))
{
@@ -357,7 +357,7 @@ namespace nana
//_m_notify_glasses
//@brief: Notify the glass windows that are overlapped with the specified vis_rect
void window_layout::_m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& r_visual)
void window_layout::_m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& /*r_visual*/)
{
typedef category::flags cat_flags;

View File

@@ -311,7 +311,7 @@ namespace detail
wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph);
impl_->wd_register.insert(wd, wd->thread_id);
if (owner && owner->other.category == category::frame_tag::value)
if (owner && (category::flags::frame == owner->other.category))
insert_frame(owner, wd);
bedrock::inc_window(wd->thread_id);
@@ -343,7 +343,7 @@ namespace detail
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(frame->other.category == category::frame_tag::value)
if(category::flags::frame == frame->other.category)
frame->other.attribute.frame->attach.push_back(wd);
return true;
}
@@ -356,9 +356,9 @@ namespace detail
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(frame->other.category == category::frame_tag::value)
if(category::flags::frame == frame->other.category)
{
if (impl_->wd_register.available(wd) && wd->other.category == category::root_tag::value && wd->root != frame->root)
if (impl_->wd_register.available(wd) && (category::flags::root == wd->other.category) && wd->root != frame->root)
{
frame->other.attribute.frame->attach.push_back(wd->root);
return true;
@@ -461,7 +461,7 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd) == false) return;
if((wd->other.category == category::root_tag::value) || (wd->other.category != category::frame_tag::value))
if((category::flags::root == wd->other.category) || (category::flags::frame != wd->other.category))
{
impl_->misc_register.erase(wd->root);
impl_->wd_register.remove(wd);
@@ -481,7 +481,7 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd))
{
if(wd->other.category == category::root_tag::value)
if(category::flags::root == wd->other.category)
native_interface::window_icon(wd->root, small_icon, big_icon);
}
}
@@ -501,9 +501,9 @@ namespace detail
native_window_type nv = nullptr;
switch(wd->other.category)
{
case category::root_tag::value:
case category::flags::root:
nv = wd->root; break;
case category::frame_tag::value:
case category::flags::frame:
nv = wd->other.attribute.frame->container; break;
default: //category::widget_tag, category::lite_widget_tag
break;
@@ -700,7 +700,7 @@ namespace detail
wd->dimension = sz;
if(category::lite_widget_tag::value != wd->other.category)
if(category::flags::lite_widget != wd->other.category)
{
bool graph_state = wd->drawer.graphics.empty();
wd->drawer.graphics.make(sz);
@@ -711,13 +711,13 @@ namespace detail
if(graph_state != wd->drawer.graphics.empty())
wd->drawer.typeface_changed();
if(category::root_tag::value == wd->other.category)
if(category::flags::root == wd->other.category)
{
wd->root_graph->make(sz);
if(false == passive)
native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height));
}
else if(category::frame_tag::value == wd->other.category)
else if(category::flags::frame == wd->other.category)
{
native_interface::window_size(wd->other.attribute.frame->container, sz);
for(auto natwd : wd->other.attribute.frame->attach)
@@ -828,7 +828,7 @@ namespace detail
//do_lazy_refresh
//@brief: defined a behavior of flush the screen
//@return: it returns true if the wnd is available
bool window_manager::do_lazy_refresh(core_window_t* wd, bool force_copy_to_screen)
bool window_manager::do_lazy_refresh(core_window_t* wd, bool force_copy_to_screen, bool refresh_tree)
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
@@ -843,8 +843,11 @@ namespace detail
{
if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen)
{
window_layer::paint(wd, false, false);
window_layer::paint(wd, false, refresh_tree);
this->map(wd, force_copy_to_screen);
wd->drawer.graphics.save_as_file("d:\\button.bmp");
wd->root_graph->save_as_file("d:\\button_root.bmp");
}
else if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
{
@@ -852,7 +855,7 @@ namespace detail
}
}
else
window_layer::paint(wd, true, false); //only refreshing if it has an invisible parent
window_layer::paint(wd, true, refresh_tree); //only refreshing if it has an invisible parent
}
wd->other.upd_state = core_window_t::update_state::none;
return true;
@@ -1362,7 +1365,7 @@ namespace detail
root_attr->menubar = nullptr;
}
if (wd->other.category == category::root_tag::value)
if (wd->other.category == category::flags::root)
{
root_runtime(wd->root)->shortkeys.clear();
wd->other.attribute.root->focus = nullptr;
@@ -1442,7 +1445,7 @@ namespace detail
}
}
if (wd->other.category == category::frame_tag::value)
if (category::flags::frame == wd->other.category)
{
//remove the frame handle from the WM frames manager.
utl::erase(root_attr->frames, wd);
@@ -1599,7 +1602,7 @@ namespace detail
for(auto i = wd->children.rbegin(); i != wd->children.rend(); ++i)
{
core_window_t* child = *i;
if((child->other.category != category::root_tag::value) && _m_effective(child, pos))
if((child->other.category != category::flags::root) && _m_effective(child, pos))
{
child = _m_find(child, pos);
if(child)

View File

@@ -212,7 +212,7 @@ namespace nana
class menu_crook
: public crook_interface
{
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color& fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color& fgcolor, const nana::rectangle& r, element_state, const data& crook_data) override
{
if(crook_data.check_state == state::unchecked)
return true;
@@ -266,7 +266,7 @@ namespace nana
class border_depressed
: public border_interface
{
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, unsigned weight)
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color&, const ::nana::rectangle& r, element_state estate, unsigned)
{
graph.rectangle(r, false, static_cast<color_rgb>((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E));
graph.rectangle(::nana::rectangle(r).pare_off(1), false, bgcolor);
@@ -277,7 +277,7 @@ namespace nana
class arrow_solid_triangle
: public arrow_interface
{
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, direction dir) override
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, direction dir) override
{
::nana::point pos{ r.x + 3, r.y + 3 };
switch (dir)
@@ -318,7 +318,7 @@ namespace nana
class arrow_hollow_triangle
: public arrow_interface
{
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override
{
int x = r.x + 3;
int y = r.y + 3;
@@ -364,7 +364,7 @@ namespace nana
class arrowhead
: public arrow_interface
{
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override
{
int x = r.x;
int y = r.y + 5;
@@ -425,7 +425,7 @@ namespace nana
class arrow_double
: public arrow_interface
{
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override
{
int x = r.x;
int y = r.y;
@@ -486,7 +486,7 @@ namespace nana
class annex_button
: public element_interface
{
bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color& fgcolor, const rectangle& r, element_state estate) override
bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color&, const rectangle& r, element_state estate) override
{
auto bgcolor = arg_bgcolor;

View File

@@ -355,13 +355,15 @@ namespace nana
msgbox::msgbox(const std::string& title)
: wd_(nullptr), title_(title), button_(ok), icon_(icon_none)
{
throw_not_utf8(title_);
// throw_not_utf8(title_);
review_utf8(title_);
}
msgbox::msgbox(window wd, const std::string& title, button_t b)
: wd_(wd), title_(title), button_(b), icon_(icon_none)
{
throw_not_utf8(title_);
// throw_not_utf8(title_);
review_utf8(title_);
}
msgbox& msgbox::icon(icon_t ic)
@@ -702,7 +704,7 @@ namespace nana
impl->spinbox.value(std::to_string(impl->value));
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized&)
{
impl->label.size({ label_px, 24 });
impl->spinbox.size({ value_px, 24 });
@@ -780,7 +782,7 @@ namespace nana
impl->spinbox.value(std::to_string(impl->value));
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized&)
{
impl->label.size(::nana::size{ label_px, 24 });
impl->spinbox.size(::nana::size{ value_px, 24 });

View File

@@ -314,6 +314,8 @@ namespace nana
::Shell_NotifyIcon(impl_->icon_added ? NIM_MODIFY : NIM_ADD, &icon_data);
impl_->icon_added = true;
#else
static_cast<void>(str); //to eliminate unused parameter compiler warning.
#endif
}
@@ -330,6 +332,8 @@ namespace nana
impl_->set_icon(impl_->icon_handle);
::DestroyIcon(pre_icon);
}
#else
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning
#endif
}
@@ -338,6 +342,8 @@ namespace nana
#if defined(NANA_WINDOWS)
auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
impl_->icons.push_back(icon);
#else
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning.
#endif
}
@@ -352,6 +358,8 @@ namespace nana
}
else
impl_->ani_timer.stop();
#else
static_cast<void>(ms); //to eliminate unused parameter compiler warning.
#endif
}

View File

@@ -15,6 +15,7 @@
#include <cmath>
#include <map>
#include <deque>
#include <nana/push_ignore_diagnostic>
#include <nana/deploy.hpp>
#include <nana/gui/place.hpp>
#include <nana/gui/programming_interface.hpp>
@@ -522,12 +523,18 @@ namespace nana
//It will delete the element and recollocate when the window destroyed.
event_handle _m_make_destroy(window wd)
{
return API::events(wd).destroy.connect([this, wd](const arg_destroy& arg)
return API::events(wd).destroy.connect([this, wd](const arg_destroy&)
{
for (auto i = elements.begin(), end = elements.end(); i != end; ++i)
{
if (!API::is_destroying(API::get_parent_window(wd)))
place_ptr_->collocate();
if (i->handle == wd)
{
elements.erase(i);
if (!API::is_destroying(API::get_parent_window(wd)))
place_ptr_->collocate();
break;
}
}
});
}
@@ -1125,7 +1132,7 @@ namespace nana
}
}
void collocate(window wd) override
void collocate(window) override
{
if (!field || !(visible && display))
return;
@@ -1321,8 +1328,6 @@ namespace nana
public:
div_splitter(place_parts::number_t init_weight)
: division(kind::splitter, std::string()),
splitter_cursor_(cursor::arrow),
pause_move_collocate_(false),
init_weight_(init_weight)
{
this->weight.assign(splitter_px);
@@ -1374,9 +1379,18 @@ namespace nana
left_pixels_ = area_left.*px_ptr;
right_pixels_ = area_right.*px_ptr;
grabbed_ = true;
}
else if(event_code::mouse_up == arg.evt_code)
{
grabbed_ = false;
}
else if (event_code::mouse_move == arg.evt_code)
{
if(!grabbed_)
return;
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w();
int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x);
@@ -1413,8 +1427,10 @@ namespace nana
}
};
splitter_.events().mouse_down.connect_unignorable(grab_fn);
splitter_.events().mouse_move.connect_unignorable(grab_fn);
auto & events = splitter_.events();
events.mouse_down.connect_unignorable(grab_fn);
events.mouse_up.connect_unignorable(grab_fn);
events.mouse_move.connect_unignorable(grab_fn);
}
auto limited_range = _m_update_splitter_range();
@@ -1527,13 +1543,14 @@ namespace nana
return area;
}
private:
nana::cursor splitter_cursor_;
nana::cursor splitter_cursor_{nana::cursor::arrow};
place_parts::splitter<true> splitter_;
nana::point begin_point_;
int left_pos_, right_pos_;
unsigned left_pixels_, right_pixels_;
dragger dragger_;
bool pause_move_collocate_; //A flag represents whether do move when collocating.
bool grabbed_{ false };
bool pause_move_collocate_{ false }; //A flag represents whether do move when collocating.
place_parts::number_t init_weight_;
};
@@ -1558,7 +1575,7 @@ namespace nana
}
}
void collocate(window wd) override
void collocate(window) override
{
if (!dockable_field)
{
@@ -2847,3 +2864,5 @@ namespace nana
}
//end class place
}//end namespace nana
#include <nana/pop_ignore_diagnostic>

View File

@@ -280,64 +280,11 @@ namespace nana
void add_pane(factory & fn)
{
rectangle r{ point(), this->size()};
//get a rectangle excluding caption
r.y = 20;
if (r.height > 20)
r.height -= 20;
else
r.height = 0;
if (!tabbar_)
auto fn_ptr = &fn;
API::dev::affinity_execute(*this, [this, fn_ptr]
{
if (panels_.size() > 0)
{
tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear();
tabbar_->events().selected([this](const event_arg&)
{
auto handle = tabbar_->attach(tabbar_->selected());
//Set caption through a caption of window specified by handle
//Empty if handle is null
caption_.caption(API::window_caption(handle));
});
tabbar_->move({ 0, r.bottom() - 20, r.width, 20 });
r.height -= 20;
std::size_t pos = 0;
for (auto & pn : panels_)
{
tabbar_->push_back(pn.widget_ptr->caption());
tabbar_->attach(pos++, *pn.widget_ptr);
}
}
}
else
r.height -= 20;
auto wdg = fn(*this);
if (tabbar_)
{
tabbar_->push_back(wdg->caption());
tabbar_->attach(panels_.size(), wdg->handle());
}
if (panels_.empty())
caption_.caption(wdg->caption());
panels_.emplace_back();
panels_.back().widget_ptr.swap(wdg);
for (auto & pn : panels_)
{
if (pn.widget_ptr)
pn.widget_ptr->move(r);
}
_m_add_pane(*fn_ptr);
});
}
void float_away(const ::nana::point& move_pos)
@@ -382,6 +329,71 @@ namespace nana
{
return (nullptr != container_);
}
private:
void _m_add_pane(factory & fn)
{
rectangle r{ point(), this->size() };
//get a rectangle excluding caption
r.y = 20;
if (r.height > 20)
r.height -= 20;
else
r.height = 0;
if (!tabbar_)
{
if (panels_.size() > 0)
{
tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear();
tabbar_->events().selected([this]
{
auto handle = tabbar_->attach(tabbar_->selected());
//Set caption through a caption of window specified by handle
//Empty if handle is null
caption_.caption(API::window_caption(handle));
});
r.height -= 20;
tabbar_->move({ 0, r.bottom(), r.width, 20 });
std::size_t pos = 0;
for (auto & pn : panels_)
{
tabbar_->push_back(pn.widget_ptr->caption());
tabbar_->attach(pos++, *pn.widget_ptr);
}
}
}
else
r.height -= 20;
auto wdg = fn(*this);
if (wdg)
{
if (tabbar_)
{
tabbar_->push_back(::nana::charset(wdg->caption()));
tabbar_->attach(panels_.size(), wdg->handle());
}
if (panels_.empty())
{
caption_.caption(wdg->caption());
}
panels_.emplace_back();
panels_.back().widget_ptr.swap(wdg);
for (auto & pn : panels_)
{
if (pn.widget_ptr)
pn.widget_ptr->move(r);
}
}
}
private:
window host_window_{nullptr};
place_parts::dock_notifier_interface* notifier_{ nullptr };

View File

@@ -104,8 +104,7 @@ namespace API
{
if (iwd->effect.edge_nimbus == effects::edge_nimbus::none)
{
basic_window::edge_nimbus_action ena = { iwd };
cont.push_back(ena);
cont.push_back(basic_window::edge_nimbus_action{ iwd, false});
}
iwd->effect.edge_nimbus = static_cast<effects::edge_nimbus>(static_cast<unsigned>(en) | static_cast<unsigned>(iwd->effect.edge_nimbus));
}
@@ -180,6 +179,11 @@ namespace API
namespace dev
{
void affinity_execute(window window_handle, const std::function<void()>& fn)
{
interface_type::affinity_execute(root(window_handle), fn);
}
bool set_events(window wd, const std::shared_ptr<general_events>& gep)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
@@ -330,7 +334,7 @@ namespace API
return nullptr;
}
//exit
//close all windows in current thread
void exit()
{
@@ -367,6 +371,42 @@ namespace API
interface_type::close_window(i);
}
}
//close all windows
void exit_all()
{
std::vector<basic_window*> v;
internal_scope_guard lock;
restrict::wd_manager().all_handles(v);
if (v.size())
{
std::vector<native_window_type> roots;
native_window_type root = nullptr;
//unsigned tid = nana::system::this_thread_id();
for (auto wd : v)
{
if (/*(wd->thread_id == tid) &&*/ (wd->root != root))
{
root = wd->root;
bool exists = false;
for (auto i = roots.cbegin(); i != roots.cend(); ++i)
{
if (*i == root)
{
exists = true;
break;
}
}
if (!exists)
roots.push_back(root);
}
}
for (auto i : roots)
interface_type::close_window(i);
}
}
//transform_shortkey_text
//@brief: This function searchs whether the text contains a '&' and removes the character for transforming.

View File

@@ -167,6 +167,8 @@ namespace nana
}
}
}
#else
static_cast<void>(pos); //to eliminate unused parameter compiler warning.
#endif
return get_primary();
}

View File

@@ -227,7 +227,7 @@ namespace nana
window_->tooltip_move(API::cursor_position(), true);
}
void show_duration(window wd, point pos, const std::string& text, std::size_t duration)
void show_duration(window /*wd*/, point pos, const std::string& text, std::size_t duration)
{
if (nullptr == window_ || window_->tooltip_empty())
{

View File

@@ -163,7 +163,7 @@ namespace nana{ namespace drawerbase
_m_press(graph, false);
}
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
void trigger::key_press(graph_reference, const arg_keyboard& arg)
{
bool ch_tabstop_next;
switch(arg.key)

View File

@@ -216,7 +216,7 @@ namespace nana{ namespace drawerbase
uiobj.check(false);
uiobj.react(false);
element_tag el = {};
element_tag el;
el.uiobj = &uiobj;

View File

@@ -611,7 +611,7 @@ namespace nana
}
}
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg)
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
{
//drawer_->set_mouse_press(true);
drawer_->set_button_state(element_state::pressed, false);
@@ -629,7 +629,7 @@ namespace nana
}
}
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg)
void trigger::mouse_up(graph_reference, const arg_mouse& arg)
{
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
{
@@ -656,7 +656,7 @@ namespace nana
}
}
void trigger::mouse_wheel(graph_reference graph, const arg_wheel& arg)
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
{
if(drawer_->widget_ptr()->enabled())
{
@@ -714,7 +714,7 @@ namespace nana
API::dev::lazy_refresh();
}
void trigger::key_char(graph_reference graph, const arg_keyboard& arg)
void trigger::key_char(graph_reference, const arg_keyboard& arg)
{
if (drawer_->editor()->respond_char(arg))
API::dev::lazy_refresh();

View File

@@ -18,7 +18,7 @@ namespace nana
namespace form
{
//class trigger
void trigger::attached(widget_reference wdg, graph_reference graph)
void trigger::attached(widget_reference wdg, graph_reference)
{
wd_ = &wdg;
API::ignore_mouse_focus(wdg, true);

View File

@@ -437,7 +437,7 @@ namespace nana
return total_w;
}
bool _m_each_line(graph_reference graph, dstream::linecontainer& line, render_status& rs)
bool _m_each_line(graph_reference graph, dstream::linecontainer&, render_status& rs)
{
std::wstring text;
iterator block_start;

View File

@@ -329,7 +329,7 @@ namespace nana
struct column_t
{
native_string_type text; ///< "text" header of the column number "index" with weigth "pixels"
unsigned pixels;
unsigned pixels; ///< width
bool visible{true};
size_type index;
std::function<bool(const std::string&, nana::any*, const std::string&, nana::any*, bool reverse)> weak_ordering;
@@ -338,6 +338,7 @@ namespace nana
column_t(native_string_type&& txt, unsigned px, size_type pos)
: text(std::move(txt)), pixels(px), index(pos)
{}
/// \todo introduce default cell format
};
using container = std::vector<column_t> ;
@@ -410,7 +411,7 @@ namespace nana
return cont_.back().index;
}
void item_width(size_type pos, unsigned width)
void item_width(size_type pos, unsigned width) ///< set the column width
{
column(pos).pixels = width;
}
@@ -427,7 +428,7 @@ namespace nana
return 0;
}
unsigned pixels() const
unsigned pixels() const ///< the visible width of the whole header
{
unsigned pixels = 0;
for(auto & m : cont_)
@@ -470,12 +471,13 @@ namespace nana
{
if(x < static_cast<int>(col.pixels))
return col.index;
x -= col.pixels;
if (col.visible)
x -= col.pixels;
}
return npos;
}
/// return the left position of the column originaly at index "pos" .
/// return the left position and width (in variable *pixels) of the column originaly at index "pos" .
int item_pos(size_type pos, unsigned * pixels) const
{
int left = 0;
@@ -493,7 +495,8 @@ namespace nana
}
return left;
}
/// return the original index of the visible col currently before(in front of) or after the col originaly at index "index"
/// return the original index of the visible col currently before(in front of) or after the col originaly at index "index"
size_type neighbor(size_type index, bool front) const
{
size_type n = npos;
@@ -509,11 +512,12 @@ namespace nana
break;
}
else if(i->visible)
n = i->index;
n = i->index;
}
return npos;
}
/// return the original index of the currently first visible col
/// return the original index of the currently first visible col
size_type begin() const
{
for(const auto & m : cont_)
@@ -532,7 +536,8 @@ namespace nana
}
return npos;
}
/// move the col originaly at index to the position currently in front (or after) the col originaly at index "to" invalidating some current index
/// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index
void move(size_type index, size_type to, bool front) throw()
{
if ((index == to) || (index >= cont_.size()) || (to >= cont_.size()))
@@ -879,7 +884,8 @@ namespace nana
list_.back().key_ptr = ptr;
return &list_.back();
}
/// add a new cat created at "pos" and return a ref to it
/// add a new cat created at "pos" and return a ref to it
category_t* create_cat(std::size_t pos, native_string_type&& text)
{
return &(*list_.emplace(this->get(pos), std::move(text)));
@@ -1828,9 +1834,7 @@ namespace nana
};//end class es_lister
//struct essence_t
//@brief: this struct gives many data for listbox,
// the state of the struct does not effect on member funcions, therefore all data members are public.
/// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public.
struct essence_t
{
enum class item_state{normal, highlighted, pressed, grabbed, floated};
@@ -1859,7 +1863,7 @@ namespace nana
struct scroll_part
{
static const unsigned scale = 16;
static const unsigned scale = 16; // ?
int offset_x;
index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category.
// need to be abs??? to see the same item after sort() ??
@@ -1942,8 +1946,8 @@ namespace nana
//number_of_lister_item
//@brief: Returns the number of items that are contained in pixels
//@param,with_rest: Means whether including extra one item that is not completely contained in reset pixels.
/// @brief Returns the number of items that are contained in pixels
/// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels.
size_type number_of_lister_items(bool with_rest) const
{
unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale);
@@ -1983,8 +1987,9 @@ namespace nana
void trace_item_abs( index_pair abs_pos )
{
if(abs_pos.item == npos && abs_pos.cat == scroll.offset_y_abs.cat
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat
if( abs_pos.item == npos
&& abs_pos.cat == scroll.offset_y_abs.cat
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat
return;
trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ;
@@ -2072,10 +2077,10 @@ namespace nana
bool v = (lister.the_number_of_expanded() > screen_number);
if(v == true && h == false)
h = (header_s > (sz.width - 2 - scroll.scale));
h = ( (header_s + 2 + scroll.scale ) > sz.width); // 2?
unsigned width = sz.width - 2 - (v ? scroll.scale : 0);
unsigned height = sz.height - 2 - (h ? scroll.scale : 0);
unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2?
unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2?
//event hander for scrollbars
auto evt_fn = [this](const arg_scroll& arg)
@@ -2168,7 +2173,8 @@ namespace nana
return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0);
}
std::pair<parts, size_t> where(int x, int y){
std::pair<parts, size_t> where(int x, int y)
{
std::pair<parts, size_t> new_where;
if(2 < x && x < static_cast<int>(graph->width()) - 2 && 1 < y && y < static_cast<int>(graph->height()) - 1)
@@ -2614,15 +2620,15 @@ namespace nana
return list_str ;
}
void es_lister::categ_selected(size_type cat, bool sel)
void es_lister::categ_selected(size_type cat, bool sel)
{
cat_proxy cpx{ess_,cat};
for (item_proxy &it : cpx )
{
if (it.selected() != sel)
cat_proxy cpx{ess_,cat};
for (item_proxy &it : cpx )
{
if (it.selected() != sel)
it.select(sel);
}
last_selected_abs = last_selected_dpl = index_pair{cat, npos};
}
last_selected_abs = last_selected_dpl = index_pair{cat, npos};
}
class drawer_header_impl
@@ -2644,6 +2650,7 @@ namespace nana
item_spliter_ = npos;
}
/// return true an set member item_spliter_ if x is in the spliter area after that header item (column)
bool mouse_spliter(const nana::rectangle& r, int x)
{
if(essence_->ptr_state == item_state::highlighted)
@@ -2658,7 +2665,7 @@ namespace nana
item_spliter_ = hd.index; // original index
return true;
}
x -= hd.pixels;
x -= hd.pixels;
}
}
}
@@ -2672,7 +2679,7 @@ namespace nana
if(is_grab)
{
ref_xpos_ = pos.x;
if(item_spliter_ != npos)
if(item_spliter_ != npos) // resize header item, not move it
orig_item_width_ = essence_->header.column(item_spliter_).pixels;
}
else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second)
@@ -2680,21 +2687,21 @@ namespace nana
}
//grab_move
//@brief: draw when an item is grabbing.
//@return: 0 = no graphics changed, 1 = just update, 2 = refresh
/// @brief draw when an item is grabbing.
/// @return 0 = no graphics changed, 1 = just update, 2 = refresh
int grab_move(const nana::rectangle& rect, const nana::point& pos)
{
if(item_spliter_ == npos)
{
draw(rect);
_m_make_float(rect, pos);
{ // move header item, not resize it
draw(rect); // first draw the entery header as it was
_m_make_float(rect, pos); // now draw one floating header item
//Draw the target strip
grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front);
return 1;
}
else
{
{ // resize header item, not move it
const auto& item = essence_->header.column(item_spliter_);
//Resize the item specified by item_spliter_.
auto new_w = orig_item_width_ - (ref_xpos_ - pos.x);
@@ -3003,9 +3010,19 @@ namespace nana
}
}
//Draws an item
//@param content_r the rectangle of list content
void _m_draw_item(const category_t& cat, const index_pair& item_pos, const int x, const int y, const int txtoff, unsigned width, const nana::rectangle& content_r, const std::vector<size_type>& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const
/// Draws an item
void _m_draw_item(const category_t& cat,
const index_pair& item_pos,
const int x,
const int y,
const int txtoff,
unsigned width,
const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn
const std::vector<size_type>& seqs,
nana::color bgcolor,
nana::color fgcolor,
item_state state
) const
{
auto & item = cat.items[item_pos.item];
@@ -3022,7 +3039,7 @@ namespace nana
if (item.flags.selected)
bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected"
else
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7);
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend
}
unsigned show_w = width - essence_->scroll.offset_x;
@@ -3148,6 +3165,7 @@ namespace nana
{
auto cell_txtcolor = fgcolor;
auto & m_cell = item.cells[column_pos];
review_utf8(m_cell.text);
nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry
if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need
@@ -3338,19 +3356,19 @@ namespace nana
if(essence_->ptr_state == item_state::pressed)
{
if(essence_->pointer_where.first == parts::header)
{
{ // moving a pressed header : grab it (or split-resize?)
essence_->ptr_state = item_state::grabbed;
nana::point pos = arg.pos;
essence_->widget_to_header(pos);
drawer_header_->grab(pos, true);
essence_->lister.wd_ptr()->set_capture(true);
update = 2;
update = 2; //0 = nothing, 1 = update, 2 = refresh
}
}
if(essence_->ptr_state == item_state::grabbed)
{
{ // moving a grabbed header
nana::point pos = arg.pos;
essence_->widget_to_header(pos);
@@ -3436,6 +3454,9 @@ namespace nana
if (lister.forward(essence_->scroll.offset_y_dpl, ptr_where.second, item_pos))
{
auto * item_ptr = (item_pos.is_item() ? &lister.at(item_pos) : nullptr);
const index_pair abs_item_pos{ item_pos.cat, lister.absolute(item_pos) };
if(ptr_where.first == parts::lister)
{
bool sel = true;
@@ -3444,28 +3465,32 @@ namespace nana
if (arg.shift)
lister.select_display_range(lister.last_selected_abs , item_pos, sel);
else if (arg.ctrl)
sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected();
sel = !item_proxy(essence_, abs_item_pos).selected();
else
lister.select_for_all(false); //cancel all selections
}
else
sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected();
{
//Clicking on a category is ignored when single selection is enabled.
//Fixed by Greentwip(issue #121)
if (item_ptr)
sel = !item_proxy(essence_, abs_item_pos).selected();
}
if(item_ptr)
{
item_ptr->flags.selected = sel;
index_pair last_selected(item_pos.cat, lister.absolute(item_pos));
arg_listbox arg{item_proxy{essence_, last_selected}, sel};
arg_listbox arg{ item_proxy{ essence_, abs_item_pos }, sel };
lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle());
if (item_ptr->flags.selected)
{
lister.cancel_others_if_single_enabled(true, last_selected);
essence_->lister.last_selected_abs = last_selected;
lister.cancel_others_if_single_enabled(true, abs_item_pos);
essence_->lister.last_selected_abs = abs_item_pos;
}
else if (essence_->lister.last_selected_abs == last_selected)
else if (essence_->lister.last_selected_abs == abs_item_pos)
essence_->lister.last_selected_abs.set_both(npos);
}
else if(!lister.single_selection())
@@ -3482,7 +3507,7 @@ namespace nana
lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle());
if (item_ptr->flags.checked)
lister.cancel_others_if_single_enabled(false, abs_pos);
lister.cancel_others_if_single_enabled(false, abs_item_pos);
}
else if (! lister.single_check())
lister.categ_checked_reverse(item_pos.cat);
@@ -3550,15 +3575,16 @@ namespace nana
}
}
void trigger::dbl_click(graph_reference graph, const arg_mouse& arg)
void trigger::dbl_click(graph_reference graph, const arg_mouse&)
{
if (essence_->pointer_where.first == essence_t::parts::header)
if (cursor::size_we == essence_->lister.wd_ptr()->cursor())
{
if (essence(). auto_width(drawer_header_->item_spliter() )) // ? in order
essence().update();
return;
}
{
//adjust the width of column to its content.
if (essence_->auto_width(drawer_header_->item_spliter() ))
essence_->update();
return;
}
if (essence_->pointer_where.first != essence_t::parts::lister)
return;
@@ -3575,7 +3601,8 @@ namespace nana
arg_listbox_category arg_cat(cat_proxy(essence_, item_pos.cat));
lister.wd_ptr()->events().category_dbl_click.emit(arg_cat, lister.wd_ptr()->handle());
if (!arg_cat.category_change_blocked()){
if (!arg_cat.category_change_blocked())
{
bool do_expand = (lister.expand(item_pos.cat) == false);
lister.expand(item_pos.cat, do_expand);
@@ -3604,8 +3631,8 @@ namespace nana
{
bool up = false;
if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0)
return ;
if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0)
return ;
switch(arg.key)
{
@@ -3623,49 +3650,46 @@ namespace nana
}
break;
case keyboard::os_pageup :
case keyboard::os_pageup :
up = true;
case keyboard::os_pagedown:
{
auto& scrl = essence_->scroll.v;
if (! scrl.make_page_scroll(!up))
return;
essence_->lister.select_for_all(false);
case keyboard::os_pagedown:
{
auto& scrl = essence_->scroll.v;
if (! scrl.make_page_scroll(!up))
return;
essence_->lister.select_for_all(false);
index_pair idx{essence_->scroll_y_dpl()};
if (!up)
essence_->lister.forward(idx, scrl.range()-1, idx);
index_pair idx{essence_->scroll_y_dpl()};
if (!up)
essence_->lister.forward(idx, scrl.range()-1, idx);
if (idx.is_item())
item_proxy::from_display(essence_, idx).select(true);
else
if(!essence_->lister.single_selection())
if (idx.is_item())
item_proxy::from_display(essence_, idx).select(true);
else if(!essence_->lister.single_selection())
essence_->lister.categ_selected(idx.cat, true);
essence_->trace_last_selected_item ();
essence_->trace_last_selected_item ();
break;
}
case keyboard::os_home:
{
essence_->lister.select_for_all(false);
break;
}
case keyboard::os_home:
{
essence_->lister.select_for_all(false);
index_pair frst{essence_->lister.first()};
if (frst.is_item())
item_proxy::from_display(essence_, frst).select(true);
else
if(!essence_->lister.single_selection())
index_pair frst{essence_->lister.first()};
if (frst.is_item())
item_proxy::from_display(essence_, frst).select(true);
else if(!essence_->lister.single_selection())
essence_->lister.categ_selected(frst.cat, true);
essence_->trace_last_selected_item ();
break;
}
case keyboard::os_end:
essence_->lister.select_for_all(false);
item_proxy::from_display(essence_, essence_->lister.last()).select(true);
essence_->trace_last_selected_item ();
break;
essence_->trace_last_selected_item ();
break;
}
case keyboard::os_end:
essence_->lister.select_for_all(false);
item_proxy::from_display(essence_, essence_->lister.last()).select(true);
essence_->trace_last_selected_item ();
break;
default:
return;
}
@@ -3677,20 +3701,19 @@ namespace nana
{
switch(arg.key)
{
case keyboard::copy:
{
export_options exp_opt {essence_->def_exp_options};
exp_opt.columns_order = essence_->header.all_headers(true);
exp_opt.only_selected_items = true;
::nana::system::dataexch().set(essence_->to_string(exp_opt));
return;
}
case keyboard::select_all :
essence_->lister.select_for_all(true);
case keyboard::copy:
{
export_options exp_opt {essence_->def_exp_options};
exp_opt.columns_order = essence_->header.all_headers(true);
exp_opt.only_selected_items = true;
::nana::system::dataexch().set(essence_->to_string(exp_opt));
return;
}
case keyboard::select_all :
essence_->lister.select_for_all(true);
refresh(graph);
API::dev::lazy_refresh();
break;
default:
return;
}
@@ -3699,6 +3722,7 @@ namespace nana
//end class trigger
//class item_proxy
item_proxy::item_proxy(essence_t * ess)
: ess_(ess)
{}
@@ -3714,23 +3738,24 @@ namespace nana
}
}
/// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort()
item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative)
{
return item_proxy{ess, ess->lister.absolute_pair(relative)};
}
item_proxy item_proxy::from_display(const index_pair &relative) const
{
return item_proxy{ess_, ess_->lister.absolute_pair(relative)};
}
/// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort()
item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative)
{
return item_proxy{ess, ess->lister.absolute_pair(relative)};
}
/// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort()
index_pair item_proxy::to_display() const
{
return ess_->lister.relative_pair(pos_);
}
item_proxy item_proxy::from_display(const index_pair &relative) const
{
return item_proxy{ess_, ess_->lister.absolute_pair(relative)};
}
bool item_proxy::empty() const
/// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort()
index_pair item_proxy::to_display() const
{
return ess_->lister.relative_pair(pos_);
}
bool item_proxy::empty() const
{
return !ess_;
}
@@ -3753,8 +3778,8 @@ namespace nana
return cat_->items.at(pos_.item).flags.checked;
}
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
item_proxy & item_proxy::select(bool s)
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
item_proxy & item_proxy::select(bool s)
{
auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat?
if(m.flags.selected == s) return *this; // ignore if no change
@@ -3968,6 +3993,7 @@ namespace nana
//end class item_proxy
//class cat_proxy
//the member cat_ is used for fast accessing to the category
cat_proxy::cat_proxy(essence_t * ess, size_type pos)
: ess_(ess),
@@ -4296,7 +4322,7 @@ namespace nana
}
//Implementation of arg_category
//Implementation of arg_listbox_category
//Contributed by leobackes(pr#97)
arg_listbox_category::arg_listbox_category(const nana::drawerbase::listbox::cat_proxy& cat) noexcept
: category(cat), block_change_(false)
@@ -4315,6 +4341,7 @@ namespace nana
//class listbox
listbox::listbox(window wd, bool visible)
{
create(wd, rectangle(), visible);
@@ -4393,7 +4420,7 @@ namespace nana
}
unsigned listbox::auto_width(size_type pos, unsigned max)
{
auto & ess = _m_ess();
auto & ess = _m_ess();
unsigned max_w = ess.auto_width(pos, max);
ess.update();
return max_w;
@@ -4479,34 +4506,33 @@ namespace nana
return *this;
}
listbox::item_proxy listbox::at(const index_pair& pos_abs) const
listbox::item_proxy listbox::at(const index_pair& pos_abs) const
{
return at(pos_abs.cat).at(pos_abs.item);
}
// Contributed by leobackes(pr#97)
listbox::index_pair listbox::at ( const point& pos ) const
{
auto & ess=_m_ess();
auto _where=ess.where(pos.x, pos.y);
index_pair item_pos{npos,npos};
if(_where.first==drawerbase::listbox::essence_t::parts::lister){
auto & offset_y = ess.scroll.offset_y_dpl;
ess.lister.forward(offset_y, _where.second, item_pos);
}
return item_pos;
}
listbox::index_pair listbox::at ( const point& pos ) const
{
auto & ess=_m_ess();
auto _where=ess.where(pos.x, pos.y);
index_pair item_pos{npos,npos};
if(_where.first==drawerbase::listbox::essence_t::parts::lister)
{
auto & offset_y = ess.scroll.offset_y_dpl;
ess.lister.forward(offset_y, _where.second, item_pos);
}
return item_pos;
}
//Contributed by leobackes(pr#97)
listbox::columns_indexs listbox::column_from_pos ( const point& pos )
{
auto & ess=_m_ess();
columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x);
return col;
}
listbox::columns_indexs listbox::column_from_pos ( const point& pos )
{
auto & ess=_m_ess();
columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x);
return col;
}
void listbox::insert(const index_pair& pos, std::string text)
{

View File

@@ -398,24 +398,28 @@ namespace nana
//Draw text, the text is transformed from orignal for hotkey character
wchar_t hotkey;
std::string::size_type hotkey_pos;
auto text = to_wstring(API::transform_shortkey_text(m.text, hotkey, &hotkey_pos));
auto text = API::transform_shortkey_text(m.text, hotkey, &hotkey_pos);
if (m.image.empty() == false)
renderer->item_image(graph, nana::point(item_r.x + 5, item_r.y + static_cast<int>(item_h_px - image_px) / 2 - 1), image_px, m.image);
renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), to_utf8(text), strpixels, attr);
renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr);
if (hotkey)
{
m.hotkey = hotkey;
if (m.flags.enabled)
{
unsigned off_w = (hotkey_pos ? graph.text_extent_size(text, static_cast<unsigned>(hotkey_pos)).width : 0);
nana::size hotkey_size = graph.text_extent_size(text.c_str() + hotkey_pos, 1);
int x = item_r.x + 40 + off_w;
int y = item_r.y + text_top_off + hotkey_size.height;
auto off_px = (hotkey_pos ? graph.text_extent_size(text.c_str(), hotkey_pos).width : 0);
auto hotkey_px = graph.text_extent_size(text.c_str() + hotkey_pos, 1).width;
graph_->line({ x, y }, { x + static_cast<int>(hotkey_size.width) - 1, y }, colors::black);
unsigned ascent, descent, inleading;
graph.text_metrics(ascent, descent, inleading);
int x = item_r.x + 40 + off_px;
int y = item_r.y + text_top_off + ascent + 1;
graph_->line({ x, y }, { x + static_cast<int>(hotkey_px)-1, y }, colors::black);
}
}
@@ -582,9 +586,12 @@ namespace nana
}
else if(m.flags.enabled)
{
std::move(fn_close_tree_)();
item_proxy ip(index, m);
m.functor.operator()(ip);
fn_close_tree_();
if (m.functor)
{
item_proxy ip(index, m);
m.functor.operator()(ip);
}
return 1;
}
}

View File

@@ -53,7 +53,7 @@ namespace nana{ namespace widgets
return cmd_;
}
virtual bool merge(const undoable_command_interface<EnumCommand>& rhs) override
virtual bool merge(const undoable_command_interface<EnumCommand>&) override
{
return false;
}
@@ -273,8 +273,8 @@ namespace nana{ namespace widgets
: editor_(editor)
{}
void merge_lines(std::size_t first, std::size_t second) override{}
void add_lines(std::size_t pos, std::size_t lines) override{}
void merge_lines(std::size_t, std::size_t) override{}
void add_lines(std::size_t, std::size_t) override{}
void pre_calc_line(std::size_t, unsigned) override{}
void pre_calc_lines(unsigned) override{}
@@ -283,12 +283,12 @@ namespace nana{ namespace widgets
return editor_.textbase_.lines();
}
std::size_t take_lines(std::size_t pos) const override
std::size_t take_lines(std::size_t) const override
{
return 1;
}
void update_line(std::size_t textline, std::size_t secondary_before) override
void update_line(std::size_t textline, std::size_t) override
{
int top = editor_._m_text_top_base() + static_cast<int>(editor_.line_height() * (textline - editor_.points_.offset.y));
editor_.graph_.rectangle({ editor_.text_area_.area.x, top, editor_.text_area_.area.width, editor_.line_height() }, true, API::bgcolor(editor_.window_));
@@ -1294,7 +1294,6 @@ namespace nana{ namespace widgets
select_.move_to_end = false;
select_.mode_selection = selection::mode::no_selected;
select_.ignore_press = false;
select_.dragged = false;
API::create_caret(wd, 1, line_height());
API::bgcolor(wd, colors::white);
@@ -1693,13 +1692,10 @@ namespace nana{ namespace widgets
if(left_button)
{
auto caret_pos_before = caret();
mouse_caret(scrpos);
if(select_.mode_selection != selection::mode::no_selected)
if (selection::mode::mouse_selected == select_.mode_selection || selection::mode::method_selected == select_.mode_selection)
set_end_caret();
else if ((!select_.dragged) && (caret_pos_before != caret()))
select_.dragged = true;
text_area_.border_renderer(graph_, _m_bgcolor());
return true;
@@ -1722,26 +1718,34 @@ namespace nana{ namespace widgets
API::set_capture(window_, true);
text_area_.captured = true;
//Set caret pos by screen point and get the caret pos.
mouse_caret(arg.pos);
if (arg.shift)
if (this->hit_select_area(behavior_->screen_to_caret(arg.pos), true))
{
if (points_.shift_begin_caret != points_.caret)
{
select_.a = points_.shift_begin_caret;
select_.b = points_.caret;
}
select_.mode_selection = selection::mode::move_selected;
}
else
{
if (!select(false))
//Set caret pos by screen point and get the caret pos.
mouse_caret(arg.pos);
if (arg.shift)
{
select_.a = points_.caret; //Set begin caret
set_end_caret();
if (points_.shift_begin_caret != points_.caret)
{
select_.a = points_.shift_begin_caret;
select_.b = points_.caret;
}
}
points_.shift_begin_caret = points_.caret;
else
{
if (!select(false))
{
select_.a = points_.caret; //Set begin caret
set_end_caret();
}
points_.shift_begin_caret = points_.caret;
}
select_.mode_selection = selection::mode::mouse_selected;
}
select_.mode_selection = selection::mode::mouse_selected;
}
text_area_.border_renderer(graph_, _m_bgcolor());
@@ -1750,19 +1754,19 @@ namespace nana{ namespace widgets
else if (event_code::mouse_up == arg.evt_code)
{
select_.ignore_press = false;
auto is_prev_no_selected = (select_.mode_selection == selection::mode::no_selected);
bool updated = false;
if (select_.mode_selection == selection::mode::mouse_selected)
{
select_.mode_selection = selection::mode::no_selected;
set_end_caret();
}
else if (is_prev_no_selected)
else if (selection::mode::move_selected == select_.mode_selection)
{
if ((!select_.dragged) || (!move_select()))
if (!move_select())
select(false);
updated = true;
}
select_.dragged = false;
API::release_capture(window_);
@@ -1772,8 +1776,7 @@ namespace nana{ namespace widgets
text_area_.border_renderer(graph_, _m_bgcolor());
//Redraw if is_prev_no_selected is true
return is_prev_no_selected;
return updated;
}
return false;
}
@@ -1913,11 +1916,21 @@ namespace nana{ namespace widgets
return ((text_area_.area.x <= pos.x && pos.x < _m_end_pos(true)) && (text_area_.area.y <= pos.y && pos.y < _m_end_pos(false)));
}
bool text_editor::hit_select_area(nana::upoint pos) const
bool text_editor::hit_select_area(nana::upoint pos, bool ignore_when_select_all) const
{
nana::upoint a, b;
if(_m_get_sort_select_points(a, b))
{
if (ignore_when_select_all)
{
if (a.x == 0 && a.y == 0 && (b.y + 1) == static_cast<unsigned>(textbase_.lines()))
{
//is select all
if (b.x == static_cast<unsigned>(textbase_.getline(b.y).size()))
return false;
}
}
if((pos.y > a.y || (pos.y == a.y && pos.x >= a.x)) && ((pos.y < b.y) || (pos.y == b.y && pos.x < b.x)))
return true;
}
@@ -1926,7 +1939,10 @@ namespace nana{ namespace widgets
bool text_editor::move_select()
{
if(hit_select_area(points_.caret) || (select_.b == points_.caret))
if (! attributes_.editable)
return false;
if(hit_select_area(points_.caret, true) || (select_.b == points_.caret))
{
points_.caret = select_.b;

View File

@@ -519,7 +519,7 @@ namespace nana
impl_->render();
}
void drawer::focus(graph_reference, const arg_focus& arg)
void drawer::focus(graph_reference, const arg_focus&)
{
impl_->reset_text();
impl_->render();
@@ -579,7 +579,7 @@ namespace nana
}
}
void drawer::resized(graph_reference graph, const arg_resized& arg)
void drawer::resized(graph_reference, const arg_resized&)
{
impl_->reset_text_area();
impl_->render();

View File

@@ -43,7 +43,7 @@ namespace nana
: public item_renderer
{
private:
virtual void background(graph_reference graph, const nana::rectangle& r, const ::nana::color& bgcolor)
virtual void background(graph_reference graph, const nana::rectangle&, const ::nana::color& bgcolor)
{
if(bgcolor_ != bgcolor)
{
@@ -59,7 +59,6 @@ namespace nana
virtual void item(graph_reference graph, const item_t& m, bool active, state_t sta)
{
//*
const nana::rectangle & r = m.r;
color bgcolor;
color blcolor;
@@ -961,7 +960,8 @@ namespace nana
auto bgcolor = API::bgcolor(basis_.wd);
auto fgcolor = API::fgcolor(basis_.wd);
item_renderer::item_t m{ ::nana::rectangle{ basis_.graph->size() } };
item_renderer::item_t m;
m.r = ::nana::rectangle{ basis_.graph->size() };
basis_.renderer->background(*basis_.graph, m.r, bgcolor);

View File

@@ -87,7 +87,7 @@ namespace drawerbase {
editor_ = nullptr;
}
void drawer::refresh(graph_reference graph)
void drawer::refresh(graph_reference)
{
editor_->render(API::is_focus_ready(*widget_));
}
@@ -115,7 +115,7 @@ namespace drawerbase {
API::dev::lazy_refresh();
}
void drawer::mouse_up(graph_reference graph, const arg_mouse& arg)
void drawer::mouse_up(graph_reference, const arg_mouse& arg)
{
if(editor_->mouse_pressed(arg))
API::dev::lazy_refresh();

View File

@@ -13,6 +13,11 @@
#include <nana/gui/wvl.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/std_thread.hpp>
#include <iostream>
#include <chrono>
//#define NANA_AUTOMATIC_GUI_TESTING
namespace nana
{
namespace detail
@@ -23,8 +28,67 @@ namespace nana
}
}
void exec()
void click(widget& w)
{
std::cout << "Automatically clicking widget "<<w.caption()<<":\n";
arg_click arg;
arg.window_handle = w.handle();
w.events().click.emit(arg, w.handle());
}
/// in seconds
void Wait(unsigned wait)
{
if (!wait) return;
std::cout << "waiting " << wait << " sec...\n";
std::this_thread::sleep_for(std::chrono::seconds{ wait });
}
void pump()
{
detail::bedrock::instance().pump_event(nullptr, false);
}
void exec(
unsigned wait, // = 1, ///< for the GUI to be constructed, in seconds
unsigned wait_end, // = 1, ///< for the GUI to be destructed, in seconds
std::function<void()>f // = {} ///< emit events to mimics user actions and may asert results
)
{
#ifdef NANA_AUTOMATIC_GUI_TESTING
std::cout << "Will wait " << wait << " sec...\n";
std::thread t([wait, &f, wait_end]()
{
Wait( wait );
std::cout << "running... \n" ;
if (f)
{
f();
std::cout << "\nCongratulations, this was not trivial !" << std::endl;
}else
{
std::cout << "\nJust a trivial test." << std::endl;
}
std::cout << "Done... \n";
std::cout << "Now again ";
Wait(wait_end);
std::cout << "Done... Now API::exit all ...\n";
API::exit_all();
});
pump();
if (t.joinable())
t.join();
#else
static_cast<void>(wait);
static_cast<void>(wait_end);
static_cast<void>(f); //to eliminte unused parameter compiler warning.
pump();
#endif
}
}//end namespace nana