From 5bc1568f3ee0951c2522fcb195e2a2a67ceec222 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 21 Jul 2015 01:14:23 +0800 Subject: [PATCH] change parameter type of click event from arg_mouse to arg_click --- include/nana/gui/detail/drawer.hpp | 4 +- include/nana/gui/detail/general_events.hpp | 8 +- include/nana/gui/widgets/button.hpp | 1 + include/nana/gui/widgets/checkbox.hpp | 2 +- include/nana/gui/widgets/label.hpp | 2 +- source/gui/detail/bedrock_pi.cpp | 14 +- source/gui/detail/drawer.cpp | 4 +- source/gui/detail/linux_X11/bedrock.cpp | 27 ++- source/gui/detail/win32/bedrock.cpp | 26 ++- source/gui/widgets/button.cpp | 40 +++- source/gui/widgets/checkbox.cpp | 2 +- source/gui/widgets/label.cpp | 2 +- source/gui/widgets/listbox.cpp | 233 ++++++++++----------- 13 files changed, 214 insertions(+), 151 deletions(-) diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index fa62974b..dfd98e88 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -46,7 +46,7 @@ namespace nana virtual void resizing(graph_reference, const arg_resizing&); virtual void resized(graph_reference, const arg_resized&); virtual void move(graph_reference, const arg_move&); - virtual void click(graph_reference, const arg_mouse&); + virtual void click(graph_reference, const arg_click&); virtual void dbl_click(graph_reference, const arg_mouse&); virtual void mouse_enter(graph_reference, const arg_mouse&); virtual void mouse_move(graph_reference, const arg_mouse&); @@ -100,7 +100,7 @@ namespace nana void bind(basic_window*); void typeface_changed(); - void click(const arg_mouse&); + void click(const arg_click&); void dbl_click(const arg_mouse&); void mouse_enter(const arg_mouse&); void mouse_move(const arg_mouse&); diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 507416bb..78db3232 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -512,6 +512,12 @@ namespace nana ::nana::window window_handle; ///< A handle to the event window }; + struct arg_click : public event_arg + { + ::nana::window window_handle; ///< A handle to the event window + bool by_mouse; ///< Determines whether the event is emitted by clicking mouse button + }; + /// provides some fundamental events that every widget owns. struct general_events { @@ -521,7 +527,7 @@ namespace nana basic_event mouse_leave; ///< the cursor leaves the window basic_event mouse_down; ///< the user presses the mouse button basic_event mouse_up; ///< the user presses the mouse button - basic_event click; ///< the window is clicked, but occurs after mouse_down and before mouse_up + basic_event click; ///< the window is clicked, but occurs after mouse_down and before mouse_up basic_event dbl_click; ///< the window is double clicked basic_event mouse_wheel; ///< the mouse wheel rotates while the window has focus basic_event mouse_dropfiles; ///< the mouse drops some external data while the window enable accepting files diff --git a/include/nana/gui/widgets/button.hpp b/include/nana/gui/widgets/button.hpp index 014a29f7..10699f26 100644 --- a/include/nana/gui/widgets/button.hpp +++ b/include/nana/gui/widgets/button.hpp @@ -45,6 +45,7 @@ namespace nana{ void mouse_up(graph_reference, const arg_mouse&) override; void key_char(graph_reference, const arg_keyboard&) override; void key_press(graph_reference, const arg_keyboard&) override; + void key_release(graph_reference, const arg_keyboard&) override; void focus(graph_reference, const arg_focus&) override; private: void _m_draw(graph_reference); diff --git a/include/nana/gui/widgets/checkbox.hpp b/include/nana/gui/widgets/checkbox.hpp index 22f87fff..021ab0a1 100644 --- a/include/nana/gui/widgets/checkbox.hpp +++ b/include/nana/gui/widgets/checkbox.hpp @@ -89,7 +89,7 @@ namespace drawerbase std::size_t checked() const; ///< Retrieves the index of the checkbox which is checked. std::size_t size() const; private: - void _m_checked(const arg_mouse&); + void _m_checked(const arg_click&); void _m_destroy(const arg_destroy&); private: std::vector ui_container_; diff --git a/include/nana/gui/widgets/label.hpp b/include/nana/gui/widgets/label.hpp index ba6a5cf0..0da88167 100644 --- a/include/nana/gui/widgets/label.hpp +++ b/include/nana/gui/widgets/label.hpp @@ -40,7 +40,7 @@ namespace nana void refresh(graph_reference) override; void mouse_move(graph_reference, const arg_mouse&) override; void mouse_leave(graph_reference, const arg_mouse&) override; - void click(graph_reference, const arg_mouse&) override; + void click(graph_reference, const arg_click&) override; private: impl_t * impl_; }; diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 64d1d354..0e6c3cf8 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -195,6 +195,16 @@ namespace nana switch (evt_code) { case event_code::click: + { + auto arg = dynamic_cast(&event_arg); + if (nullptr == arg) + return; + + wd->drawer.click(*arg); + if (!draw_only) + evts_ptr->click.emit(*arg); + } + break; case event_code::dbl_click: case event_code::mouse_enter: case event_code::mouse_move: @@ -211,10 +221,6 @@ namespace nana switch (evt_code) { - case event_code::click: - drawer_event_fn = &drawer::click; - evt_addr = &evts_ptr->click; - break; case event_code::dbl_click: drawer_event_fn = &drawer::dbl_click; evt_addr = &evts_ptr->dbl_click; diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index 084219d0..1cce7648 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -49,7 +49,7 @@ namespace nana overrided_ &= ~(1 << static_cast(event_code::move)); } - void drawer_trigger::click(graph_reference, const arg_mouse&) + void drawer_trigger::click(graph_reference, const arg_click&) { overrided_ &= ~(1 << static_cast(event_code::click)); } @@ -155,7 +155,7 @@ namespace nana realizer_->typeface_changed(graphics); } - void drawer::click(const arg_mouse& arg) + void drawer::click(const arg_click& arg) { _m_emit(event_code::click, arg, &drawer_trigger::click); } diff --git a/source/gui/detail/linux_X11/bedrock.cpp b/source/gui/detail/linux_X11/bedrock.cpp index f541f13a..6e31cbea 100644 --- a/source/gui/detail/linux_X11/bedrock.cpp +++ b/source/gui/detail/linux_X11/bedrock.cpp @@ -699,14 +699,17 @@ namespace detail bool dbl_click = (last_mouse_down_window == msgwnd) && (xevent.xbutton.time - last_mouse_down_time <= 400); last_mouse_down_time = xevent.xbutton.time; last_mouse_down_window = msgwnd; - auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); - if(new_focus && !new_focus->flags.ignore_mouse_focus) + if (Button1 == xevent.xbutton.button) //Sets the focus only if left button is pressed { - context.event_window = new_focus; - auto kill_focus = brock.wd_manager.set_focus(new_focus, false); - if(kill_focus != new_focus) - brock.wd_manager.do_lazy_refresh(kill_focus, false); + auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); + if (new_focus && !new_focus->flags.ignore_mouse_focus) + { + context.event_window = new_focus; + auto kill_focus = brock.wd_manager.set_focus(new_focus, false); + if (kill_focus != new_focus) + brock.wd_manager.do_lazy_refresh(kill_focus, false); + } } auto retain = msgwnd->together.events_ptr; @@ -774,7 +777,9 @@ namespace detail if((arg.button == ::nana::mouse::left_button) && hit) { msgwnd->flags.action = mouse_action::over; - arg.evt_code = event_code::click; + arg_click arg; + arg.window_handle = reinterpret_cast(msgwnd); + arg.by_mouse = true; emit_drawer(&drawer::click, msgwnd, arg, &context); fire_click = true; } @@ -794,7 +799,9 @@ namespace detail if(fire_click) { - arg.evt_code = event_code::click; + arg_click arg; + arg.window_handle = reinterpret_cast(msgwnd); + arg.by_mouse = true; evt_ptr->click.emit(arg); } @@ -806,7 +813,9 @@ namespace detail } else if(fire_click) { - arg.evt_code = event_code::click; + arg_click arg; + arg.window_handle = reinterpret_cast(msgwnd); + arg.by_mouse = true; msgwnd->together.events_ptr->click.emit(arg); } brock.wd_manager.do_lazy_refresh(msgwnd, false); diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 5475b227..9d98f2fe 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -949,12 +949,16 @@ namespace detail if(msgwnd->flags.enabled) { pressed_wd = msgwnd; - auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); - if(new_focus && (!new_focus->flags.ignore_mouse_focus)) + + if (WM_LBUTTONDOWN == message) //Sets focus only if left button is pressed { - auto kill_focus = brock.wd_manager.set_focus(new_focus, false); - if(kill_focus != new_focus) - brock.wd_manager.do_lazy_refresh(kill_focus, false); + auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window); + 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) + brock.wd_manager.do_lazy_refresh(kill_focus, false); + } } arg_mouse arg; @@ -1007,7 +1011,9 @@ namespace detail msgwnd->flags.action = mouse_action::over; if (::nana::mouse::left_button == arg.button) { - arg.evt_code = event_code::click; + arg_click arg; + arg.window_handle = reinterpret_cast(msgwnd); + arg.by_mouse = true; emit_drawer(&drawer::click, msgwnd, arg, &context); fire_click = true; } @@ -1021,7 +1027,9 @@ namespace detail if (fire_click) { - arg.evt_code = event_code::click; + arg_click arg; + arg.window_handle = reinterpret_cast(msgwnd); + arg.by_mouse = true; retain->click.emit(arg); } @@ -1033,7 +1041,9 @@ namespace detail } else if (fire_click) { - arg.evt_code = event_code::click; + arg_click arg; + arg.window_handle = reinterpret_cast(msgwnd); + arg.by_mouse = true; retain->click.emit(arg); } brock.wd_manager.do_lazy_refresh(msgwnd, false); diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index fd007531..aed15ec5 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -126,7 +126,6 @@ namespace nana{ namespace drawerbase attr_.e_state = element_state::pressed; attr_.keep_pressed = true; - _m_draw(graph); API::capture_window(*wdg_, true); API::lazy_refresh(); @@ -158,12 +157,20 @@ namespace nana{ namespace drawerbase void trigger::key_char(graph_reference, const arg_keyboard& arg) { - if (static_cast(keyboard::enter) == arg.key || static_cast(keyboard::space) == arg.key) + if (static_cast(keyboard::enter) == arg.key) emit_click(); } - void trigger::key_press(graph_reference, const arg_keyboard& arg) + void trigger::key_press(graph_reference graph, const arg_keyboard& arg) { + if (keyboard::space == static_cast(arg.key)) + { + attr_.e_state = element_state::pressed; + attr_.keep_pressed = true; + _m_draw(graph); + API::lazy_refresh(); + return; + } bool ch_tabstop_next; switch(arg.key) { @@ -179,6 +186,25 @@ namespace nana{ namespace drawerbase API::move_tabstop(*wdg_, ch_tabstop_next); } + void trigger::key_release(graph_reference graph, const arg_keyboard& arg) + { + if (arg.key != static_cast(keyboard::space)) + return; + + emit_click(); + + attr_.keep_pressed = false; + + if (element_state::pressed == attr_.e_state) + attr_.e_state = element_state::hovered; + else + attr_.e_state = element_state::normal; + + attr_.pushed = false; + _m_draw(graph); + API::lazy_refresh(); + } + void trigger::focus(graph_reference graph, const arg_focus& arg) { attr_.focused = arg.getting; @@ -343,14 +369,20 @@ namespace nana{ namespace drawerbase void trigger::emit_click() { + /* arg_mouse arg; arg.evt_code = event_code::click; - arg.window_handle = wdg_->handle(); + arg.window_handle = wdg_->handle(); //deprecated arg.ctrl = arg.shift = false; arg.button = ::nana::mouse::left_button; arg.mid_button = arg.right_button = false; arg.left_button = true; arg.pos.x = arg.pos.y = 1; + */ + + arg_click arg; + arg.window_handle = wdg_->handle(); + arg.by_mouse = false; API::emit_event(event_code::click, arg.window_handle, arg); } diff --git a/source/gui/widgets/checkbox.cpp b/source/gui/widgets/checkbox.cpp index 8993a8b7..d672726f 100644 --- a/source/gui/widgets/checkbox.cpp +++ b/source/gui/widgets/checkbox.cpp @@ -231,7 +231,7 @@ namespace checkbox return ui_container_.size(); } - void radio_group::_m_checked(const arg_mouse& arg) + void radio_group::_m_checked(const arg_click& arg) { for (auto & i : ui_container_) i.uiobj->check(arg.window_handle == i.uiobj->handle()); diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index 66e76027..b07bd8fb 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -730,7 +730,7 @@ namespace nana } } - void trigger::click(graph_reference, const arg_mouse&) + void trigger::click(graph_reference, const arg_click&) { //make a copy, because the listener may popup a window, and then //user moves the mouse. it will reset the url when the mouse is moving out from the element. diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 2507c2e7..38faca94 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -371,12 +371,11 @@ namespace nana bool visible(bool v) { - if(visible_ != v) - { - visible_ = v; - return true; - } - return false; + if (visible_ == v) + return false; + + visible_ = v; + return true; } bool sortable() const @@ -632,21 +631,23 @@ namespace nana return *this; } - nana::string to_string(const export_options& exp_opt) const - { - nana::string item_str; - bool first{true}; - for( size_type idx{}; idxscroll_y_dpl_refresh(); + } - void es_lister::scroll_refresh() - { - ess_->scroll_y_dpl_refresh(); - } - - void es_lister::move_select(bool upwards, bool unselect_previous, bool trace_selected) + void es_lister::move_select(bool upwards, bool unselect_previous, bool trace_selected) + { + auto next_selected_dpl = relative_pair ( last_selected_abs); // last_selected_dpl; // ?? + if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat { - auto next_selected_dpl = relative_pair ( last_selected_abs); // last_selected_dpl; // ?? - if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat + bool good = false; + for(size_type i = 0, size = list_.size(); i < size; ++i) // run all cat { - bool good = false; - for(size_type i = 0, size = list_.size(); i < size; ++i) // run all cat + if(size_item(i)) { - if(size_item(i)) - { - //The first category which contains at least one item. - next_selected_dpl.cat = i; - next_selected_dpl.item = 0; - good = true; - break; - } - } - if(! good ) return; // items in listbox : nothing to select (and an empty but visible cat?) - } - - //start moving - while(true) - { - if(upwards == false) - { - if(good(next_selected_dpl.cat)) - { - if (size_item(next_selected_dpl.cat) > next_selected_dpl.item + 1) - { - ++next_selected_dpl.item; - } - else - { - next_selected_dpl.item = 0; - if (size_categ() > next_selected_dpl.cat + 1) - ++next_selected_dpl.cat; - else - next_selected_dpl.cat = 0; - } - } - else - next_selected_dpl.set_both(0); - } - else - { - if (0 == next_selected_dpl.item) - { - //there is an item at least definitely, because the start pos is an available item. - do - { - if (0 == next_selected_dpl.cat) - next_selected_dpl.cat = size_categ() - 1; - else - --next_selected_dpl.cat; - - }while (0 == size_item(next_selected_dpl.cat)); - - next_selected_dpl.item = size_item(next_selected_dpl.cat) - 1; - } - else - --next_selected_dpl.item; - } - - if (good(next_selected_dpl.cat)) - { - expand(next_selected_dpl.cat, true); // revise expand - - if (good(next_selected_dpl)) - { - if (unselect_previous && !single_selection_ ) - select_for_all(false); - - /// 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::from_display(ess_, next_selected_dpl).select(true); - - if (trace_selected) - ess_->trace_item_dpl(next_selected_dpl); - } + //The first category which contains at least one item. + next_selected_dpl.cat = i; + next_selected_dpl.item = 0; + good = true; break; } - else break; } + if(! good ) return; // items in listbox : nothing to select (and an empty but visible cat?) } + //start moving + while(true) + { + if(upwards == false) + { + if(good(next_selected_dpl.cat)) + { + if (size_item(next_selected_dpl.cat) > next_selected_dpl.item + 1) + { + ++next_selected_dpl.item; + } + else + { + next_selected_dpl.item = 0; + if (size_categ() > next_selected_dpl.cat + 1) + ++next_selected_dpl.cat; + else + next_selected_dpl.cat = 0; + } + } + else + next_selected_dpl.set_both(0); + } + else + { + if (0 == next_selected_dpl.item) + { + //there is an item at least definitely, because the start pos is an available item. + do + { + if (0 == next_selected_dpl.cat) + next_selected_dpl.cat = size_categ() - 1; + else + --next_selected_dpl.cat; + + }while (0 == size_item(next_selected_dpl.cat)); + + next_selected_dpl.item = size_item(next_selected_dpl.cat) - 1; + } + else + --next_selected_dpl.item; + } + + if (good(next_selected_dpl.cat)) + { + expand(next_selected_dpl.cat, true); // revise expand + + if (good(next_selected_dpl)) + { + if (unselect_previous && !single_selection_ ) + select_for_all(false); + + /// 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::from_display(ess_, next_selected_dpl).select(true); + + if (trace_selected) + ess_->trace_item_dpl(next_selected_dpl); + } + break; + } + else break; + } + } + nana::string es_lister::to_string(const export_options& exp_opt) const + { + nana::string list_str; + bool first{true}; + for(auto & cat: cat_container()) { - nana::string list_str; - bool first{true}; - for(auto & cat: cat_container()) - { - if(first) - first=false; - else - list_str += (cat.text + exp_opt.endl); + if(first) + first=false; + else + list_str += (cat.text + exp_opt.endl); - for (auto i : cat.sorted) - { - auto& it= cat.items[i] ; - if(it.flags.selected || !exp_opt.only_selected_items) - list_str += (it.to_string(exp_opt) + exp_opt.endl); - } + for (auto i : cat.sorted) + { + auto& it= cat.items[i] ; + if(it.flags.selected || !exp_opt.only_selected_items) + list_str += (it.to_string(exp_opt) + exp_opt.endl); } - return list_str ; } + return list_str ; + } void es_lister::categ_selected(size_type cat, bool sel) { @@ -2567,7 +2567,7 @@ namespace nana { if(hd.visible) { - if((static_cast(hd.pixels) - 2 < x) && (x < static_cast(hd.pixels) + 3)) + if((static_cast(hd.pixels) < x + 2) && (x < static_cast(hd.pixels) + 3)) { item_spliter_ = hd.index; // original index return true; @@ -2617,9 +2617,8 @@ namespace nana essence_->header.item_width(item_spliter_, (new_w < static_cast(essence_->suspension_width + 20) ? essence_->suspension_width + 20 : new_w)); auto 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); - } + essence_->adjust_scroll_life(); return 2; }