Merge branch 'hotfix-1.7.2' into develop

This commit is contained in:
Jinhao 2019-09-11 00:54:47 +08:00
commit a65eec2bb9
16 changed files with 224 additions and 67 deletions

View File

@ -44,7 +44,7 @@ matrix:
before_install: before_install:
- cd .. - cd ..
- git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git nana-demo - git clone --depth=1 --branch=master https://github.com/qPCR4vir/nana-demo.git nana-demo
- export PATH="$HOME/bin:$PATH" - export PATH="$HOME/bin:$PATH"
- wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.12/cmake-3.12.0-rc3-Linux-x86_64.sh || true - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.12/cmake-3.12.0-rc3-Linux-x86_64.sh || true
- chmod -R +x /tmp/tools - chmod -R +x /tmp/tools

View File

@ -38,13 +38,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AN
endif() endif()
if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang
target_compile_options(nana PUBLIC -stdlib=libstdc++)
endif ()
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
target_compile_options(nana PRIVATE -fmax-errors=3) target_compile_options(nana PRIVATE -fmax-errors=3)
endif() endif()

View File

@ -89,7 +89,7 @@
#define NANA_MINGW #define NANA_MINGW
#endif // MINGW #endif // MINGW
#elif defined(APPLE) //Mac OS X #elif defined(__APPLE__) || defined(APPLE) //Mac OS X
//Symbols for MACOS //Symbols for MACOS
#define NANA_MACOS #define NANA_MACOS
#define NANA_POSIX #define NANA_POSIX

View File

