From e7b8e603e4a77a69194dbaccc3cd9b9c9ba71c81 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 21:02:40 +0200 Subject: [PATCH 01/19] using geometric_scheme --- include/nana/gui/widgets/listbox.hpp | 27 +++++-- source/gui/widgets/listbox.cpp | 109 ++++++++++++++------------- 2 files changed, 77 insertions(+), 59 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index cfad6214..9ed36a89 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -532,14 +532,14 @@ namespace nana /// \todo how to implement some geometrical parameters ?? unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this unsigned min_header_width{ 20 }; ///< non counting suspension_width - unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...") - unsigned ext_w { 5 }; ///< ?? - unsigned header_height { 20 }; ///< header height header_size - unsigned text_height { 0 }; ///< 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 { 0 }; ///< 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_after { 3 }; + unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") + unsigned ext_w { 5 }; ///< def= . ?? + unsigned header_height { 20 }; ///< def= . header height header_size + unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font + unsigned item_height_ex { 2 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex + unsigned item_height { 16 }; ///< the trigger will set this TO item_height = text_height + item_height_ex + unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 + unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 }; } @@ -586,6 +586,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, 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() which call API::detail::make_scheme(::nana::detail::scheme_factory()) +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(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)... \see nana::drawerbase::listbox::cat_proxy \see nana::drawerbase::listbox::item_proxy diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 707eb339..3fde21a8 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1845,10 +1845,10 @@ namespace nana bool auto_draw{true}; bool checkable{false}; bool if_image{false}; - unsigned header_size{25}; - unsigned item_size{24}; - unsigned text_height{0}; - unsigned suspension_width{0}; + //unsigned header_size{25}; + //unsigned item_size{24}; + //unsigned text_height{0}; + //unsigned suspension_width{0}; ::nana::listbox::export_options def_exp_options; @@ -1951,7 +1951,7 @@ namespace nana 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); - 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! @@ -2068,10 +2068,10 @@ namespace nana window wd = lister.wd_ptr()->handle(); //H scroll enabled - bool h = (header_s > sz.width - 4); - - unsigned lister_s = sz.height - 2 - header_visible_px() - (h ? scroll.scale : 0); - size_type screen_number = (lister_s / item_size); + 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 > head_scroll ? sz.height - head_scroll : 0 ; + size_type screen_number = (lister_s / scheme_ptr->item_height); //V scroll enabled bool v = (lister.the_number_of_expanded() > screen_number); @@ -2164,7 +2164,7 @@ namespace nana nana::rectangle checkarea(int x, int y) const { - return nana::rectangle(x + 4, y + (item_size - 16) / 2, 16, 16); + return nana::rectangle(x + 4, y + (static_cast(scheme_ptr->item_height) - 16) / 2, 16, 16); } int item_xpos(const nana::rectangle& r) const @@ -2178,23 +2178,25 @@ namespace nana std::pair new_where; if(2 < x && x < static_cast(graph->width()) - 2 && 1 < y && y < static_cast(graph->height()) - 1) - { - if(header.visible() && y < static_cast(header_size + 1)) - { + { /// we are inside + + if(header.visible() && y < static_cast(scheme_ptr->header_height + 1)) + { /// we are in the header + x -= (2 - scroll.offset_x); new_where.first = parts::header; new_where.second = static_cast(header.item_by_x(x)); } 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; if(checkable) { nana::rectangle 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(top)).is_hit(x, y)) new_where.first = parts::checker; } @@ -2222,7 +2224,7 @@ namespace nana void widget_to_header(nana::point& pos) { --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 @@ -2232,7 +2234,7 @@ namespace nana if (lister.wd_ptr()->borderless()) { r = graph->size(); - r.height = header_size; + r.height = scheme_ptr->header_height; return !r.empty(); } @@ -2242,7 +2244,7 @@ namespace nana r.x = 2; r.y = 1; r.width = graph->width() - ex_width; - r.height = header_size; + r.height = scheme_ptr->header_height; return true; } } @@ -2251,7 +2253,7 @@ namespace nana 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 @@ -2317,8 +2319,9 @@ namespace nana 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 }; for (const auto &cat : lister.cat_container()) for (const auto &it : cat.items) @@ -2660,7 +2663,8 @@ namespace nana { if(hd.visible) { - if((static_cast(hd.pixels) < x + 2) && (x < static_cast(hd.pixels) + 3)) + if(( static_cast(hd.pixels) < x + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_before)) + && (x < static_cast(hd.pixels) + static_cast(essence_->scheme_ptr->header_mouse_spliter_area_after)) ) { item_spliter_ = hd.index; // original index return true; @@ -2670,7 +2674,7 @@ namespace nana } } else if(essence_->ptr_state == item_state::normal) - item_spliter_ = npos; + item_spliter_ = npos; return false; } @@ -2707,7 +2711,10 @@ namespace nana auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); 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(); if(new_w < (rect.width + essence_->scroll.offset_x)) essence_->scroll.offset_x = (new_w > rect.width ? new_w - rect.width : 0); @@ -2723,7 +2730,7 @@ namespace nana { 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 state = item_state::normal; @@ -2823,11 +2830,11 @@ namespace nana { 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()); - int txtop = (essence_->header_size - essence_->text_height) / 2; - _m_draw_header_item(ext_graph, 0, 0, essence_->header_size, txtop, colors::white, item, item_state::floated); + int txtop = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; + _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_; ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5); @@ -2888,7 +2895,7 @@ namespace nana int x = essence_->item_xpos(rect); 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); @@ -2925,7 +2932,7 @@ namespace nana item_index = lister.absolute_pair(item_index); _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; @@ -2940,7 +2947,7 @@ namespace nana 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); - y += essence_->item_size; + y += essence_->scheme_ptr->item_height; if(false == i_categ->expand) continue; @@ -2956,7 +2963,7 @@ namespace nana item_pos.item = lister.absolute(item_pos); _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; } } @@ -2977,14 +2984,14 @@ namespace nana bgcolor = bgcolor.blend(static_cast(0x99defd), 0.8); 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(0x3399) }; facade arrow("double"); arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south); arrow.draw( *graph, {}, txt_color, - { x + 5, y + static_cast(essence_->item_size - 16) / 2, 16, 16 }, + { x + 5, y + static_cast(essence_->scheme_ptr->item_height - 16) / 2, 16, 16 }, element_state::normal); graph->string({ x + 20, y + txtoff }, categ.text, txt_color); @@ -2998,7 +3005,7 @@ namespace nana if (x + 35 + extend_text_w < x + width) { - ::nana::point pos{ x + 30 + static_cast(extend_text_w), y + static_cast(essence_->item_size) / 2 }; + ::nana::point pos{ x + 30 + static_cast(extend_text_w), y + static_cast(essence_->scheme_ptr->item_height) / 2 }; graph->line(pos, { x + static_cast(width)-5, pos.y }, txt_color); } @@ -3047,7 +3054,7 @@ namespace nana auto graph = essence_->graph; //draw the background - graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->item_size }, true, bgcolor); + graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->scheme_ptr->item_height }, true, bgcolor); int item_xpos = x; unsigned extreme_text = x; @@ -3094,7 +3101,7 @@ namespace nana { nana::rectangle img_r(item.img_show_size); img_r.x = content_pos + item_xpos + static_cast(16 - item.img_show_size.width) / 2; - img_r.y = y + static_cast(essence_->item_size - item.img_show_size.height) / 2; + img_r.y = y + static_cast(essence_->scheme_ptr->item_height - item.img_show_size.height) / 2; item.img.stretch(rectangle{ item.img.size() }, *graph, img_r); } content_pos += 18; @@ -3114,7 +3121,7 @@ namespace nana auto wdg_w = header.pixels - static_cast(content_pos); 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; if (wdg_x < content_r.x) @@ -3129,7 +3136,7 @@ namespace nana else 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->inline_ptr->resize(sz); @@ -3176,7 +3183,7 @@ namespace nana if (item_state::highlighted == state) it_bgcolor = it_bgcolor.blend(static_cast(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; } @@ -3188,10 +3195,10 @@ namespace nana if (static_cast(ts.width) > static_cast(header.pixels) - (content_pos + item_xpos)) // it was an excess { //The text is painted over the next subitem // here beging the ... - int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->suspension_width); + int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->scheme_ptr->suspension_width); // 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"..."); //Erase the part that over the next subitem only if the right of column is less than right of listbox @@ -3199,21 +3206,21 @@ namespace nana { 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(header.pixels), y + 2, - ts.width + static_cast(content_pos)-header.pixels, essence_->item_size - 4 }, true); + ts.width + static_cast(content_pos)-header.pixels, essence_->scheme_ptr->item_height - 4 }, true); } extreme_text = (std::max)(extreme_text, item_xpos + content_pos + ts.width); } } } - graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast(essence_->item_size) - 1 }, static_cast(0xEBF4F9)); + graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast(essence_->scheme_ptr->item_height) - 1 }, static_cast(0xEBF4F9)); } item_xpos += static_cast(header.pixels); if (display_order + 1 >= seqs.size() && static_cast(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); } } @@ -3260,13 +3267,13 @@ namespace nana { //Draw selecting inner rectangle auto graph = essence_->graph; - graph->rectangle({ x, y, width, essence_->item_size }, false, static_cast(0x99defd)); + graph->rectangle({ x, y, width, essence_->scheme_ptr->item_height }, false, static_cast(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 + 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 + essence_->item_size - 1); + graph->set_pixel(x + width - 1, y + essence_->scheme_ptr->item_height - 1); } private: essence_t * essence_; @@ -3329,9 +3336,9 @@ namespace nana void trigger::typeface_changed(graph_reference graph) { - essence_->text_height = graph.text_extent_size(L"jHWn0123456789/item_size = essence_->text_height + 6; - essence_->suspension_width = graph.text_extent_size(L"...").width; + essence_->scheme_ptr->text_height = graph.text_extent_size(L"jHWn0123456789/scheme_ptr->item_height = essence_->scheme_ptr->text_height + essence_->scheme_ptr->item_height_ex; + essence_->scheme_ptr->suspension_width = graph.text_extent_size("...").width; } void trigger::refresh(graph_reference) From feb26995da493376cfa3896383955b84926ff8f7 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 21:03:40 +0200 Subject: [PATCH 02/19] debug --- include/nana/gui/widgets/listbox.hpp | 6 ++--- source/gui/widgets/listbox.cpp | 34 +++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 9ed36a89..9b29a7a7 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -17,8 +17,6 @@ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP -#include - #include "widget.hpp" #include "detail/inline_widget.hpp" #include @@ -541,6 +539,8 @@ namespace nana unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 + void debug_print(const std::string &msg); + }; } }//end namespace drawerbase @@ -747,6 +747,4 @@ the nana::detail::basic_window member pointer scheme void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana - -#include #endif diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3fde21a8..8ec0e69d 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -28,13 +28,33 @@ #include #include #include +#include // for debug namespace nana -{ +{ + void debug(const std::string &msg, const rectangle&r) + { + std::cerr <<"\n" <scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); + essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); + essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); + essence_->graph = &graph; typeface_changed(graph); @@ -3348,10 +3372,18 @@ namespace nana nana::rectangle r; + essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); + if (essence_->header.visible() && essence_->rect_header(r)) drawer_header_->draw(r); + + debug("Header: ", r); + if (essence_->rect_lister(r)) drawer_lister_->draw(r); + + debug("Lister: ", r); + _m_draw_border(); } From 55819dc7d39beff85453f3623a7c66cfde4d93f9 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 27 Mar 2016 21:04:11 +0200 Subject: [PATCH 03/19] small fix --- source/gui/widgets/listbox.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8ec0e69d..f925aea6 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1883,7 +1883,7 @@ namespace nana struct scroll_part { - static const unsigned scale = 16; // ? + static const unsigned scale = 16; // ? int offset_x; index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. // need to be abs??? to see the same item after sort() ?? @@ -2123,7 +2123,7 @@ namespace nana 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()) { scroll.h.create(wd, r); @@ -2138,7 +2138,7 @@ namespace nana 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()) { scroll.v.create(wd, r); @@ -2159,7 +2159,7 @@ namespace nana { 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; } else @@ -2182,7 +2182,7 @@ 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 + (static_cast(scheme_ptr->item_height) - 16) / 2, 16, 16); } @@ -2205,7 +2205,7 @@ namespace nana x -= (2 - scroll.offset_x); new_where.first = parts::header; - new_where.second = static_cast(header.item_by_x(x)); + new_where.second = header.item_by_x(x); } else { From e84f6117614804afbd75e955a0009469df4aed89 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:16:38 +0200 Subject: [PATCH 04/19] original default values --- include/nana/gui/widgets/listbox.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 9b29a7a7..c1ff7ef4 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -529,13 +529,13 @@ namespace nana /// \todo how to implement some geometrical parameters ?? 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{ 8 }; ///< def= . the trigger will set this to the width if ("...") - unsigned ext_w { 5 }; ///< def= . ?? - unsigned header_height { 20 }; ///< def= . header height header_size + 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 }; ///< def=25 . header height header_size unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font unsigned item_height_ex { 2 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex - unsigned item_height { 16 }; ///< the trigger will set this TO item_height = text_height + item_height_ex + unsigned item_height { 16 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 From 09da5347198642a0209efabc0a57a269e43df4d8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:22:38 +0200 Subject: [PATCH 05/19] code review and int/unsigned consistence --- source/gui/widgets/listbox.cpp | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index f925aea6..1a2ff1c3 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2356,8 +2356,8 @@ namespace nana unsigned ext_w = scheme_ptr->ext_w; if (pos == 0 && checkable) // only before the first column (display_order=0 ?) - ext_w += 18; - header.item_width(pos, max_w + ext_w + 1 < max ? max_w + ext_w + 1 : max); + ext_w += 18; // add to geom. scheme (width of the checker) ?? + header.item_width(pos, std::min(max, max_w + ext_w + 1 )); return max_w; } @@ -2842,7 +2842,7 @@ namespace nana { facade arrow("hollow_triangle"); arrow.direction(essence_->lister.sort_reverse() ? ::nana::direction::south : ::nana::direction::north); - arrow.draw(graph, {}, colors::black, { x + static_cast(item.pixels - 16) / 2, -4, 16, 16 }, element_state::normal); + arrow.draw(graph, {}, colors::black, { x + (static_cast(item.pixels) - 16) / 2, -4, 16, 16 }, element_state::normal); // geometric scheme? } } @@ -2892,11 +2892,11 @@ namespace nana auto bgcolor = wdptr->bgcolor(); auto fgcolor = wdptr->fgcolor(); - unsigned header_w = essence_->header.pixels(); + int header_w = essence_->header.pixels(); essence_->graph->palette(false, bgcolor); - if(header_w - essence_->scroll.offset_x < rect.width) - essence_->graph->rectangle(rectangle{ point(rect.x + static_cast(header_w)-essence_->scroll.offset_x, rect.y), - size(static_cast(rect.width) + essence_->scroll.offset_x - static_cast(header_w), rect.height) }, + if( header_w - essence_->scroll.offset_x < static_cast(rect.width) ) + essence_->graph->rectangle(rectangle{ point(rect.x + header_w -essence_->scroll.offset_x, rect.y), + size(static_cast(rect.width) + essence_->scroll.offset_x - header_w , rect.height) }, true); es_lister & lister = essence_->lister; @@ -3040,12 +3040,12 @@ namespace nana /// Draws an item void _m_draw_item(const category_t& cat, const index_pair& item_pos, - const int x, - const int y, - const int txtoff, + const int x, ///< left coordinate ? + const int y, ///< top coordinate + const int txtoff, ///< below y to print the text unsigned width, const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn - const std::vector& seqs, + const std::vector& seqs, ///< columns to print nana::color bgcolor, nana::color fgcolor, item_state state @@ -3069,11 +3069,11 @@ namespace nana 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; - if(show_w >= content_r.width) show_w = content_r.width; + unsigned show_w = std::min(content_r.width, width - essence_->scroll.offset_x); auto graph = essence_->graph; - //draw the background + + //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; @@ -3094,7 +3094,7 @@ namespace nana { if (essence_->checkable) { - content_pos += 18; + content_pos += 18; // checker width, geom scheme? element_state estate = element_state::normal; if (essence_->pointer_where.first == parts::checker) @@ -3120,17 +3120,17 @@ namespace nana if (item.img) { nana::rectangle img_r(item.img_show_size); - img_r.x = content_pos + item_xpos + static_cast(16 - item.img_show_size.width) / 2; - img_r.y = y + static_cast(essence_->scheme_ptr->item_height - item.img_show_size.height) / 2; + img_r.x = content_pos + item_xpos + (16 - static_cast(item.img_show_size.width)) / 2; // center in 16 - geom scheme? + img_r.y = y + (static_cast(essence_->scheme_ptr->item_height) - static_cast(item.img_show_size.height)) / 2; // center item.img.stretch(rectangle{ item.img.size() }, *graph, img_r); } - content_pos += 18; + content_pos += 18; // image width, geom scheme? } } bool draw_column = true; - if (static_cast(content_pos) < header.pixels) + if ( content_pos < static_cast(header.pixels)) // we have room { auto inline_wdg = _m_get_inline_pane(cat, column_pos); if (inline_wdg) From ec2396f3cd33e60ad704f70d65ba7287af2eea81 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:23:50 +0200 Subject: [PATCH 06/19] use essence_->scheme_ptr->ext_w; before text --- source/gui/widgets/listbox.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 1a2ff1c3..6bcdefca 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2836,7 +2836,7 @@ namespace nana } 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(essence_->scheme_ptr->ext_w), txtop }, item.text, fgcolor); if(item.index == essence_->lister.sort_index()) { @@ -3085,9 +3085,9 @@ namespace nana const auto & header = essence_->header.column(column_pos); // deduce the corresponding header which is in a kind of dislay order 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 if (0 == display_order) From 42e6d309c8a6a6f239f939bd5e3f5b31a70a95fc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:25:53 +0200 Subject: [PATCH 07/19] FIX a drawing defect and code review --- source/gui/widgets/listbox.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 6bcdefca..8c802110 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3076,8 +3076,8 @@ namespace nana //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; - unsigned extreme_text = x; + int item_xpos = 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 { @@ -3212,23 +3212,25 @@ namespace nana { 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(ts.width) > static_cast(header.pixels) - (content_pos + item_xpos)) // it was an excess + int item_right = item_xpos + static_cast(header.pixels); + int text_right = item_xpos + content_pos + static_cast(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 ... - int xpos = item_xpos + static_cast(header.pixels) - static_cast(essence_->scheme_ptr->suspension_width); + int xpos = item_right - static_cast(essence_->scheme_ptr->suspension_width); // litter rect with the item bg end ... - 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->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"..."); //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(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->rectangle(rectangle{ item_xpos + static_cast(header.pixels), y + 2, - ts.width + static_cast(content_pos)-header.pixels, essence_->scheme_ptr->item_height - 4 }, true); + graph->rectangle(rectangle( item_right, y /*+ 2*/, excess, essence_->scheme_ptr->item_height /*- 4*/ ), true); } - extreme_text = (std::max)(extreme_text, item_xpos + content_pos + ts.width); + extreme_text = std::max(extreme_text, text_right); } } } @@ -3238,9 +3240,9 @@ namespace nana } item_xpos += static_cast(header.pixels); - if (display_order + 1 >= seqs.size() && static_cast(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_->scheme_ptr->item_height - 4}, true, item.bgcolor); + graph->rectangle(rectangle(item_xpos , y + 2, extreme_text - item_xpos, essence_->scheme_ptr->item_height - 4), true, item.bgcolor); } } @@ -3569,7 +3571,6 @@ namespace nana } } - void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) { using item_state = essence_t::item_state; From a2990b49bb4cc2e8179cf24ffbfca931e2d2e3da Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 28 Mar 2016 03:47:23 +0200 Subject: [PATCH 08/19] reset defaults and debug --- include/nana/gui/widgets/listbox.hpp | 12 +++---- source/gui/widgets/listbox.cpp | 50 ++++++++++++++-------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index c1ff7ef4..422c0bcc 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -532,14 +532,14 @@ namespace nana unsigned min_header_width{ 20 }; ///< def=20 . non counting suspension_width unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") 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 }; ///< def=25 . header height header_size + unsigned header_height { 25 }; ///< def=25 . header height header_size unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font - unsigned item_height_ex { 2 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex - unsigned item_height { 16 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex - unsigned header_mouse_spliter_area_before{ 4 }; ///< def=2 - unsigned header_mouse_spliter_area_after { 4 }; ///< def=3 + unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. 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 }; ///< def=2. But 4 is better... IMO + unsigned header_mouse_spliter_area_after { 3 }; ///< def=3. But 4 is better... - void debug_print(const std::string &msg); + //void debug_print(const std::string &msg); }; } diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8c802110..bbda3c47 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -32,29 +32,29 @@ namespace nana { - void debug(const std::string &msg, const rectangle&r) - { - std::cerr <<"\n" <scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); - essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); + //essence_->scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); + //essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); - essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); + //essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); essence_->graph = &graph; typeface_changed(graph); @@ -3374,17 +3374,17 @@ namespace nana nana::rectangle r; - essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); + //essence_->scheme_ptr->debug_print("From trigger::refresh(graph_reference) "); if (essence_->header.visible() && essence_->rect_header(r)) drawer_header_->draw(r); - debug("Header: ", r); + //debug("Header: ", r); if (essence_->rect_lister(r)) drawer_lister_->draw(r); - debug("Lister: ", r); + //debug("Lister: ", r); _m_draw_border(); } From 8da9520d01bb6fdbc196a532a5503b1d3869582e Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 31 Mar 2016 23:34:15 +0200 Subject: [PATCH 09/19] only central repaint? --- source/gui/widgets/listbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index bbda3c47..33232611 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -3242,7 +3242,7 @@ namespace nana item_xpos += static_cast(header.pixels); if (display_order + 1 >= seqs.size() && extreme_text > item_xpos) { - graph->rectangle(rectangle(item_xpos , y + 2, extreme_text - item_xpos, essence_->scheme_ptr->item_height - 4), true, item.bgcolor); + graph->rectangle(rectangle(item_xpos , y /*+ 2*/, extreme_text - item_xpos, essence_->scheme_ptr->item_height /*- 4*/), true, item.bgcolor); } } From aba060360603a9e57d02356db53b1f51c45738c8 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 19 Apr 2016 00:16:36 +0200 Subject: [PATCH 10/19] 3 instead of 1 step by list wheel scroll --- source/gui/widgets/listbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 707eb339..3ff96ced 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2289,9 +2289,9 @@ namespace nana index_pair target; if(upwards == false) - lister.forward(scroll.offset_y_dpl, 1, target); + lister.forward(scroll.offset_y_dpl, 3, target); // scheme ?? else - lister.backward(scroll.offset_y_dpl, 1, target); + lister.backward(scroll.offset_y_dpl, 3, target); if (target == scroll.offset_y_dpl) return false; From 526c6bc6ba35bd6b704d17e1fcce4dd738426524 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 20 Apr 2016 01:52:25 +0200 Subject: [PATCH 11/19] still not merged with develop --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3e64fdb9..d7868e3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: - llvm-toolchain-precise 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" - 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 From 28ec691485a68b009b991a54cb6afde6e0b648e4 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 10 May 2016 12:48:00 +0800 Subject: [PATCH 12/19] small changes --- source/gui/detail/bedrock_windows.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 7bd5d505..d6747a97 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -28,6 +26,9 @@ #include #include +#include +#include + #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x020A #endif From 3069d998f04f0b84794f751ef7749d0b8765a307 Mon Sep 17 00:00:00 2001 From: Besh81 Date: Tue, 10 May 2016 18:10:53 +0200 Subject: [PATCH 13/19] textbox and combox behaviours textbox: when uneditable the caret is hide combox: when uneditable (default) - inherit the textbox behaviour - open the lister clicking the textbox area also --- source/gui/widgets/combox.cpp | 37 ++++++++++---------- source/gui/widgets/skeletons/text_editor.cpp | 13 +++++-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index c5df35f8..aec594ca 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -171,7 +171,7 @@ namespace nana if(editor_) { editor_->editable(enb); - + editor_->show_caret(enb); if (!enb) { editor_->ext_renderer().background = [this](graph_reference graph, const ::nana::rectangle&, const ::nana::color&) @@ -245,22 +245,23 @@ namespace nana void open_lister_if_push_button_positioned() { - if((nullptr == state_.lister) && !items_.empty() && (parts::push_button == state_.pointer_where)) - { - module_.items.clear(); - std::copy(items_.cbegin(), items_.cend(), std::back_inserter(module_.items)); - state_.lister = &form_loader()(widget_->handle(), nana::rectangle(0, widget_->size().height, widget_->size().width, 10), true); - state_.lister->renderer(item_renderer_); - state_.lister->set_module(module_, image_pixels_); - state_.item_index_before_selection = module_.index; - //The lister window closes by itself. I just take care about the destroy event. - //The event should be destroy rather than unload. Because the unload event is invoked while - //the lister is not closed, if popuping a message box, the lister will cover the message box. - state_.lister->events().destroy.connect_unignorable([this] + if(nullptr == state_.lister && !items_.empty()) + if((parts::push_button == state_.pointer_where && editor_->attr().editable) || !editor_->attr().editable) { - _m_lister_close_sig(); - }); - } + module_.items.clear(); + std::copy(items_.cbegin(), items_.cend(), std::back_inserter(module_.items)); + state_.lister = &form_loader()(widget_->handle(), nana::rectangle(0, widget_->size().height, widget_->size().width, 10), true); + state_.lister->renderer(item_renderer_); + state_.lister->set_module(module_, image_pixels_); + state_.item_index_before_selection = module_.index; + //The lister window closes by itself. I just take care about the destroy event. + //The event should be destroy rather than unload. Because the unload event is invoked while + //the lister is not closed, if popuping a message box, the lister will cover the message box. + state_.lister->events().destroy.connect_unignorable([this] + { + _m_lister_close_sig(); + }); + } } void scroll_items(bool upwards) @@ -622,8 +623,8 @@ namespace nana if(drawer_->widget_ptr()->enabled()) { auto * editor = drawer_->editor(); - if (!editor->mouse_pressed(arg)) - drawer_->open_lister_if_push_button_positioned(); + editor->mouse_pressed(arg); + drawer_->open_lister_if_push_button_positioned(); drawer_->draw(); if(editor->attr().editable) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index fc6086cc..21fa8cdc 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1639,11 +1639,14 @@ namespace nana{ namespace widgets bool text_editor::mouse_move(bool left_button, const point& scrpos) { 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; API::window_cursor(window_, cur); + if(!attributes_.editable) + return false; + if(left_button) { auto caret_pos_before = caret(); @@ -1662,6 +1665,9 @@ namespace nana{ namespace widgets bool text_editor::mouse_pressed(const arg_mouse& arg) { + if(!attributes_.editable) + return false; + if (event_code::mouse_down == arg.evt_code) { if (!hit_text_area(arg.pos)) @@ -1790,6 +1796,9 @@ namespace nana{ namespace widgets reset_caret_pixels(); } + if(!attributes_.editable) + visible = false; + API::caret_visible(window_, visible); if(visible) @@ -3065,7 +3074,7 @@ namespace nana{ namespace widgets graph_.palette(false, scheme_->selection.get_color()); //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); for (auto & ent : reordered) From 9f61e21c87243ed0a209b9a8fe487b6a3bdd9700 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 11 May 2016 07:41:59 +0800 Subject: [PATCH 14/19] guarantee consistent KeyRelease behavior on all supported platform. X will send a KeyRelease after KeyPress even though the key is still pressed. --- source/detail/x11/msg_dispatcher.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source/detail/x11/msg_dispatcher.hpp b/source/detail/x11/msg_dispatcher.hpp index 7ba64b4f..2f1688e0 100644 --- a/source/detail/x11/msg_dispatcher.hpp +++ b/source/detail/x11/msg_dispatcher.hpp @@ -1,6 +1,6 @@ /* * 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. * (See accompanying file LICENSE_1_0.txt or copy at @@ -164,7 +164,7 @@ namespace detail private: void _m_msg_driver() { - int fd_X11 = ConnectionNumber(display_); + const int fd_X11 = ConnectionNumber(display_); msg_packet_tag msg_pack; XEvent event; @@ -177,6 +177,18 @@ namespace detail if(pending) { ::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)) continue; } From a30eef53ecb1df156b98dcb52f13062a3dd07856 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 12 May 2016 23:34:40 +0800 Subject: [PATCH 15/19] fix bug that menu_popuper doesn't popup a menu --- source/gui/widgets/menu.cpp | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index e132f7b5..7c585f3e 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -1370,24 +1370,8 @@ namespace nana return; } } - bool popup = false; - switch(mouse_) - { - 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) + + if((mouse::any_button == mouse_) || (mouse_ == arg.button)) mobj_.popup(owner_, pos_.x, pos_.y); } //end class From c3611ff2d29bd4730a73aa05951a946b0df5a405 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 19 May 2016 15:30:07 +0800 Subject: [PATCH 16/19] fix an issue that any_cast returns null if value type has cv-specifier --- include/nana/any.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nana/any.hpp b/include/nana/any.hpp index 491169fc..ed711146 100644 --- a/include/nana/any.hpp +++ b/include/nana/any.hpp @@ -150,7 +150,7 @@ namespace nana if (!operand) return nullptr; - auto holder = dynamic_cast*>(operand->content_); + auto holder = dynamic_cast::type>*>(operand->content_); return (holder ? &holder->value : nullptr); } From 32d988e1a7f4ea5fd1938758593ab0f28491fefa Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 2 Jun 2016 01:01:03 +0800 Subject: [PATCH 17/19] minor changes --- include/nana/gui/widgets/listbox.hpp | 4 ++++ source/gui/widgets/listbox.cpp | 11 ++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 422c0bcc..b5781ad2 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -17,6 +17,8 @@ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP +#include + #include "widget.hpp" #include "detail/inline_widget.hpp" #include @@ -747,4 +749,6 @@ the nana::detail::basic_window member pointer scheme void _m_erase_key(nana::detail::key_interface*); }; }//end namespace nana + +#include #endif diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 476528aa..bf1260cc 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2341,7 +2341,7 @@ namespace nana unsigned auto_width(size_type pos, unsigned max = 100000) { - max = std::min(max, scheme_ptr->max_header_width); + max = (std::min)(max, scheme_ptr->max_header_width); unsigned max_w{ 0 }; for (const auto &cat : lister.cat_container()) for (const auto &it : cat.items) @@ -2357,7 +2357,7 @@ namespace nana unsigned ext_w = scheme_ptr->ext_w; if (pos == 0 && checkable) // only before the first column (display_order=0 ?) ext_w += 18; // add to geom. scheme (width of the checker) ?? - header.item_width(pos, std::min(max, max_w + ext_w + 1 )); + header.item_width(pos, (std::min)(max, max_w + ext_w + 1 )); return max_w; } @@ -3069,7 +3069,7 @@ namespace nana bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend } - unsigned show_w = std::min(content_r.width, width - essence_->scroll.offset_x); + unsigned show_w = (std::min)(content_r.width, width - essence_->scroll.offset_x); auto graph = essence_->graph; @@ -3230,7 +3230,7 @@ namespace nana graph->palette(false, bgcolor); // we need to erase the excess, because some cell may not draw text over graph->rectangle(rectangle( item_right, y /*+ 2*/, excess, essence_->scheme_ptr->item_height /*- 4*/ ), true); } - extreme_text = std::max(extreme_text, text_right); + extreme_text = (std::max)(extreme_text, text_right); } } } @@ -3343,10 +3343,7 @@ namespace nana void trigger::attached(widget_reference widget, graph_reference graph) { - //essence_->scheme_ptr = &static_cast<::nana::listbox&>(widget).scheme(); - //essence_->scheme_ptr->debug_print("In trigger::attached with &static_cast<::nana::listbox&>(widget).scheme();"); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); - //essence_->scheme_ptr->debug_print("In trigger::attached with static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));"); essence_->graph = &graph; typeface_changed(graph); From 108a31d907d55fdb5870364d03c25f5e822cd157 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 5 Jun 2016 01:28:43 +0800 Subject: [PATCH 18/19] fix an integer division by zero of text_editor issue --- source/gui/widgets/skeletons/text_editor.cpp | 31 +++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 2ec36439..0c8cf46a 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -477,7 +477,8 @@ namespace nana{ namespace widgets std::size_t _m_textline_from_screen(int y) const { const std::size_t textlines = editor_.textbase_.lines(); - if (0 == textlines) + const auto line_px = static_cast(editor_.line_height()); + if ((0 == textlines) || (0 == line_px)) return 0; const int offset_top = editor_.points_.offset.y; @@ -486,7 +487,7 @@ namespace nana{ namespace widgets if (y < text_area_top) y = offset_top ? offset_top - 1 : 0; else - y = (y - text_area_top) / static_cast(editor_.line_height()) + offset_top; + y = (y - text_area_top) / line_px + offset_top; return (textlines <= static_cast(y) ? textlines - 1 : static_cast(y)); } @@ -1106,28 +1107,24 @@ namespace nana{ namespace widgets //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 { - const int text_area_top = editor_.text_area_.area.y; - const int offset_top = editor_.points_.offset.y; + const auto line_px = static_cast(editor_.line_height()); - if (0 == editor_.textbase_.lines()) + if ((0 == editor_.textbase_.lines()) || (0 == line_px)) { secondary = 0; return 0; } - std::size_t screen_line; - if (y < text_area_top) - { - screen_line = (text_area_top - y) / static_cast(editor_.line_height()); - if (screen_line > static_cast(offset_top)) - screen_line = 0; - else - screen_line = static_cast(offset_top)-screen_line; - } - else - screen_line = static_cast((y - text_area_top) / static_cast(editor_.line_height()) + offset_top); + const int text_area_top = editor_.text_area_.area.y; + const int offset_top = editor_.points_.offset.y; - auto primary = _m_textline(screen_line, secondary); + auto screen_line = (text_area_top - y) / line_px; + if ((y < text_area_top) && (screen_line > offset_top)) + screen_line = 0; + else + screen_line = offset_top - screen_line; + + auto primary = _m_textline(static_cast(screen_line), secondary); if (primary < linemtr_.size()) return primary; From 5ab0cfdd17ae2ca1b9063abb6428197c70cba4c9 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 5 Jun 2016 02:36:38 +0800 Subject: [PATCH 19/19] fix a notifier error that can't set icon from its exe file --- include/nana/gui/notifier.hpp | 2 +- source/gui/detail/native_window_interface.cpp | 19 +---- source/gui/notifier.cpp | 77 ++++++++----------- source/paint/image.cpp | 17 ++++ source/paint/image_accessor.hpp | 30 ++++++++ 5 files changed, 84 insertions(+), 61 deletions(-) create mode 100644 source/paint/image_accessor.hpp diff --git a/include/nana/gui/notifier.hpp b/include/nana/gui/notifier.hpp index 48442a96..3e136cdb 100644 --- a/include/nana/gui/notifier.hpp +++ b/include/nana/gui/notifier.hpp @@ -1,7 +1,7 @@ /* * Definition of Notifier * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index b21eb270..4f356b83 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -28,24 +28,9 @@ #include #endif -namespace nana{ - namespace paint - { - class image_accessor - { - public: -#if defined(NANA_WINDOWS) - static HICON icon(const nana::paint::image& img) - { - auto ico = dynamic_cast(img.image_ptr_.get()); - if(ico && ico->ptr()) - return *(ico->ptr()); - return nullptr; - } -#endif - }; - } +#include "../../paint/image_accessor.hpp" +namespace nana{ namespace detail{ #if defined(NANA_WINDOWS) diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 4a9f6ac3..d541788b 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -1,17 +1,17 @@ /* - * Implementation of Notifier - * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * @file: nana/gui/notifier.cpp - * @contributors: - * Jan - * Benjamin Navarro(pr#81) - */ +* Implementation of Notifier +* 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/gui/notifier.cpp +* @contributors: +* Jan +* Benjamin Navarro(pr#81) +*/ #include #include #include @@ -33,9 +33,11 @@ #include #endif +#include "../paint/image_accessor.hpp" + namespace nana { - typedef std::lock_guard lock_guard; + using lock_guard = std::lock_guard; struct notifier::implement { @@ -47,13 +49,15 @@ namespace nana detail::notifier_events events; bool icon_added = false; std::size_t play_index; -#if defined(NANA_WINDOWS) - HICON icon_handle = nullptr; - std::vector icons; - void set_icon(HICON icon) + paint::image icon; + ::std::vector 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; memset(&icon_data, 0, sizeof icon_data); @@ -62,13 +66,13 @@ namespace nana icon_data.uID = id; icon_data.uFlags = NIF_MESSAGE | NIF_ICON; 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); icon_added = true; } - } #endif + } }; arg_notifier::operator nana::arg_mouse() const @@ -287,12 +291,6 @@ namespace nana icon_data.hWnd = reinterpret_cast(impl_->native_handle); icon_data.uID = impl_->id; ::Shell_NotifyIcon(NIM_DELETE, &icon_data); - - if (impl_->icon_handle) - ::DestroyIcon(impl_->icon_handle); - - for (auto handle : impl_->icons) - ::DestroyIcon(handle); #endif API::umake_event(impl_->evt_destroy); notifications::instance().cancel(impl_->native_handle, impl_->id); @@ -321,30 +319,23 @@ namespace nana void notifier::icon(const std::string& icon_file) { -#if defined(NANA_WINDOWS) - auto pre_icon = impl_->icon_handle; - auto ico = (HICON)::LoadImageW(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - if (ico) + paint::image image_ico{ icon_file }; + auto icon_handle = paint::image_accessor::icon(image_ico); + if (icon_handle) { - impl_->icon_handle = ico; impl_->ani_timer.stop(); impl_->play_index = 0; - impl_->set_icon(impl_->icon_handle); - ::DestroyIcon(pre_icon); + impl_->set_icon(image_ico); + impl_->icon = image_ico; } -#else - static_cast(icon_file); //to eliminate unused parameter compiler warning -#endif } void notifier::insert_icon(const std::string& icon_file) { -#if defined(NANA_WINDOWS) - auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - impl_->icons.push_back(icon); -#else - static_cast(icon_file); //to eliminate unused parameter compiler warning. -#endif + paint::image image_ico{ icon_file }; + auto icon_handle = paint::image_accessor::icon(image_ico); + if (icon_handle) + impl_->icons.emplace_back(static_cast(image_ico)); } void notifier::period(unsigned ms) diff --git a/source/paint/image.cpp b/source/paint/image.cpp index 529c5c44..a1e2c889 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -34,10 +34,27 @@ #include "detail/image_bmp.hpp" #include "detail/image_ico.hpp" +#include "image_accessor.hpp" + namespace nana { namespace paint { +#if defined(NANA_WINDOWS) + HICON image_accessor::icon(const nana::paint::image& img) + { + auto ico = dynamic_cast(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 { //class image_ico diff --git a/source/paint/image_accessor.hpp b/source/paint/image_accessor.hpp new file mode 100644 index 00000000..73060e7e --- /dev/null +++ b/source/paint/image_accessor.hpp @@ -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 \ No newline at end of file