Merge branch 'hotfix-1.7.2' into develop
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -6,8 +6,11 @@ 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")
|
||||
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
|
||||
@@ -15,8 +18,13 @@ 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 $<BUILD_INTERFACE:${NANA_INCLUDE_DIR}>
|
||||
$<INSTALL_INTERFACE:include> )
|
||||
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()
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Compiler>
|
||||
<Add option="-std=c++11" />
|
||||
<Add option="-Wall" />
|
||||
<Add option="-std=c++11" />
|
||||
<Add option="-g" />
|
||||
<Add directory="../../include" />
|
||||
<Add directory="../../extrlib/mingw" />
|
||||
|
||||
@@ -561,22 +561,19 @@ namespace std {
|
||||
}
|
||||
} // std
|
||||
#else
|
||||
|
||||
//Implements the missing functions for various version of experimental/filesystem
|
||||
# if defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM)
|
||||
namespace std
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
//Visual Studio 2017
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 1912)) || \
|
||||
(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 801))
|
||||
#if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \
|
||||
(!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603))
|
||||
path weakly_canonical(const path& p);
|
||||
path weakly_canonical(const path& p, std::error_code& err);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif //NANA_USING_NANA_FILESYSTEM
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#include <memory>
|
||||
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> color_;
|
||||
};//end namespace color_proxy
|
||||
|
||||
/// define common color and geometrical properties
|
||||
struct widget_geometrics
|
||||
{
|
||||
virtual ~widget_geometrics() = default;
|
||||
|
||||
@@ -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<implement> impl_;
|
||||
};
|
||||
|
||||
/// Integer input
|
||||
class integer
|
||||
: public abstract_content
|
||||
{
|
||||
@@ -146,6 +152,7 @@ namespace nana
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
/// Floating-point number input.
|
||||
class real
|
||||
: public abstract_content
|
||||
{
|
||||
@@ -164,6 +171,7 @@ namespace nana
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
/// String input or an option from a dropdown list.
|
||||
class text
|
||||
: public abstract_content
|
||||
{
|
||||
@@ -192,6 +200,7 @@ namespace nana
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
/// Date input
|
||||
class date
|
||||
: public abstract_content
|
||||
{
|
||||
@@ -214,6 +223,10 @@ namespace nana
|
||||
std::unique_ptr<implement> 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<implement> 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<typename ...Args>
|
||||
bool show(Args&& ... args)
|
||||
{
|
||||
@@ -251,7 +279,11 @@ namespace nana
|
||||
return _m_open(contents, false);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
/// 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<typename ...Args>
|
||||
bool show_modal(Args&& ... args)
|
||||
{
|
||||
std::vector<abstract_content*> 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<bool(window)> verifier);
|
||||
|
||||
/** Sets the minimum width for the entry fields
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -98,6 +98,7 @@ namespace nana{ namespace widgets
|
||||
|
||||
void set_accept(std::function<bool(char_type)>);
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<typename Category, typename DrawerTrigger, typename Events = ::nana::general_events, typename Scheme = ::nana::widget_geometrics,
|
||||
typename = typename std::enable_if<std::is_base_of<::nana::drawer_trigger, DrawerTrigger>::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<typename Category,
|
||||
typename DrawerTrigger,
|
||||
typename Events = ::nana::general_events,
|
||||
typename Scheme = ::nana::widget_geometrics,
|
||||
typename = typename std::enable_if<std::is_base_of<::nana::drawer_trigger, DrawerTrigger>::value>::type>
|
||||
class widget_object: public detail::widget_base
|
||||
{
|
||||
protected:
|
||||
@@ -293,8 +301,13 @@ namespace nana
|
||||
std::unique_ptr<scheme_type> 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<typename DrawerTrigger, typename Events, typename Scheme> //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<typename DrawerTrigger,
|
||||
typename Events,
|
||||
typename Scheme>
|
||||
class widget_object<category::lite_widget_tag, DrawerTrigger, Events, Scheme>: 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<typename DrawerTrigger, typename Events, typename Scheme> //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<typename DrawerTrigger,
|
||||
typename Events,
|
||||
typename Scheme>
|
||||
class widget_object<category::root_tag, DrawerTrigger, Events, Scheme>: public detail::widget_base
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -1399,16 +1399,15 @@ namespace std
|
||||
}//end namespace filesystem
|
||||
}//end namespace std
|
||||
|
||||
#else //NANA_USING_NANA_FILESYSTEM
|
||||
# if defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM)
|
||||
#else //else NANA_USING_NANA_FILESYSTEM
|
||||
|
||||
//Defines the functions that are not provided by experimental/filesystem
|
||||
namespace std
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 1912)) || \
|
||||
(!defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 801))
|
||||
#if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \
|
||||
(!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603))
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@@ -1551,10 +1550,9 @@ namespace std
|
||||
{
|
||||
return weakly_canonical(p, &err);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif //NANA_USING_NANA_FILESYSTEM
|
||||
|
||||
|
||||
@@ -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<restrict::imm_set_composition_window_type>(
|
||||
::GetProcAddress(imm32, "ImmSetCompositionWindow"));
|
||||
|
||||
restrict::imm_get_composition_string = reinterpret_cast<restrict::imm_get_composition_string_type>(
|
||||
::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<HFONT>(native_font), sizeof logfont, &logfont);
|
||||
msgwnd = brock.focus();
|
||||
if (msgwnd && msgwnd->flags.enabled)
|
||||
{
|
||||
auto & wd_manager = brock.wd_manager();
|
||||
auto composition_index = static_cast<DWORD>(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<wchar_t>(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;
|
||||
|
||||
@@ -96,6 +96,11 @@ namespace nana
|
||||
overridden_ &= ~(1 << static_cast<int>(event_code::focus));
|
||||
}
|
||||
|
||||
void drawer_trigger::key_ime(graph_reference, const arg_ime&)
|
||||
{
|
||||
overridden_ &= ~(1 << static_cast<int>(event_code::key_ime));
|
||||
}
|
||||
|
||||
void drawer_trigger::key_press(graph_reference, const arg_keyboard&)
|
||||
{
|
||||
overridden_ &= ~(1 << static_cast<int>(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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* A Message Box Class
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
@@ -7,10 +7,15 @@
|
||||
* (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
|
||||
*/
|
||||
#define NOMINMAX
|
||||
#include <algorithm> // max
|
||||
#include <functional>
|
||||
#include <cstdlib> //include std::abs
|
||||
|
||||
#include <nana/gui/compact.hpp>
|
||||
#include <nana/gui/msgbox.hpp>
|
||||
@@ -27,8 +32,7 @@
|
||||
#include <nana/datetime.hpp>
|
||||
#include <nana/internationalization.hpp>
|
||||
#include <nana/gui/filebox.hpp>
|
||||
#include <functional>
|
||||
#include <cstdlib> //include std::abs
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#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<unsigned>& 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<unsigned>& 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 << "<margin=10 vert <desc weight=" << desc_extent.height << "><vert margin=[10]";
|
||||
|
||||
for (std::size_t i = 0; i < contents; ++i)
|
||||
{
|
||||
unsigned px = 27;
|
||||
if (each_height[i] > 27)
|
||||
px = each_height[i];
|
||||
unsigned px = std::max(27u, each_height[i]);
|
||||
|
||||
ss_content << "<weight=" << (px + 3) << " margin=[3] input_" << i << ">";
|
||||
ss_content << "<height=" << (px + 3) << " margin=[3] input_" << i << ">";
|
||||
|
||||
height += px + 1;
|
||||
height += px + 3;
|
||||
}
|
||||
|
||||
ss_content << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>>";
|
||||
|
||||
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<size::value_type>(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<size::value_type>(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<size::value_type>(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<size::value_type>(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<size::value_type>(double(sz.height) * scale_factor );
|
||||
height += sz.height;
|
||||
}
|
||||
|
||||
@@ -608,16 +616,28 @@ namespace nana
|
||||
}
|
||||
else
|
||||
sz = imgs[1].size();
|
||||
sz.height = static_cast<size::value_type>(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<size::value_type>(double(sz.height) * scale_factor);
|
||||
height += sz.height;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "vert<img_top weight="<<img_sz[0].height<<"><<img_left weight="<<img_sz[2].width<<">"<<ss_content.str()<<"<img_right weight="<<img_sz[3].width<<">><img_bottom weight="<<img_sz[1].height<<">";
|
||||
ss << "vert< img_top height="<<img_sz[0].height<<">"
|
||||
<<" << img_left width=" <<img_sz[2].width <<">"
|
||||
<<" <margin=10 vert <description height=" << description_size.height << ">" // added height: 2x10
|
||||
<<" <vert margin=[10]" // added height: 10
|
||||
<< ss_content.str()
|
||||
<<" >"
|
||||
<<" <height=38 margin=[15] <><width=170 buttons arrange=80 gap=10>"
|
||||
<<" >>" // added height: 38
|
||||
<<" < img_right width=" <<img_sz[3].width
|
||||
<<" >>< img_bottom height="<<img_sz[1].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 };
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<unsigned>(value_px * (double(value_) / double(max_)));
|
||||
value_px = unsigned(double(value_px) * (double(value_) / double(max_)));
|
||||
|
||||
if (value_px != value_px_)
|
||||
{
|
||||
|
||||
@@ -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_))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user