Merge branch 'hotfix-1.3' into develop

This commit is contained in:
Jinhao 2016-06-10 17:08:48 +08:00
commit 2f9056cc7a
14 changed files with 294 additions and 214 deletions

View File

@ -56,7 +56,7 @@ matrix:
- llvm-toolchain-precise - llvm-toolchain-precise
before_install: before_install:
- git clone --depth=1 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo - git clone --depth=1 --branch=hotfix-1.3 https://github.com/qPCR4vir/nana-demo.git nana-demo
- export PATH="$HOME/bin:$PATH" - export PATH="$HOME/bin:$PATH"
- mkdir ~/bin - mkdir ~/bin
- wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true

View File

@ -150,7 +150,7 @@ namespace nana
if (!operand) if (!operand)
return nullptr; return nullptr;
auto holder = dynamic_cast<any::holder<Value>*>(operand->content_); auto holder = dynamic_cast<any::holder<typename std::decay<Value>::type>*>(operand->content_);
return (holder ? &holder->value : nullptr); return (holder ? &holder->value : nullptr);
} }

View File

@ -1,7 +1,7 @@
/* /*
* Definition of Notifier * Definition of Notifier
* Nana C++ Library(http://www.nanapro.org) * 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. * 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

View File

@ -11,8 +11,9 @@
* @contributors: * @contributors:
* Hiroshi Seki * Hiroshi Seki
* Ariel Vina-Rodriguez * Ariel Vina-Rodriguez
* leobackes * leobackes(pr#86,pr#97)
* Benjamin Navarro * Benjamin Navarro(pr#81)
* besh81(pr#130)
*/ */
#ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP
@ -491,7 +492,7 @@ namespace nana
}; };
/// The event argument type for listbox's category_dbl_click /// The event argument type for listbox's category_dbl_click
struct arg_listbox_category struct arg_category
: public event_arg : public event_arg
{ {
drawerbase::listbox::cat_proxy category; drawerbase::listbox::cat_proxy category;
@ -502,7 +503,7 @@ namespace nana
/// Determines whether expension/shrink of category is blocked /// Determines whether expension/shrink of category is blocked
bool category_change_blocked() const noexcept; bool category_change_blocked() const noexcept;
arg_listbox_category(const drawerbase::listbox::cat_proxy&) noexcept; arg_category(const drawerbase::listbox::cat_proxy&) noexcept;
private: private:
mutable bool block_change_; mutable bool block_change_;
}; };
@ -514,9 +515,14 @@ namespace nana
struct listbox_events struct listbox_events
: public general_events : public general_events
{ {
/// An envent occurs when the toggle of a listbox item is checked.
basic_event<arg_listbox> checked; basic_event<arg_listbox> checked;
/// An event occurs when a listbox item is clicked.
basic_event<arg_listbox> selected; basic_event<arg_listbox> selected;
basic_event<arg_listbox_category> category_dbl_click; ///< An event occurs when a listbox category is double clicking.
/// An event occurs when a listbox category is double clicking.
basic_event<arg_listbox_category> category_dbl_click;
}; };
struct scheme struct scheme
@ -529,15 +535,17 @@ namespace nana
/// \todo how to implement some geometrical parameters ?? /// \todo how to implement some geometrical parameters ??
unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this
unsigned min_header_width{ 20 }; ///< non counting suspension_width unsigned min_header_width{ 20 }; ///< def=20 . non counting suspension_width
unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...") unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...")
unsigned ext_w { 5 }; ///< ?? unsigned ext_w { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1
unsigned header_height { 20 }; ///< header height header_size unsigned header_height { 25 }; ///< def=25 . header height header_size
unsigned text_height { 0 }; ///< the trigger will set this to the height of the text font unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font
unsigned item_height_ex { 6 }; ///< 6? item_height = text_height + item_height_ex unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex
unsigned item_height { 0 }; ///< the trigger will set this TO item_height = text_height + item_height_ex unsigned item_height { 24 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex
unsigned header_mouse_spliter_area_before{ 2 }; unsigned header_mouse_spliter_area_before{ 2 }; ///< def=2. But 4 is better... IMO
unsigned header_mouse_spliter_area_after { 3 }; unsigned header_mouse_spliter_area_after { 3 }; ///< def=3. But 4 is better...
//void debug_print(const std::string &msg);
}; };
} }
@ -584,6 +592,17 @@ By \a clicking on one header the list get \a reordered, first up, and then down
} }
listbox.anyobj(0, 0, 10); //the type of customer's object is int. listbox.anyobj(0, 0, 10); //the type of customer's object is int.
listbox.anyobj(0, 0, 20); listbox.anyobj(0, 0, 20);
5. listbox is a widget_object, with template parameters drawerbase::listbox::trigger and drawerbase::listbox::scheme
amon others.
That means that listbox have a member trigger_ constructed first and accecible with get_drawer_trigger() and
a member (unique pointer to) scheme_ accesible with scheme_type& scheme() created in the constructor
with API::dev::make_scheme<Scheme>() which call API::detail::make_scheme(::nana::detail::scheme_factory<Scheme>())
which call restrict::bedrock.make_scheme(static_cast<::nana::detail::scheme_factory_base&&>(factory));
which call pi_data_->scheme.create(std::move(factory));
which call factory.create(scheme_template(std::move(factory)));
which call (new Scheme(static_cast<Scheme&>(other)));
and which in create is setted with: API::dev::set_scheme(handle_, scheme_.get()); which save the scheme pointer in
the nana::detail::basic_window member pointer scheme
\todo doc: actualize this example listbox.at(0)... \todo doc: actualize this example listbox.at(0)...
\see nana::drawerbase::listbox::cat_proxy \see nana::drawerbase::listbox::cat_proxy
\see nana::drawerbase::listbox::item_proxy \see nana::drawerbase::listbox::item_proxy

View File