@ -560,7 +560,7 @@ namespace std {
#endif #endif
} }
} // std } // std
#else #else //#if NANA_USING_NANA_FILESYSTEM
//Implements the missing functions for various version of experimental/filesystem //Implements the missing functions for various version of experimental/filesystem
namespace std namespace std
{ {
@ -568,7 +568,7 @@ namespace std {
{ {
//Visual Studio 2017 //Visual Studio 2017
#if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \ #if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \
(!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603)) (!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603 || (__GNUC__* 100 + __GNUC_MINOR__ < 801)))
path weakly_canonical(const path& p); path weakly_canonical(const path& p);
path weakly_canonical(const path& p, std::error_code& err); path weakly_canonical(const path& p, std::error_code& err);
#endif #endif

View File

@ -48,7 +48,7 @@ namespace nana
template<typename Function> template<typename Function>
void elapse(Function && fn) void elapse(Function && fn)
{ {
elapse_.connect(std::forward<Function>(fn)); elapse_->connect(std::forward<Function>(fn));
} }
void reset(); void reset();
@ -66,7 +66,7 @@ namespace nana
private: private:
unsigned _m_interval() const; unsigned _m_interval() const;
private: private:
nana::basic_event<arg_elapse> elapse_; std::shared_ptr<nana::basic_event<arg_elapse>> elapse_;
implement * const impl_; implement * const impl_;
}; };
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/** /**
* A Character Encoding Set Implementation * A Character Encoding Set Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2019 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
@ -245,8 +245,12 @@ namespace nana
int bytes = ::WideCharToMultiByte(CP_ACP, 0, s, -1, 0, 0, 0, 0); int bytes = ::WideCharToMultiByte(CP_ACP, 0, s, -1, 0, 0, 0, 0);
if(bytes > 1) if(bytes > 1)
{ {
mbstr.resize(bytes - 1); // the bytes is the length of the string with null character.
::WideCharToMultiByte(CP_ACP, 0, s, -1, &(mbstr[0]), bytes - 1, 0, 0); mbstr.resize(bytes);
::WideCharToMultiByte(CP_ACP, 0, s, -1, &(mbstr[0]), bytes, 0, 0);
//Remove the null character written by WideCharToMultiByte
mbstr.pop_back();
} }
return true; return true;
#else #else
@ -279,8 +283,12 @@ namespace nana
int chars = ::MultiByteToWideChar(CP_ACP, 0, s, -1, 0, 0); int chars = ::MultiByteToWideChar(CP_ACP, 0, s, -1, 0, 0);
if(chars > 1) if(chars > 1)
{ {
wcstr.resize(chars - 1); // the length of the string with null character.
::MultiByteToWideChar(CP_ACP, 0, s, -1, &wcstr[0], chars - 1); wcstr.resize(chars);
::MultiByteToWideChar(CP_ACP, 0, s, -1, &wcstr[0], chars);
// remove the null character written by MultiByteToWideChar
wcstr.pop_back();
} }
#else #else
locale_initializer::init(); locale_initializer::init();

View File

@ -1407,7 +1407,7 @@ namespace std
namespace filesystem namespace filesystem
{ {
#if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \ #if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \
(!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603)) (!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603 || (__GNUC__* 100 + __GNUC_MINOR__ < 801)))
namespace detail namespace detail
{ {

View File

@ -622,6 +622,7 @@ namespace detail
} }
break; break;
case ConfigureNotify: case ConfigureNotify:
++(root_runtime->x11msg.config);
if(msgwnd->dimension.width != static_cast<unsigned>(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast<unsigned>(xevent.xconfigure.height)) if(msgwnd->dimension.width != static_cast<unsigned>(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast<unsigned>(xevent.xconfigure.height))
{ {
auto & cf = xevent.xconfigure; auto & cf = xevent.xconfigure;
@ -890,7 +891,12 @@ namespace detail
case MapNotify: case MapNotify:
case UnmapNotify: case UnmapNotify:
if(xevent.type == MapNotify) if(xevent.type == MapNotify)
{
++(root_runtime->x11msg.map);
x11_apply_exposed_position(native_window); x11_apply_exposed_position(native_window);
}
else
++(root_runtime->x11msg.unmap);
brock.event_expose(msgwnd, (xevent.type == MapNotify)); brock.event_expose(msgwnd, (xevent.type == MapNotify));
context.platform.motion_window = nullptr; context.platform.motion_window = nullptr;

View File

@ -173,15 +173,22 @@ namespace detail
static LRESULT WINAPI Bedrock_WIN32_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static LRESULT WINAPI Bedrock_WIN32_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
HINSTANCE windows_module_handle()
{
MEMORY_BASIC_INFORMATION mbi;
static int dummy;
VirtualQuery(&dummy, &mbi, sizeof(mbi));
return reinterpret_cast<HINSTANCE>(mbi.AllocationBase);
}
bedrock::bedrock() bedrock::bedrock()
: pi_data_(new pi_data), : pi_data_(new pi_data),
impl_(new private_impl) impl_(new private_impl)
{ {
nana::detail::platform_spec::instance(); //to guaranty the platform_spec object is initialized before using. nana::detail::platform_spec::instance(); //to guaranty the platform_spec object is initialized before using.
WNDCLASSEX wincl; WNDCLASSEX wincl;
wincl.hInstance = ::GetModuleHandle(0); wincl.hInstance = windows_module_handle();
wincl.lpszClassName = L"NanaWindowInternal"; wincl.lpszClassName = L"NanaWindowInternal";
wincl.lpfnWndProc = &Bedrock_WIN32_WindowProc; wincl.lpfnWndProc = &Bedrock_WIN32_WindowProc;
wincl.style = CS_DBLCLKS | CS_OWNDC; wincl.style = CS_DBLCLKS | CS_OWNDC;
@ -229,6 +236,8 @@ namespace detail
delete impl_; delete impl_;
delete pi_data_; delete pi_data_;
::UnregisterClass(L"NanaWindowInternal", windows_module_handle());
} }

View File

@ -21,6 +21,10 @@
#include <map> #include <map>
#ifdef NANA_X11
# include <atomic>
#endif
namespace nana{ namespace nana{
namespace detail namespace detail
{ {
@ -75,6 +79,15 @@ namespace nana{
root_misc(root_misc&&); root_misc(root_misc&&);
root_misc(basic_window * wd, unsigned width, unsigned height); root_misc(basic_window * wd, unsigned width, unsigned height);
~root_misc(); ~root_misc();
#ifdef NANA_X11
struct x11msg_confirm
{
std::atomic<std::size_t> config{ 0 };
std::atomic<std::size_t> map{ 0 };
std::atomic<std::size_t> unmap{ 0 };
}x11msg;
#endif
private: private:
root_misc(const root_misc&) = delete; root_misc(const root_misc&) = delete;
root_misc& operator=(const root_misc&) = delete; root_misc& operator=(const root_misc&) = delete;

View File

@ -25,6 +25,7 @@
# include <map> # include <map>
#elif defined(NANA_X11) #elif defined(NANA_X11)
# include <nana/system/platform.hpp> # include <nana/system/platform.hpp>
# include "inner_fwd_implement.hpp"
#endif #endif
#include "../../paint/image_accessor.hpp" #include "../../paint/image_accessor.hpp"
@ -34,6 +35,10 @@ namespace nana{
namespace detail{ namespace detail{
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
//This function is defined in bedrock_windows.cpp
HINSTANCE windows_module_handle();
class tray_manager class tray_manager
{ {
struct window_extra_t struct window_extra_t
@ -199,26 +204,87 @@ namespace nana{
namespace x11_wait namespace x11_wait
{ {
struct param
{
Window handle;
root_misc * misc;
std::size_t comp_value;
};
static Bool configure(Display *disp, XEvent *evt, char *arg) static Bool configure(Display *disp, XEvent *evt, char *arg)
{ {
return disp && evt && arg && (evt->type == ConfigureNotify) && (evt->xconfigure.window == *reinterpret_cast<Window*>(arg)); auto p = reinterpret_cast<param*>(arg);
if(p)
{
if(p->misc->x11msg.config != p->comp_value)
return true;
if(disp && evt && (evt->type == ConfigureNotify))
{
if(evt->xconfigure.window == p->handle)
return true;
}
}
return false;
} }
static Bool map(Display *disp, XEvent *evt, char *arg) static Bool map(Display *disp, XEvent *evt, char *arg)
{ {
return disp && evt && arg && (evt->type == MapNotify) && (evt->xmap.window == *reinterpret_cast<Window*>(arg)); auto p = reinterpret_cast<param*>(arg);
if(p)
{
if(p->misc->x11msg.map != p->comp_value)
return true;
if(disp && evt && (evt->type == MapNotify))
{
if(evt->xmap.window == p->handle)
return true;
}
}
return false;
} }
static Bool unmap(Display *disp, XEvent *evt, char *arg) static Bool unmap(Display *disp, XEvent *evt, char *arg)
{ {
return disp && evt && arg && (evt->type == MapNotify) && (evt->xunmap.window == *reinterpret_cast<Window*>(arg)); auto p = reinterpret_cast<param*>(arg);
if(p)
{
if(p->misc->x11msg.unmap != p->comp_value)
return true;
if(disp && evt && (evt->type == UnmapNotify))
{
if(evt->xunmap.window == p->handle)
return true;
}
}
return false;
} }
} }
static void x11_wait_for(Window wd, Bool(*pred_fn)(Display*, XEvent*, char*)) static void x11_wait_for(Window wd, Bool(*pred_fn)(Display*, XEvent*, char*), std::size_t comp_value)
{ {
auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast<native_window_type>(wd));
x11_wait::param p;
p.handle = wd;
p.misc = misc;
if(pred_fn == &x11_wait::configure)
p.comp_value = misc->x11msg.config;
else if(pred_fn == &x11_wait::map)
p.comp_value = misc->x11msg.map;
else if(pred_fn == &x11_wait::unmap)
p.comp_value = misc->x11msg.unmap;
//Checks whether the msg is received.
if(p.comp_value != comp_value)
return;
p.comp_value = comp_value;
XEvent dummy; XEvent dummy;
::XPeekIfEvent(restrict::spec.open_display(), &dummy, pred_fn, reinterpret_cast<XPointer>(&wd)); ::XPeekIfEvent(restrict::spec.open_display(), &dummy, pred_fn, reinterpret_cast<XPointer>(&p));
} }
#endif #endif
@ -315,7 +381,7 @@ namespace nana{
HWND native_wd = ::CreateWindowEx(style_ex, L"NanaWindowInternal", L"Nana Window", HWND native_wd = ::CreateWindowEx(style_ex, L"NanaWindowInternal", L"Nana Window",
style, style,
pt.x, pt.y, 100, 100, pt.x, pt.y, 100, 100,
reinterpret_cast<HWND>(owner), 0, ::GetModuleHandle(0), 0); reinterpret_cast<HWND>(owner), 0, windows_module_handle(), 0);
//A window may have a border, this should be adjusted the client area fit for the specified size. //A window may have a border, this should be adjusted the client area fit for the specified size.
::RECT client; ::RECT client;
@ -504,7 +570,7 @@ namespace nana{
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS,
r.x, r.y, r.width, r.height, r.x, r.y, r.width, r.height,
reinterpret_cast<HWND>(parent), // The window is a child-window to desktop reinterpret_cast<HWND>(parent), // The window is a child-window to desktop
0, ::GetModuleHandle(0), 0); 0, windows_module_handle(), 0);
#elif defined(NANA_X11) #elif defined(NANA_X11)
nana::detail::platform_scope_guard psg; nana::detail::platform_scope_guard psg;
@ -758,13 +824,17 @@ namespace nana{
if(show == is_window_visible(wd)) if(show == is_window_visible(wd))
return; return;
auto misc = bedrock::instance().wd_manager().root_runtime(wd);
if(show) if(show)
{ {
std::size_t cmp_value = misc->x11msg.map;
::XMapWindow(disp, reinterpret_cast<Window>(wd)); ::XMapWindow(disp, reinterpret_cast<Window>(wd));
//Wait for the mapping notify to update the local attribute of visibility so that //Wait for the mapping notify to update the local attribute of visibility so that
//the followed window_visible() call can return the updated visibility value. //the followed window_visible() call can return the updated visibility value.
x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::map); x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::map, cmp_value);
Window grab = restrict::spec.grab(0); Window grab = restrict::spec.grab(0);
if(grab == reinterpret_cast<Window>(wd)) if(grab == reinterpret_cast<Window>(wd))
@ -772,10 +842,12 @@ namespace nana{
} }
else else
{ {
std::size_t cmp_value = misc->x11msg.unmap;
::XUnmapWindow(disp, reinterpret_cast<Window>(wd)); ::XUnmapWindow(disp, reinterpret_cast<Window>(wd));
//Wait for the mapping notify to update the local attribute of visibility so that //Wait for the mapping notify to update the local attribute of visibility so that
//the followed window_visible() call can return the updated visibility value. //the followed window_visible() call can return the updated visibility value.
x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::unmap); x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::unmap, cmp_value);
} }
} }
static_cast<void>(active); //eliminate unused parameter compiler warning. static_cast<void>(active); //eliminate unused parameter compiler warning.
@ -1019,11 +1091,15 @@ namespace nana{
y += origin_y; y += origin_y;
} }
auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast<native_window_type>(wd));
std::size_t cmp_value = misc->x11msg.config;
::XMoveWindow(disp, reinterpret_cast<Window>(wd), x, y); ::XMoveWindow(disp, reinterpret_cast<Window>(wd), x, y);
//Wait for the configuration notify to update the local attribute of position so that //Wait for the configuration notify to update the local attribute of position so that
//the followed window_position() call can return the updated position value. //the followed window_position() call can return the updated position value.
x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::configure);
x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::configure, cmp_value);
#endif #endif
} }
@ -1109,6 +1185,9 @@ namespace nana{
y += origin_y; y += origin_y;
} }
auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast<native_window_type>(wd));
std::size_t cmp_value = misc->x11msg.config;
::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height); ::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height);
//Wait for the configuration notify to update the local attribute of position so that //Wait for the configuration notify to update the local attribute of position so that
@ -1116,7 +1195,7 @@ namespace nana{
//It seems that XMoveResizeWindow doesn't need x11_wait_for. But x11_wait_for is still called //It seems that XMoveResizeWindow doesn't need x11_wait_for. But x11_wait_for is still called
//to make sure the local attribute is updated. //to make sure the local attribute is updated.
x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::configure); x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::configure, cmp_value);
return true; return true;
#endif #endif
@ -1283,11 +1362,15 @@ namespace nana{
hints.min_height = hints.max_height = sz.height; hints.min_height = hints.max_height = sz.height;
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints); ::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
} }
auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast<native_window_type>(wd));
std::size_t cmp_value = misc->x11msg.config;
::XResizeWindow(disp, reinterpret_cast<Window>(wd), sz.width, sz.height); ::XResizeWindow(disp, reinterpret_cast<Window>(wd), sz.width, sz.height);
//It seems that XResizeWindow doesn't need x11_wait_for. But x11_wait_for is still called //It seems that XResizeWindow doesn't need x11_wait_for. But x11_wait_for is still called
//to make sure the local attribute is updated. //to make sure the local attribute is updated.
x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::configure); x11_wait_for(reinterpret_cast<Window>(wd), x11_wait::configure, cmp_value);
return true; return true;
#endif #endif
} }

View File

@ -1517,6 +1517,15 @@ namespace nana
path_type parent_path{ str }; path_type parent_path{ str };
str += (len + 1); str += (len + 1);
// if only one file was selected, the ofn.lpstrFile
// is returning only that file, without any parent
if (!*str)
{
targets.emplace_back(parent_path);
impl_->path = parent_path.parent_path().u8string();
}
else
{
while(*str) while(*str)
{ {
len = ::wcslen(str); len = ::wcslen(str);
@ -1525,6 +1534,7 @@ namespace nana
} }
impl_->path = parent_path.u8string(); impl_->path = parent_path.u8string();
} }
}
else else
{ {
wfile.resize(std::wcslen(wfile.data())); wfile.resize(std::wcslen(wfile.data()));

View File

@ -146,6 +146,7 @@ namespace nana
//draw caption //draw caption
auto text = to_wstring(API::window_caption(window_handle_)); auto text = to_wstring(API::window_caption(window_handle_));
if((graph.size().width > 20) && (graph.size().width - 20 > 10))
text_rd_->render({ 3, 1 }, text.data(), text.size(), graph.size().width - 20, paint::text_renderer::mode::truncate_with_ellipsis); text_rd_->render({ 3, 1 }, text.data(), text.size(), graph.size().width - 20, paint::text_renderer::mode::truncate_with_ellipsis);
//draw x button //draw x button

View File

@ -111,13 +111,13 @@ namespace nana
{ {
public: public:
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
timer_core(timer* sender, timer_identifier tmid, basic_event<arg_elapse>& evt_elapse): timer_core(timer* sender, timer_identifier tmid, std::shared_ptr<basic_event<arg_elapse>> evt_elapse):
sender_(sender), sender_(sender),
timer_(tmid), timer_(tmid),
evt_elapse_(evt_elapse) evt_elapse_(evt_elapse)
{} {}
#else #else
timer_core(timer* sender, basic_event<arg_elapse>& evt_elapse): timer_core(timer* sender, std::shared_ptr<basic_event<arg_elapse>> evt_elapse):
sender_(sender), sender_(sender),
timer_(this), timer_(this),
evt_elapse_(evt_elapse) evt_elapse_(evt_elapse)
@ -142,12 +142,15 @@ namespace nana
{ {
arg_elapse arg; arg_elapse arg;
arg.sender = sender_; arg.sender = sender_;
evt_elapse_.emit(arg, nullptr);
//retain the object to avoid it to be deleted during calling of emit
auto retain = evt_elapse_;
retain->emit(arg, nullptr);
} }
private: private:
timer * const sender_; timer * const sender_;
const timer_identifier timer_; const timer_identifier timer_;
nana::basic_event<arg_elapse> & evt_elapse_; std::shared_ptr<nana::basic_event<arg_elapse>> evt_elapse_;
}; //end class timer_core }; //end class timer_core
@ -175,8 +178,9 @@ namespace nana
}; };
//class timer //class timer
timer::timer() timer::timer():
: impl_(new implement) elapse_(std::make_shared<nana::basic_event<arg_elapse>>()),
impl_(new implement)
{ {
} }
@ -195,7 +199,7 @@ namespace nana
void timer::reset() void timer::reset()
{ {
stop(); stop();
elapse_.clear(); elapse_->clear();
} }
void timer::start() void timer::start()

View File

@ -2314,7 +2314,8 @@ namespace nana
size_type count_of_exposed(bool with_rest) const size_type count_of_exposed(bool with_rest) const
{ {
auto lister_s = this->content_view->view_area().height; auto lister_s = this->content_view->view_area().height;
return (lister_s / item_height()) + (with_rest && (lister_s % item_height()) ? 1 : 0); return (lister_s / item_height()) + (with_rest &&
listbox_ptr->scroll_operation()->visible(true) && (lister_s % item_height()) ? 1 : 0);
} }
void update(bool ignore_auto_draw = false) noexcept void update(bool ignore_auto_draw = false) noexcept
@ -3338,16 +3339,27 @@ namespace nana
return false; return false;
} }
// init ir end to grab a header
void grab(const nana::point& pos, bool is_grab) void grab(const nana::point& pos, bool is_grab)
{ {
if(is_grab) if(is_grab) // init grabbing the header
{ {
grabs_.start_pos = pos.x; grabs_.start_pos = pos.x;
if(grabs_.splitter != npos) // resize header item, not move it if(grabs_.splitter == npos) // No splitter, no resize header, just moving
return;
// splitter grabbed - resize the header: take initial width
grabs_.item_width = essence_->header.at(grabs_.splitter).width_px; grabs_.item_width = essence_->header.at(grabs_.splitter).width_px;
} }
else if((grab_terminal_.index != npos) && (grab_terminal_.index != essence_->pointer_where.second)) else // end to grab the header
essence_->header.move(essence_->pointer_where.second, grab_terminal_.index, grab_terminal_.place_front); if (grabs_.splitter != npos) // some Splitter grab, just resizing, no need to move
return;
else if( (grab_terminal_.index != npos)
&& (grab_terminal_.index != essence_->pointer_where.second) )
// move header to terminal position
essence_->header.move(essence_->pointer_where.second, // from
grab_terminal_.index, // to
grab_terminal_.place_front);
} }
//grab_move //grab_move
@ -4295,7 +4307,10 @@ namespace nana
auto const good_list_r = essence_->rect_lister(list_r); auto const good_list_r = essence_->rect_lister(list_r);
auto & ptr_where = essence_->pointer_where; auto & ptr_where = essence_->pointer_where;
if((ptr_where.first == parts::header) && (ptr_where.second != npos || (drawer_header_->splitter() != npos)))
if( (ptr_where.first == parts::header) // click on header
&& ( ptr_where.second != npos // in ..
|| (drawer_header_->splitter() != npos))) // or splitter
{ {
essence_->ptr_state = item_state::pressed; essence_->ptr_state = item_state::pressed;
if(good_head_r) if(good_head_r)
@ -4304,7 +4319,8 @@ namespace nana
update = true; update = true;
} }
} }
else if(ptr_where.first == parts::list || ptr_where.first == parts::checker) else if( ptr_where.first == parts::list // click on list
|| ptr_where.first == parts::checker) // on a checker
{ {
index_pair item_pos = lister.advance(essence_->first_display(), static_cast<int>(ptr_where.second)); index_pair item_pos = lister.advance(essence_->first_display(), static_cast<int>(ptr_where.second));
@ -4477,13 +4493,16 @@ namespace nana
bool need_refresh = false; bool need_refresh = false;
//Don't sort the column when the mouse is due to released for stopping resizing column. //Don't sort the column when the mouse is due to released for stopping resizing column.
if ((drawer_header_->splitter() == npos) && essence_->header.attrib().sortable && essence_->pointer_where.first == parts::header && prev_state == item_state::pressed) if ( (drawer_header_->splitter() == npos) // no header splitter was selected
&& essence_->header.attrib().sortable
&& essence_->pointer_where.first == parts::header
&& prev_state == item_state::pressed)
{ {
//Try to sort the column //Try to sort the column
if(essence_->pointer_where.second < essence_->header.cont().size()) if(essence_->pointer_where.second < essence_->header.cont().size())
need_refresh = essence_->lister.sort_column(essence_->pointer_where.second, nullptr); need_refresh = essence_->lister.sort_column(essence_->pointer_where.second, nullptr);
} }
else if (item_state::grabbed == prev_state) else if (item_state::grabbed == prev_state) // selected splitter and grabbed
{ {
nana::point pos = arg.pos; nana::point pos = arg.pos;
essence_->widget_to_header(pos); essence_->widget_to_header(pos);
@ -6095,7 +6114,15 @@ namespace nana
auto listbox::last_visible() const -> index_pair auto listbox::last_visible() const -> index_pair
{ {
return _m_ess().lister.advance(_m_ess().first_display(), static_cast<int>(_m_ess().count_of_exposed(true))); if(!const_cast<listbox*>(this)->scroll_operation()->visible(true))
{
auto last_cat = size_categ()-1;
index_pair ip(last_cat, at(last_cat).size()-1);
if(last_cat == 0 && ip.item == npos) // if the listbox is empty
ip.cat = npos; // return empty index_pair
return ip;
}
return _m_ess().lister.advance(_m_ess().first_display(), static_cast<int>(_m_ess().count_of_exposed(true)-1));
} }
auto listbox::visibles() const -> index_pairs auto listbox::visibles() const -> index_pairs

View File

@ -104,6 +104,7 @@ namespace nana
delete ptr; delete ptr;
cont_.clear(); cont_.clear();
right_ = npos;
} }
@ -683,6 +684,7 @@ namespace nana
if(m && (m->textout != show)) if(m && (m->textout != show))
{ {
m->textout = show; m->textout = show;
m->pixels = 0; //force width calculation
API::refresh_window(this->handle()); API::refresh_window(this->handle());
} }
} }