Merge remote-tracking branch 'cnjinhao/hotfix-1.5.5' into hotfix-1.5.5
This commit is contained in:
commit
2ccfda24d0
@ -91,6 +91,8 @@ namespace nana
|
|||||||
substitute = 0x1A, //Ctrl+Z
|
substitute = 0x1A, //Ctrl+Z
|
||||||
escape = 0x1B,
|
escape = 0x1B,
|
||||||
space = 0x20, //Space
|
space = 0x20, //Space
|
||||||
|
del = 0x7F, //Delete
|
||||||
|
os_del = del, //Deprecated
|
||||||
|
|
||||||
//The following names are intuitive name of ASCII control codes
|
//The following names are intuitive name of ASCII control codes
|
||||||
select_all = start_of_headline,
|
select_all = start_of_headline,
|
||||||
@ -106,8 +108,8 @@ namespace nana
|
|||||||
os_ctrl = 0x11,
|
os_ctrl = 0x11,
|
||||||
os_pageup = 0x21, os_pagedown,
|
os_pageup = 0x21, os_pagedown,
|
||||||
os_arrow_left = 0x25, os_arrow_up, os_arrow_right, os_arrow_down,
|
os_arrow_left = 0x25, os_arrow_up, os_arrow_right, os_arrow_down,
|
||||||
os_insert = 0x2D, os_del ,
|
os_insert = 0x2D,
|
||||||
os_end = 0x23 , os_home //Pos 1
|
os_end = 0x23, os_home //Pos 1
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Platform Implementation
|
* Platform Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -66,11 +66,11 @@ namespace detail
|
|||||||
|
|
||||||
static nana::point window_position(native_window_type);
|
static nana::point window_position(native_window_type);
|
||||||
static void move_window(native_window_type, int x, int y);
|
static void move_window(native_window_type, int x, int y);
|
||||||
static void move_window(native_window_type, const rectangle&);
|
static bool move_window(native_window_type, const rectangle&);
|
||||||
static void bring_top(native_window_type, bool activated);
|
static void bring_top(native_window_type, bool activated);
|
||||||
static void set_window_z_order(native_window_type, native_window_type wd_after, z_order_action action_if_no_wd_after);
|
static void set_window_z_order(native_window_type, native_window_type wd_after, z_order_action action_if_no_wd_after);
|
||||||
|
|
||||||
static void window_size(native_window_type, const size&);
|
static bool window_size(native_window_type, const size&);
|
||||||
static void get_window_rect(native_window_type, rectangle&);
|
static void get_window_rect(native_window_type, rectangle&);
|
||||||
static void window_caption(native_window_type, const native_string_type&);
|
static void window_caption(native_window_type, const native_string_type&);
|
||||||
static native_string_type window_caption(native_window_type);
|
static native_string_type window_caption(native_window_type);
|
||||||
|
|||||||
@ -85,12 +85,14 @@ namespace nana
|
|||||||
|
|
||||||
bool changed() const; ///< Returns true if the graphics object is operated
|
bool changed() const; ///< Returns true if the graphics object is operated
|
||||||
bool empty() const; ///< Returns true if the graphics object does not refer to any resource.
|
bool empty() const; ///< Returns true if the graphics object does not refer to any resource.
|
||||||
operator const void*() const;
|
explicit operator bool() const noexcept;
|
||||||
|
|
||||||
drawable_type handle() const;
|
drawable_type handle() const;
|
||||||
const void* pixmap() const;
|
const void* pixmap() const;
|
||||||
const void* context() const;
|
const void* context() const;
|
||||||
|
|
||||||
|
void swap(graphics& other) noexcept;
|
||||||
|
|
||||||
/// Creates a graphics/drawable resource
|
/// Creates a graphics/drawable resource
|
||||||
/**
|
/**
|
||||||
* @param sz The dimension of the graphics to be requested. If sz is empty, it performs as release().
|
* @param sz The dimension of the graphics to be requested. If sz is empty, it performs as release().
|
||||||
|
|||||||
@ -47,16 +47,6 @@ namespace detail
|
|||||||
bool visible;
|
bool visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct move_window
|
|
||||||
{
|
|
||||||
enum { Pos = 1, Size = 2};
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
unsigned width;
|
|
||||||
unsigned height;
|
|
||||||
unsigned ignore; //determinate that pos or size would be ignored.
|
|
||||||
};
|
|
||||||
|
|
||||||
struct map_thread
|
struct map_thread
|
||||||
{
|
{
|
||||||
rectangle update_area;
|
rectangle update_area;
|
||||||
@ -77,7 +67,6 @@ namespace detail
|
|||||||
async_set_focus,
|
async_set_focus,
|
||||||
remote_flush_surface,
|
remote_flush_surface,
|
||||||
remote_thread_destroy_window,
|
remote_thread_destroy_window,
|
||||||
remote_thread_move_window,
|
|
||||||
operate_caret, //wParam: 1=Destroy, 2=SetPos
|
operate_caret, //wParam: 1=Destroy, 2=SetPos
|
||||||
remote_thread_set_window_pos,
|
remote_thread_set_window_pos,
|
||||||
remote_thread_set_window_text,
|
remote_thread_set_window_text,
|
||||||
|
|||||||
@ -245,22 +245,31 @@ namespace detail
|
|||||||
_m_event_filter(evt_code, wd, thrd);
|
_m_event_filter(evt_code, wd, thrd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wd->other.upd_state == core_window_t::update_state::none)
|
using update_state = basic_window::update_state;
|
||||||
wd->other.upd_state = core_window_t::update_state::lazy;
|
|
||||||
|
if(wd->other.upd_state == update_state::none)
|
||||||
|
wd->other.upd_state = update_state::lazy;
|
||||||
|
|
||||||
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
||||||
|
|
||||||
//A child of wd may not be drawn if it was out of wd's range before wd resized,
|
bool good_wd = false;
|
||||||
//so refresh all children of wd when a resized occurs.
|
if(wd_manager().available(wd))
|
||||||
if(ask_update || (event_code::resized == evt_code))
|
|
||||||
{
|
{
|
||||||
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code));
|
//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) || (update_state::refreshed == wd->other.upd_state))
|
||||||
|
{
|
||||||
|
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wd->other.upd_state = update_state::none;
|
||||||
|
|
||||||
|
good_wd = true;
|
||||||
}
|
}
|
||||||
else if(wd_manager().available(wd))
|
|
||||||
wd->other.upd_state = core_window_t::update_state::none;
|
|
||||||
|
|
||||||
if(thrd) thrd->event_window = prev_wd;
|
if(thrd) thrd->event_window = prev_wd;
|
||||||
return true;
|
return good_wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt)
|
void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt)
|
||||||
@ -438,8 +447,8 @@ namespace detail
|
|||||||
keysym = keyboard::os_arrow_left + (keysym - XK_Left); break;
|
keysym = keyboard::os_arrow_left + (keysym - XK_Left); break;
|
||||||
case XK_Insert:
|
case XK_Insert:
|
||||||
keysym = keyboard::os_insert; break;
|
keysym = keyboard::os_insert; break;
|
||||||
case XK_Delete:
|
case XK_Delete: case XK_KP_Delete:
|
||||||
keysym = keyboard::os_del; break;
|
keysym = keyboard::del; break;
|
||||||
case XK_Shift_L: case XK_Shift_R: //shift
|
case XK_Shift_L: case XK_Shift_R: //shift
|
||||||
keysym = keyboard::os_shift; break;
|
keysym = keyboard::os_shift; break;
|
||||||
case XK_Control_L: case XK_Control_R: //ctrl
|
case XK_Control_L: case XK_Control_R: //ctrl
|
||||||
|
|||||||
@ -601,40 +601,6 @@ namespace detail
|
|||||||
::HeapFree(::GetProcessHeap(), 0, stru);
|
::HeapFree(::GetProcessHeap(), 0, stru);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case nana::detail::messages::remote_thread_move_window:
|
|
||||||
{
|
|
||||||
auto * mw = reinterpret_cast<nana::detail::messages::move_window*>(wParam);
|
|
||||||
|
|
||||||
::RECT r;
|
|
||||||
::GetWindowRect(wd, &r);
|
|
||||||
if(mw->ignore & mw->Pos)
|
|
||||||
{
|
|
||||||
mw->x = r.left;
|
|
||||||
mw->y = r.top;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HWND owner = ::GetWindow(wd, GW_OWNER);
|
|
||||||
if(owner)
|
|
||||||
{
|
|
||||||
::RECT owr;
|
|
||||||
::GetWindowRect(owner, &owr);
|
|
||||||
::POINT pos = {owr.left, owr.top};
|
|
||||||
::ScreenToClient(owner, &pos);
|
|
||||||
mw->x += (owr.left - pos.x);
|
|
||||||
mw->y += (owr.top - pos.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mw->ignore & mw->Size)
|
|
||||||
{
|
|
||||||
mw->width = r.right - r.left;
|
|
||||||
mw->height = r.bottom - r.top;
|
|
||||||
}
|
|
||||||
::MoveWindow(wd, mw->x, mw->y, mw->width, mw->height, true);
|
|
||||||
delete mw;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case nana::detail::messages::remote_thread_set_window_pos:
|
case nana::detail::messages::remote_thread_set_window_pos:
|
||||||
::SetWindowPos(wd, reinterpret_cast<HWND>(wParam), 0, 0, 0, 0, static_cast<UINT>(lParam));
|
::SetWindowPos(wd, reinterpret_cast<HWND>(wParam), 0, 0, 0, 0, static_cast<UINT>(lParam));
|
||||||
return true;
|
return true;
|
||||||
@ -775,6 +741,19 @@ namespace detail
|
|||||||
if (thrd) thrd->event_window = prev_event_wd;
|
if (thrd) thrd->event_window = prev_event_wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Translate OS Virtual-Key into ASCII code
|
||||||
|
wchar_t translate_virtual_key(WPARAM vkey)
|
||||||
|
{
|
||||||
|
switch (vkey)
|
||||||
|
{
|
||||||
|
case VK_DELETE:
|
||||||
|
return 127;
|
||||||
|
case VK_DECIMAL:
|
||||||
|
return 46;
|
||||||
|
}
|
||||||
|
return static_cast<wchar_t>(vkey);
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK Bedrock_WIN32_WindowProc(HWND root_window, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK Bedrock_WIN32_WindowProc(HWND root_window, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT window_proc_value = 0;
|
LRESULT window_proc_value = 0;
|
||||||
@ -1436,7 +1415,7 @@ namespace detail
|
|||||||
arg.evt_code = event_code::key_press;
|
arg.evt_code = event_code::key_press;
|
||||||
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
arg.ignore = false;
|
arg.ignore = false;
|
||||||
arg.key = static_cast<wchar_t>(wParam);
|
arg.key = translate_virtual_key(wParam);
|
||||||
brock.get_key_state(arg);
|
brock.get_key_state(arg);
|
||||||
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
|
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
|
||||||
|
|
||||||
@ -1522,7 +1501,7 @@ namespace detail
|
|||||||
arg_keyboard arg;
|
arg_keyboard arg;
|
||||||
arg.evt_code = event_code::key_release;
|
arg.evt_code = event_code::key_release;
|
||||||
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
arg.key = static_cast<wchar_t>(wParam);
|
arg.key = translate_virtual_key(wParam);
|
||||||
brock.get_key_state(arg);
|
brock.get_key_state(arg);
|
||||||
arg.ignore = false;
|
arg.ignore = false;
|
||||||
brock.emit(event_code::key_release, msgwnd, arg, true, &context);
|
brock.emit(event_code::key_release, msgwnd, arg, true, &context);
|
||||||
@ -1639,18 +1618,21 @@ namespace detail
|
|||||||
_m_event_filter(evt_code, wd, thrd);
|
_m_event_filter(evt_code, wd, thrd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wd->other.upd_state == core_window_t::update_state::none)
|
using update_state = basic_window::update_state;
|
||||||
wd->other.upd_state = core_window_t::update_state::lazy;
|
|
||||||
|
if (update_state::none == wd->other.upd_state)
|
||||||
|
wd->other.upd_state = update_state::lazy;
|
||||||
|
|
||||||
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
||||||
|
|
||||||
bool good_wd = false;
|
bool good_wd = false;
|
||||||
if (wd_manager().available(wd))
|
if (wd_manager().available(wd))
|
||||||
{
|
{
|
||||||
if (ask_update)
|
//Ignore ask_update if update state is refreshed.
|
||||||
|
if (ask_update || (update_state::refreshed == wd->other.upd_state))
|
||||||
wd_manager().do_lazy_refresh(wd, false);
|
wd_manager().do_lazy_refresh(wd, false);
|
||||||
else
|
else
|
||||||
wd->other.upd_state = basic_window::update_state::none;
|
wd->other.upd_state = update_state::none;
|
||||||
|
|
||||||
good_wd = true;
|
good_wd = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -863,30 +863,27 @@ namespace nana{
|
|||||||
void native_interface::move_window(native_window_type wd, int x, int y)
|
void native_interface::move_window(native_window_type wd, int x, int y)
|
||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
if(::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
|
::RECT r;
|
||||||
|
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
|
||||||
|
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
|
||||||
|
if(owner)
|
||||||
{
|
{
|
||||||
nana::detail::messages::move_window * mw = new nana::detail::messages::move_window;
|
::RECT owner_rect;
|
||||||
mw->x = x;
|
::GetWindowRect(owner, &owner_rect);
|
||||||
mw->y = y;
|
::POINT pos = {owner_rect.left, owner_rect.top};
|
||||||
mw->ignore = mw->Size;
|
::ScreenToClient(owner, &pos);
|
||||||
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::remote_thread_move_window, reinterpret_cast<WPARAM>(mw), 0);
|
x += (owner_rect.left - pos.x);
|
||||||
|
y += (owner_rect.top - pos.y);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
|
||||||
|
if (::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
|
||||||
{
|
{
|
||||||
::RECT r;
|
nana::internal_revert_guard irg;
|
||||||
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
|
|
||||||
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
|
|
||||||
if(owner)
|
|
||||||
{
|
|
||||||
::RECT owner_rect;
|
|
||||||
::GetWindowRect(owner, &owner_rect);
|
|
||||||
::POINT pos = {owner_rect.left, owner_rect.top};
|
|
||||||
::ScreenToClient(owner, &pos);
|
|
||||||
x += (owner_rect.left - pos.x);
|
|
||||||
y += (owner_rect.top - pos.y);
|
|
||||||
}
|
|
||||||
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.right - r.left, r.bottom - r.top, true);
|
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.right - r.left, r.bottom - r.top, true);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.right - r.left, r.bottom - r.top, true);
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
Display * disp = restrict::spec.open_display();
|
Display * disp = restrict::spec.open_display();
|
||||||
|
|
||||||
@ -908,41 +905,36 @@ namespace nana{
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_interface::move_window(native_window_type wd, const rectangle& r)
|
bool native_interface::move_window(native_window_type wd, const rectangle& r)
|
||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
if(::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
|
|
||||||
|
int x = r.x;
|
||||||
|
int y = r.y;
|
||||||
|
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
|
||||||
|
if(owner)
|
||||||
{
|
{
|
||||||
auto * mw = new nana::detail::messages::move_window;
|
::RECT owner_rect;
|
||||||
mw->x = r.x;
|
::GetWindowRect(owner, &owner_rect);
|
||||||
mw->y = r.y;
|
::POINT pos = {owner_rect.left, owner_rect.top};
|
||||||
mw->width = r.width;
|
::ScreenToClient(owner, &pos);
|
||||||
mw->height = r.height;
|
x += (owner_rect.left - pos.x);
|
||||||
mw->ignore = 0;
|
y += (owner_rect.top - pos.y);
|
||||||
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::remote_thread_move_window, reinterpret_cast<WPARAM>(mw), 0);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
int x = r.x;
|
|
||||||
int y = r.y;
|
|
||||||
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
|
|
||||||
if(owner)
|
|
||||||
{
|
|
||||||
::RECT owner_rect;
|
|
||||||
::GetWindowRect(owner, &owner_rect);
|
|
||||||
::POINT pos = {owner_rect.left, owner_rect.top};
|
|
||||||
::ScreenToClient(owner, &pos);
|
|
||||||
x += (owner_rect.left - pos.x);
|
|
||||||
y += (owner_rect.top - pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT client, wd_area;
|
RECT client, wd_area;
|
||||||
::GetClientRect(reinterpret_cast<HWND>(wd), &client);
|
::GetClientRect(reinterpret_cast<HWND>(wd), &client);
|
||||||
::GetWindowRect(reinterpret_cast<HWND>(wd), &wd_area);
|
::GetWindowRect(reinterpret_cast<HWND>(wd), &wd_area);
|
||||||
unsigned ext_w = (wd_area.right - wd_area.left) - client.right;
|
unsigned ext_w = (wd_area.right - wd_area.left) - client.right;
|
||||||
unsigned ext_h = (wd_area.bottom - wd_area.top) - client.bottom;
|
unsigned ext_h = (wd_area.bottom - wd_area.top) - client.bottom;
|
||||||
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.width + ext_w, r.height + ext_h, true);
|
|
||||||
|
if (::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
|
||||||
|
{
|
||||||
|
nana::internal_revert_guard irg;
|
||||||
|
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.width + ext_w, r.height + ext_h, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.width + ext_w, r.height + ext_h, true));
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
Display * disp = restrict::spec.open_display();
|
Display * disp = restrict::spec.open_display();
|
||||||
long supplied;
|
long supplied;
|
||||||
@ -984,6 +976,7 @@ namespace nana{
|
|||||||
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
|
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
|
||||||
|
|
||||||
::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height);
|
::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height);
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,32 +1055,28 @@ namespace nana{
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_interface::window_size(native_window_type wd, const size& sz)
|
bool native_interface::window_size(native_window_type wd, const size& sz)
|
||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
if(::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
|
::RECT r;
|
||||||
|
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
|
||||||
|
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
|
||||||
|
HWND parent = ::GetParent(reinterpret_cast<HWND>(wd));
|
||||||
|
if(parent && (parent != owner))
|
||||||
{
|
{
|
||||||
auto * mw = new nana::detail::messages::move_window;
|
::POINT pos = {r.left, r.top};
|
||||||
mw->width = sz.width;
|
::ScreenToClient(parent, &pos);
|
||||||
mw->height = sz.height;
|
r.left = pos.x;
|
||||||
mw->ignore = mw->Pos;
|
r.top = pos.y;
|
||||||
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::remote_thread_move_window, reinterpret_cast<WPARAM>(mw), 0);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
|
||||||
{
|
{
|
||||||
::RECT r;
|
nana::internal_revert_guard irg;
|
||||||
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
|
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), r.left, r.top, static_cast<int>(sz.width), static_cast<int>(sz.height), true));
|
||||||
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
|
|
||||||
HWND parent = ::GetParent(reinterpret_cast<HWND>(wd));
|
|
||||||
if(parent && (parent != owner))
|
|
||||||
{
|
|
||||||
::POINT pos = {r.left, r.top};
|
|
||||||
::ScreenToClient(parent, &pos);
|
|
||||||
r.left = pos.x;
|
|
||||||
r.top = pos.y;
|
|
||||||
}
|
|
||||||
::MoveWindow(reinterpret_cast<HWND>(wd), r.left, r.top, static_cast<int>(sz.width), static_cast<int>(sz.height), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), r.left, r.top, static_cast<int>(sz.width), static_cast<int>(sz.height), true));
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
auto disp = restrict::spec.open_display();
|
auto disp = restrict::spec.open_display();
|
||||||
nana::detail::platform_scope_guard psg;
|
nana::detail::platform_scope_guard psg;
|
||||||
@ -1104,6 +1093,7 @@ namespace nana{
|
|||||||
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
|
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
|
||||||
}
|
}
|
||||||
::XResizeWindow(disp, reinterpret_cast<Window>(wd), sz.width, sz.height);
|
::XResizeWindow(disp, reinterpret_cast<Window>(wd), sz.width, sz.height);
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -953,24 +953,45 @@ namespace detail
|
|||||||
if (wd->dimension == sz)
|
if (wd->dimension == sz)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
//Before resiz the window, creates the new graphics
|
||||||
|
paint::graphics graph;
|
||||||
|
paint::graphics root_graph;
|
||||||
|
if (category::flags::lite_widget != wd->other.category)
|
||||||
|
{
|
||||||
|
//If allocation fails, here throws std::bad_alloc.
|
||||||
|
graph.make(sz);
|
||||||
|
if (category::flags::root == wd->other.category)
|
||||||
|
root_graph.make(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pre_sz = wd->dimension;
|
||||||
|
|
||||||
wd->dimension = sz;
|
wd->dimension = sz;
|
||||||
|
|
||||||
if(category::flags::lite_widget != wd->other.category)
|
if(category::flags::lite_widget != wd->other.category)
|
||||||
{
|
{
|
||||||
bool graph_state = wd->drawer.graphics.empty();
|
bool graph_state = wd->drawer.graphics.empty();
|
||||||
wd->drawer.graphics.make(sz);
|
wd->drawer.graphics.swap(graph);
|
||||||
|
|
||||||
//It shall make a typeface_changed() call when the graphics state is changing.
|
//It shall make a typeface_changed() call when the graphics state is changing.
|
||||||
//Because when a widget is created with zero-size, it may get some wrong result in typeface_changed() call
|
//Because when a widget is created with zero-size, it may get some wrong results in typeface_changed() call
|
||||||
//due to the invaliable graphics object.
|
//due to the invaliable graphics object.
|
||||||
if(graph_state != wd->drawer.graphics.empty())
|
if(graph_state != wd->drawer.graphics.empty())
|
||||||
wd->drawer.typeface_changed();
|
wd->drawer.typeface_changed();
|
||||||
|
|
||||||
if(category::flags::root == wd->other.category)
|
if(category::flags::root == wd->other.category)
|
||||||
{
|
{
|
||||||
wd->root_graph->make(sz);
|
//wd->root_graph->make(sz);
|
||||||
|
wd->root_graph->swap(root_graph);
|
||||||
if(false == passive)
|
if(false == passive)
|
||||||
native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height));
|
if (!native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)))
|
||||||
|
{
|
||||||
|
wd->dimension = pre_sz;
|
||||||
|
wd->drawer.graphics.swap(graph);
|
||||||
|
wd->root_graph->swap(root_graph);
|
||||||
|
wd->drawer.typeface_changed();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifndef WIDGET_FRAME_DEPRECATED
|
#ifndef WIDGET_FRAME_DEPRECATED
|
||||||
else if(category::flags::frame == wd->other.category)
|
else if(category::flags::frame == wd->other.category)
|
||||||
|
|||||||
@ -403,8 +403,15 @@ namespace nana
|
|||||||
ess_->state.nullify_mouse = true;
|
ess_->state.nullify_mouse = true;
|
||||||
|
|
||||||
auto & menu_ptr = ess_->state.menu;
|
auto & menu_ptr = ess_->state.menu;
|
||||||
|
|
||||||
|
//menu_wd will be assigned with the handle of a menu window,
|
||||||
|
//It is used for checking whether the menu is closed. A menu handler
|
||||||
|
//may close the form, checking with the data member of this trigger
|
||||||
|
//is invalid, because the form is closed, the object of menubar may not exist.
|
||||||
|
window menu_wd = nullptr;
|
||||||
if(ess_->state.menu)
|
if(ess_->state.menu)
|
||||||
{
|
{
|
||||||
|
menu_wd = menu_ptr->handle();
|
||||||
switch(arg.key)
|
switch(arg.key)
|
||||||
{
|
{
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
@ -466,8 +473,11 @@ namespace nana
|
|||||||
case keyboard::os_arrow_up:
|
case keyboard::os_arrow_up:
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
case keyboard::enter:
|
case keyboard::enter:
|
||||||
if(ess_->open_menu(true))
|
if (ess_->open_menu(true))
|
||||||
|
{
|
||||||
|
menu_wd = menu_ptr->handle();
|
||||||
menu_ptr->goto_next(true);
|
menu_ptr->goto_next(true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case keyboard::escape:
|
case keyboard::escape:
|
||||||
if(essence::behavior::focus == ess_->state.behave)
|
if(essence::behavior::focus == ess_->state.behave)
|
||||||
@ -481,15 +491,21 @@ namespace nana
|
|||||||
if(index != npos)
|
if(index != npos)
|
||||||
{
|
{
|
||||||
ess_->state.active = index;
|
ess_->state.active = index;
|
||||||
if(ess_->open_menu(true))
|
if (ess_->open_menu(true))
|
||||||
|
{
|
||||||
|
menu_wd = menu_ptr->handle();
|
||||||
menu_ptr->goto_next(true);
|
menu_ptr->goto_next(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh(graph);
|
if (API::is_window(menu_wd))
|
||||||
API::dev::lazy_refresh();
|
{
|
||||||
|
refresh(graph);
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::key_release(graph_reference graph, const arg_keyboard& arg)
|
void trigger::key_release(graph_reference graph, const arg_keyboard& arg)
|
||||||
|
|||||||
@ -1233,7 +1233,7 @@ namespace nana{ namespace widgets
|
|||||||
case keyboard::os_pagedown:
|
case keyboard::os_pagedown:
|
||||||
_m_handle_move_key(arg);
|
_m_handle_move_key(arg);
|
||||||
break;
|
break;
|
||||||
case keyboard::os_del:
|
case keyboard::del:
|
||||||
// send delete to set_accept function
|
// send delete to set_accept function
|
||||||
if (this->attr().editable && (!impl_->capacities.pred_acceptive || impl_->capacities.pred_acceptive(key)))
|
if (this->attr().editable && (!impl_->capacities.pred_acceptive || impl_->capacities.pred_acceptive(key)))
|
||||||
del();
|
del();
|
||||||
@ -1689,7 +1689,7 @@ namespace nana{ namespace widgets
|
|||||||
impl_->try_refresh = sync_graph::refresh;
|
impl_->try_refresh = sync_graph::refresh;
|
||||||
|
|
||||||
//_m_put calcs the lines
|
//_m_put calcs the lines
|
||||||
_m_reset_content_size(false);
|
_m_reset_content_size(true);
|
||||||
impl_->cview->sync(false);
|
impl_->cview->sync(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -269,7 +269,7 @@ namespace paint
|
|||||||
return (!impl_->handle);
|
return (!impl_->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics::operator const void *() const
|
graphics::operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return impl_->handle;
|
return impl_->handle;
|
||||||
}
|
}
|
||||||
@ -291,9 +291,15 @@ namespace paint
|
|||||||
return (impl_->handle ? impl_->handle->context : nullptr);
|
return (impl_->handle ? impl_->handle->context : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void graphics::swap(graphics& other) noexcept
|
||||||
|
{
|
||||||
|
if (context() != other.context())
|
||||||
|
impl_.swap(other.impl_);
|
||||||
|
}
|
||||||
|
|
||||||
void graphics::make(const ::nana::size& sz)
|
void graphics::make(const ::nana::size& sz)
|
||||||
{
|
{
|
||||||
if(impl_->handle == nullptr || impl_->size != sz)
|
if (impl_->handle == nullptr || impl_->size != sz)
|
||||||
{
|
{
|
||||||
if (sz.empty())
|
if (sz.empty())
|
||||||
{
|
{
|
||||||
@ -302,9 +308,10 @@ namespace paint
|
|||||||
}
|
}
|
||||||
|
|
||||||
//The object will be delete while dwptr_ is performing a release.
|
//The object will be delete while dwptr_ is performing a release.
|
||||||
drawable_type dw = new nana::detail::drawable_impl_type;
|
std::shared_ptr<nana::detail::drawable_impl_type> dw{ new nana::detail::drawable_impl_type, detail::drawable_deleter{} };
|
||||||
|
|
||||||
//Reuse the old font
|
//Reuse the old font
|
||||||
if(impl_->platform_drawable)
|
if (impl_->platform_drawable)
|
||||||
{
|
{
|
||||||
drawable_type reuse = impl_->platform_drawable.get();
|
drawable_type reuse = impl_->platform_drawable.get();
|
||||||
dw->font = reuse->font;
|
dw->font = reuse->font;
|
||||||
@ -314,8 +321,13 @@ namespace paint
|
|||||||
dw->font = impl_->font_shadow.impl_->real_font;
|
dw->font = impl_->font_shadow.impl_->real_font;
|
||||||
|
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
HDC hdc = ::GetDC(0);
|
HDC hdc = ::GetDC(nullptr);
|
||||||
HDC cdc = ::CreateCompatibleDC(hdc);
|
HDC cdc = ::CreateCompatibleDC(hdc);
|
||||||
|
if (nullptr == cdc)
|
||||||
|
{
|
||||||
|
::ReleaseDC(nullptr, hdc);
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
}
|
||||||
|
|
||||||
BITMAPINFO bmi;
|
BITMAPINFO bmi;
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
@ -328,34 +340,60 @@ namespace paint
|
|||||||
|
|
||||||
HBITMAP bmp = ::CreateDIBSection(cdc, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&(dw->pixbuf_ptr)), 0, 0);
|
HBITMAP bmp = ::CreateDIBSection(cdc, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&(dw->pixbuf_ptr)), 0, 0);
|
||||||
|
|
||||||
if(bmp)
|
if (nullptr == bmp)
|
||||||
{
|
|
||||||
::DeleteObject((HBITMAP)::SelectObject(cdc, bmp));
|
|
||||||
::DeleteObject(::SelectObject(cdc, dw->font->native_handle()));
|
|
||||||
|
|
||||||
dw->context = cdc;
|
|
||||||
dw->pixmap = bmp;
|
|
||||||
::SetBkMode(cdc, TRANSPARENT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
::DeleteDC(cdc);
|
::DeleteDC(cdc);
|
||||||
delete dw;
|
::ReleaseDC(nullptr, hdc);
|
||||||
dw = nullptr;
|
throw std::bad_alloc{};
|
||||||
release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::DeleteObject((HBITMAP)::SelectObject(cdc, bmp));
|
||||||
|
::DeleteObject(::SelectObject(cdc, dw->font->native_handle()));
|
||||||
|
|
||||||
|
dw->context = cdc;
|
||||||
|
dw->pixmap = bmp;
|
||||||
|
::SetBkMode(cdc, TRANSPARENT);
|
||||||
|
|
||||||
::ReleaseDC(0, hdc);
|
::ReleaseDC(0, hdc);
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
auto & spec = nana::detail::platform_spec::instance();
|
auto & spec = nana::detail::platform_spec::instance();
|
||||||
Display* disp = spec.open_display();
|
{
|
||||||
int screen = DefaultScreen(disp);
|
nana::detail::platform_scope_guard psg;
|
||||||
Window root = ::XRootWindow(disp, screen);
|
|
||||||
dw->pixmap = ::XCreatePixmap(disp, root, sz.width, sz.height, DefaultDepth(disp, screen));
|
spec.set_error_handler();
|
||||||
dw->context = ::XCreateGC(disp, dw->pixmap, 0, 0);
|
|
||||||
#if defined(NANA_USE_XFT)
|
Display* disp = spec.open_display();
|
||||||
dw->xftdraw = ::XftDrawCreate(disp, dw->pixmap, spec.screen_visual(), spec.colormap());
|
int screen = DefaultScreen(disp);
|
||||||
#endif
|
Window root = ::XRootWindow(disp, screen);
|
||||||
|
auto pixmap = ::XCreatePixmap(disp, root, sz.width, sz.height, DefaultDepth(disp, screen));
|
||||||
|
if(spec.error_code)
|
||||||
|
{
|
||||||
|
spec.rev_error_handler();
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
auto context = ::XCreateGC(disp, pixmap, 0, 0);
|
||||||
|
if (spec.error_code)
|
||||||
|
{
|
||||||
|
::XFreePixmap(disp, pixmap);
|
||||||
|
spec.rev_error_handler();
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
# if defined(NANA_USE_XFT)
|
||||||
|
auto xftdraw = ::XftDrawCreate(disp, pixmap, spec.screen_visual(), spec.colormap());
|
||||||
|
if (spec.error_code)
|
||||||
|
{
|
||||||
|
::XFreeGC(disp, context);
|
||||||
|
::XFreePixmap(disp, pixmap);
|
||||||
|
|
||||||
|
spec.rev_error_handler();
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
dw->xftdraw = xftdraw;
|
||||||
|
# endif
|
||||||
|
dw->pixmap = pixmap;
|
||||||
|
dw->context = context;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(dw)
|
if(dw)
|
||||||
{
|
{
|
||||||
@ -366,8 +404,8 @@ namespace paint
|
|||||||
#else
|
#else
|
||||||
dw->update_text_color();
|
dw->update_text_color();
|
||||||
#endif
|
#endif
|
||||||
impl_->platform_drawable.reset(dw, detail::drawable_deleter{});
|
impl_->platform_drawable = dw;
|
||||||
impl_->handle = dw;
|
impl_->handle = dw.get();
|
||||||
impl_->size = sz;
|
impl_->size = sz;
|
||||||
|
|
||||||
impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;
|
impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user