From d13677f703988023df7e7d16d2723106a394febb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 12 Apr 2015 23:45:02 +0200 Subject: [PATCH 001/105] add empty group files --- build/vc2013/nana.vcxproj | 123 +++++++++ build/vc2013/nana.vcxproj.filters | 410 +++++++++++++++++++++++++++++ include/nana/gui/widgets/group.hpp | 37 +++ source/gui/widgets/group.cpp | 25 ++ 4 files changed, 595 insertions(+) create mode 100644 include/nana/gui/widgets/group.hpp create mode 100644 source/gui/widgets/group.cpp diff --git a/build/vc2013/nana.vcxproj b/build/vc2013/nana.vcxproj index 7e216758..62b7f037 100644 --- a/build/vc2013/nana.vcxproj +++ b/build/vc2013/nana.vcxproj @@ -213,6 +213,7 @@ + @@ -247,6 +248,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/vc2013/nana.vcxproj.filters b/build/vc2013/nana.vcxproj.filters index f0f82981..d04ac84d 100644 --- a/build/vc2013/nana.vcxproj.filters +++ b/build/vc2013/nana.vcxproj.filters @@ -58,6 +58,51 @@ {e95b4a72-643f-4416-af95-b0bbaf7f0c57} + + {d421a05b-b868-4c3d-bdac-ff57d09f8d07} + + + {64c22f90-dce2-40dc-be98-edc9fe8951e8} + + + {91301ff5-79ac-40cc-a6db-bca2097ea763} + + + {81c62a28-ef5f-43f7-a6ce-e6c186cb411a} + + + {4a1db6f0-a4ee-4514-8e89-54ef9d52e3b8} + + + {c92e890a-ffd5-4efd-8b37-78ed9bbea1e1} + + + {63401f37-26a3-423e-87e6-6840344c3056} + + + {61385c08-f06b-4cf3-8e05-9b47d546164b} + + + {e9eadc97-4a14-4a4e-bb52-52d3a20e2693} + + + {5667eac1-0887-4936-9502-eac4dd8c1c1d} + + + {e6c4a4d9-b4b5-4c56-bb2a-486f3f777ecb} + + + {ac132633-f80c-4983-8e47-fa7fc17f666e} + + + {ee3e9e63-7221-409e-9659-25864e576e16} + + + {ef87057b-dff2-40aa-a05e-9dcd0b335c30} + + + {8ea232cf-bd7c-47e3-a694-6a8898b677d7} + @@ -300,5 +345,370 @@ Source Files\nana\gui\widgets + + Source Files\nana\gui\widgets + + + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui\widgets\detail + + + Header Files\gui\widgets\detail + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\detail\linux_X11 + + + Header Files\detail\linux_X11 + + + Header Files\detail\linux_X11 + + + Header Files\detail\win32 + + + Header Files\extrlib + + + Header Files\extrlib + + + Header Files\extrlib + + + Header Files\extrlib + + + Header Files\filesystem + + + Header Files\filesystem + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\pat + + + Header Files\system + + + Header Files\system + + + Header Files\system + + + Header Files\system + + + Header Files\threads + + + Header Files\gui\widgets + \ No newline at end of file diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp new file mode 100644 index 00000000..d876becb --- /dev/null +++ b/include/nana/gui/widgets/group.hpp @@ -0,0 +1,37 @@ +/** + * A group widget implementation + * Nana C++ Library(http://www.nanaro.org) + * Copyright(C) 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/widgets/group.hpp + * + * @contributors: Stefan Pfeifer (st-321), Jinhao, Ariel Vina-Rodriguez (qPCR4vir) + * + * @brief group is a widget used to visually group and layout other widgets. + */ + +#ifndef NANA_GUI_WIDGETS_GROUP_HPP +#define NANA_GUI_WIDGETS_GROUP_HPP + +#include +#include +#include +#include +#include + +namespace nana{ + class group + : public panel + { + + + }; + + + +}//end namespace nana +#endif diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp new file mode 100644 index 00000000..e0958124 --- /dev/null +++ b/source/gui/widgets/group.cpp @@ -0,0 +1,25 @@ +/** + * A group widget implementation + * Nana C++ Library(http://www.nanaro.org) + * Copyright(C) 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/widgets/group.cpp + * + * @contributors: Stefan Pfeifer (st-321), Jinhao, Ariel Vina-Rodriguez (qPCR4vir) + * + * @brief group is a widget used to visually group and layout other widgets. + */ + + +#include + +namespace nana{ + + + +}//end namespace nana + From ae2a2aeec4a8fa271236f2e3e0fe7c89b68e3b47 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 13 Apr 2015 01:59:30 +0200 Subject: [PATCH 002/105] group with internal panel and place Non tested --- include/nana/gui/widgets/group.hpp | 18 +++++++++++---- source/gui/widgets/group.cpp | 35 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index d876becb..6cd15af1 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -27,11 +27,21 @@ namespace nana{ class group : public panel { - - + place plc_outer{*this}; + panel content {*this}; + label titel/* {*this}*/; + place plc_inner{content}; + unsigned int gap; + public: + group( widget &owner, ///< + string titel_ ={}, ///< + bool format =false, ///< Use a formated label? + unsigned gap =2, ///< betwen the content and the external limit + rectangle r ={} ///< + ); + place& plc (){ return plc_inner; } + window inner(){ return content; } }; - - }//end namespace nana #endif diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index e0958124..d613b63d 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -18,8 +18,43 @@ #include namespace nana{ + group::group( widget &owner, ///< + string titel_ /*={}*/, ///< + bool format /*=false*/, ///< + unsigned gap /*=2*/, ///< + rectangle r /*={} */ ///< + ) + : panel (owner, r), + titel (*this, titel_) + { + titel.format(format); + ::nana::size sz = titel.measure(1000); + std::stringstream ft; + ft << "vertical margin=[0," << gap << "," << gap << "," << gap << "]" + << " >" + << " "; + plc_outer.div(ft.str().c_str()); + plc_outer["titel" ] << titel; + plc_outer["content"] << content; + plc_outer.collocate(); + + color obg = owner.bgcolor(); + titel.bgcolor(obg.blend(colors::black, 0.975) ); + color bg=obg.blend(colors::black, 0.950 ); + bgcolor(bg); + + drawing dw(*this); + dw.draw([gap,sz,bg,obg](paint::graphics& graph) + { + graph.rectangle(true, obg); + graph.round_rectangle(rectangle( point ( gap-1 , sz.height/2 ), + nana::size (graph.width()-2*(gap-1), graph.height()-sz.height/2-(gap-1)) + ), + 3,3, colors::gray_border, true, bg); + }); + } }//end namespace nana From 73e5d3fd8f233700028c4e387012673f26b61cfb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 13 Apr 2015 10:53:20 +0200 Subject: [PATCH 003/105] refine group --- include/nana/gui/widgets/group.hpp | 5 +++-- source/gui/widgets/group.cpp | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index 6cd15af1..19cb6dce 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -33,14 +33,15 @@ namespace nana{ place plc_inner{content}; unsigned int gap; public: - group( widget &owner, ///< - string titel_ ={}, ///< + group( window parent, ///< + string titel_ ={STR("")}, ///< bool format =false, ///< Use a formated label? unsigned gap =2, ///< betwen the content and the external limit rectangle r ={} ///< ); place& plc (){ return plc_inner; } window inner(){ return content; } + label& lbl (){ return titel; } }; }//end namespace nana diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index d613b63d..b4905afe 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -18,13 +18,13 @@ #include namespace nana{ - group::group( widget &owner, ///< + group::group( window parent, ///< string titel_ /*={}*/, ///< bool format /*=false*/, ///< unsigned gap /*=2*/, ///< rectangle r /*={} */ ///< ) - : panel (owner, r), + : panel (parent, r), titel (*this, titel_) { titel.format(format); @@ -40,15 +40,18 @@ namespace nana{ plc_outer["content"] << content; plc_outer.collocate(); - color obg = owner.bgcolor(); - titel.bgcolor(obg.blend(colors::black, 0.975) ); - color bg=obg.blend(colors::black, 0.950 ); - bgcolor(bg); + color pbg = API::bgcolor( parent); + titel.bgcolor(pbg.blend(colors::black, 0.975) ); + color bg=pbg.blend(colors::black, 0.950 ); + bgcolor(pbg); + content.bgcolor(bg); drawing dw(*this); - dw.draw([gap,sz,bg,obg](paint::graphics& graph) + + // This drawing function is owner by the onwer of dw (the outer panel of the group widget), not by dw !! + dw.draw([gap,sz,bg,pbg](paint::graphics& graph) { - graph.rectangle(true, obg); + graph.rectangle(true, pbg); graph.round_rectangle(rectangle( point ( gap-1 , sz.height/2 ), nana::size (graph.width()-2*(gap-1), graph.height()-sz.height/2-(gap-1)) ), From 2da65827a06af9fa3e8ee309831fa77794fba1d8 Mon Sep 17 00:00:00 2001 From: beru Date: Tue, 5 May 2015 14:13:16 +0900 Subject: [PATCH 004/105] improve cursor move keys support in text editor refs refs #1 --- .../gui/widgets/skeletons/text_editor.hpp | 6 +- source/gui/widgets/combox.cpp | 6 +- source/gui/widgets/skeletons/text_editor.cpp | 165 +++++++++++++++++- source/gui/widgets/spinbox.cpp | 4 +- source/gui/widgets/textbox.cpp | 4 +- 5 files changed, 173 insertions(+), 12 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 976c168d..952d6ba2 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -157,8 +157,8 @@ namespace nana{ namespace widgets void set_accept(std::function); void set_accept(accepts); - bool respond_char(char_type); - bool respond_key(char_type); + bool respond_char(const arg_keyboard& arg); + bool respond_key(const arg_keyboard& arg); void typeface_changed(); @@ -286,6 +286,8 @@ namespace nana{ namespace widgets unsigned _m_char_by_pixels(const nana::char_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl); unsigned _m_pixels_by_char(const nana::string&, std::size_t pos) const; static bool _m_is_right_text(const unicode_bidi::entity&); + void _handle_move_key(const arg_keyboard& arg); + private: std::unique_ptr behavior_; undoable undo_; diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index b1d401f5..24dfd5e1 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -685,7 +685,7 @@ namespace nana { case keyboard::os_arrow_left: case keyboard::os_arrow_right: - drawer_->editor()->respond_key(arg.key); + drawer_->editor()->respond_key(arg); drawer_->editor()->reset_caret(); break; case keyboard::os_arrow_up: @@ -714,14 +714,14 @@ namespace nana } } if (call_other_keys) - drawer_->editor()->respond_key(arg.key); + drawer_->editor()->respond_key(arg); API::lazy_refresh(); } void trigger::key_char(graph_reference graph, const arg_keyboard& arg) { - if (drawer_->editor()->respond_char(arg.key)) + if (drawer_->editor()->respond_char(arg)) API::lazy_refresh(); } //end class trigger diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 0a2f9261..562446b5 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -461,6 +461,7 @@ namespace nana{ namespace widgets editor_._m_scrollbar(); return (adjusted_cond || adjusted_cond2); } + private: std::size_t _m_textline_from_screen(int y) const { @@ -1349,8 +1350,9 @@ namespace nana{ namespace widgets attributes_.acceptive = acceptive; } - bool text_editor::respond_char(char_type key) //key is a character of ASCII code + bool text_editor::respond_char(const arg_keyboard& arg) //key is a character of ASCII code { + char_type key = arg.key; switch (key) { case keyboard::end_of_text: @@ -1400,14 +1402,28 @@ namespace nana{ namespace widgets return false; } - bool text_editor::respond_key(char_type key) + bool text_editor::respond_key(const arg_keyboard& arg) { + char_type key = arg.key; switch (key) - { + { +#if 0 case keyboard::os_arrow_left: move_left(); break; case keyboard::os_arrow_right: move_right(); break; case keyboard::os_arrow_up: move_ns(true); break; case keyboard::os_arrow_down: move_ns(false); break; +#else + case keyboard::os_arrow_left: + case keyboard::os_arrow_right: + case keyboard::os_arrow_up: + case keyboard::os_arrow_down: + case keyboard::os_home: + case keyboard::os_end: + case keyboard::os_pageup: + case keyboard::os_pagedown: + _handle_move_key(arg); + break; +#endif case keyboard::os_del: if (this->attr().editable) del(); @@ -2217,6 +2233,149 @@ namespace nana{ namespace widgets points_.xpos = points_.caret.x; } + void text_editor::_handle_move_key(const arg_keyboard& arg) + { + bool changed = false; + nana::upoint caret = points_.caret; + char_t key = arg.key; + size_t nlines = textbase_.lines(); + if (arg.ctrl) { + switch (key) { + case keyboard::os_arrow_left: + case keyboard::os_arrow_right: + // TODO: move the caret word by word + break; + case keyboard::os_home: + if (caret.y != 0) { + caret.y = 0; + points_.offset.y = 0; + changed = true; + } + break; + case keyboard::os_end: + if (caret.y != nlines - 1) { + caret.y = nlines - 1; + changed = true; + } + break; + } + } + size_t lnsz = textbase_.getline(caret.y).size(); + switch (key) { + case keyboard::os_arrow_left: + if (caret.x != 0) { + --caret.x; + changed = true; + }else { + if (caret.y != 0) { + --caret.y; + caret.x = textbase_.getline(caret.y).size(); + changed = true; + } + } + break; + case keyboard::os_arrow_right: + if (caret.x < lnsz) { + ++caret.x; + changed = true; + }else { + if (caret.y != nlines - 1) { + ++caret.y; + caret.x = 0; + changed = true; + } + } + break; + case keyboard::os_arrow_up: + case keyboard::os_arrow_down: + { + auto screen_pt = behavior_->caret_to_screen(caret); + int offset = line_height(); + if (key == keyboard::os_arrow_up) { + offset = -offset; + } + screen_pt.y += offset; + auto new_caret = behavior_->screen_to_caret(screen_pt); + if (new_caret != caret) { + caret = new_caret; + if (screen_pt.y < 0) { + scroll(true, true); + } + changed = true; + } + } + break; + case keyboard::os_home: + if (caret.x != 0) { + caret.x = 0; + changed = true; + } + break; + case keyboard::os_end: + if (caret.x < lnsz) { + caret.x = lnsz; + changed = true; + } + break; + case keyboard::os_pageup: + if (caret.y >= (int)screen_lines() && points_.offset.y >= (int)screen_lines()) { + points_.offset.y -= screen_lines(); + caret.y -= screen_lines(); + changed = true; + } + break; + case keyboard::os_pagedown: + if (caret.y + screen_lines() <= behavior_->take_lines()) { + points_.offset.y += screen_lines(); + caret.y += screen_lines(); + changed = true; + } + break; + } + if (select_.a != caret || select_.b != caret) { + changed = true; + } + if (changed) { + if (arg.shift) { + switch (key) { + case keyboard::os_arrow_left: + case keyboard::os_arrow_up: + case keyboard::os_home: + case keyboard::os_pageup: + if (points_.caret == select_.b) { + select_.b = select_.a; + }else { + select_.b = std::max(select_.b, points_.caret); + } + select_.a = caret; + break; + case keyboard::os_arrow_right: + case keyboard::os_arrow_down: + case keyboard::os_end: + case keyboard::os_pagedown: + if (select_.b == points_.caret) { + select_.a = std::min(select_.a, points_.caret); + }else { + select_.a = std::max(select_.b, points_.caret); + } + select_.b = caret; + break; + } + }else { + select_.b = caret; + select_.a = caret; + } + if (select_.a > select_.b) { + std::swap(select_.a, select_.b); + } + points_.caret = caret; + behavior_->adjust_caret_into_screen(); + render(true); + _m_scrollbar(); + points_.xpos = points_.caret.x; + } + } + nana::upoint text_editor::mouse_caret(const point& scrpos) //From screen position { points_.caret = behavior_->screen_to_caret(scrpos); diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 6be8deb2..c5830b1f 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -560,7 +560,7 @@ namespace nana void drawer::key_press(graph_reference, const arg_keyboard& arg) { - if (impl_->editor()->respond_key(arg.key)) + if (impl_->editor()->respond_key(arg)) { impl_->editor()->reset_caret(); impl_->draw_spins(); @@ -570,7 +570,7 @@ namespace nana void drawer::key_char(graph_reference, const arg_keyboard& arg) { - if (impl_->editor()->respond_char(arg.key)) + if (impl_->editor()->respond_char(arg)) { if (!impl_->value(impl_->editor()->text())) impl_->draw_spins(); diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 4bb6a670..fd2d9c86 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -136,7 +136,7 @@ namespace drawerbase { void drawer::key_press(graph_reference, const arg_keyboard& arg) { - if(editor_->respond_key(arg.key)) + if(editor_->respond_key(arg)) { editor_->reset_caret(); API::lazy_refresh(); @@ -145,7 +145,7 @@ namespace drawerbase { void drawer::key_char(graph_reference, const arg_keyboard& arg) { - if (editor_->respond_char(arg.key)) + if (editor_->respond_char(arg)) API::lazy_refresh(); } From 52d040a95d2a5136f1a79d7aa25f3fc5a2637bda Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:50:30 +0200 Subject: [PATCH 005/105] FIX: trace the whole cat when selected, not just the last item --- source/gui/widgets/listbox.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 53ee6eff..a44d7d47 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1595,26 +1595,21 @@ namespace nana bool categ_selected(size_type cat, bool sel) { bool changed = false; - auto & items = _m_at(cat)->items; - index_pair pos(cat, 0); - for(auto & m : items) + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) { - if(m.flags.selected != sel) - { - m.flags.selected = sel; - - arg_listbox arg{ item_proxy(ess_, pos), sel }; - wd_ptr()->events().selected.emit(arg); + if (it.selected() != sel) changed = true; + it.select(sel); if (sel) // not check for single_selection_ - last_selected_abs = pos; - else if (last_selected_abs == pos) + last_selected_abs = it->pos(); + + else if (last_selected_abs == it->pos()) last_selected_abs.set_both(npos); } - ++pos.item; - } + last_selected_abs = index_pair{cat,npos}; return changed; } From 31639cb34d88609c562ce1f0ce116873465b2b72 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:53:27 +0200 Subject: [PATCH 006/105] to find the first item or cat --- source/gui/widgets/listbox.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index a44d7d47..2de8d4c2 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1639,7 +1639,20 @@ namespace nana /// absolute position of the last displayed item index_pair last_displ() const { - return absolute ( last_displ() ); + return absolute ( last() ); + } + + /// can be used as the absolute position of the first absolute item, or as the display pos of the first displayed item + index_pair first() const + { + index_pair fst{0,npos}; + good_item(fst,fst); + return fst; + } + /// absolute position of the first displayed item + index_pair first_displ() const + { + return absolute ( first() ); } bool good(size_type cat) const From 65ebdccd907d81e84a92b87b59052ab04e4f4132 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:54:37 +0200 Subject: [PATCH 007/105] FIX: let check this 0,0 is good --- source/gui/widgets/listbox.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 2de8d4c2..de1a04ce 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1664,32 +1664,32 @@ namespace nana { return ((pos.cat < list_.size()) && (pos.item < size_item(pos.cat))); } - + /// if good return the same item (in arg item), or just the next cat and true, but If fail return false bool good_item(index_pair pos, index_pair& item) const { if (!good(pos.cat)) - return false; + return false; // cat out of range if (pos.is_category()) { - item = pos; - if (0 == pos.cat) - item.item = 0; - + item = pos; // return the cat self + if (0 == pos.cat) // but for cat 0 return first item + item.item = 0; // let check this is good + else return true; } - auto i = _m_at(pos.cat); + auto i = _m_at(pos.cat); // pos is not a cat and i point to it cat if (pos.item < i->items.size()) { - item = pos; + item = pos; // good item, return it return true; } - if (++i == list_.end()) + if (++i == list_.end()) // item out of range and no more cat return false; - item.cat = pos.cat + 1; + item.cat = pos.cat + 1; // select the next cat item.item = npos; return true; } From bcb2d5b6fc002d326e56a7269dd5b5b5d0b451bc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:55:57 +0200 Subject: [PATCH 008/105] FIX: crash if finding pos of cat --- 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 de1a04ce..6fc0bdd9 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1697,7 +1697,7 @@ namespace nana ///Translate relative position (position in display) into absolute position (original data order) size_type absolute(const index_pair& display_pos) const { - if(sorted_index_ == npos) + if(sorted_index_ == npos || display_pos.item == npos) return display_pos.item ; auto & catobj = *_m_at(display_pos.cat); From d4d1a79af89fbf4a3cbd390ff3cd3ee52a8b5d90 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:57:44 +0200 Subject: [PATCH 009/105] FIX: a +1 error during navigation of listbox with categories --- include/nana/gui/widgets/listbox.hpp | 1 + source/gui/widgets/listbox.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 8a2f1938..fc487460 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -366,6 +366,7 @@ namespace nana return iter; } + /// Append an item at abs end of the category, using the strins to set the columns (cells) of the new item. void append(std::initializer_list); size_type columns() const; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 6fc0bdd9..8618d4c0 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1747,13 +1747,12 @@ namespace nana return true; } - if(list_.size() <= from.cat) return false; - if(from.is_category()) { // this is a category, so... // and offs is not 0, this category would not be candidated. // the algorithm above to calc the offset item is always starting with a item. + // we can not select, navigate or highlight begining from a cat? --offs; from.item = 0; } @@ -1762,7 +1761,7 @@ namespace nana if(icat->expand) { - std::size_t item_left_in_this_cat = icat->items.size() -1- from.item; + std::size_t item_left_in_this_cat = icat->items.size()- from.item -1; if(offs <= item_left_in_this_cat ) { item = from; @@ -1771,14 +1770,15 @@ namespace nana } else { - offs -= item_left_in_this_cat ; + offs -= (item_left_in_this_cat+1) ; item = from; - item.item += item_left_in_this_cat ; + item.item += item_left_in_this_cat ;// select the last item } } ++from.cat; ++icat; + for(; icat != list_.end(); ++icat, ++from.cat) { item.cat = from.cat; @@ -2203,7 +2203,7 @@ namespace nana } else { - new_where.second = (y - header_visible_px() + 1) / item_size; + new_where.second = ((y + 1) - header_visible_px()) / item_size; // y>1 ! new_where.first = parts::lister; if(checkable) { @@ -3444,7 +3444,7 @@ namespace nana { auto i = ess_->lister.cat_container().begin(); std::advance(i, pos.cat); - cat_ = &(*i); + cat_ = &(*i); // what is pos is a cat? } } @@ -3489,7 +3489,7 @@ namespace nana /// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected item_proxy & item_proxy::select(bool s) { - auto & m = cat_->items.at(pos_.item); // a ref to the real item + auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat? if(m.flags.selected == s) return *this; // ignore if no change m.flags.selected = s; // actually change selection From 7863dcdba63c82b7d60122ac8c6a58537460a618 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:59:59 +0200 Subject: [PATCH 010/105] FIX: crash in page down and home of a listbox with categories, trying to create an item_proxy {cat, npos} and select it --- source/gui/widgets/listbox.cpp | 48 ++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8618d4c0..176b335a 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1598,17 +1598,17 @@ namespace nana cat_proxy cpx{ess_,cat}; for (item_proxy &it : cpx ) - { + { if (it.selected() != sel) - changed = true; + changed = true; it.select(sel); - if (sel) // not check for single_selection_ + if (sel) // not check for single_selection_ last_selected_abs = it->pos(); else if (last_selected_abs == it->pos()) - last_selected_abs.set_both(npos); - } + last_selected_abs.set_both(npos); + } last_selected_abs = index_pair{cat,npos}; return changed; } @@ -1653,7 +1653,7 @@ namespace nana index_pair first_displ() const { return absolute ( first() ); - } + } bool good(size_type cat) const { @@ -1676,7 +1676,7 @@ namespace nana if (0 == pos.cat) // but for cat 0 return first item item.item = 0; // let check this is good else - return true; + return true; } auto i = _m_at(pos.cat); // pos is not a cat and i point to it cat @@ -1738,7 +1738,7 @@ namespace nana /// all arg are relative to display order, or all are absolute, but not mixed bool forward(index_pair from, size_type offs, index_pair& item) const { - if(!good_item(from, from)) + if(!good_item(from, from)) return false; if(offs == 0) @@ -1771,7 +1771,7 @@ namespace nana else { offs -= (item_left_in_this_cat+1) ; - item = from; + item = from; item.item += item_left_in_this_cat ;// select the last item } } @@ -3378,21 +3378,35 @@ namespace nana if (! scrl.make_page_scroll(!up)) return; essence_->lister.select_for_all(false); - if (up) - item_proxy {essence_, essence_->scroll_y_abs()}.select(true); - else - { - index_pair idx{essence_->scroll_y_dpl()}; + + index_pair idx{essence_->scroll_y_dpl()}; + if (!up) essence_->lister.forward(idx, scrl.range()-1, idx); - item_proxy::from_display(essence_,idx).select(true); - } + + if (idx.is_item()) + item_proxy::from_display(essence_, idx).select(true); + else + if(!essence_->lister.single_selection()) + essence_->lister.categ_selected(idx.cat, true); + + essence_->trace_last_selected_item (); + break; } case keyboard::os_home: + { essence_->lister.select_for_all(false); - item_proxy::from_display(essence_, {0,0}).select(true); + + index_pair frst{essence_->lister.first()}; + if (frst.is_item()) + item_proxy::from_display(essence_, frst).select(true); + else + if(!essence_->lister.single_selection()) + essence_->lister.categ_selected(frst.cat, true); + essence_->trace_last_selected_item (); break; + } case keyboard::os_end: essence_->lister.select_for_all(false); item_proxy::from_display(essence_, essence_->lister.last()).select(true); From 6fd15140a927e4a6a8bef4d7a1f108e9b7ab5cf0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 14:56:15 +0200 Subject: [PATCH 011/105] introduce cat_proxy::select(bool sel) --- include/nana/gui/widgets/listbox.hpp | 3 ++ source/gui/widgets/listbox.cpp | 57 ++++++++++++++++++---------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index fc487460..0e7d76b1 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -374,6 +374,9 @@ namespace nana cat_proxy& text(nana::string); nana::string text() const; + cat_proxy & select(bool); + bool selected() const; + /// Behavior of a container void push_back(nana::string); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 176b335a..9e63f0f6 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1592,26 +1592,7 @@ namespace nana } /// set all items in cat to selection sel, emiting events, actualizing last_selected_abs, but not check for single_selection_ - bool categ_selected(size_type cat, bool sel) - { - bool changed = false; - - cat_proxy cpx{ess_,cat}; - for (item_proxy &it : cpx ) - { - if (it.selected() != sel) - changed = true; - it.select(sel); - - if (sel) // not check for single_selection_ - last_selected_abs = it->pos(); - - else if (last_selected_abs == it->pos()) - last_selected_abs.set_both(npos); - } - last_selected_abs = index_pair{cat,npos}; - return changed; - } + bool categ_selected(size_type cat, bool sel); void reverse_categ_selected(size_type categ) { @@ -2458,7 +2439,7 @@ namespace nana } } - nana::string es_lister::to_string(const export_options& exp_opt) const + nana::string es_lister::to_string(const export_options& exp_opt) const { nana::string list_str; bool first{true}; @@ -2479,6 +2460,22 @@ namespace nana return list_str ; } + bool es_lister::categ_selected(size_type cat, bool sel) + { + bool changed = false; // we need this?? + + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) + { + if (it.selected() != sel) + changed = true; + it.select(sel); + } + + last_selected_abs = last_selected_dpl = index_pair {cat, npos}; + + return changed; // we need this?? + } class drawer_header_impl { @@ -3737,6 +3734,24 @@ namespace nana } } + cat_proxy & cat_proxy::select(bool sel) + { + for (item_proxy &it : *this ) + it.select(sel); + + ess_->lister.last_selected_abs = + ess_->lister.last_selected_dpl = index_pair {this->pos_, npos}; + + return *this; + } + bool cat_proxy::selected() const + { + for (item_proxy &it : *this ) + if (!it.selected()) + return false; + return true; + } + auto cat_proxy::columns() const -> size_type { return ess_->header.cont().size(); From df22696e25a5736559fb0e14f397a0eb8f639dac Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 7 May 2015 22:42:04 +0200 Subject: [PATCH 012/105] comments... --- include/nana/gui/widgets/listbox.hpp | 65 +++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 0e7d76b1..01fe6ae4 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -163,9 +163,9 @@ namespace nana typedef std::vector selection; - //struct essence_t - //@brief: this struct gives many data for listbox, - // the state of the struct does not effect on member funcions, therefore all data members are public. + /// struct essence_t + ///@brief: this struct gives many data for listbox, + /// the state of the struct does not effect on member funcions, therefore all data members are public. struct essence_t; struct category_t; @@ -366,7 +366,7 @@ namespace nana return iter; } - /// Append an item at abs end of the category, using the strins to set the columns (cells) of the new item. + /// Appends one item at the end of this category with the specifies text in the column fields void append(std::initializer_list); size_type columns() const; @@ -481,12 +481,63 @@ namespace nana } }//end namespace drawerbase -/*! \brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. +/*! \class listbox +\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. A category is a text with can be \a selected, \a checked and \a expanded to show the items. An item is formed by \a column-fields, each corresponding to one of the \a headers. An item can be \a selected and \a checked. -The user can \a drag the header to \a reisize it or to \a reorganize it. -By \a clicking on a header the list get \a reordered, first up, and then down alternatively. +The user can \a drag the header to \a resize it or to \a reorganize it. +By \a clicking on one header the list get \a reordered, first up, and then down alternatively. + +1. The resolver is used to resolute an object of the specified type for a listbox item. +2. The any_objective of listbox have a 2-Dimension indexing. The first dimension is for the category, and the second one is for the item of the specified category. + int main() + { + using namespace nana::gui; + form fm; + listbox lb(fm, nana::rectangle(10, 10, 280, 120)); + lb.append_header(STR("Header"), 200); + lb.append_item(STR("int")); + lb.append_item(STR("double")); + lb.anyobj(0, 0, 10); + lb.anyobj(0, 1, 0.1); + int * pi = lb.anyobj(0, 0); // it returns a nullptr if there is not an int object specified. + double * pd = lb.anyobj(0, 1); // it returns a nullptr if there is not an double object specified. + fm.show(); + exec(); + } +3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. +4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: + Irreflexivity (comp(x, x) returns false) + and + antisymmetry(comp(a, b) != comp(b, a) returns true) + A simple example. + bool sort_compare( const nana::string& s1, nana::any*, + const nana::string& s2, nana::any*, bool reverse) + { + return (reverse ? s1 > s2 : s1 < s2); + } + listbox.set_sort_compare(0, sort_compare); + The listbox supports attaching a customer's object for each item, therefore the items can be + sorted by comparing these customer's object. + bool sort_compare( const nana::string&, nana::any* o1, + const nana::string&, nana::any* o2, bool reverse) + { + if(o1 && o2) //some items may not attach a customer object. + { + int * i1 = o1->get(); + int * i2 = o2->get(); + return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2)); + ;//some types may not be int. + } + return false; + } + listbox.anyobj(0, 0, 10); //the type of customer's object is int. + listbox.anyobj(0, 0, 20); +\todo doc: actualize this example listbox.at(0)... +\see nana::drawerbase::listbox::cat_proxy +\see nana::drawerbase::listbox::item_proxy +\example listbox_Resolver.cpp */ class listbox : public widget_object, From 444449dfaa24172b6e8f609eea96bdcdc176cf53 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 7 May 2015 22:48:20 +0200 Subject: [PATCH 013/105] let listbox append_header return the pos of the new header --- include/nana/gui/widgets/listbox.hpp | 3 ++- source/gui/widgets/listbox.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 01fe6ae4..34046a6f 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -561,9 +561,10 @@ By \a clicking on one header the list get \a reordered, first up, and then down void auto_draw(bool); ///); ///(cont_.size())); + return cont_.back().index; } void item_width(size_type pos, unsigned width) { - if (pos >= cont_.size()) - return; - for(auto & m : cont_) - { if(m.index == pos) + { m.pixels = width; + return; } } @@ -3994,11 +3993,12 @@ namespace nana _m_ess().set_auto_draw(ad); } - void listbox::append_header(nana::string text, unsigned width) + listbox::size_type listbox::append_header(nana::string text, unsigned width) { auto & ess = _m_ess(); - ess.header.create(std::move(text), width); + listbox::size_type index = ess.header.create(std::move(text), width); ess.update(); + return index; } listbox& listbox::header_width(size_type pos, unsigned pixels) From 371633f23f7fabf0dc7c263bc230d5f2787ee3c4 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 7 May 2015 22:50:26 +0200 Subject: [PATCH 014/105] listbox auto_width set the column width to fit the current longest text --- include/nana/gui/widgets/listbox.hpp | 14 ++++++++------ source/gui/widgets/listbox.cpp | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 34046a6f..ca4bb8ed 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -367,7 +367,7 @@ namespace nana } /// Appends one item at the end of this category with the specifies text in the column fields - void append(std::initializer_list); + void append(std::initializer_list); size_type columns() const; @@ -559,15 +559,17 @@ By \a clicking on one header the list get \a reordered, first up, and then down listbox(window, bool visible); listbox(window, const rectangle& = {}, bool visible = true); - void auto_draw(bool); ///); ///); ///< Appends categories at the end cat_proxy insert(cat_proxy, nana::string); cat_proxy at(size_type pos) const; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8a979678..3588576f 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -412,7 +412,7 @@ namespace nana { m.pixels = width; return; - } + } } unsigned item_width(size_type pos) const @@ -4008,6 +4008,24 @@ namespace nana ess.update(); return *this; } + unsigned listbox::auto_width(size_type pos, unsigned max) + { + unsigned max_w{0}; + auto & ess = _m_ess(); + for (const auto &cat : ess.lister.cat_container()) + for (const auto &it : cat.items ) + { + if (pos >= it.cells.size()) continue; + // precalcule text geometry + unsigned ts = static_cast ( ess.graph->text_extent_size(it.cells[pos].text).width); + if (max_w < ts) + max_w = ts; + } + if (!max_w) return 0; + header_width(pos, max_w < max ? max_w : max); + ess.update(); + return max_w; + } unsigned listbox::header_width(size_type pos) const { From e696fff7791f1dcf3f92cdaff0ae30d88f8b7bc3 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 8 May 2015 00:31:32 +0200 Subject: [PATCH 015/105] implement double click to auto resize a column in listbox --- include/nana/gui/widgets/listbox.hpp | 19 ++--------- source/gui/widgets/listbox.cpp | 47 +++++++++++++++++++--------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index ca4bb8ed..87309008 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -477,6 +477,9 @@ namespace nana color_proxy header_grabbed{ static_cast(0x8BD6F6)}; color_proxy header_floated{ static_cast(0xBABBBC)}; color_proxy item_selected{ static_cast(0xD5EFFC) }; + + unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ?? + ext_w = 5; }; } }//end namespace drawerbase @@ -490,22 +493,6 @@ The user can \a drag the header to \a resize it or to \a reorganize it. By \a clicking on one header the list get \a reordered, first up, and then down alternatively. 1. The resolver is used to resolute an object of the specified type for a listbox item. -2. The any_objective of listbox have a 2-Dimension indexing. The first dimension is for the category, and the second one is for the item of the specified category. - int main() - { - using namespace nana::gui; - form fm; - listbox lb(fm, nana::rectangle(10, 10, 280, 120)); - lb.append_header(STR("Header"), 200); - lb.append_item(STR("int")); - lb.append_item(STR("double")); - lb.anyobj(0, 0, 10); - lb.anyobj(0, 1, 0.1); - int * pi = lb.anyobj(0, 0); // it returns a nullptr if there is not an int object specified. - double * pd = lb.anyobj(0, 1); // it returns a nullptr if there is not an double object specified. - fm.show(); - exec(); - } 3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. 4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: Irreflexivity (comp(x, x) returns false) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3588576f..9c8eccf7 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2304,7 +2304,29 @@ namespace nana break; } } - private: + + unsigned auto_width(size_type pos, unsigned max=3000) /// \todo introduce parametr max_header_width + { + unsigned max_w{0} ; + for (const auto &cat : lister.cat_container()) + for (const auto &it : cat.items ) + { + if (pos >= it.cells.size()) continue; + // precalcule text geometry + unsigned ts = static_cast ( graph->text_extent_size(it.cells[pos].text).width); + if (max_w < ts) + max_w = ts; + } + if (!max_w) return 0; + + 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); + return max_w; + } + + private: void _m_answer_scroll(const arg_mouse& arg) { if(arg.evt_code == event_code::mouse_move && arg.left_button == false) return; @@ -2907,7 +2929,7 @@ namespace nana cell_txtcolor = m_cell.custom_format->fgcolor; } - int ext_w = 5; + int ext_w = essence_->scheme_ptr->ext_w; if(first && essence_->checkable) // draw the checkbox if need, only before the first column (display_order=0 ?) { ext_w += 18; @@ -3306,6 +3328,14 @@ namespace nana void trigger::dbl_click(graph_reference graph, const arg_mouse&) { + if (essence_->pointer_where.first == essence_t::parts::header) + if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) + { + if (essence(). auto_width(drawer_header_->item_spliter() )) // ? in order + essence().update(); + return; + } + if (essence_->pointer_where.first != essence_t::parts::lister) return; @@ -4010,19 +4040,8 @@ namespace nana } unsigned listbox::auto_width(size_type pos, unsigned max) { - unsigned max_w{0}; auto & ess = _m_ess(); - for (const auto &cat : ess.lister.cat_container()) - for (const auto &it : cat.items ) - { - if (pos >= it.cells.size()) continue; - // precalcule text geometry - unsigned ts = static_cast ( ess.graph->text_extent_size(it.cells[pos].text).width); - if (max_w < ts) - max_w = ts; - } - if (!max_w) return 0; - header_width(pos, max_w < max ? max_w : max); + unsigned max_w = ess.auto_width(pos, max); ess.update(); return max_w; } From f0f6246ccc7acf2b7f4b77fe38d0126d8a268086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rajko=20=C4=90or=C4=91evi=C4=87?= Date: Sun, 10 May 2015 12:01:35 +0200 Subject: [PATCH 016/105] Letting cmake to decide which standard to use, if compiler doesn't support c++14 it will fall back to c++11 as was before. --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dba9e2c9..242a1ea2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/include/nana/) if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(NANA_SOURCE_DIR ${CMAKE_SOURCE_DIR}/source) @@ -161,3 +161,5 @@ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) + +set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) From f4ceafbe6cc48bd31947f59aed2d59fb57110489 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 10 May 2015 15:28:59 +0200 Subject: [PATCH 017/105] testing and doxy comment audio and screen --- include/nana/audio/player.hpp | 5 ++++- include/nana/gui/screen.hpp | 17 ++++++++++++++--- source/audio/detail/audio_stream.cpp | 3 ++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/nana/audio/player.hpp b/include/nana/audio/player.hpp index 278e0ecc..24378214 100644 --- a/include/nana/audio/player.hpp +++ b/include/nana/audio/player.hpp @@ -4,7 +4,10 @@ #include namespace nana{ namespace audio -{ /// play an audio file in Windows WAV format +{ /// class player + /// \brief play an audio file in PCM Windows WAV format + /// + /// \include audio_player.cpp class player : private nana::noncopyable { diff --git a/include/nana/gui/screen.hpp b/include/nana/gui/screen.hpp index ef9126e8..06c344ee 100644 --- a/include/nana/gui/screen.hpp +++ b/include/nana/gui/screen.hpp @@ -34,27 +34,38 @@ namespace nana virtual const ::nana::rectangle& workarea() const = 0; }; + /// Provides some functions to get the metrics of the monitors \include screen.cpp class screen { struct implement; public: - static ::nana::size desktop_size(); - static ::nana::size primary_monitor_size(); + /// gets the size in pixel of the whole virtual desktop + static ::nana::size desktop_size(); + + /// gets the resolution in pixel of the primary monitor, + /// if there is only one monitor installed in the system, + /// the return value of primary_monitor_size is equal to desktop_size's. + static ::nana::size primary_monitor_size(); + screen(); /// Reload has no preconditions, it's safe to call on moved-from void reload(); - /// Returns the number of display monitors + /// Returns the number of display monitors installed in the system std::size_t count() const; + /// gets the display monitor that contains the specified point display& from_point(const point&); + + /// gets the display monitor that contains the specified window display& from_window(window); display& get_display(std::size_t index) const; display& get_primary() const; + /// applies a given function to all display monitors void for_each(std::function) const; private: std::shared_ptr impl_; diff --git a/source/audio/detail/audio_stream.cpp b/source/audio/detail/audio_stream.cpp index 96def3d9..998b85bf 100644 --- a/source/audio/detail/audio_stream.cpp +++ b/source/audio/detail/audio_stream.cpp @@ -8,7 +8,8 @@ namespace nana{ namespace audio //class audio_stream bool audio_stream::open(const nana::string& file) { - fs_.open(static_cast(nana::charset(file)), std::ios::binary); + std::string fname{nana::charset(file)};//static_cast() + fs_.open(fname, std::ios::binary); if(fs_) { wave_spec::master_riff_chunk riff; From 990de7867b799612881ec03e667cf7490f683f13 Mon Sep 17 00:00:00 2001 From: beru Date: Sat, 16 May 2015 21:10:20 +0900 Subject: [PATCH 018/105] add OFN_NOCHANGEDIR flag to OPENFILENAME::Flags in nana::filebox::show http://blogs.msdn.com/b/oldnewthing/archive/2010/11/12/10089878.aspx setting OFN_NOCHANGEDIR flag to OPENFILENAME::Flags is effective for GetOpenFileName API on Windows7. add const qualifier to nana::paint::graphics::save_as_file add support for small icon on Windows. The system displays the large icon in the ALT+TAB dialog box, and the small icon in the window caption. https://msdn.microsoft.com/en-us/library/windows/desktop/ms632643%28v=vs.85%29.aspx --- .../gui/detail/native_window_interface.hpp | 2 ++ include/nana/gui/detail/window_manager.hpp | 4 ++- include/nana/gui/programming_interface.hpp | 3 ++ include/nana/paint/detail/image_bmp.hpp | 6 ++++ include/nana/paint/detail/image_ico.hpp | 1 + .../paint/detail/image_impl_interface.hpp | 1 + include/nana/paint/graphics.hpp | 2 +- include/nana/paint/image.hpp | 1 + source/gui/detail/native_window_interface.cpp | 24 +++++++++++++ source/gui/detail/window_manager.cpp | 35 +++++++++++++++---- source/gui/filebox.cpp | 1 + source/gui/programming_interface.cpp | 10 ++++++ source/paint/graphics.cpp | 2 +- source/paint/image.cpp | 32 +++++++++++++++++ 14 files changed, 114 insertions(+), 10 deletions(-) diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index 39cd7c49..66f6ac94 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -45,6 +45,8 @@ namespace detail static void enable_dropfiles(native_window_type, bool); static void enable_window(native_window_type, bool); static bool window_icon(native_window_type, const paint::image&); + // (On Windows) The system displays the large icon in the ALT+TAB dialog box, and the small icon in the window caption. + static bool window_icon(native_window_type, const paint::image& big_icon, const paint::image& small_icon); static void activate_owner(native_window_type); static void activate_window(native_window_type); static void close_window(native_window_type); diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index 37c9c150..1d9d70b2 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -112,7 +112,6 @@ namespace detail void signal_fire_caption(core_window_t*, const nana::char_t*); nana::string signal_fire_caption(core_window_t*); void event_filter(core_window_t*, bool is_make, event_code); - void default_icon(const nana::paint::image&); bool available(core_window_t*); bool available(core_window_t *, core_window_t*); @@ -133,7 +132,10 @@ namespace detail //@brief: Delete window handle, the handle type must be a root and a frame. void destroy_handle(core_window_t*); + void default_icon(const paint::image&); + void default_icon(const paint::image& big_icon, const paint::image& small_icon); void icon(core_window_t*, const paint::image&); + void icon(core_window_t*, const paint::image& big_icon, const paint::image& small_icon); //show //@brief: show or hide a window diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index c2430ccd..d1a0536f 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -120,7 +120,10 @@ namespace API } void window_icon_default(const paint::image&); + void window_icon_default(const paint::image& big_icon, const paint::image& small_icon); void window_icon(window, const paint::image&); + void window_icon(window, const paint::image& big_icon, const paint::image& small_icon); + bool empty_window(window); ///< Determines whether a window is existing. bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window. void enable_dropfiles(window, bool); diff --git a/include/nana/paint/detail/image_bmp.hpp b/include/nana/paint/detail/image_bmp.hpp index 5397faef..8ffba1ba 100644 --- a/include/nana/paint/detail/image_bmp.hpp +++ b/include/nana/paint/detail/image_bmp.hpp @@ -75,6 +75,12 @@ namespace nana{ namespace paint this->close(); } + bool open(void* buff, size_t sz) + { + // TODO: read a BMP file from memory + return false; + } + bool open(const nana::char_t* filename) { if(nullptr == filename) return false; diff --git a/include/nana/paint/detail/image_ico.hpp b/include/nana/paint/detail/image_ico.hpp index 8c66d19b..58a31d00 100644 --- a/include/nana/paint/detail/image_ico.hpp +++ b/include/nana/paint/detail/image_ico.hpp @@ -23,6 +23,7 @@ namespace nana{ namespace paint image_ico(bool is_ico); bool open(const nana::char_t* filename); + bool open(void* buff, size_t sz); bool alpha_channel() const; bool empty() const; void close(); diff --git a/include/nana/paint/detail/image_impl_interface.hpp b/include/nana/paint/detail/image_impl_interface.hpp index b2a7df50..b1fa8d37 100644 --- a/include/nana/paint/detail/image_impl_interface.hpp +++ b/include/nana/paint/detail/image_impl_interface.hpp @@ -16,6 +16,7 @@ namespace nana{ namespace paint{ typedef nana::paint::graphics& graph_reference; virtual ~image_impl_interface() = 0; //The destructor is defined in ../image.cpp virtual bool open(const nana::char_t* filename) = 0; + virtual bool open(void* buff, size_t sz) = 0; // reads image from memory virtual bool alpha_channel() const = 0; virtual bool empty() const = 0; virtual void close() = 0; diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index aac4712a..e790fc89 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -130,7 +130,7 @@ namespace nana void setsta(); ///< Clears the status if the graphics object had been changed void set_changed(); void release(); - void save_as_file(const char*); + void save_as_file(const char*) const; // saves image as a bitmap file void set_color(const ::nana::color&); void set_text_color(const ::nana::color&); diff --git a/include/nana/paint/image.hpp b/include/nana/paint/image.hpp index b335a4fe..4f9fa0df 100644 --- a/include/nana/paint/image.hpp +++ b/include/nana/paint/image.hpp @@ -37,6 +37,7 @@ namespace paint image& operator=(const image& rhs); image& operator=(image&&); bool open(const nana::string& filename); + bool open_icon(void* buff, size_t sz); // opens a icon from memory bool empty() const; operator unspecified_bool_t() const; void close(); diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 0101a804..61e38772 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -537,6 +537,30 @@ namespace nana{ return false; } + bool native_interface::window_icon(native_window_type wd, const paint::image& big_icon, const paint::image& small_icon) + { +#if defined(NANA_WINDOWS) + HICON h_big_icon = paint::image_accessor::icon(big_icon); + HICON h_small_icon = paint::image_accessor::icon(small_icon); + if (h_big_icon || h_small_icon) + { + nana::detail::platform_spec::instance().keep_window_icon(wd, (!big_icon.empty() ? big_icon : small_icon)); + if (h_big_icon) { + ::SendMessage(reinterpret_cast(wd), WM_SETICON, ICON_BIG, reinterpret_cast(h_big_icon)); + } + if (h_small_icon) { + ::SendMessage(reinterpret_cast(wd), WM_SETICON, ICON_SMALL, reinterpret_cast(h_small_icon)); + } + return true; + } +#elif defined(NANA_X11) + return window_icon(wd, big_icon); +#endif + return false; + } + + + void native_interface::activate_owner(native_window_type wd) { #if defined(NANA_WINDOWS) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index b7719985..df217407 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -43,7 +43,8 @@ namespace detail root_register misc_register; handle_manager wd_register; signal_manager signal; - paint::image default_icon; + paint::image default_icon_big; + paint::image default_icon_small; }; //end struct wdm_private_impl @@ -199,11 +200,6 @@ namespace detail } } - void window_manager::default_icon(const paint::image& img) - { - impl_->default_icon = img; - } - bool window_manager::available(core_window_t* wd) { return impl_->wd_register.available(wd); @@ -264,7 +260,7 @@ namespace detail insert_frame(owner, wd); bedrock::inc_window(wd->thread_id); - this->icon(wd, impl_->default_icon); + this->icon(wd, impl_->default_icon_big, impl_->default_icon_small); return wd; } return nullptr; @@ -404,6 +400,18 @@ namespace detail } } + void window_manager::default_icon(const paint::image& img) + { + impl_->default_icon_big = img; + impl_->default_icon_small = img; + } + + void window_manager::default_icon(const nana::paint::image& big, const nana::paint::image& small) + { + impl_->default_icon_big = big; + impl_->default_icon_small = small; + } + void window_manager::icon(core_window_t* wd, const paint::image& img) { if(false == img.empty()) @@ -417,6 +425,19 @@ namespace detail } } + void window_manager::icon(core_window_t* wd, const paint::image& big_icon, const paint::image& small_icon) + { + if(!big_icon.empty() || !small_icon.empty()) + { + std::lock_guard lock(mutex_); + if (impl_->wd_register.available(wd)) + { + if(wd->other.category == category::root_tag::value) + native_interface::window_icon(wd->root, big_icon, small_icon); + } + } + } + //show //@brief: show or hide a window bool window_manager::show(core_window_t* wd, bool visible) diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index 14ab8b67..0e0171df 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -1021,6 +1021,7 @@ namespace nana if (!impl_->open_or_save) ofn.Flags = OFN_OVERWRITEPROMPT; //Overwrite prompt if it is save mode + ofn.Flags |= OFN_NOCHANGEDIR; if(FALSE == (impl_->open_or_save ? ::GetOpenFileName(&ofn) : ::GetSaveFileName(&ofn))) return false; diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index d6f8b483..5170b54b 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -359,11 +359,21 @@ namespace API restrict::window_manager.default_icon(img); } + void window_icon_default(const paint::image& big_icon, const paint::image& small_icon) + { + restrict::window_manager.default_icon(big_icon, small_icon); + } + void window_icon(window wd, const paint::image& img) { restrict::window_manager.icon(reinterpret_cast(wd), img); } + void window_icon(window wd, const paint::image& big_icon, const paint::image& small_icon) + { + restrict::window_manager.icon(reinterpret_cast(wd), big_icon, small_icon); + } + bool empty_window(window wd) { return (restrict::window_manager.available(reinterpret_cast(wd)) == false); diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 8e61e8dd..155d650e 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -812,7 +812,7 @@ namespace paint size_.width = size_.height = 0; } - void graphics::save_as_file(const char* file) + void graphics::save_as_file(const char* file) const { if(handle_) { diff --git a/source/paint/image.cpp b/source/paint/image.cpp index a6fcd598..dbcc6510 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -69,6 +69,31 @@ namespace paint return false; } + bool image_ico::open(void* buff, size_t sz) + { + close(); +#if defined(NANA_WINDOWS) + HICON handle = CreateIconFromResource((PBYTE)buff, sz, TRUE, 0x00030000); + if(handle) + { + ICONINFO info; + if (::GetIconInfo(handle, &info) != 0) + { + HICON * p = new HICON(handle); + ptr_ = std::shared_ptr(p, handle_deleter()); + size_.width = (info.xHotspot << 1); + size_.height = (info.yHotspot << 1); + ::DeleteObject(info.hbmColor); + ::DeleteObject(info.hbmMask); + return true; + } + } +#else + if(is_ico_){} //kill the unused compiler warning in Linux. +#endif + return false; + } + bool image_ico::alpha_channel() const { return false; @@ -235,6 +260,13 @@ namespace paint return false; } + bool image::open_icon(void* buff, size_t sz) + { + image::image_impl_interface * helper = new detail::image_ico(true); + image_ptr_ = std::shared_ptr(helper); + return helper->open(buff, sz); + } + bool image::empty() const { return ((nullptr == image_ptr_) || image_ptr_->empty()); From aac94e238b9247a37740dd17ee610992ec0aeb5d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 17 May 2015 09:47:58 +0800 Subject: [PATCH 019/105] input widgets keep focus when form/panel is clicked see API::ignore_mouse_focus --- include/nana/gui/detail/basic_window.hpp | 9 +++++---- include/nana/gui/programming_interface.hpp | 3 +++ source/gui/detail/basic_window.cpp | 5 +++-- source/gui/detail/linux_X11/bedrock.cpp | 17 ++++++++++++----- source/gui/detail/win32/bedrock.cpp | 22 +++++++++++++++------- source/gui/detail/window_manager.cpp | 2 +- source/gui/programming_interface.cpp | 20 ++++++++++++++++++++ source/gui/widgets/form.cpp | 5 +++-- source/gui/widgets/panel.cpp | 9 ++++++--- 9 files changed, 68 insertions(+), 24 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 659f4316..5534e738 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -21,7 +21,7 @@ #include namespace nana{ - class widget; //declaration ofr nana/widgets/widget.hpp + class widget; //declaration of nana/widgets/widget.hpp namespace detail { struct basic_window; @@ -165,9 +165,10 @@ namespace detail bool dropable :1; //Whether the window has make mouse_drop event. bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen. bool borderless :1; - bool make_bground_declared : 1; //explicitly make bground for bground effects - bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus. - unsigned Reserved :20; + bool make_bground_declared : 1; //explicitly make bground for bground effects + bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus. + bool ignore_mouse_focus : 1; //A flag indicates whether the widget accepts focus when clicking on it + unsigned Reserved :19; unsigned char tab; //indicate a window that can receive the keyboard TAB mouse_action action; }flags; diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index c2430ccd..57765e76 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -300,6 +300,9 @@ namespace API nana::mouse_action mouse_action(window); nana::element_state element_state(window); + + bool ignore_mouse_focus(window, bool ignore); ///< Enables/disables the mouse focus, it returns the previous state + bool ignore_mouse_focus(window); ///< Determines whether the mouse focus is enabled }//end namespace API }//end namespace nana diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 96aec1fa..16889dff 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -346,8 +346,9 @@ namespace nana flags.refreshing = false; flags.destroying = false; flags.borderless = false; - flags.make_bground_declared = false; - flags.ignore_menubar_focus = false; + flags.make_bground_declared = false; + flags.ignore_menubar_focus = false; + flags.ignore_mouse_focus = false; visible = false; diff --git a/source/gui/detail/linux_X11/bedrock.cpp b/source/gui/detail/linux_X11/bedrock.cpp index 44ccef61..d6ad0255 100644 --- a/source/gui/detail/linux_X11/bedrock.cpp +++ b/source/gui/detail/linux_X11/bedrock.cpp @@ -1027,12 +1027,19 @@ namespace detail { arg_keyboard argkey; brock.get_key_state(argkey); - auto the_next = brock.wd_manager.tabstop(msgwnd, !argkey.shift); - if(the_next) + auto tstop_wd = brock.wd_manager.tabstop(msgwnd, argkey.shift); + while (tstop_wd) { - brock.wd_manager.set_focus(the_next, false); - brock.wd_manager.do_lazy_refresh(the_next, true); - root_runtime->condition.tabstop_focus_changed = true; + if (!tstop_wd->flags.ignore_mouse_focus) + { + brock.wd_manager.set_focus(tstop_wd, false); + brock.wd_manager.do_lazy_refresh(msgwnd, false); + brock.wd_manager.do_lazy_refresh(tstop_wd, true); + root_runtime->condition.tabstop_focus_changed = true; + break; + } + + tstop_wd = brock.wd_manager.tabstop(tstop_wd, is_forward); } } else if(keyboard::alt == keychar) diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 4a9d0f11..1e44cb4e 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -935,7 +935,7 @@ namespace detail { pressed_wd = msgwnd; auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); - if(new_focus) + if(new_focus && (!new_focus->flags.ignore_mouse_focus)) { auto kill_focus = brock.wd_manager.set_focus(new_focus, false); if(kill_focus != new_focus) @@ -1393,13 +1393,21 @@ namespace detail { if((wParam == 9) && (false == (msgwnd->flags.tab & tab_type::eating))) //Tab { - auto the_next = brock.wd_manager.tabstop(msgwnd, (::GetKeyState(VK_SHIFT) >= 0)); - if(the_next) + bool is_forward = (::GetKeyState(VK_SHIFT) >= 0); + + auto tstop_wd = brock.wd_manager.tabstop(msgwnd, is_forward); + while (tstop_wd) { - brock.wd_manager.set_focus(the_next, false); - brock.wd_manager.do_lazy_refresh(msgwnd, false); - brock.wd_manager.do_lazy_refresh(the_next, true); - root_runtime->condition.tabstop_focus_changed = true; + if (!tstop_wd->flags.ignore_mouse_focus) + { + brock.wd_manager.set_focus(tstop_wd, false); + brock.wd_manager.do_lazy_refresh(msgwnd, false); + brock.wd_manager.do_lazy_refresh(tstop_wd, true); + root_runtime->condition.tabstop_focus_changed = true; + break; + } + + tstop_wd = brock.wd_manager.tabstop(tstop_wd, is_forward); } } else diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index b7719985..8188a1cb 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -1037,7 +1037,7 @@ namespace detail { ++i; core_window_t* ts = (i != end ? (*i) : tabs.front()); - return (ts != wd ? ts : 0); + return (ts != wd ? ts : nullptr); } else return tabs.front(); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index d6f8b483..b4238fbd 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -1284,5 +1284,25 @@ namespace API } return nana::element_state::normal; } + + bool ignore_mouse_focus(window wd, bool ignore) + { + auto iwd = reinterpret_cast(wd); + internal_scope_guard lock; + if (restrict::window_manager.available(iwd)) + { + auto state = iwd->flags.ignore_mouse_focus; + iwd->flags.ignore_mouse_focus = ignore; + return state; + } + return false; + } + + bool ignore_mouse_focus(window wd) + { + auto iwd = reinterpret_cast(wd); + internal_scope_guard lock; + return (restrict::window_manager.available(iwd) ? iwd->flags.ignore_mouse_focus : false); + } }//end namespace API }//end namespace nana diff --git a/source/gui/widgets/form.cpp b/source/gui/widgets/form.cpp index 0c8cfc43..eab587ad 100644 --- a/source/gui/widgets/form.cpp +++ b/source/gui/widgets/form.cpp @@ -18,9 +18,10 @@ namespace nana namespace form { //class trigger - void trigger::attached(widget_reference widget, graph_reference graph) + void trigger::attached(widget_reference wdg, graph_reference graph) { - wd_ = &widget; + wd_ = &wdg; + API::ignore_mouse_focus(wdg, true); } void trigger::refresh(graph_reference graph) diff --git a/source/gui/widgets/panel.cpp b/source/gui/widgets/panel.cpp index d360d916..8b09f6f0 100644 --- a/source/gui/widgets/panel.cpp +++ b/source/gui/widgets/panel.cpp @@ -20,10 +20,13 @@ namespace nana namespace panel { //class drawer - void drawer::attached(widget_reference widget, graph_reference) + void drawer::attached(widget_reference wdg, graph_reference) { - widget.caption(STR("Nana Panel")); - window_ = widget.handle(); + wdg.caption(STR("panel widget")); + window_ = wdg.handle(); + + API::ignore_mouse_focus(wdg, true); + } void drawer::refresh(graph_reference graph) From 80da9007ef1577b8911f44d08706bb9b318e864a Mon Sep 17 00:00:00 2001 From: beru Date: Sun, 17 May 2015 15:02:09 +0900 Subject: [PATCH 020/105] add functionality to associate label with other widget as a "for" attribute of HTML