From de9043e223084aab6dae8c2591aca381711e9202 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 23 Jul 2019 04:37:14 +0800 Subject: [PATCH 01/73] fix bug where listbox::item_proxy::empty behaves incorrectly --- include/nana/gui/widgets/listbox.hpp | 4 ++++ source/gui/widgets/listbox.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 4827a227..bdd08f59 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -824,6 +824,10 @@ namespace nana /// Determines whether the item is displayed on the screen bool displayed() const; + /// Determines whether the item_proxy refers to invalid item. + /** + * @return true if the item_proxy refers to an invalid item, false otherwise. + */ bool empty() const noexcept; /// Checks/unchecks the item diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 460e28f4..41347095 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -4762,7 +4762,7 @@ namespace nana bool item_proxy::empty() const noexcept { - return !ess_; + return !(ess_ && ess_->lister.good(pos_)); } item_proxy & item_proxy::check(bool ck, bool scroll_view) From 6c6d80b41474978ea7694071239635e170709639 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Sun, 28 Jul 2019 10:28:59 +0200 Subject: [PATCH 02/73] FIX 2. missed included in installed nana consumed with cmake --- build/cmake/install_nana.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/cmake/install_nana.cmake b/build/cmake/install_nana.cmake index 45636484..77faf037 100644 --- a/build/cmake/install_nana.cmake +++ b/build/cmake/install_nana.cmake @@ -6,7 +6,7 @@ if(NANA_CMAKE_INSTALL) # Is your responsability to ensure all compiler options are compatible with the compilation # of the project linking to the nana lib here generated target_sources(nana PRIVATE ${HEADERS}) - target_include_directories(nana PRIVATE ${NANA_INCLUDE_DIR}) + # target_include_directories(nana PRIVATE ${NANA_INCLUDE_DIR}) message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") # Actually in DESTDIR/CMAKE_INSTALL_PREFIX/lib but in windows there is no DESTDIR/ part. install(TARGETS nana @@ -15,6 +15,8 @@ if(NANA_CMAKE_INSTALL) RUNTIME DESTINATION bin) install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) # in ${CMAKE_INSTALL_PREFIX}/include/nana message("The Nana include files will be installed in ${CMAKE_INSTALL_PREFIX}/include") + target_include_directories(nana PUBLIC $ + $ ) else() # this is the prefered method to consume nana with cmake target_sources(nana PUBLIC ${HEADERS}) From 88f6af584c1db92382b2009675e173e993e6abd1 Mon Sep 17 00:00:00 2001 From: Ariel Vina-Rodriguez Date: Mon, 29 Jul 2019 00:01:25 +0200 Subject: [PATCH 03/73] delete commented code --- build/cmake/install_nana.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/build/cmake/install_nana.cmake b/build/cmake/install_nana.cmake index 77faf037..de51757d 100644 --- a/build/cmake/install_nana.cmake +++ b/build/cmake/install_nana.cmake @@ -6,7 +6,6 @@ if(NANA_CMAKE_INSTALL) # Is your responsability to ensure all compiler options are compatible with the compilation # of the project linking to the nana lib here generated target_sources(nana PRIVATE ${HEADERS}) - # target_include_directories(nana PRIVATE ${NANA_INCLUDE_DIR}) message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") # Actually in DESTDIR/CMAKE_INSTALL_PREFIX/lib but in windows there is no DESTDIR/ part. install(TARGETS nana From 7a1c299ff799425d092d48a1d3d4da049f71e8c7 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 31 Jul 2019 16:56:23 +0200 Subject: [PATCH 04/73] explicit conversion --- source/gui/widgets/progress.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gui/widgets/progress.cpp b/source/gui/widgets/progress.cpp index 49fbda99..fb727af1 100644 --- a/source/gui/widgets/progress.cpp +++ b/source/gui/widgets/progress.cpp @@ -96,11 +96,11 @@ namespace nana { if (widget_) { - auto value_px = (widget_->size().width - border_px * 2); + unsigned value_px = (widget_->size().width - border_px * 2); //avoid overflow if (unknown_ || (value_ < max_)) - value_px = static_cast(value_px * (double(value_) / double(max_))); + value_px = unsigned(double(value_px) * (double(value_) / double(max_))); if (value_px != value_px_) { From 9e859f79918f806ee374eff9033b03f3f15a7ca0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 31 Jul 2019 17:31:43 +0200 Subject: [PATCH 05/73] back to safe option for almost everyone. --- build/cmake/install_nana.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build/cmake/install_nana.cmake b/build/cmake/install_nana.cmake index de51757d..7c949646 100644 --- a/build/cmake/install_nana.cmake +++ b/build/cmake/install_nana.cmake @@ -1,4 +1,4 @@ -option(NANA_CMAKE_INSTALL "Install nana when compile the library (to be consumed without cmake)" ON) +option(NANA_CMAKE_INSTALL "Install nana after compiling the library (to be consumed WITHOUT cmake!!)" OFF) # Install the include directories too. if(NANA_CMAKE_INSTALL) @@ -7,6 +7,10 @@ if(NANA_CMAKE_INSTALL) # of the project linking to the nana lib here generated target_sources(nana PRIVATE ${HEADERS}) message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") + message("WARNING !!! You are using the 'installed' nana! Not recommended! ") + message("If this was not your intention, please tern OFF option NANA_CMAKE_INSTALL ") + message("for example by adding: -DNANA_CMAKE_INSTALL=OFF to your call to cmake. ") + # Actually in DESTDIR/CMAKE_INSTALL_PREFIX/lib but in windows there is no DESTDIR/ part. install(TARGETS nana ARCHIVE DESTINATION lib @@ -18,6 +22,9 @@ if(NANA_CMAKE_INSTALL) $ ) else() # this is the prefered method to consume nana with cmake + message("You are using nana directly from original sources. (Recommended!) " + "If this was not your intention, and what you want is to install precomplied nana first, then " + "please tern ON option NANA_CMAKE_INSTALL ") target_sources(nana PUBLIC ${HEADERS}) target_include_directories(nana PUBLIC ${NANA_INCLUDE_DIR}) endif() From bcf604a9b608ee9cbd2339772eda82216791d072 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Wed, 31 Jul 2019 17:41:27 +0200 Subject: [PATCH 06/73] not wanting to start xfvb --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82604edf..0629aeb6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,15 +53,15 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : - # travis don't have a physical monitor. We need to install an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/ - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - - sleep 3 # give xvfb some time to start # we have: qPCR4vir/nana/../nana-demo and now we are in: qPCR4vir/nana/ our executable tests will access: ../nana-demo/Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) #- cd ../nana-demo - mkdir demo-build - cd demo-build +services: + - # travis don't have a physical monitor. We need to install an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/ + - xvfb + script: - cmake -G"Unix Makefiles" ../nana-demo -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON -DNANA_CMAKE_INSTALL=OFF - make install From 129b83e68f4bd7abef4eb9e4e1e3f38944fa1fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A7=80=ED=95=9C?= Date: Thu, 1 Aug 2019 15:24:46 +0900 Subject: [PATCH 07/73] fix the strange behavior of Korean ime composition window. Because Hangul is a combination character, WM_IME_STARTCOMPOSITION is only called once when the IME input is started, so the position of the composition window is strange. Therefore, I solved the problem by controlling the state of characters combined using WM_IME_COMPOSITION and WM_IME_CHAR. We have also improved to support other IME languages such as Chinese and Japanese. --- include/nana/gui/detail/drawer.hpp | 2 + include/nana/gui/detail/event_code.hpp | 1 + include/nana/gui/detail/general_events.hpp | 13 ++++ include/nana/gui/widgets/combox.hpp | 1 + .../gui/widgets/skeletons/text_editor.hpp | 3 + include/nana/gui/widgets/spinbox.hpp | 1 + include/nana/gui/widgets/textbox.hpp | 1 + source/gui/detail/bedrock_windows.cpp | 74 ++++++++++++++++--- source/gui/detail/drawer.cpp | 10 +++ source/gui/widgets/combox.cpp | 7 ++ source/gui/widgets/skeletons/text_editor.cpp | 37 ++++++++++ source/gui/widgets/spinbox.cpp | 7 ++ source/gui/widgets/textbox.cpp | 7 ++ 13 files changed, 152 insertions(+), 12 deletions(-) diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index 46796573..ce7ade4f 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -85,6 +85,7 @@ namespace nana virtual void mouse_dropfiles(graph_reference, const arg_dropfiles&); virtual void focus(graph_reference, const arg_focus&); + virtual void key_ime(graph_reference, const arg_ime&); virtual void key_press(graph_reference, const arg_keyboard&); virtual void key_char(graph_reference, const arg_keyboard&); virtual void key_release(graph_reference, const arg_keyboard&); @@ -140,6 +141,7 @@ namespace nana void resized(const arg_resized&, const bool); void move(const arg_move&, const bool); void focus(const arg_focus&, const bool); + void key_ime(const arg_ime& arg, const bool bForce__EmitInternal); void key_press(const arg_keyboard&, const bool); void key_char(const arg_keyboard&, const bool); void key_release(const arg_keyboard&, const bool); diff --git a/include/nana/gui/detail/event_code.hpp b/include/nana/gui/detail/event_code.hpp index 2c63cb4c..a9802e4a 100644 --- a/include/nana/gui/detail/event_code.hpp +++ b/include/nana/gui/detail/event_code.hpp @@ -34,6 +34,7 @@ namespace nana unload, ///< A form is closed by clicking the X button, only works for root widget. destroy, ///< A widget is about to be destroyed. focus, ///< A widget's focus is changed. + key_ime, key_press, ///< A keyboard is pressed on a focus widget. key_char, ///< The focus widget received a character. key_release, ///< A keyboard is released on a focus widget. diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index f58f9680..1bcc5be1 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -466,6 +466,19 @@ namespace nana reason focus_reason; ///< determines how the widget receives keyboard focus, it is ignored when 'getting' is equal to false }; + struct arg_ime: public event_arg + { + enum class reason + { + composition, + result + }; + + ::nana::window window_handle; ///< A handle to the event window + reason ime_reason; + std::wstring composition_string; + }; + struct arg_keyboard : public event_arg { event_code evt_code; ///< it is event_code::key_press in current event diff --git a/include/nana/gui/widgets/combox.hpp b/include/nana/gui/widgets/combox.hpp index f6ba12df..3d52de05 100644 --- a/include/nana/gui/widgets/combox.hpp +++ b/include/nana/gui/widgets/combox.hpp @@ -65,6 +65,7 @@ namespace nana void mouse_up(graph_reference, const arg_mouse&) override; void mouse_move(graph_reference, const arg_mouse&) override; void mouse_wheel(graph_reference, const arg_wheel&) override; + void key_ime(graph_reference, const arg_ime&) override; void key_press(graph_reference, const arg_keyboard&) override; void key_char(graph_reference, const arg_keyboard&) override; private: diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 5f691543..5657af7c 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -98,6 +98,7 @@ namespace nana{ namespace widgets void set_accept(std::function); void set_accept(accepts); + bool respond_ime(const arg_ime& arg); bool respond_char(const arg_keyboard& arg); bool respond_key(const arg_keyboard& arg); @@ -328,6 +329,8 @@ namespace nana{ namespace widgets nana::upoint caret; //position of caret by text, it specifies the position of a new character nana::upoint shift_begin_caret; }points_; + + size_t composition_size_ { 0 }; }; }//end namespace skeletons }//end namespace widgets diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index 2f489f1d..ee99e149 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -66,6 +66,7 @@ namespace nana void mouse_move(graph_reference, const arg_mouse&) override; void mouse_up(graph_reference, const arg_mouse& arg) override; void mouse_leave(graph_reference, const arg_mouse&) override; + void key_ime(graph_reference, const arg_ime& arg) override; void key_press(graph_reference, const arg_keyboard&) override; void key_char(graph_reference, const arg_keyboard&) override; void resized(graph_reference, const arg_resized&) override; diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 8557c68a..58c60df7 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -83,6 +83,7 @@ namespace nana void mouse_enter(graph_reference, const arg_mouse&) override; void mouse_leave(graph_reference, const arg_mouse&) override; void dbl_click(graph_reference, const arg_mouse&) override; + void key_ime(graph_reference, const arg_ime&) override; void key_press(graph_reference, const arg_keyboard&)override; void key_char(graph_reference, const arg_keyboard&) override; void mouse_wheel(graph_reference, const arg_wheel&) override; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 829c909a..d05a6119 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -77,6 +77,9 @@ namespace detail typedef BOOL (__stdcall* imm_set_composition_window_type)(HIMC, LPCOMPOSITIONFORM); imm_set_composition_window_type imm_set_composition_window; + + typedef LONG(__stdcall* imm_get_composition_string_type)(HIMC, DWORD, LPVOID, DWORD); + imm_get_composition_string_type imm_get_composition_string; } #pragma pack(1) //Decoder of WPARAM and LPARAM @@ -210,6 +213,9 @@ namespace detail restrict::imm_set_composition_window = reinterpret_cast( ::GetProcAddress(imm32, "ImmSetCompositionWindow")); + + restrict::imm_get_composition_string = reinterpret_cast( + ::GetProcAddress(imm32, "ImmGetCompositionStringW")); } bedrock::~bedrock() @@ -639,6 +645,8 @@ namespace detail case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_IME_STARTCOMPOSITION: + case WM_IME_COMPOSITION: + case WM_IME_CHAR: case WM_DROPFILES: case WM_MOUSELEAVE: case WM_MOUSEWHEEL: //The WM_MOUSELAST may not include the WM_MOUSEWHEEL/WM_MOUSEHWHEEL when the version of SDK is low. @@ -786,25 +794,67 @@ namespace detail } break; case WM_IME_STARTCOMPOSITION: - if (msgwnd->other.attribute.root->ime_enabled) + break; + case WM_IME_COMPOSITION: + if (lParam & (GCS_COMPSTR | GCS_RESULTSTR)) { - auto native_font = msgwnd->drawer.graphics.typeface().handle(); - LOGFONTW logfont; - ::GetObjectW(reinterpret_cast(native_font), sizeof logfont, &logfont); + msgwnd = brock.focus(); + if (msgwnd && msgwnd->flags.enabled) + { + auto & wd_manager = brock.wd_manager(); + auto composition_index = static_cast(lParam & (GCS_COMPSTR | GCS_RESULTSTR)); - HIMC imc = restrict::imm_get_context(root_window); - restrict::imm_set_composition_font(imc, &logfont); + arg_ime arg; + arg.window_handle = msgwnd; + if (lParam & GCS_COMPSTR) + { + arg.ime_reason = arg_ime::reason::composition; + } + if (lParam & GCS_RESULTSTR) + { + arg.ime_reason = arg_ime::reason::result; + } - POINT pos; - ::GetCaretPos(&pos); + HIMC imc = restrict::imm_get_context(root_window); + auto size = restrict::imm_get_composition_string(imc, composition_index, nullptr, 0); + if (size > 0) + { + wchar_t * buffer = new wchar_t[100 / sizeof(wchar_t) + 1]; + size = restrict::imm_get_composition_string(imc, composition_index, buffer, size + sizeof(wchar_t)); + buffer[size / sizeof(wchar_t)] = '\0'; + arg.composition_string = std::move(buffer); + delete[] buffer; + } + restrict::imm_release_context(root_window, imc); - COMPOSITIONFORM cf = { CFS_POINT }; - cf.ptCurrentPos = pos; - restrict::imm_set_composition_window(imc, &cf); - restrict::imm_release_context(root_window, imc); + if (wd_manager.available(msgwnd)) + draw_invoker(&drawer::key_ime, msgwnd, arg, &context); + + wd_manager.do_lazy_refresh(msgwnd, false); + } } def_window_proc = true; break; + case WM_IME_CHAR: + msgwnd = brock.focus(); + if (msgwnd && msgwnd->flags.enabled) + { + auto & wd_manager = brock.wd_manager(); + + arg_keyboard arg; + arg.evt_code = event_code::key_char; + arg.window_handle = msgwnd; + arg.key = static_cast(wParam); + brock.get_key_state(arg); + arg.ignore = false; + + msgwnd->annex.events_ptr->key_char.emit(arg, msgwnd); + if ((false == arg.ignore) && wd_manager.available(msgwnd)) + draw_invoker(&drawer::key_char, msgwnd, arg, &context); + + wd_manager.do_lazy_refresh(msgwnd, false); + } + break; case WM_GETMINMAXINFO: { bool take_over = false; diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index 5b21161b..6baa2626 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -96,6 +96,11 @@ namespace nana overridden_ &= ~(1 << static_cast(event_code::focus)); } + void drawer_trigger::key_ime(graph_reference, const arg_ime&) + { + overridden_ &= ~(1 << static_cast(event_code::key_ime)); + } + void drawer_trigger::key_press(graph_reference, const arg_keyboard&) { overridden_ &= ~(1 << static_cast(event_code::key_press)); @@ -318,6 +323,11 @@ namespace nana _m_emit(event_code::focus, arg, &drawer_trigger::focus, bForce__EmitInternal); } + void drawer::key_ime(const arg_ime& arg, const bool bForce__EmitInternal) + { + _m_emit(event_code::key_ime, arg, &drawer_trigger::key_ime, bForce__EmitInternal); + } + void drawer::key_press(const arg_keyboard& arg, const bool bForce__EmitInternal) { _m_emit(event_code::key_press, arg, &drawer_trigger::key_press, bForce__EmitInternal); diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index 816d4ee9..d66019fc 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -773,6 +773,13 @@ namespace nana API::dev::lazy_refresh(); } + void trigger::key_ime(graph_reference, const arg_ime& arg) + { + drawer_->editor()->respond_ime(arg); + if (drawer_->editor()->try_refresh()) + API::dev::lazy_refresh(); + } + void trigger::key_char(graph_reference, const arg_keyboard& arg) { drawer_->editor()->respond_char(arg); diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 9049165f..7d8c4475 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1163,6 +1163,43 @@ namespace nana { impl_->capacities.acceptive = acceptive; } + bool text_editor::respond_ime(const arg_ime& arg) + { + if (!API::window_enabled(window_)) + return false; + + if (select_.a != select_.b) + { + points_.caret = _m_erase_select(false); + } + + for (size_t i = 0; i < composition_size_; ++i) + { + backspace(false, false); + } + + if (arg.ime_reason == arg_ime::reason::composition) + { + composition_size_ = arg.composition_string.length(); + points_.caret = _m_put(std::move(arg.composition_string), false); + + _m_reset_content_size(true); + textbase().text_changed(); + + if (this->_m_adjust_view()) + impl_->cview->sync(false); + + reset_caret(); + impl_->try_refresh = sync_graph::refresh; + } + else + { + composition_size_ = 0; + } + + return true; + } + bool text_editor::respond_char(const arg_keyboard& arg) //key is a character of ASCII code { if (!API::window_enabled(window_)) diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 74169085..1b200100 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -621,6 +621,13 @@ namespace nana API::dev::lazy_refresh(); } + void drawer::key_ime(graph_reference, const arg_ime& arg) + { + impl_->editor()->respond_ime(arg); + if (impl_->editor()->try_refresh()) + API::dev::lazy_refresh(); + } + void drawer::key_press(graph_reference, const arg_keyboard& arg) { if (impl_->editor()->respond_key(arg)) diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 100a832d..87dc761c 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -152,6 +152,13 @@ namespace drawerbase { API::dev::lazy_refresh(); } + void drawer::key_ime(graph_reference, const arg_ime& arg) + { + editor_->respond_ime(arg); + if (editor_->try_refresh()) + API::dev::lazy_refresh(); + } + void drawer::key_press(graph_reference, const arg_keyboard& arg) { editor_->respond_key(arg); From ba1af33d7618d8a6b8a28d6cfc73fce6d81b4c6b Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 1 Aug 2019 13:19:12 +0200 Subject: [PATCH 08/73] doxygen documentation --- include/nana/gui/detail/widget_geometrics.hpp | 4 +- include/nana/gui/msgbox.hpp | 52 +++++++++++++++---- include/nana/gui/widgets/widget.hpp | 39 ++++++++++---- 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/include/nana/gui/detail/widget_geometrics.hpp b/include/nana/gui/detail/widget_geometrics.hpp index d172536e..91cdff6c 100644 --- a/include/nana/gui/detail/widget_geometrics.hpp +++ b/include/nana/gui/detail/widget_geometrics.hpp @@ -17,7 +17,8 @@ #include namespace nana { - class color_proxy + /// a tool to share and set a color common to many uses + class color_proxy { public: color_proxy(const color_proxy&); @@ -38,6 +39,7 @@ namespace nana std::shared_ptr color_; };//end namespace color_proxy + /// define common color and geometrical properties struct widget_geometrics { virtual ~widget_geometrics() = default; diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index c67795f6..5b822194 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -1,13 +1,13 @@ -/* +/** * A Message Box Class * Nana C++ Library(http://www.nanapro.org) -* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) +* Copyright(C) 2003-2019 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/msgbox.hpp +* @file nana/gui/msgbox.hpp */ #ifndef NANA_GUI_MSGBOX_HPP @@ -81,8 +81,8 @@ namespace nana return *this; } - /// \brief Displays the message that buffered in the stream. - /// @return, the button that user clicked. + /// \brief Displays the message buffered in the stream. + /// @return, the button the user clicked. pick_t show() const; /// A function object method alternative to show() @@ -98,6 +98,9 @@ namespace nana icon_t icon_; }; + /// Simple convenience dialog to get values from the user. + /// + /// The input value can be a boolean, string, a number, an option from a dropdown list or a date. class inputbox { struct abstract_content @@ -110,6 +113,8 @@ namespace nana }; public: + + /// Shows a checkbox for boolean input class boolean : public abstract_content { @@ -128,6 +133,7 @@ namespace nana std::unique_ptr impl_; }; + /// Integer input class integer : public abstract_content { @@ -146,6 +152,7 @@ namespace nana std::unique_ptr impl_; }; + /// Floating-point number input. class real : public abstract_content { @@ -164,6 +171,7 @@ namespace nana std::unique_ptr impl_; }; + /// String input or an option from a dropdown list. class text : public abstract_content { @@ -192,6 +200,7 @@ namespace nana std::unique_ptr impl_; }; + /// Date input class date : public abstract_content { @@ -214,6 +223,10 @@ namespace nana std::unique_ptr impl_; }; + /// Path of a file. + /// + /// The path requires an object of filebox. When the user clicks the `Browse` button, + /// it invokes the filebox with proper configurations to query a filename. class path : public abstract_content { @@ -231,11 +244,26 @@ namespace nana std::unique_ptr impl_; }; - inputbox(window, ::std::string description, ::std::string title = ::std::string()); + inputbox(window owner, ///< A handle to an owner window (just a parent form or widget works) + ::std::string description, ///< tells users what the purpose for the input. It can be a formatted-text. + ::std::string title = ::std::string() ///< The title for the inputbox. + ); - void image(::nana::paint::image, bool is_left, const rectangle& valid_area = {}); - void image_v(::nana::paint::image, bool is_top, const rectangle& valid_area = {}); + /// shows images at left/right side of inputbox + void image(::nana::paint::image image, ///< The image + bool is_left, ///< true to place the image at left side, false to the right side + const rectangle& valid_area = {} ///< The area of the image to be displayed + ); + /// shows images at top/bottom side of inputbox + void image_v(::nana::paint::image, ///< The image + bool is_top, ///< `true` to place the image at top side, `false` at bottom side + const rectangle& valid_area = {} ///< The area of the image to be displayed + ); + + /// Shows the inputbox and wait for the user input. + /// + /// This method shows the inputbox without preventing the user interacts with other windows. template bool show(Args&& ... args) { @@ -251,7 +279,11 @@ namespace nana return _m_open(contents, false); } - template + /// Shows the inputbox and wait for the user input blocking other windows. + /// + /// This method blocks the execution and prevents user interaction with other + /// windows until the inputbox is closed. + template bool show_modal(Args&& ... args) { std::vector contents; @@ -267,7 +299,7 @@ namespace nana return _m_open(contents, true); } - /// Sets a verifier to verify the user input. + /// Sets a verifier to verify the user input, taking a handle to the inputbox. void verify(std::function verifier); /** Sets the minimum width for the entry fields diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index fe8fe543..ce46843a 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -7,7 +7,7 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/widgets/widget.hpp + * @file nana/gui/widgets/widget.hpp */ #ifndef NANA_GUI_WIDGET_HPP @@ -48,8 +48,8 @@ namespace nana widget() = default; virtual ~widget() = default; - virtual window handle() const = 0; ///< Returns the handle of window, returns 0 if window is not created. - bool empty() const; ///< Determines whether the manipulator is handling a window. + virtual window handle() const = 0; ///< Returns the handle of window, returns 0 if window is not created. + bool empty() const; ///< Determines whether the manipulator is handling a window. void close(); window parent() const; @@ -169,9 +169,17 @@ namespace nana }; } - /// Base class of all the classes defined as a widget window. Defaultly a widget_tag - template::value>::type> //type DrawerTrigger must be derived from nana::drawer_trigger + /// Base class of all the classes defined as a widget window. Defaultly a widget_tag + /// + /// \tparam Category + /// \tparam DrawerTrigger must be derived from nana::drawer_trigger + /// \tparam Events + /// \tparam Scheme + template::value>::type> class widget_object: public detail::widget_base { protected: @@ -293,8 +301,13 @@ namespace nana std::unique_ptr scheme_; };//end class widget_object - /// Base class of all the classes defined as a non-graphics-buffer widget window. The second template parameter DrawerTrigger is always ignored.\see nana::panel - template //type DrawerTrigger must be derived from nana::drawer_trigger + /// Base class of all the classes defined as a non-graphics-buffer widget window. + /// + /// The second template parameter DrawerTrigger is always ignored.\see nana::panel + /// type DrawerTrigger must be derived from nana::drawer_trigger + template class widget_object: public detail::widget_base { protected: @@ -359,8 +372,14 @@ namespace nana };//end class widget_object - /// Base class of all the classes defined as a root window. \see nana::form - template //type DrawerTrigger must be derived from nana::drawer_trigger + /// Base class of all the classes defined as a root window. \see nana::form + /// + /// \tparam DrawerTrigger must be derived from nana::drawer_trigger + /// \tparam Events + /// \tparam Scheme + template class widget_object: public detail::widget_base { protected: From 0b339c155275d93daed7456f9ab52fc9041b2479 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 1 Aug 2019 14:00:54 +0200 Subject: [PATCH 09/73] FIX https://github.com/cnjinhao/nana/issues/465 --- source/gui/msgbox.cpp | 88 ++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 9d0467d0..5b94ab89 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -1,4 +1,4 @@ -/* +/** * A Message Box Class * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) @@ -7,11 +7,16 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/msgbox.hpp + * @file nana/gui/msgbox.hpp * @Contributors * James Bremner + * Ariel Vina-Rodriguez */ +#include // max +#include +#include //include std::abs + #include #include #include @@ -27,8 +32,7 @@ #include #include #include -#include -#include //include std::abs + #if defined(NANA_WINDOWS) #include #elif defined(NANA_X11) @@ -494,21 +498,29 @@ namespace nana //end class msgbox - //class inputbox + //class inputbox todo: add schema class inputbox_window : public ::nana::form { public: - inputbox_window(window owner, paint::image (&imgs)[4], ::nana::rectangle (&valid_areas)[4], const ::std::string & desc, const ::std::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) + inputbox_window(window owner, + paint::image (&imgs)[4], ///< 4 ref to images + ::nana::rectangle (&valid_areas)[4], + const ::std::string & description, + const ::std::string& title, + std::size_t contents, + unsigned fixed_pixels, + const std::vector& each_height) + : form(owner, API::make_center(owner, 500, 300), appear::decorate<>()) { - throw_not_utf8(desc); + throw_not_utf8(description); throw_not_utf8(title); - desc_.create(*this); - desc_.format(true).caption(desc); - auto desc_extent = desc_.measure(470); + description_.create(*this); + description_.format(true).caption(description); + auto description_size = description_.measure(470); btn_ok_.create(*this); btn_ok_.i18n(i18n_eval("NANA_BUTTON_OK")); @@ -527,32 +539,26 @@ namespace nana close(); }); - unsigned height = 20 + desc_extent.height + 10 + 38; - + unsigned height = 20 + description_size.height + 10 + 38; std::stringstream ss_content; - ss_content << " 27) - px = each_height[i]; + unsigned px = std::max(27u, each_height[i]); - ss_content << ""; + ss_content << ""; - height += px + 1; + height += px + 3; } - ss_content << ">>>"; - - if (desc_extent.width < 200) - desc_extent.width = 200; + if (description_size.width < 200) + description_size.width = 200; //Make sure the complete display of input extent - if (desc_extent.width < fixed_pixels) - desc_extent.width = fixed_pixels; + if (description_size.width < fixed_pixels) + description_size.width = fixed_pixels; - desc_extent.width += 20; + description_size.width += 20; // 2x margin 10 ::nana::size img_sz[4]; @@ -566,8 +572,9 @@ namespace nana } else sz = imgs[2].size(); - sz.width = static_cast(double(sz.width) * (double(height) / double(sz.height))); - desc_extent.width += sz.width; + const double scale_factor = double(height) / double(sz.height); + sz.width = static_cast(double(sz.width) * scale_factor); + description_size.width += sz.width; } if (imgs[3]) //Right @@ -581,7 +588,7 @@ namespace nana else sz = imgs[3].size(); sz.width = static_cast(double(sz.width) * (double(height) / double(sz.height))); - desc_extent.width += sz.width; + description_size.width += sz.width; } if (imgs[0]) //Top @@ -594,7 +601,8 @@ namespace nana } else sz = imgs[0].size(); - sz.height = static_cast(double(sz.height) * (double(desc_extent.width) / double(sz.width))); + const double scale_factor = double(description_size.width) / double(sz.width); + sz.height = static_cast(double(sz.height) * scale_factor ); height += sz.height; } @@ -608,16 +616,28 @@ namespace nana } else sz = imgs[1].size(); - sz.height = static_cast(double(sz.height) * (double(desc_extent.width) / double(sz.width))); + const double scale_factor = double(description_size.width) / double(sz.width); + sz.height = static_cast(double(sz.height) * scale_factor); height += sz.height; } std::stringstream ss; - ss << "vert<"<>"; + ss << "vert< img_top height="<" + <<" << img_left width=" <" + <<" " // added height: 2x10 + <<" " + <<" " + <<" >>" // added height: 38 + <<" < img_right width=" <>< img_bottom height="<"; + + // added height: 10 x3 = 30 + 38 auto& place = this->get_place(); place.div(ss.str().c_str()); - place["desc"] << desc_; + place["description"] << description_; place["buttons"] << btn_ok_ << btn_cancel_; const char * img_fields[4] = {"img_top", "img_bottom", "img_left", "img_right"}; @@ -635,7 +655,7 @@ namespace nana place.field_display(img_fields[i], imgs[i]); } - move(API::make_center(this->owner(), desc_extent.width, height)); + move(API::make_center(this->owner(), description_size.width, height)); caption(title); } @@ -659,7 +679,7 @@ namespace nana return valid_input_; } private: - ::nana::label desc_; + ::nana::label description_; ::nana::button btn_ok_; ::nana::button btn_cancel_; bool valid_input_{ false }; From 0a9e69f5de5a5825e99029bf0c028007d54fdaa5 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 1 Aug 2019 14:38:45 +0200 Subject: [PATCH 10/73] try #define NOMINMAX --- source/gui/msgbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 5b94ab89..4d4ffc36 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -12,7 +12,7 @@ * James Bremner * Ariel Vina-Rodriguez */ - +#define NOMINMAX #include // max #include #include //include std::abs From e9affe5cdf47ccf8195b3bd24b19ffc6a4dd4641 Mon Sep 17 00:00:00 2001 From: Xeverous <20820409+Xeverous@users.noreply.github.com> Date: Thu, 1 Aug 2019 20:34:12 +0200 Subject: [PATCH 11/73] added option to link C++ standard library statically --- build/cmake/shared_libs.cmake | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/build/cmake/shared_libs.cmake b/build/cmake/shared_libs.cmake index febb3b42..4ae6798c 100644 --- a/build/cmake/shared_libs.cmake +++ b/build/cmake/shared_libs.cmake @@ -1,5 +1,6 @@ option(BUILD_SHARED_LIBS "Compile nana as a shared library." OFF) +option(NANA_STATIC_STDLIB "Link nana statically to C++ standard library" ON) if(BUILD_SHARED_LIBS) # todo test @@ -35,12 +36,8 @@ if(BUILD_SHARED_LIBS) # todo test endif() endif() -if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AND NOT MINGW?? +if(NANA_STATIC_STDLIB) + target_compile_options(nana + PUBLIC $<$, $>: -static-libgcc -static-libstdc++>) +endif() - if(BUILD_SHARED_LIBS) - target_compile_options(nana PUBLIC -lgcc -lstdc++) - else() - target_link_libraries(nana PUBLIC -static-libgcc -static-libstdc++) - endif(BUILD_SHARED_LIBS) - -endif() \ No newline at end of file From d0251ed6c3c23026c0adf584ead7d39be7b6f7af Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 5 Aug 2019 06:14:23 +0800 Subject: [PATCH 12/73] add filesystem workaround(#471) --- build/codeblocks/nana.cbp | 2 +- include/nana/filesystem/filesystem.hpp | 9 +++------ source/filesystem/filesystem.cpp | 10 ++++------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/build/codeblocks/nana.cbp b/build/codeblocks/nana.cbp index 188c964d..5beaa6f0 100644 --- a/build/codeblocks/nana.cbp +++ b/build/codeblocks/nana.cbp @@ -14,8 +14,8 @@