diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index fca2b828..4443ef2c 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -58,7 +58,7 @@ namespace detail static nana::point window_position(native_window_type); static void move_window(native_window_type, int x, int y); static void move_window(native_window_type, const rectangle&); - static void bring_to_top(native_window_type); + static void bring_top(native_window_type, bool activated); static void set_window_z_order(native_window_type, native_window_type wd_after, z_order_action action_if_no_wd_after); static void window_size(native_window_type, const size&); diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 72386fe6..450fd4e3 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -158,7 +158,7 @@ namespace API void move_window(window, int x, int y); void move_window(window wd, const rectangle&); - void bring_to_top(window); + void bring_top(window, bool activated); bool set_window_z_order(window wd, window wd_after, z_order_action action_if_no_wd_after); nana::size window_size(window); diff --git a/include/nana/gui/widgets/form.hpp b/include/nana/gui/widgets/form.hpp index ed6a2fc6..9f4d1e2a 100644 --- a/include/nana/gui/widgets/form.hpp +++ b/include/nana/gui/widgets/form.hpp @@ -45,6 +45,8 @@ namespace nana form(window, const ::nana::size& = { 300, 200 }, const appearance& = {}); /// Creates a window at the point and size specified by rect, with the specified appearance. This window is always floating above its owner. form(window, const rectangle&, const appearance& = {}); + + void modality() const; }; class nested_form : public widget_object diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index d0110ba4..de67a203 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -81,6 +81,10 @@ namespace nana general_events& events() const; void umake_event(event_handle eh) const; ///< Deletes an event callback by a handle. + + widget& register_shortkey(char_t); ///< Registers a shortkey. To remove a registered key, pass 0. + + widget& take_active(bool activated, window take_if_not_activated); widget& tooltip(const nana::string&); operator dummy_bool_type() const; @@ -327,11 +331,6 @@ namespace nana API::activate_window(handle_); } - void bring_to_top() - { - API::bring_to_top(handle_); - } - window handle() const { return handle_; @@ -342,6 +341,11 @@ namespace nana return API::root(handle_); } + void bring_top(bool activated) + { + API::bring_top(handle(), activated); + } + window owner() const { return API::get_owner_window(handle_); @@ -362,9 +366,15 @@ namespace nana API::zoom_window(handle_, ask_for_max); } - bool is_zoomed(bool ask_for_max) const + bool is_zoomed(bool check_maximized) const { - return API::is_window_zoomed(handle_, ask_for_max); + return API::is_window_zoomed(handle_, check_maximized); + } + + widget_object& z_order(window wd_after, z_order_action action_if_no_wd_after) + { + API::set_window_z_order(handle_, wd_after, action_if_no_wd_after); + return *this; } protected: DrawerTrigger& get_drawer_trigger() diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 541bba9b..5c7f015f 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -933,7 +933,7 @@ namespace nana{ #endif } - void native_interface::bring_to_top(native_window_type wd) + void native_interface::bring_top(native_window_type wd, bool activated) { #if defined(NANA_WINDOWS) HWND native_wd = reinterpret_cast(wd); @@ -944,7 +944,7 @@ namespace nana{ HWND fg_wd = ::GetForegroundWindow(); DWORD fg_tid = ::GetWindowThreadProcessId(fg_wd, nullptr); ::AttachThreadInput(::GetCurrentThreadId(), fg_tid, TRUE); - ::ShowWindow(native_wd, SW_SHOWNORMAL); + ::ShowWindow(native_wd, activated ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE); ::SetWindowPos(native_wd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); ::SetWindowPos(native_wd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); ::AttachThreadInput(::GetCurrentThreadId(), fg_tid, FALSE); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 404c5c61..2ba00823 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -529,9 +529,9 @@ namespace API } } - void bring_to_top(window wd) + void bring_top(window wd, bool activated) { - restrict::interface_type::bring_to_top(root(wd)); + restrict::interface_type::bring_top(root(wd), activated); } bool set_window_z_order(window wd, window wd_after, z_order_action action_if_no_wd_after) diff --git a/source/gui/widgets/form.cpp b/source/gui/widgets/form.cpp index a6bb9df1..a95a9608 100644 --- a/source/gui/widgets/form.cpp +++ b/source/gui/widgets/form.cpp @@ -49,6 +49,11 @@ namespace nana form::form(window owner, const rectangle& r, const appearance& apr) : form_base_t(owner, false, r, apr) {} + + void form::modality() const + { + API::modal_window(handle()); + } //end class form //class nested_form diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 5c106f2a..5d41a9dc 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1059,15 +1059,14 @@ namespace nana{ namespace widgets secondary_pos.y = 0; unsigned len = 0; - auto & mtr = linemtr_[charpos.y]; - for (auto & ts : mtr.line_sections) + for (auto & ts : linemtr_[charpos.y].line_sections) { len = static_cast(ts.end - ts.begin); if (len >= secondary_pos.x) return true; ++secondary_pos.y; - secondary_pos.x -= static_cast(len); + secondary_pos.x -= len; } --secondary_pos.y; secondary_pos.x = len; @@ -1476,12 +1475,11 @@ namespace nana{ namespace widgets bool text_editor::getline(std::size_t pos, nana::string& text) const { - if(pos < textbase_.lines()) - { - text = textbase_.getline(pos); - return true; - } - return false; + if (textbase_.lines() <= pos) + return false; + + text = textbase_.getline(pos); + return true; } void text_editor::text(nana::string str) @@ -1634,12 +1632,11 @@ namespace nana{ namespace widgets bool text_editor::mask(nana::char_t ch) { - if(mask_char_ != ch) - { - mask_char_ = ch; - return true; - } - return false; + if (mask_char_ == ch) + return false; + + mask_char_ = ch; + return true; } unsigned text_editor::width_pixels() const @@ -2264,7 +2261,6 @@ namespace nana{ namespace widgets if(a.y != b.y) { textbase_.erase(a.y, a.x, nana::string::npos); - textbase_.erase(a.y + 1, b.y - a.y - 1); textbase_.erase(a.y + 1, 0, b.x); @@ -2420,7 +2416,7 @@ namespace nana{ namespace widgets if(static_cast(width) - points_.offset.x >= _m_endx()) { //Out of screen text area points_.offset.x = width - _m_endx() + 1; - string_type::size_type rest_size = lnstr.size() - points_.caret.x; + auto rest_size = lnstr.size() - points_.caret.x; points_.offset.x += static_cast(_m_text_extent_size(lnstr.c_str() + points_.caret.x, (rest_size >= static_cast(many) ? static_cast(many) : rest_size)).width); return true; } @@ -2506,14 +2502,14 @@ namespace nana{ namespace widgets void text_editor::_m_draw_string(int top, const ::nana::expr_color& clr, const nana::upoint& str_pos, const nana::string& linestr, bool if_mask) const { - int x = text_area_.area.x - points_.offset.x; - int xend = text_area_.area.x + static_cast(text_area_.area.width); + ::nana::point text_pos{ text_area_.area.x - points_.offset.x, top }; + const int xend = text_area_.area.x + static_cast(text_area_.area.width); if (if_mask && mask_char_) { nana::string maskstr; maskstr.append(linestr.size(), mask_char_); - graph_.string({ x, top }, maskstr, clr); + graph_.string(text_pos, maskstr, clr); return; } @@ -2539,20 +2535,20 @@ namespace nana{ namespace widgets std::size_t len = ent.end - ent.begin; unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((x + static_cast(str_w) > text_area_.area.x) && (x < xend)) + if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < xend)) { if (selected) { graph_.set_text_color(colors::white); - graph_.rectangle({ x, top, str_w, line_h_pixels }, true); + graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true); } - graph_.string({x, top}, ent.begin, len); + graph_.string(text_pos, ent.begin, len); } - x += static_cast(str_w); + text_pos.x += static_cast(str_w); } if (selected) - graph_.rectangle({ x, top, whitespace_w, line_h_pixels }, true); + graph_.rectangle({ text_pos, { whitespace_w, line_h_pixels } }, true); } else { @@ -2576,22 +2572,22 @@ namespace nana{ namespace widgets { std::size_t len = ent.end - ent.begin; unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((x + static_cast(str_w) > text_area_.area.x) && (x < xend)) + if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < xend)) { std::size_t pos = ent.begin - strbeg + str_pos.x; - if (pos + len <= a.x || pos >= b.x) + if ((pos + len <= a.x || pos >= b.x) || (a.x <= pos && pos + len <= b.x)) { - //NOT selected - graph_.set_text_color(clr); - graph_.string({ x, top }, ent.begin, len); - } - else if (a.x <= pos && pos + len <= b.x) - { - //Whole selected - graph_.rectangle({ x, top, str_w, line_h_pixels }, true); - graph_.set_text_color(colors::white); - graph_.string({x, top}, ent.begin, len); + //NOT selected or Wholly seleceted + if (a.x <= pos) + { + graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true); + graph_.set_text_color(colors::white); + } + else + graph_.set_text_color(clr); + + graph_.string(text_pos, ent.begin, len); } else if (pos <= a.x && a.x < pos + len) { //Partial selected @@ -2606,19 +2602,25 @@ namespace nana{ namespace widgets graph_.set_text_color(clr); if (_m_is_right_text(ent)) { //RTL - rtl_string(point{x, top}, ent.begin, len, str_w, head_w, sel_w); + rtl_string(text_pos, ent.begin, len, str_w, head_w, sel_w); } else { //LTR - graph_.string({ x, top }, ent.begin, a.x - pos); + graph_.string(text_pos, ent.begin, a.x - pos); - graph_.rectangle({x + static_cast(head_w), top, sel_w, line_h_pixels}, true); + auto part_pos = text_pos; + part_pos.x += static_cast(head_w); + + graph_.rectangle({ part_pos, { sel_w, line_h_pixels } }, true); graph_.set_text_color(colors::white); - graph_.string({ x + static_cast(head_w), top }, ent.begin + (a.x - pos), endpos - a.x); + graph_.string(part_pos, ent.begin + (a.x - pos), endpos - a.x); if (static_cast(endpos) < pos + len) - graph_.string({x + static_cast(head_w + sel_w), top}, ent.begin + (endpos - pos), pos + len - endpos); + { + part_pos.x += static_cast(sel_w); + graph_.string(part_pos, ent.begin + (endpos - pos), pos + len - endpos); + } } } } @@ -2630,20 +2632,20 @@ namespace nana{ namespace widgets if (_m_is_right_text(ent)) { //RTL graph_.set_text_color(clr); - rtl_string({x, top}, ent.begin, len, str_w, 0, sel_w); + rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w); } else { //LTR - graph_.rectangle({ x, top, sel_w, line_h_pixels }, true); + graph_.rectangle({ text_pos, { sel_w, line_h_pixels } }, true); graph_.set_text_color(colors::white); - graph_.string({ x, top }, ent.begin, endpos - pos); + graph_.string(text_pos, ent.begin, endpos - pos); graph_.set_text_color(clr); - graph_.string({x + static_cast(sel_w), top}, ent.begin + (endpos - pos), pos + len - endpos); + graph_.string(text_pos + ::nana::point(static_cast(sel_w), 0), ent.begin + (endpos - pos), pos + len - endpos); } } } - x += static_cast(str_w); + text_pos.x += static_cast(str_w); } } else if (a.y == str_pos.y) @@ -2652,43 +2654,43 @@ namespace nana{ namespace widgets { std::size_t len = ent.end - ent.begin; unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((x + static_cast(str_w) > text_area_.area.x) && (x < xend)) + if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < xend)) { graph_.set_text_color(clr); std::size_t pos = ent.begin - strbeg + str_pos.x; - if (pos + len <= a.x) + if ((pos + len <= a.x) || (a.x < pos)) //Not selected or Wholly selected { - //Not selected - graph_.string({x, top}, ent.begin, len); - } - else if (a.x < pos) - { - //Whole selected - graph_.rectangle({ x, top, str_w, line_h_pixels }, true, { 0x33, 0x99, 0xFF }); - graph_.set_text_color(colors::white); - graph_.string({x, top}, ent.begin, len); + if (a.x < pos) + { + graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true, { 0x33, 0x99, 0xFF }); + graph_.set_text_color(colors::white); + } + graph_.string(text_pos, ent.begin, len); } else { unsigned head_w = graph_.glyph_extent_size(ent.begin, len, 0, a.x - pos).width; if (_m_is_right_text(ent)) { //RTL - rtl_string(point{x, top}, ent.begin, len, str_w, head_w, str_w - head_w); + rtl_string(text_pos, ent.begin, len, str_w, head_w, str_w - head_w); } else { //LTR - graph_.string({ x, top }, ent.begin, a.x - pos); - graph_.rectangle({ x + static_cast(head_w), top, str_w - head_w, line_h_pixels }, true); + graph_.string(text_pos, ent.begin, a.x - pos); + + ::nana::point part_pos{ text_pos.x + static_cast(head_w), text_pos.y }; + + graph_.rectangle({ part_pos, {str_w - head_w, line_h_pixels } }, true); graph_.set_text_color(colors::white); - graph_.string({ x + static_cast(head_w), top }, ent.begin + a.x - pos, len - (a.x - pos)); + graph_.string(part_pos, ent.begin + a.x - pos, len - (a.x - pos)); } } } - x += static_cast(str_w); + text_pos.x += static_cast(str_w); } if (a.y <= static_cast(str_pos.y) && static_cast(str_pos.y) < b.y) - graph_.rectangle({ x, top, whitespace_w, line_h_pixels }, true); + graph_.rectangle({ text_pos, { whitespace_w, line_h_pixels } }, true); } else if (b.y == str_pos.y) { @@ -2696,37 +2698,37 @@ namespace nana{ namespace widgets { std::size_t len = ent.end - ent.begin; unsigned str_w = graph_.text_extent_size(ent.begin, len).width; - if ((x + static_cast(str_w) > text_area_.area.x) && (x < xend)) + if ((text_pos.x + static_cast(str_w) > text_area_.area.x) && (text_pos.x < xend)) { std::size_t pos = ent.begin - strbeg + str_pos.x; graph_.set_text_color(clr); if (pos + len <= b.x) { - graph_.rectangle({ x, top, str_w, line_h_pixels }, true); + graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true); graph_.set_text_color(colors::white); - graph_.string({ x, top }, ent.begin, len); + graph_.string(text_pos, ent.begin, len); } else if (pos <= b.x && b.x < pos + len) { unsigned sel_w = graph_.glyph_extent_size(ent.begin, len, 0, b.x - pos).width; if (_m_is_right_text(ent)) { //RTL - rtl_string(point{ x, top }, ent.begin, len, str_w, 0, sel_w); + rtl_string(text_pos, ent.begin, len, str_w, 0, sel_w); } else { - graph_.rectangle({ x, top, sel_w, line_h_pixels }, true); + graph_.rectangle({ text_pos, { sel_w, line_h_pixels } }, true); graph_.set_text_color(colors::white); - graph_.string({ x, top }, ent.begin, b.x - pos); + graph_.string(text_pos, ent.begin, b.x - pos); graph_.set_text_color(clr); - graph_.string({ x + static_cast(sel_w), top }, ent.begin + b.x - pos, len - (b.x - pos)); + graph_.string(text_pos + ::nana::point(static_cast(sel_w), 0), ent.begin + b.x - pos, len - (b.x - pos)); } } else - graph_.string({x, top}, ent.begin, len); + graph_.string(text_pos, ent.begin, len); } - x += static_cast(str_w); + text_pos.x += static_cast(str_w); } } } diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index 277365b5..205a4d9c 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -171,6 +171,21 @@ namespace nana API::umake_event(eh); } + widget& widget::register_shortkey(char_t key) + { + if (key) + API::register_shortkey(handle(), static_cast(key)); + else + API::unregister_shortkey(handle()); + return *this; + } + + widget& widget::take_active(bool activated, window take_if_not_activated) + { + API::take_active(handle(), activated, take_if_not_activated); + return *this; + } + widget& widget::tooltip(const nana::string& text) { nana::tooltip::set(*this, text);