@ -1,6 +1,6 @@
/* /*
* Message Dispatcher Implementation * Message Dispatcher Implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -164,7 +164,7 @@ namespace detail
private: private:
void _m_msg_driver() void _m_msg_driver()
{ {
int fd_X11 = ConnectionNumber(display_); const int fd_X11 = ConnectionNumber(display_);
msg_packet_tag msg_pack; msg_packet_tag msg_pack;
XEvent event; XEvent event;
@ -177,6 +177,18 @@ namespace detail
if(pending) if(pending)
{ {
::XNextEvent(display_, &event); ::XNextEvent(display_, &event);
if(KeyRelease == event.type)
{
//Check whether the key is pressed, because X will send KeyRelease when pressing and
//holding a key if auto repeat is on.
char keymap[32];
::XQueryKeymap(display_, keymap);
if(keymap[event.xkey.keycode / 8] & (1 << (event.xkey.keycode % 8)))
continue;
}
if(::XFilterEvent(&event, None)) if(::XFilterEvent(&event, None))
continue; continue;
} }

View File

@ -26,8 +26,6 @@
#include <nana/gui/detail/element_store.hpp> #include <nana/gui/detail/element_store.hpp>
#include <nana/gui/detail/color_schemes.hpp> #include <nana/gui/detail/color_schemes.hpp>
#include <iostream>
#ifndef WM_MOUSEWHEEL #ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A #define WM_MOUSEWHEEL 0x020A
#endif #endif

View File

@ -28,24 +28,9 @@
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#endif #endif
namespace nana{ #include "../../paint/image_accessor.hpp"
namespace paint
{
class image_accessor
{
public:
#if defined(NANA_WINDOWS)
static HICON icon(const nana::paint::image& img)
{
auto ico = dynamic_cast<paint::detail::image_ico*>(img.image_ptr_.get());
if(ico && ico->ptr())
return *(ico->ptr());
return nullptr;
}
#endif
};
}
namespace nana{
namespace detail{ namespace detail{
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)

View File

@ -1,7 +1,7 @@
/* /*
* Implementation of Notifier * Implementation of Notifier
* Nana C++ Library(http://www.nanapro.org) * 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. * 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
@ -33,9 +33,11 @@
#include <iostream> #include <iostream>
#endif #endif
#include "../paint/image_accessor.hpp"
namespace nana namespace nana
{ {
typedef std::lock_guard<std::recursive_mutex> lock_guard; using lock_guard = std::lock_guard<std::recursive_mutex>;
struct notifier::implement struct notifier::implement
{ {
@ -47,13 +49,15 @@ namespace nana
detail::notifier_events events; detail::notifier_events events;
bool icon_added = false; bool icon_added = false;
std::size_t play_index; std::size_t play_index;
#if defined(NANA_WINDOWS)
HICON icon_handle = nullptr;
std::vector<HICON> icons;
void set_icon(HICON icon) paint::image icon;
::std::vector<paint::image> icons;
void set_icon(const paint::image& ico)
{ {
if (icon_handle) #if defined(NANA_WINDOWS)
auto ico_handle = paint::image_accessor::icon(ico);
if (ico_handle)
{ {
NOTIFYICONDATA icon_data; NOTIFYICONDATA icon_data;
memset(&icon_data, 0, sizeof icon_data); memset(&icon_data, 0, sizeof icon_data);
@ -62,13 +66,13 @@ namespace nana
icon_data.uID = id; icon_data.uID = id;
icon_data.uFlags = NIF_MESSAGE | NIF_ICON; icon_data.uFlags = NIF_MESSAGE | NIF_ICON;
icon_data.uCallbackMessage = nana::detail::messages::tray; icon_data.uCallbackMessage = nana::detail::messages::tray;
icon_data.hIcon = icon; icon_data.hIcon = ico_handle;
::Shell_NotifyIcon(icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); ::Shell_NotifyIcon(icon_added ? NIM_MODIFY : NIM_ADD, &icon_data);
icon_added = true; icon_added = true;
} }
}
#endif #endif
}
}; };
arg_notifier::operator nana::arg_mouse() const arg_notifier::operator nana::arg_mouse() const
@ -287,12 +291,6 @@ namespace nana
icon_data.hWnd = reinterpret_cast<HWND>(impl_->native_handle); icon_data.hWnd = reinterpret_cast<HWND>(impl_->native_handle);
icon_data.uID = impl_->id; icon_data.uID = impl_->id;
::Shell_NotifyIcon(NIM_DELETE, &icon_data); ::Shell_NotifyIcon(NIM_DELETE, &icon_data);
if (impl_->icon_handle)
::DestroyIcon(impl_->icon_handle);
for (auto handle : impl_->icons)
::DestroyIcon(handle);
#endif #endif
API::umake_event(impl_->evt_destroy); API::umake_event(impl_->evt_destroy);
notifications::instance().cancel(impl_->native_handle, impl_->id); notifications::instance().cancel(impl_->native_handle, impl_->id);
@ -321,30 +319,23 @@ namespace nana
void notifier::icon(const std::string& icon_file) void notifier::icon(const std::string& icon_file)
{ {
#if defined(NANA_WINDOWS) paint::image image_ico{ icon_file };
auto pre_icon = impl_->icon_handle; auto icon_handle = paint::image_accessor::icon(image_ico);
auto ico = (HICON)::LoadImageW(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); if (icon_handle)
if (ico)
{ {
impl_->icon_handle = ico;
impl_->ani_timer.stop(); impl_->ani_timer.stop();
impl_->play_index = 0; impl_->play_index = 0;
impl_->set_icon(impl_->icon_handle); impl_->set_icon(image_ico);
::DestroyIcon(pre_icon); impl_->icon = image_ico;
} }
#else
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning
#endif
} }
void notifier::insert_icon(const std::string& icon_file) void notifier::insert_icon(const std::string& icon_file)
{ {
#if defined(NANA_WINDOWS) paint::image image_ico{ icon_file };
auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); auto icon_handle = paint::image_accessor::icon(image_ico);
impl_->icons.push_back(icon); if (icon_handle)
#else impl_->icons.emplace_back(static_cast<paint::image&&>(image_ico));
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning.
#endif
} }
void notifier::period(unsigned ms) void notifier::period(unsigned ms)

View File

@ -171,7 +171,7 @@ namespace nana
if(editor_) if(editor_)
{ {
editor_->editable(enb); editor_->editable(enb);
editor_->show_caret(enb);
if (!enb) if (!enb)
{ {
editor_->ext_renderer().background = [this](graph_reference graph, const ::nana::rectangle&, const ::nana::color&) editor_->ext_renderer().background = [this](graph_reference graph, const ::nana::rectangle&, const ::nana::color&)
@ -245,7 +245,7 @@ namespace nana
void open_lister_if_push_button_positioned() void open_lister_if_push_button_positioned()
{ {
if((nullptr == state_.lister) && !items_.empty() && (parts::push_button == state_.pointer_where)) if((nullptr == state_.lister) && !items_.empty() && (!editor_->attr().editable || (parts::push_button == state_.pointer_where)))
{ {
module_.items.clear(); module_.items.clear();
std::copy(items_.cbegin(), items_.cend(), std::back_inserter(module_.items)); std::copy(items_.cbegin(), items_.cend(), std::back_inserter(module_.items));
@ -618,7 +618,7 @@ namespace nana
if(drawer_->widget_ptr()->enabled()) if(drawer_->widget_ptr()->enabled())
{ {
auto * editor = drawer_->editor(); auto * editor = drawer_->editor();
if (!editor->mouse_pressed(arg)) editor->mouse_pressed(arg);
drawer_->open_lister_if_push_button_positioned(); drawer_->open_lister_if_push_button_positioned();
drawer_->draw(); drawer_->draw();

View File

@ -13,6 +13,7 @@
* Ariel Vina-Rodriguez * Ariel Vina-Rodriguez
* leobackes(pr#86,pr#97) * leobackes(pr#86,pr#97)
* Benjamin Navarro(pr#81) * Benjamin Navarro(pr#81)
* besh81(pr#130)
* *
*/ */
@ -28,13 +29,33 @@
#include <algorithm> #include <algorithm>
#include <nana/system/dataexch.hpp> #include <nana/system/dataexch.hpp>
#include <cassert> #include <cassert>
#include <iostream> // for debug
namespace nana namespace nana
{ {
//void debug(const std::string &msg, const rectangle&r)
//{
// std::cerr <<"\n" <<msg << "(" << r.x << ", " << r.y << " (" << r.width << ", " << r.height << ") )";
//}
namespace drawerbase namespace drawerbase
{ {
namespace listbox namespace listbox
{ {
//void scheme::debug_print(const std::string &msg)
//{
//
// std::cerr << "\n " << msg;
// std::cerr << "\n max_header_width: " << max_header_width;
// std::cerr << "\n min_header_width: " << min_header_width;
// std::cerr << "\n suspension_width: " << suspension_width;
// std::cerr << "\n ext_w: " << ext_w;
// std::cerr << "\n header_height: " << header_height;
// std::cerr << "\n text_height: " << text_height;
// std::cerr << "\n item_height_ex: " << item_height_ex;
// std::cerr << "\n item_height: " << item_height;
// std::cerr << "\n header_mouse_spliter_area_before: " << header_mouse_spliter_area_before;
// std::cerr << "\n header_mouse_spliter_area_after: " << header_mouse_spliter_area_after;
//}
//struct cell //struct cell
cell::format::format(const ::nana::color& bgcolor, const ::nana::color& fgcolor) cell::format::format(const ::nana::color& bgcolor, const ::nana::color& fgcolor)
: bgcolor{ bgcolor }, fgcolor{ fgcolor } : bgcolor{ bgcolor }, fgcolor{ fgcolor }
@ -1870,10 +1891,10 @@ namespace nana
bool auto_draw{true}; bool auto_draw{true};
bool checkable{false}; bool checkable{false};
bool if_image{false}; bool if_image{false};
unsigned header_size{25}; //unsigned header_size{25};
unsigned item_size{24}; //unsigned item_size{24};
unsigned text_height{0}; //unsigned text_height{0};
unsigned suspension_width{0}; //unsigned suspension_width{0};
::nana::listbox::export_options def_exp_options; ::nana::listbox::export_options def_exp_options;
@ -1976,7 +1997,7 @@ namespace nana
size_type number_of_lister_items(bool with_rest) const 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); unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale);
return (lister_s / item_size) + (with_rest && (lister_s % item_size) ? 1 : 0); return (lister_s / scheme_ptr->item_height) + (with_rest && (lister_s % scheme_ptr->item_height) ? 1 : 0);
} }
//keep the first selected item in the display area: the distances are in display positions! //keep the first selected item in the display area: the distances are in display positions!
@ -2093,10 +2114,10 @@ namespace nana
window wd = lister.wd_ptr()->handle(); window wd = lister.wd_ptr()->handle();
//H scroll enabled //H scroll enabled
bool h = (header_s > sz.width - 4); bool h = (header_s + 4 > sz.width ); // 4?
unsigned head_scroll = 2 + header_visible_px() + (h ? scroll.scale : 0); // 2?
unsigned lister_s = sz.height - 2 - header_visible_px() - (h ? scroll.scale : 0); unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0 ;
size_type screen_number = (lister_s / item_size); size_type screen_number = (lister_s / scheme_ptr->item_height);
//V scroll enabled //V scroll enabled
bool v = (lister.the_number_of_expanded() > screen_number); bool v = (lister.the_number_of_expanded() > screen_number);
@ -2128,7 +2149,7 @@ namespace nana
if(h) if(h)
{ {
rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); rectangle r(1, sz.height - scroll.scale - 1, width, scroll.scale); // -?
if(scroll.h.empty()) if(scroll.h.empty())
{ {
scroll.h.create(wd, r); scroll.h.create(wd, r);
@ -2143,7 +2164,7 @@ namespace nana
if(v) if(v)
{ {
rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); rectangle r(sz.width - 1 - scroll.scale, 1, scroll.scale, height); // -?
if(scroll.v.empty()) if(scroll.v.empty())
{ {
scroll.v.create(wd, r); scroll.v.create(wd, r);
@ -2164,7 +2185,7 @@ namespace nana
{ {
if(header_s > r.width) if(header_s > r.width)
{ {
if((header_s - scroll.offset_x) < r.width) if(header_s < r.width - scroll.offset_x)
scroll.offset_x = header_s - r.width; scroll.offset_x = header_s - r.width;
} }
else else
@ -2187,9 +2208,9 @@ namespace nana
} }
} }
nana::rectangle checkarea(int x, int y) const nana::rectangle checkarea(int x, int y) const /// move to scheme ?? 16 ?
{ {
return nana::rectangle(x + 4, y + (item_size - 16) / 2, 16, 16); return nana::rectangle(x + 4, y + (static_cast<int>(scheme_ptr->item_height) - 16) / 2, 16, 16);
} }
int item_xpos(const nana::rectangle& r) const int item_xpos(const nana::rectangle& r) const
@ -2203,23 +2224,25 @@ namespace nana
std::pair<parts, size_t> new_where; 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) if(2 < x && x < static_cast<int>(graph->width()) - 2 && 1 < y && y < static_cast<int>(graph->height()) - 1)
{ { /// we are inside
if(header.visible() && y < static_cast<int>(header_size + 1))
{ if(header.visible() && y < static_cast<int>(scheme_ptr->header_height + 1))
{ /// we are in the header
x -= (2 - scroll.offset_x); x -= (2 - scroll.offset_x);
new_where.first = parts::header; new_where.first = parts::header;
new_where.second = static_cast<int>(header.item_by_x(x)); new_where.second = header.item_by_x(x);
} }
else else
{ {
new_where.second = ((y + 1) - header_visible_px()) / item_size; // y>1 ! new_where.second = ((y + 1) - header_visible_px()) / scheme_ptr->item_height; // y>1 !
new_where.first = parts::lister; new_where.first = parts::lister;
if(checkable) if(checkable)
{ {
nana::rectangle r; nana::rectangle r;
if(rect_lister(r)) if(rect_lister(r))
{ {
std::size_t top = new_where.second * item_size + header_visible_px(); std::size_t top = new_where.second * scheme_ptr->item_height + header_visible_px();
if(checkarea(item_xpos(r), static_cast<int>(top)).is_hit(x, y)) if(checkarea(item_xpos(r), static_cast<int>(top)).is_hit(x, y))
new_where.first = parts::checker; new_where.first = parts::checker;
} }
@ -2247,7 +2270,7 @@ namespace nana
void widget_to_header(nana::point& pos) void widget_to_header(nana::point& pos)
{ {
--pos.y; --pos.y;
pos.x += (scroll.offset_x - 2); pos.x += (scroll.offset_x - 2); // why not: pos.x -= (scroll.offset_x + 1);
} }
bool rect_header(nana::rectangle& r) const bool rect_header(nana::rectangle& r) const
@ -2257,7 +2280,7 @@ namespace nana
if (lister.wd_ptr()->borderless()) if (lister.wd_ptr()->borderless())
{ {
r = graph->size(); r = graph->size();
r.height = header_size; r.height = scheme_ptr->header_height;
return !r.empty(); return !r.empty();
} }
@ -2267,7 +2290,7 @@ namespace nana
r.x = 2; r.x = 2;
r.y = 1; r.y = 1;
r.width = graph->width() - ex_width; r.width = graph->width() - ex_width;
r.height = header_size; r.height = scheme_ptr->header_height;
return true; return true;
} }
} }
@ -2276,7 +2299,7 @@ namespace nana
unsigned header_visible_px() const unsigned header_visible_px() const
{ {
return (header.visible() ? header_size : 0); return (header.visible() ? scheme_ptr->header_height : 0);
} }
bool rect_lister(nana::rectangle& r) const bool rect_lister(nana::rectangle& r) const
@ -2314,9 +2337,9 @@ namespace nana
index_pair target; index_pair target;
if(upwards == false) if(upwards == false)
lister.forward(scroll.offset_y_dpl, 1, target); lister.forward(scroll.offset_y_dpl, 3, target); // scheme ??
else else
lister.backward(scroll.offset_y_dpl, 1, target); lister.backward(scroll.offset_y_dpl, 3, target);
if (target == scroll.offset_y_dpl) if (target == scroll.offset_y_dpl)
return false; return false;
@ -2342,8 +2365,9 @@ namespace nana
return seqs; return seqs;
} }
unsigned auto_width(size_type pos, unsigned max = 3000) /// \todo introduce parametr max_header_width unsigned auto_width(size_type pos, unsigned max = 100000)
{ {
max = (std::min)(max, scheme_ptr->max_header_width);
unsigned max_w{ 0 }; unsigned max_w{ 0 };
for (const auto &cat : lister.cat_container()) for (const auto &cat : lister.cat_container())
for (const auto &it : cat.items) for (const auto &it : cat.items)
@ -2358,8 +2382,8 @@ namespace nana
unsigned ext_w = scheme_ptr->ext_w; unsigned ext_w = scheme_ptr->ext_w;
if (pos == 0 && checkable) // only before the first column (display_order=0 ?) if (pos == 0 && checkable) // only before the first column (display_order=0 ?)
ext_w += 18; ext_w += 18; // add to geom. scheme (width of the checker) ??
header.item_width(pos, max_w + ext_w + 1 < max ? max_w + ext_w + 1 : max); header.item_width(pos, (std::min)(max, max_w + ext_w + 1 ));
return max_w; return max_w;
} }
@ -2685,7 +2709,8 @@ namespace nana
{ {
if(hd.visible) if(hd.visible)
{ {
if((static_cast<int>(hd.pixels) < x + 2) && (x < static_cast<int>(hd.pixels) + 3)) if(( static_cast<int>(hd.pixels) < x + static_cast<int>(essence_->scheme_ptr->header_mouse_spliter_area_before))
&& (x < static_cast<int>(hd.pixels) + static_cast<int>(essence_->scheme_ptr->header_mouse_spliter_area_after)) )
{ {
item_spliter_ = hd.index; // original index item_spliter_ = hd.index; // original index
return true; return true;
@ -2732,7 +2757,10 @@ namespace nana
auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); auto new_w = orig_item_width_ - (ref_xpos_ - pos.x);
if(item.pixels != new_w) if(item.pixels != new_w)
{ {
essence_->header.item_width(item_spliter_, (new_w < (essence_->suspension_width + 20) ? essence_->suspension_width + 20 : new_w)); essence_->header.item_width(item_spliter_,
(new_w < ( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width) ?
( essence_->scheme_ptr->suspension_width + essence_->scheme_ptr->min_header_width)
: new_w) );
new_w = essence_->header.pixels(); new_w = essence_->header.pixels();
if(new_w < (rect.width + essence_->scroll.offset_x)) if(new_w < (rect.width + essence_->scroll.offset_x))
essence_->scroll.offset_x = (new_w > rect.width ? new_w - rect.width : 0); essence_->scroll.offset_x = (new_w > rect.width ? new_w - rect.width : 0);
@ -2748,7 +2776,7 @@ namespace nana
{ {
graph_reference graph = *(essence_->graph); graph_reference graph = *(essence_->graph);
int text_top = (r.height - essence_->text_height) / 2 + r.y; int text_top = (r.height - essence_->scheme_ptr->text_height) / 2 + r.y;
auto text_color = essence_->lister.wd_ptr()->fgcolor(); auto text_color = essence_->lister.wd_ptr()->fgcolor();
auto state = item_state::normal; auto state = item_state::normal;
@ -2834,13 +2862,13 @@ namespace nana
} }
graph.gradual_rectangle({ x, y, item.pixels, height }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true); graph.gradual_rectangle({ x, y, item.pixels, height }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true);
graph.string({ x + 5, txtop }, item.text, fgcolor); graph.string({ x + static_cast<int>(essence_->scheme_ptr->ext_w), txtop }, item.text, fgcolor);
if(item.index == essence_->lister.sort_index()) if(item.index == essence_->lister.sort_index())
{ {
facade<element::arrow> arrow("hollow_triangle"); facade<element::arrow> arrow("hollow_triangle");
arrow.direction(essence_->lister.sort_reverse() ? ::nana::direction::south : ::nana::direction::north); arrow.direction(essence_->lister.sort_reverse() ? ::nana::direction::south : ::nana::direction::north);
arrow.draw(graph, {}, colors::black, { x + static_cast<int>(item.pixels - 16) / 2, -4, 16, 16 }, element_state::normal); arrow.draw(graph, {}, colors::black, { x + (static_cast<int>(item.pixels) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme?
} }
} }
@ -2848,11 +2876,11 @@ namespace nana
{ {
const auto & item = essence_->header.column(essence_->pointer_where.second); const auto & item = essence_->header.column(essence_->pointer_where.second);
nana::paint::graphics ext_graph({ item.pixels, essence_->header_size }); nana::paint::graphics ext_graph({ item.pixels, essence_->scheme_ptr->header_height });
ext_graph.typeface(essence_->graph->typeface()); ext_graph.typeface(essence_->graph->typeface());
int txtop = (essence_->header_size - essence_->text_height) / 2; int txtop = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2;
_m_draw_header_item(ext_graph, 0, 0, essence_->header_size, txtop, colors::white, item, item_state::floated); _m_draw_header_item(ext_graph, 0, 0, essence_->scheme_ptr->header_height, txtop, colors::white, item, item_state::floated);
int xpos = essence_->header.item_pos(item.index, nullptr) + pos.x - ref_xpos_; int xpos = essence_->header.item_pos(item.index, nullptr) + pos.x - ref_xpos_;
ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5);
@ -2890,11 +2918,11 @@ namespace nana
auto bgcolor = wdptr->bgcolor(); auto bgcolor = wdptr->bgcolor();
auto fgcolor = wdptr->fgcolor(); auto fgcolor = wdptr->fgcolor();
unsigned header_w = essence_->header.pixels(); int header_w = essence_->header.pixels();
essence_->graph->palette(false, bgcolor); essence_->graph->palette(false, bgcolor);
if(header_w - essence_->scroll.offset_x < rect.width) if( header_w - essence_->scroll.offset_x < static_cast<int>(rect.width) )
essence_->graph->rectangle(rectangle{ point(rect.x + static_cast<int>(header_w)-essence_->scroll.offset_x, rect.y), essence_->graph->rectangle(rectangle{ point(rect.x + header_w -essence_->scroll.offset_x, rect.y),
size(static_cast<int>(rect.width) + essence_->scroll.offset_x - static_cast<int>(header_w), rect.height) }, size(static_cast<int>(rect.width) + essence_->scroll.offset_x - header_w , rect.height) },
true); true);
es_lister & lister = essence_->lister; es_lister & lister = essence_->lister;
@ -2913,7 +2941,7 @@ namespace nana
int x = essence_->item_xpos(rect); int x = essence_->item_xpos(rect);
int y = rect.y; int y = rect.y;
int txtoff = (essence_->item_size - essence_->text_height) / 2; int txtoff = (essence_->scheme_ptr->item_height - essence_->scheme_ptr->text_height) / 2;
auto i_categ = lister.get(essence_->scroll.offset_y_dpl.cat); auto i_categ = lister.get(essence_->scroll.offset_y_dpl.cat);
@ -2950,7 +2978,7 @@ namespace nana
item_index = lister.absolute_pair(item_index); item_index = lister.absolute_pair(item_index);
_m_draw_item(*i_categ, item_index, x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state); _m_draw_item(*i_categ, item_index, x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state);
y += essence_->item_size; y += essence_->scheme_ptr->item_height;
} }
++i_categ; ++i_categ;
@ -2965,7 +2993,7 @@ namespace nana
state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal); state = (tracker.is_category() && (idx.cat == tracker.cat) ? item_state::highlighted : item_state::normal);
_m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state); _m_draw_categ(*i_categ, rect.x - essence_->scroll.offset_x, y, txtoff, header_w, rect, bgcolor, state);
y += essence_->item_size; y += essence_->scheme_ptr->item_height;
if(false == i_categ->expand) if(false == i_categ->expand)
continue; continue;
@ -2981,7 +3009,7 @@ namespace nana
item_pos.item = lister.absolute(item_pos); item_pos.item = lister.absolute(item_pos);
_m_draw_item(*i_categ, item_pos, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); _m_draw_item(*i_categ, item_pos, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state);
y += essence_->item_size; y += essence_->scheme_ptr->item_height;
++idx.item; ++idx.item;
} }
} }
@ -3002,14 +3030,14 @@ namespace nana
bgcolor = bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8); bgcolor = bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8);
auto graph = essence_->graph; auto graph = essence_->graph;
graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true, bgcolor); graph->rectangle(rectangle{ x, y, width, essence_->scheme_ptr->item_height }, true, bgcolor);
color txt_color{ static_cast<color_rgb>(0x3399) }; color txt_color{ static_cast<color_rgb>(0x3399) };
facade<element::arrow> arrow("double"); facade<element::arrow> arrow("double");
arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south); arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south);
arrow.draw( *graph, {}, txt_color, arrow.draw( *graph, {}, txt_color,
{ x + 5, y + static_cast<int>(essence_->item_size - 16) / 2, 16, 16 }, { x + 5, y + static_cast<int>(essence_->scheme_ptr->item_height - 16) / 2, 16, 16 },
element_state::normal); element_state::normal);
graph->string({ x + 20, y + txtoff }, categ.text, txt_color); graph->string({ x + 20, y + txtoff }, categ.text, txt_color);
@ -3023,7 +3051,7 @@ namespace nana
if (x + 35 + extend_text_w < x + width) if (x + 35 + extend_text_w < x + width)
{ {
::nana::point pos{ x + 30 + static_cast<int>(extend_text_w), y + static_cast<int>(essence_->item_size) / 2 }; ::nana::point pos{ x + 30 + static_cast<int>(extend_text_w), y + static_cast<int>(essence_->scheme_ptr->item_height) / 2 };
graph->line(pos, { x + static_cast<int>(width)-5, pos.y }, txt_color); graph->line(pos, { x + static_cast<int>(width)-5, pos.y }, txt_color);
} }
@ -3038,12 +3066,12 @@ namespace nana
/// Draws an item /// Draws an item
void _m_draw_item(const category_t& cat, void _m_draw_item(const category_t& cat,
const index_pair& item_pos, const index_pair& item_pos,
const int x, const int x, ///< left coordinate ?
const int y, const int y, ///< top coordinate
const int txtoff, const int txtoff, ///< below y to print the text
unsigned width, unsigned width,
const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn
const std::vector<size_type>& seqs, const std::vector<size_type>& seqs, ///< columns to print
nana::color bgcolor, nana::color bgcolor,
nana::color fgcolor, nana::color fgcolor,
item_state state item_state state
@ -3067,15 +3095,15 @@ namespace nana
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend 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; unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.offset_x);
if(show_w >= content_r.width) show_w = content_r.width;
auto graph = essence_->graph; auto graph = essence_->graph;
//draw the background
graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->item_size }, true, bgcolor); //draw the background for the whole item
graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->scheme_ptr->item_height }, true, bgcolor);
int item_xpos = x; int item_xpos = x;
unsigned extreme_text = x; int extreme_text = x;
for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed
{ {
@ -3083,16 +3111,16 @@ namespace nana
const auto & header = essence_->header.column(column_pos); // deduce the corresponding header which is in a kind of dislay order const auto & header = essence_->header.column(column_pos); // deduce the corresponding header which is in a kind of dislay order
auto it_bgcolor = bgcolor; auto it_bgcolor = bgcolor;
if (header.pixels > 5) if (header.pixels > essence_->scheme_ptr->ext_w )
{ {
int content_pos = 5; int content_pos = essence_->scheme_ptr->ext_w;
//Draw the image in the 1st column in display order //Draw the image in the 1st column in display order
if (0 == display_order) if (0 == display_order)
{ {
if (essence_->checkable) if (essence_->checkable)
{ {
content_pos += 18; content_pos += 18; // checker width, geom scheme?
element_state estate = element_state::normal; element_state estate = element_state::normal;
if (essence_->pointer_where.first == parts::checker) if (essence_->pointer_where.first == parts::checker)
@ -3118,17 +3146,17 @@ namespace nana
if (item.img) if (item.img)
{ {
nana::rectangle img_r(item.img_show_size); nana::rectangle img_r(item.img_show_size);
img_r.x = content_pos + item_xpos + static_cast<int>(16 - item.img_show_size.width) / 2; img_r.x = content_pos + item_xpos + (16 - static_cast<int>(item.img_show_size.width)) / 2; // center in 16 - geom scheme?
img_r.y = y + static_cast<int>(essence_->item_size - item.img_show_size.height) / 2; img_r.y = y + (static_cast<int>(essence_->scheme_ptr->item_height) - static_cast<int>(item.img_show_size.height)) / 2; // center
item.img.stretch(rectangle{ item.img.size() }, *graph, img_r); item.img.stretch(rectangle{ item.img.size() }, *graph, img_r);
} }
content_pos += 18; content_pos += 18; // image width, geom scheme?
} }
} }
bool draw_column = true; bool draw_column = true;
if (static_cast<unsigned>(content_pos) < header.pixels) if ( content_pos < static_cast<int>(header.pixels)) // we have room
{ {
auto inline_wdg = _m_get_inline_pane(cat, column_pos); auto inline_wdg = _m_get_inline_pane(cat, column_pos);
if (inline_wdg) if (inline_wdg)
@ -3139,7 +3167,7 @@ namespace nana
auto wdg_w = header.pixels - static_cast<unsigned>(content_pos); auto wdg_w = header.pixels - static_cast<unsigned>(content_pos);
bool visible_state = true; bool visible_state = true;
if (::nana::overlap(content_r, { wdg_x, y, wdg_w, essence_->item_size }, pane_r)) if (::nana::overlap(content_r, { wdg_x, y, wdg_w, essence_->scheme_ptr->item_height }, pane_r))
{ {
::nana::point pane_pos; ::nana::point pane_pos;
if (wdg_x < content_r.x) if (wdg_x < content_r.x)
@ -3154,7 +3182,7 @@ namespace nana
else else
visible_state = false; visible_state = false;
::nana::size sz{ wdg_w, essence_->item_size }; ::nana::size sz{ wdg_w, essence_->scheme_ptr->item_height };
inline_wdg->pane_widget.size(sz); inline_wdg->pane_widget.size(sz);
inline_wdg->inline_ptr->resize(sz); inline_wdg->inline_ptr->resize(sz);
@ -3201,7 +3229,7 @@ namespace nana
if (item_state::highlighted == state) if (item_state::highlighted == state)
it_bgcolor = it_bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8); it_bgcolor = it_bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8);
graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->item_size }, true, it_bgcolor); graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->scheme_ptr->item_height }, true, it_bgcolor);
cell_txtcolor = m_cell.custom_format->fgcolor; cell_txtcolor = m_cell.custom_format->fgcolor;
} }
@ -3210,35 +3238,37 @@ namespace nana
{ {
graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text, cell_txtcolor); // draw full text of the cell index (column) graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text, cell_txtcolor); // draw full text of the cell index (column)
if (static_cast<int>(ts.width) > static_cast<int>(header.pixels) - (content_pos + item_xpos)) // it was an excess int item_right = item_xpos + static_cast<int>(header.pixels);
int text_right = item_xpos + content_pos + static_cast<int>(ts.width);
int excess = text_right - item_right ;
if (excess > 0) // it was an excess
{ {
//The text is painted over the next subitem // here beging the ... //The text is painted over the next subitem // here beging the ...
int xpos = item_xpos + static_cast<int>(header.pixels) - static_cast<int>(essence_->suspension_width); int xpos = item_right - static_cast<int>(essence_->scheme_ptr->suspension_width);
// litter rect with the item bg end ... // litter rect with the item bg end ...
graph->rectangle(rectangle{ xpos, y + 2, essence_->suspension_width, essence_->item_size - 4 }, true, it_bgcolor); graph->rectangle(rectangle{ xpos, y /*+ 2*/, essence_->scheme_ptr->suspension_width, essence_->scheme_ptr->item_height /*- 4*/ }, true, it_bgcolor);
graph->string(point{ xpos, y + 2 }, L"..."); graph->string(point{ xpos, y /*+ 2*/ }, L"...");
//Erase the part that over the next subitem only if the right of column is less than right of listbox //Erase the part that over the next subitem only if the right of column is less than right of listbox
if (item_xpos + content_pos < content_r.right() - static_cast<int>(header.pixels)) if (item_right < content_r.right() )
{ {
graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over
graph->rectangle(rectangle{ item_xpos + static_cast<int>(header.pixels), y + 2, graph->rectangle(rectangle( item_right, y /*+ 2*/, excess, essence_->scheme_ptr->item_height /*- 4*/ ), true);
ts.width + static_cast<unsigned>(content_pos)-header.pixels, essence_->item_size - 4 }, true);
} }
extreme_text = (std::max)(extreme_text, item_xpos + content_pos + ts.width); extreme_text = (std::max)(extreme_text, text_right);
} }
} }
} }
graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast<int>(essence_->item_size) - 1 }, static_cast<color_rgb>(0xEBF4F9)); graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast<int>(essence_->scheme_ptr->item_height) - 1 }, static_cast<color_rgb>(0xEBF4F9));
} }
item_xpos += static_cast<int>(header.pixels); item_xpos += static_cast<int>(header.pixels);
if (display_order + 1 >= seqs.size() && static_cast<int>(extreme_text) > item_xpos) if (display_order + 1 >= seqs.size() && extreme_text > item_xpos)
{ {
graph->rectangle(rectangle{item_xpos , y + 2, extreme_text - item_xpos, essence_->item_size - 4}, true, item.bgcolor); graph->rectangle(rectangle(item_xpos , y /*+ 2*/, extreme_text - item_xpos, essence_->scheme_ptr->item_height /*- 4*/), true, item.bgcolor);
} }
} }
@ -3285,13 +3315,13 @@ namespace nana
{ {
//Draw selecting inner rectangle //Draw selecting inner rectangle
auto graph = essence_->graph; auto graph = essence_->graph;
graph->rectangle({ x, y, width, essence_->item_size }, false, static_cast<color_rgb>(0x99defd)); graph->rectangle({ x, y, width, essence_->scheme_ptr->item_height }, false, static_cast<color_rgb>(0x99defd));
graph->rectangle({ x + 1, y + 1, width - 2, essence_->item_size - 2 }, false, colors::white); graph->rectangle({ x + 1, y + 1, width - 2, essence_->scheme_ptr->item_height - 2 }, false, colors::white);
graph->set_pixel(x, y); graph->set_pixel(x, y);
graph->set_pixel(x, y + essence_->item_size - 1); graph->set_pixel(x, y + essence_->scheme_ptr->item_height - 1);
graph->set_pixel(x + width - 1, y); graph->set_pixel(x + width - 1, y);
graph->set_pixel(x + width - 1, y + essence_->item_size - 1); graph->set_pixel(x + width - 1, y + essence_->scheme_ptr->item_height - 1);
} }
private: private:
essence_t * essence_; essence_t * essence_;
@ -3340,6 +3370,7 @@ namespace nana
void trigger::attached(widget_reference widget, graph_reference graph) void trigger::attached(widget_reference widget, graph_reference graph)
{ {
essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));
essence_->graph = &graph; essence_->graph = &graph;
typeface_changed(graph); typeface_changed(graph);
@ -3354,9 +3385,9 @@ namespace nana
void trigger::typeface_changed(graph_reference graph) void trigger::typeface_changed(graph_reference graph)
{ {
essence_->text_height = graph.text_extent_size(L"jHWn0123456789/<?'{[|\\_").height; essence_->scheme_ptr->text_height = graph.text_extent_size(L"jHWn0123456789/<?'{[|\\_").height;
essence_->item_size = essence_->text_height + 6; essence_->scheme_ptr->item_height = essence_->scheme_ptr->text_height + essence_->scheme_ptr->item_height_ex;
essence_->suspension_width = graph.text_extent_size(L"...").width; essence_->scheme_ptr->suspension_width = graph.text_extent_size("...").width;
} }
void trigger::refresh(graph_reference) void trigger::refresh(graph_reference)
@ -3366,10 +3397,18 @@ namespace nana
nana::rectangle r; nana::rectangle r;
//essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) ");
if (essence_->header.visible() && essence_->rect_header(r)) if (essence_->header.visible() && essence_->rect_header(r))
drawer_header_->draw(r); drawer_header_->draw(r);
//debug("Header: ", r);
if (essence_->rect_lister(r)) if (essence_->rect_lister(r))
drawer_lister_->draw(r); drawer_lister_->draw(r);
//debug("Lister: ", r);
_m_draw_border(); _m_draw_border();
} }
@ -3558,7 +3597,6 @@ namespace nana
} }
} }
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) void trigger::mouse_up(graph_reference graph, const arg_mouse& arg)
{ {
using item_state = essence_t::item_state; using item_state = essence_t::item_state;
@ -4354,12 +4392,12 @@ namespace nana
{ {
} }
void arg_listbox_category::block_category_change() const noexcept void arg_category::block_category_change() const noexcept
{ {
block_change_ = true; block_change_ = true;
} }
bool arg_listbox_category::category_change_blocked() const noexcept bool arg_category::category_change_blocked() const noexcept
{ {
return block_change_; return block_change_;
} }

View File

@ -1370,24 +1370,8 @@ namespace nana
return; return;
} }
} }
bool popup = false;
switch(mouse_) if((mouse::any_button == mouse_) || (mouse_ == arg.button))
{
case mouse::left_button:
popup = arg.left_button;
break;
case mouse::middle_button:
popup = arg.mid_button;
break;
case mouse::right_button:
popup = arg.right_button;
break;
case mouse::any_button:
popup = true;
default:
break;
}
if(popup)
mobj_.popup(owner_, pos_.x, pos_.y); mobj_.popup(owner_, pos_.x, pos_.y);
} }
//end class //end class

View File

@ -485,7 +485,8 @@ namespace nana{ namespace widgets
std::size_t _m_textline_from_screen(int y) const std::size_t _m_textline_from_screen(int y) const
{ {
const std::size_t textlines = editor_.textbase_.lines(); const std::size_t textlines = editor_.textbase_.lines();
if (0 == textlines) const auto line_px = static_cast<int>(editor_.line_height());
if ((0 == textlines) || (0 == line_px))
return 0; return 0;
const int offset_top = editor_.points_.offset.y; const int offset_top = editor_.points_.offset.y;
@ -494,7 +495,7 @@ namespace nana{ namespace widgets
if (y < text_area_top) if (y < text_area_top)
y = offset_top ? offset_top - 1 : 0; y = offset_top ? offset_top - 1 : 0;
else else
y = (y - text_area_top) / static_cast<int>(editor_.line_height()) + offset_top; y = (y - text_area_top) / line_px + offset_top;
return (textlines <= static_cast<std::size_t>(y) ? textlines - 1 : static_cast<std::size_t>(y)); return (textlines <= static_cast<std::size_t>(y) ? textlines - 1 : static_cast<std::size_t>(y));
} }
@ -1115,28 +1116,24 @@ namespace nana{ namespace widgets
//secondary, index of line that the text was splitted into multilines. //secondary, index of line that the text was splitted into multilines.
std::size_t _m_textline_from_screen(int y, std::size_t & secondary) const std::size_t _m_textline_from_screen(int y, std::size_t & secondary) const
{ {
const int text_area_top = editor_.text_area_.area.y; const auto line_px = static_cast<int>(editor_.line_height());
const int offset_top = editor_.points_.offset.y;
if (0 == editor_.textbase_.lines()) if ((0 == editor_.textbase_.lines()) || (0 == line_px))
{ {
secondary = 0; secondary = 0;
return 0; return 0;
} }
std::size_t screen_line; const int text_area_top = editor_.text_area_.area.y;
if (y < text_area_top) const int offset_top = editor_.points_.offset.y;
{
screen_line = (text_area_top - y) / static_cast<int>(editor_.line_height()); auto screen_line = (text_area_top - y) / line_px;
if (screen_line > static_cast<std::size_t>(offset_top)) if ((y < text_area_top) && (screen_line > offset_top))
screen_line = 0; screen_line = 0;
else else
screen_line = static_cast<std::size_t>(offset_top)-screen_line; screen_line = offset_top - screen_line;
}
else
screen_line = static_cast<std::size_t>((y - text_area_top) / static_cast<int>(editor_.line_height()) + offset_top);
auto primary = _m_textline(screen_line, secondary); auto primary = _m_textline(static_cast<std::size_t>(screen_line), secondary);
if (primary < linemtr_.size()) if (primary < linemtr_.size())
return primary; return primary;
@ -1690,11 +1687,14 @@ namespace nana{ namespace widgets
bool text_editor::mouse_move(bool left_button, const point& scrpos) bool text_editor::mouse_move(bool left_button, const point& scrpos)
{ {
cursor cur = cursor::iterm; cursor cur = cursor::iterm;
if ((!hit_text_area(scrpos)) && (!text_area_.captured)) if(((!hit_text_area(scrpos)) && (!text_area_.captured)) || !attributes_.editable || !API::window_enabled(window_))
cur = cursor::arrow; cur = cursor::arrow;
API::window_cursor(window_, cur); API::window_cursor(window_, cur);
if(!attributes_.editable)
return false;
if(left_button) if(left_button)
{ {
mouse_caret(scrpos); mouse_caret(scrpos);
@ -1710,6 +1710,9 @@ namespace nana{ namespace widgets
bool text_editor::mouse_pressed(const arg_mouse& arg) bool text_editor::mouse_pressed(const arg_mouse& arg)
{ {
if(!attributes_.editable)
return false;
if (event_code::mouse_down == arg.evt_code) if (event_code::mouse_down == arg.evt_code)
{ {
if (select_.ignore_press || (!hit_text_area(arg.pos))) if (select_.ignore_press || (!hit_text_area(arg.pos)))
@ -1872,6 +1875,9 @@ namespace nana{ namespace widgets
reset_caret_pixels(); reset_caret_pixels();
} }
if(!attributes_.editable)
visible = false;
API::caret_visible(window_, visible); API::caret_visible(window_, visible);
if(visible) if(visible)
@ -3195,7 +3201,7 @@ namespace nana{ namespace widgets
graph_.palette(false, scheme_->selection.get_color()); graph_.palette(false, scheme_->selection.get_color());
//The text is not selected or the whole line text is selected //The text is not selected or the whole line text is selected
if (!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y)) if(!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y) || !attributes_.editable)
{ {
bool selected = (a.y < str_pos.y && str_pos.y < b.y); bool selected = (a.y < str_pos.y && str_pos.y < b.y);
for (auto & ent : reordered) for (auto & ent : reordered)

View File

@ -34,10 +34,27 @@
#include "detail/image_bmp.hpp" #include "detail/image_bmp.hpp"
#include "detail/image_ico.hpp" #include "detail/image_ico.hpp"
#include "image_accessor.hpp"
namespace nana namespace nana
{ {
namespace paint namespace paint
{ {
#if defined(NANA_WINDOWS)
HICON image_accessor::icon(const nana::paint::image& img)
{
auto ico = dynamic_cast<paint::detail::image_ico*>(img.image_ptr_.get());
if (ico && ico->ptr())
return *(ico->ptr());
return nullptr;
}
#else
int image_accessor::icon(const image&)
{
return 0;
}
#endif
namespace detail namespace detail
{ {
//class image_ico //class image_ico

View File

@ -0,0 +1,30 @@
/*
* Paint Image Accessor
* Nana C++ Library(http://www.nanapro.org)
* 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
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file nana/paint/image_accessor.hpp
* @brief A declaration of class image_accessor. It is used to access image private data, internal use.
*/
#ifndef NANA_PAINT_IMAGE_ACCESS_HEADER_INCLUDED
#define NANA_PAINT_IMAGE_ACCESS_HEADER_INCLUDED
namespace nana
{
namespace paint
{
class image_accessor
{
public:
#if defined(NANA_WINDOWS)
static HICON icon(const image&);
#else
static int icon(const image&);
#endif
};
}
}
#endif