Merge branch 'develop' into prepare-utf8

This commit is contained in:
Jinhao 2016-01-03 14:18:03 +08:00
commit 0bb7c788d5
13 changed files with 522 additions and 108 deletions

1
.gitignore vendored
View File

@ -38,6 +38,7 @@ lib/
*.ninja*
CMakeCache.txt
CMakeFiles/
.idea/
cmake_install.cmake
*.DS_Store
.idea/

View File

@ -3,6 +3,23 @@
# Contributor:
# Robert Hauck - Enable support for PNG/Freetype
# Qiangqiang Wu - Add biicode support
# Ariel Vina-Rodriguez (qPCR4vir)
#https://cmake.org/cmake-tutorial/
#https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption
# use CACHE FORCE or set(USE_meganz_mingw_std_threads ON) or delete CMakecache.txt or the entirely build dir
# if your changes don't execute
option(USE_meganz_mingw_std_threads "replaced boost.thread with meganz's mingw-std-threads." OFF)
option(USE_UNICODE "Use Unicode Character Set" ON)
option(ENABLE_PNG "Enable the use of PNG" OFF)
option(LIBPNG_FROM_OS "Use libpng from operating system." ON)
option(ENABLE_JPEG "Enable the use of JPEG" OFF)
option(LIBJPEG_FROM_OS "Use libjpeg from operating system." ON)
option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF)
option(CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON)
option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF)
option(CMAKE_STD_make_unique_NOT_SUPPORTED "Add support for make_unique<>()." OFF)
#set(CMAKE_STD_make_unique_NOT_SUPPORTED OFF)
# set compile flags
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
@ -18,37 +35,47 @@ if(BIICODE)
add_biicode_targets()
return()
endif()
endif(BIICODE)
project(nana)
cmake_minimum_required(VERSION 2.8)
#Global MSVC definitions
if(WIN32)
if(MSVC)
add_definitions(-DWIN32)
#Global MSVC definitions
if(MSVC)
option(WIN32_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON)
# ??
if(WIN32_USE_MP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
endif()
endif(WIN32_USE_MP)
endif(MSVC)
if(MINGW)
add_definitions(-DMINGW)
#Find PNG
if(USE_meganz_mingw_std_threads)
add_definitions(-DUSE_github_com_meganz_mingw_std_threads)
# remove_definitions()
endif(USE_meganz_mingw_std_threads)
endif(MINGW)
endif(WIN32)
#Unicode
option(USE_UNICODE "Use Unicode Character Set")
if(USE_UNICODE)
add_definitions(-DNANA_UNICODE)
endif()
endif(USE_UNICODE)
if(APPLE)
add_definitions(-DAPPLE)
include_directories(/opt/X11/include/)
elseif(UNIX)
add_definitions(-Dlinux)
endif()
endif(APPLE)
@ -56,19 +83,10 @@ if(UNIX)
find_package(Freetype)
if (FREETYPE_FOUND)
include_directories( ${FREETYPE_INCLUDE_DIRS})
endif()
endif()
if(WIN32)
add_definitions(-DWIN32)
if(MINGW)
add_definitions(-DMINGW)
endif()
endif()
endif(FREETYPE_FOUND)
endif(UNIX)
#Find PNG
option(ENABLE_PNG "Enable the use of PNG")
option(LIBPNG_FROM_OS "Use libpng from operating system.")
if(ENABLE_PNG)
add_definitions(-DNANA_ENABLE_PNG)
if(LIBPNG_FROM_OS)
@ -76,13 +94,11 @@ if(ENABLE_PNG)
if (PNG_FOUND)
include_directories( ${PNG_INCLUDE_DIRS})
add_definitions(-DUSE_LIBPNG_FROM_OS)
endif()
endif()
endif()
endif(PNG_FOUND)
endif(LIBPNG_FROM_OS)
endif(ENABLE_PNG)
#Find JPEG
option(ENABLE_JPEG "Enable the use of JPEG")
option(LIBJPEG_FROM_OS "Use libjpeg from operating system.")
if(ENABLE_JPEG)
add_definitions(-DNANA_ENABLE_JPEG)
if(LIBJPEG_FROM_OS)
@ -90,12 +106,23 @@ if(ENABLE_JPEG)
if (JPEG_FOUND)
include_directories( ${JPEG_INCLUDE_DIRS})
add_definitions(-DUSE_LIBJPEG_FROM_OS)
endif()
endif()
endif()
endif(JPEG_FOUND)
endif(LIBJPEG_FROM_OS)
endif(ENABLE_JPEG)
#Unicode
if(CMAKE_VERBOSE_PREPROCESSOR)
add_definitions(-DVERBOSE_PREPROCESSOR)
endif(CMAKE_VERBOSE_PREPROCESSOR)
# STD_make_unique_NOT_SUPPORTED
if(CMAKE_STD_make_unique_NOT_SUPPORTED)
add_definitions(-DSTD_make_unique_NOT_SUPPORTED)
endif(CMAKE_STD_make_unique_NOT_SUPPORTED)
set(NANA_SOURCE_DIR ${CMAKE_SOURCE_DIR}/source)
set(NANA_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
@ -116,13 +143,16 @@ aux_source_directory(${NANA_SOURCE_DIR}/paint/detail NANA_PAINT_DETAIL_SOURCE)
aux_source_directory(${NANA_SOURCE_DIR}/system NANA_SYSTEM_SOURCE)
aux_source_directory(${NANA_SOURCE_DIR}/threads NANA_THREADS_SOURCE)
#To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library
#and Use SOURCE_GROUP if all your sources are in the same directory
add_library(${PROJECT_NAME} ${NANA_SOURCE}
${NANA_DETAIL_SOURCE}
${NANA_FILESYSTEM_SOURCE}
#if(NOT APPLE)
if(NOT APPLE)
${NANA_AUDIO_SOURCE}
${NANA_AUDIO_DETAIL_SOURCE}
#endif
endif (NOT APPLE)
${NANA_GUI_SOURCE}
${NANA_GUI_DETAIL_SOURCE}
${NANA_GUI_WIDGETS_SOURCE}
@ -132,17 +162,82 @@ add_library(${PROJECT_NAME} ${NANA_SOURCE}
${NANA_SYSTEM_SOURCE}
${NANA_THREADS_SOURCE})
#if(APPLE)
target_link_libraries(${PROJECT_NAME} -L/opt/X11/lib/ -lX11 -lXft -lpng -liconv)
#endif()
if(APPLE)
#Headers: use INCLUDE_DIRECTORIES
# Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES
target_link_libraries(${PROJECT_NAME} -L/opt/X11/lib/ -lX11 -lXft -lpng -liconv)
endif(APPLE)
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)
# ??
install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include)
set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 )
add_executable(nana_test test.cpp)
set_property( TARGET nana_test PROPERTY CXX_STANDARD 14 )
target_link_libraries(nana_test ${PROJECT_NAME})
if (BUILD_NANA_DEMOS)
set (CMAKE_INSTALL_PREFIX ${DEMO_BIN})
set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin)
set(CMAKE_INSTALL_PREFIX )
add_executable(file_explorer ../nana-demo/file_explorer.cpp)
set_property( TARGET file_explorer PROPERTY CXX_STANDARD 14 )
target_link_libraries(file_explorer ${PROJECT_NAME})
install(TARGETS file_explorer RUNTIME DESTINATION &{DEMO_BIN})
add_executable(calculator ../nana-demo/calculator.cpp)
set_property( TARGET calculator PROPERTY CXX_STANDARD 14 )
target_link_libraries(calculator ${PROJECT_NAME})
install(TARGETS calculator RUNTIME DESTINATION &{DEMO_BIN})
add_executable(FreeMe ../nana-demo/FreeMe.cpp)
set_property( TARGET FreeMe PROPERTY CXX_STANDARD 14 )
target_link_libraries(FreeMe ${PROJECT_NAME})
install(TARGETS FreeMe RUNTIME DESTINATION &{DEMO_BIN})
add_executable(notepad ../nana-demo/notepad.cpp)
set_property( TARGET notepad PROPERTY CXX_STANDARD 14 )
target_link_libraries(notepad ${PROJECT_NAME})
install(TARGETS notepad RUNTIME DESTINATION &{DEMO_BIN})
add_executable(widget_show ../nana-demo/widget_show.cpp)
set_property( TARGET widget_show PROPERTY CXX_STANDARD 14 )
target_link_libraries(widget_show ${PROJECT_NAME})
install(TARGETS widget_show RUNTIME DESTINATION &{DEMO_BIN})
add_executable(widget_show2 ../nana-demo/widget_show2.cpp)
set_property( TARGET widget_show2 PROPERTY CXX_STANDARD 14 )
target_link_libraries(widget_show2 ${PROJECT_NAME})
install(TARGETS widget_show2 RUNTIME DESTINATION &{DEMO_BIN})
add_executable(a_group_impl ../nana-demo/Examples/a_group_impl.cpp)
set_property( TARGET a_group_impl PROPERTY CXX_STANDARD 14 )
target_link_libraries(a_group_impl ${PROJECT_NAME})
add_executable(animate-bmp ../nana-demo/Examples/animate-bmp.cpp)
set_property( TARGET animate-bmp PROPERTY CXX_STANDARD 14 )
target_link_libraries(animate-bmp ${PROJECT_NAME})
add_executable(audio_player ../nana-demo/Examples/audio_player.cpp)
set_property( TARGET audio_player PROPERTY CXX_STANDARD 14 )
target_link_libraries(audio_player ${PROJECT_NAME})
#add_executable(nana_test test.cpp)
#set_property( TARGET nana_test PROPERTY CXX_STANDARD 14 )
#target_link_libraries(nana_test ${PROJECT_NAME})
#set(NANA_DEMOS_DIR ${CMAKE_SOURCE_DIR}/../nana-demo)
#set(NANA_EXAMPLES_DIR ${CMAKE_SOURCE_DIR}/../Examples/nana-demo/)
# https://cmake.org/cmake/help/v3.3/command/file.html?highlight=glob#file
#file( GLOB_RECURSE DEMO_SOURCES RELATIVE ../nana-demo *.cpp )
#foreach( demofile ${DEMO_SOURCES} )
# string( REPLACE ".cpp" "" demoname ${demofile} )
# add_executable( ${demoname} ${demofile} )
# set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 )
# target_link_libraries(${demoname} ${PROJECT_NAME})
#endforeach( demofile ${DEMO_SOURCES} )
endif(BUILD_NANA_DEMOS)

View File

@ -7,7 +7,39 @@
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/config.hpp
* @file nana/config.hpp
*
* @brief Provide switches to adapt to the target OS, use of external libraries or workarounds compiler errors or lack of std C++ support.
*
* To control target OS/compiler:
* - NANA_WINDOWS
* - NANA_MINGW
* - NANA_POSIX
* - NANA_LINUX
* - NANA_MACOS
* - NANA_X11
* - NANA_UNICODE
*
* External libraries:
* - NANA_LIBPNG, USE_LIBPNG_FROM_OS
* - NANA_LIBJPEG, USE_LIBJPEG_FROM_OS
*
* (see: Feature-testing recommendations for C++
* in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0096r0.html
* for example: __cpp_lib_experimental_filesystem = 201406 in <experimental/filesystem)
*
* Workaround to known compiler errors, unnecessary warnings or lack of C++11/14/17 support:
* - _SCL_SECURE_NO_WARNNGS, _CRT_SECURE_NO_DEPRECATE (VC)
* - STD_CODECVT_NOT_SUPPORTED (VC RC, <codecvt> is a known issue on libstdc++, it works on libc++)
* - STD_THREAD_NOT_SUPPORTED (GCC < 4.8.1)
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
* - USE_github_com_meganz_mingw_std_threads (MinGW with GCC < 4.8.1)
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
* - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8)
* - VERBOSE_PREPROCESSOR, STOP_VERBOSE_PREPROCESSOR
* - STD_make_unique_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
* or __cpp_lib_make_unique
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0096r0.html#detail.cpp14.n3656
*/
#ifndef NANA_CONFIG_HPP
@ -67,18 +99,31 @@
// google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources.
#define STD_CODECVT_NOT_SUPPORTED
#endif // _MSC_VER == 1900
#endif // _MSVC
#if defined(__clang__)
#elif defined(__clang__) //Clang
#include <iosfwd> //Introduces some implement-specific flags of ISO C++ Library
#if defined(__GLIBCPP__) || defined(__GLIBCXX__)
//<codecvt> is a known issue on libstdc++, it works on libc++
#define STD_CODECVT_NOT_SUPPORTED
#endif
#elif defined(__GNUC__) //GCC
#include <iosfwd> //Introduces some implement-specific flags of ISO C++ Library
#if defined(__GLIBCPP__) || defined(__GLIBCXX__)
//<codecvt> is a known issue on libstdc++, it works on libc++
#define STD_CODECVT_NOT_SUPPORTED
//It's a known issue of libstdc++ on MinGW
//introduce to_string/to_wstring workarounds for disabled capacity of stdlib
#ifdef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
#if (__GNUC__ < 5)
# define STD_TO_STRING_NOT_SUPPORTED
#endif
#define STD_TO_WSTRING_NOT_SUPPORTED
#endif
#endif
#if (__GNUC__ == 4)
@ -89,16 +134,29 @@
//but if USE_github_com_meganz_mingw_std_threads is enabled,
//boost.thread will be replaced with meganz's mingw-std-threads.
// https://github.com/meganz/mingw-std-threads
//#define USE_github_com_meganz_mingw_std_threads
#if !defined( USE_github_com_meganz_mingw_std_threads )
//#define USE_github_com_meganz_mingw_std_threads
#endif
#if !defined(STD_make_unique_NOT_SUPPORTED)
#define STD_make_unique_NOT_SUPPORTED
#endif //STD_make_unique_NOT_SUPPORTED
#endif
#if defined(NANA_MINGW)
//It's a known issue under MinGW
//It's a knonwn issue under MinGW
#define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
#endif
#if ((__GNUC_MINOR__ < 8) || defined(NANA_MINGW))
#define STD_TO_STRING_NOT_SUPPORTED
#if (__GNUC_MINOR__ < 8)
//introduce to_string/to_wstring workaround for lack of stdlib definitions
#ifndef STD_TO_STRING_NOT_SUPPORTED
# define STD_TO_STRING_NOT_SUPPORTED
#endif
#ifndef STD_TO_WSTRING_NOT_SUPPORTED
# define STD_TO_WSTRING_NOT_SUPPORTED
#endif
#endif
#endif
#endif
@ -151,5 +209,13 @@
#endif
#endif
#if !defined(VERBOSE_PREPROCESSOR)
//#define VERBOSE_PREPROCESSOR
#endif
#endif //NANA_CONFIG_HPP
#if !defined(STOP_VERBOSE_PREPROCESSOR)
#define STOP_VERBOSE_PREPROCESSOR
#endif
#endif // NANA_CONFIG_HPP

View File

@ -3,8 +3,8 @@
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* 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/deploy.hpp
@ -15,9 +15,12 @@
#ifndef NANA_DEPLOY_HPP
#define NANA_DEPLOY_HPP
#include <stdexcept>
#include <nana/config.hpp>
#if defined(VERBOSE_PREPROCESSOR)
#include <nana/verbose_preprocessor.hpp>
#endif
#include <stdexcept>
#include <nana/charset.hpp>
//Implement workarounds for GCC/MinGW which version is below 4.8.2
@ -71,7 +74,12 @@ namespace std
std::string to_string(long long);
std::string to_string(unsigned long long);
std::string to_string(float);
}
#endif
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
namespace std
{
std::wstring to_wstring(long double);
std::wstring to_wstring(double);
std::wstring to_wstring(unsigned);
@ -146,4 +154,44 @@ namespace nana
#define NANA_RGB(a) (((DWORD)(a) & 0xFF)<<16) | ((DWORD)(a) & 0xFF00) | (((DWORD)(a) & 0xFF0000) >> 16 )
#if defined(STD_make_unique_NOT_SUPPORTED)
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>
namespace std {
template<class T> struct _Unique_if {
typedef unique_ptr<T> _Single_object;
};
template<class T> struct _Unique_if<T[]> {
typedef unique_ptr<T[]> _Unknown_bound;
};
template<class T, size_t N> struct _Unique_if<T[N]> {
typedef void _Known_bound;
};
template<class T, class... Args>
typename _Unique_if<T>::_Single_object
make_unique(Args&&... args) {
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
template<class T>
typename _Unique_if<T>::_Unknown_bound
make_unique(size_t n) {
typedef typename remove_extent<T>::type U;
return unique_ptr<T>(new U[n]());
}
template<class T, class... Args>
typename _Unique_if<T>::_Known_bound
make_unique(Args&&...) = delete;
}
#endif //STD_make_unique_NOT_SUPPORTED
#endif //NANA_MACROS_HPP

View File

@ -72,10 +72,12 @@ namespace detail
static void capture_window(native_window_type, bool);
static nana::point cursor_position();
static native_window_type get_owner_window(native_window_type);
static native_window_type parent_window(native_window_type);
static native_window_type parent_window(native_window_type child, native_window_type new_parent, bool returns_previous);
//For Caret
static void caret_create(native_window_type, const ::nana::size&);
static void caret_create(native_window_type, const ::nana::size&);
static void caret_destroy(native_window_type);
static void caret_pos(native_window_type, const ::nana::point&);
static void caret_pos(native_window_type, const ::nana::point&);
static void caret_visible(native_window_type, bool);
static void set_focus(native_window_type);

View File

@ -0,0 +1,56 @@
/**
* Nana Verbose preprocessor
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 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/verbose_preprocessor.hpp
*
* @brief show the values of configuration constants during compilation to facilitate build debugging.
*
* Set VERBOSE_PREPROCESSOR to 1 to show the messages or to 0 for a normal build.
* Normally set to 0. Set to 1 only in case you want to debug the build system because it is extremely repetitive and slow.
*
* @authors Ariel Vina-Rodriguez (qPCR4vir)
*
*/
// Created by ariel.rodriguez on 08.12.2015.
//
#ifndef NANA_VERBOSE_PREPROCESSOR_H
#define NANA_VERBOSE_PREPROCESSOR_H
#if defined(VERBOSE_PREPROCESSOR)
#define STRING2(x) #x
#define STRING(x) STRING2(x)
#pragma message ( "\nVerbose preprocessor =" STRING(VERBOSE_PREPROCESSOR)" , \n STOP_VERBOSE_PREPROCESSOR=" STRING(STOP_VERBOSE_PREPROCESSOR) )
#pragma message ( "\nWindows: \n _WIN32=" STRING(_WIN32) ", \n __WIN32__ =" STRING(__WIN32__) " , \n WIN32=" STRING(WIN32)" , \n NANA_WINDOWS=" STRING(NANA_WINDOWS) )
#pragma message ( "\nUNICODE: \n NANA_UNICODE=" STRING(NANA_UNICODE) ", \n _UNICODE =" STRING(_UNICODE) " , \n UNICODE=" STRING(UNICODE) )
#pragma message ( "\nMinGW: \n __MINGW32__=" STRING(__MINGW32__) ", \n __MINGW64__=" STRING(__MINGW64__) " , \n MINGW=" STRING(MINGW) )
#pragma message ( "\nGNU: \n __GNUC__=" STRING(__GNUC__) ", \n __GNUC_MINOR__=" STRING(__GNUC_MINOR__) " , \n __GNUC_PATCHLEVEL__=" STRING(__GNUC_PATCHLEVEL__) )
#pragma message ( "\nSTD: \nSTD_CODECVT_NOT_SUPPORTED=" STRING(STD_CODECVT_NOT_SUPPORTED) " , \nSTD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) )
#pragma message ( "\nSTD: \nUSE_github_com_meganz_mingw_std_threads=" STRING(USE_github_com_meganz_mingw_std_threads) " , \nSTD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) )
#pragma message ( "\nClang compiler: \n__clang__=" STRING(__clang__) ", \n__GLIBCPP__=" STRING(__GLIBCPP__) " , \n__GLIBCXX__=" STRING(__GLIBCXX__) )
#pragma message ( "\nMSC: \n_MSC_VER=" STRING(_MSC_VER) ", \n_MSC_FULL_VER=" STRING(_MSC_FULL_VER ) )
#if defined(STOP_VERBOSE_PREPROCESSOR)
#error ("\nCompilation stopped to avoid annoying messages")
#endif
#endif // VERBOSE_PREPROCESSOR
#endif //NANA_VERBOSE_PREPROCESSOR_H

View File

@ -299,6 +299,7 @@ namespace std
#endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
#ifdef STD_TO_STRING_NOT_SUPPORTED
#include <sstream>
namespace std
{
std::string to_string(double v)
@ -363,7 +364,13 @@ namespace std
ss << v;
return ss.str();
}
}
#endif // STD_TO_STRING_NOT_SUPPORTED
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
#include <sstream>
namespace std
{
std::wstring to_wstring(double v)
{
std::wstringstream ss;

View File

@ -281,7 +281,8 @@ namespace nana{
attr_mask, &win_attr);
if(handle)
{
if(owner)
//make owner if it is a popup window
if((!nested) && owner)
restrict::spec.make_owner(owner, reinterpret_cast<native_window_type>(handle));
XTextProperty name;
@ -417,8 +418,6 @@ namespace nana{
if(handle)
{
restrict::spec.make_owner(parent, reinterpret_cast<native_window_type>(handle));
XTextProperty name;
char text[] = "Nana Child Window";
char * str = text;
@ -786,21 +785,30 @@ namespace nana{
#if defined(NANA_WINDOWS)
::RECT r;
::GetWindowRect(reinterpret_cast<HWND>(wd), & r);
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
if(owner)
HWND coord_wd = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
if (!coord_wd)
coord_wd = ::GetParent(reinterpret_cast<HWND>(wd));
if (coord_wd)
{
::POINT pos = {r.left, r.top};
::ScreenToClient(owner, &pos);
::ScreenToClient(coord_wd, &pos);
return nana::point(pos.x, pos.y);
}
return nana::point(r.left, r.top);
#elif defined(NANA_X11)
int x, y;
nana::detail::platform_scope_guard psg;
Window root = reinterpret_cast<Window>(restrict::spec.get_owner(wd));
if(root == 0) root = restrict::spec.root_window();
Window coord_wd = reinterpret_cast<Window>(restrict::spec.get_owner(wd));
if(!coord_wd)
{
coord_wd = reinterpret_cast<Window>(parent_window(wd));
if(!coord_wd)
coord_wd = restrict::spec.root_window();
}
Window child;
if(True == ::XTranslateCoordinates(restrict::spec.open_display(), reinterpret_cast<Window>(wd), root, 0, 0, &x, &y, &child))
if(True == ::XTranslateCoordinates(restrict::spec.open_display(), reinterpret_cast<Window>(wd), coord_wd, 0, 0, &x, &y, &child))
return nana::point(x, y);
return nana::point(0, 0);
#endif
@ -1190,6 +1198,54 @@ namespace nana{
#endif
}
native_window_type native_interface::parent_window(native_window_type wd)
{
#ifdef NANA_WINDOWS
return reinterpret_cast<native_window_type>(::GetParent(reinterpret_cast<HWND>(wd)));
#elif defined(NANA_X11)
Window root;
Window parent;
Window * children;
unsigned size;
platform_scope_guard lock;
if(0 != ::XQueryTree(restrict::spec.open_display(), reinterpret_cast<Window>(wd),
&root, &parent, &children, &size))
{
::XFree(children);
return reinterpret_cast<native_window_type>(parent);
}
return nullptr;
#endif
}
native_window_type native_interface::parent_window(native_window_type child, native_window_type new_parent, bool returns_previous)
{
#ifdef NANA_WINDOWS
auto prev = ::SetParent(reinterpret_cast<HWND>(child), reinterpret_cast<HWND>(new_parent));
if (prev)
::PostMessage(prev, WM_CHANGEUISTATE, UIS_INITIALIZE, NULL);
::SetWindowPos(reinterpret_cast<HWND>(child), NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
return reinterpret_cast<native_window_type>(returns_previous ? prev : nullptr);
#elif defined(NANA_X11)
native_window_type prev = nullptr;
platform_scope_guard lock;
if(returns_previous)
prev = parent_window(child);
::XReparentWindow(restrict::spec.open_display(),
reinterpret_cast<Window>(child), reinterpret_cast<Window>(new_parent),
0, 0);
return prev;
#endif
}
void native_interface::caret_create(native_window_type wd, const ::nana::size& caret_sz)
{
#if defined(NANA_WINDOWS)

View File

@ -140,7 +140,7 @@ namespace nana
for (++i; i < end; ++i)
{
core_window_t* cover = *i;
if (cover->visible && (nullptr == cover->effect.bground))
if ((category::flags::root != cover->other.category) && cover->visible && (nullptr == cover->effect.bground))
{
if (overlap(vis_rect, rectangle{ cover->pos_root, cover->dimension }, block.r))
{
@ -271,9 +271,15 @@ namespace nana
for (auto child : wd->children)
{
//it will not past children if no drawer and visible is false.
if ((false == child->visible) || ((child->other.category != category::lite_widget_tag::value) && child->drawer.graphics.empty()))
if ((false == child->visible) || ((category::flags::lite_widget != child->other.category) && child->drawer.graphics.empty()))
continue;
if (category::flags::root == child->other.category)
{
paint(child, is_child_refreshed, is_child_refreshed);
continue;
}
if (nullptr == child->effect.bground)
{
if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect))

View File

@ -291,6 +291,14 @@ namespace detail
if (result.native_handle)
{
core_window_t* wd = new core_window_t(owner, widget_notifier_interface::get_notifier(wdg), (category::root_tag**)nullptr);
if (nested)
{
wd->owner = nullptr;
wd->parent = owner;
wd->index = static_cast<unsigned>(owner->children.size());
owner->children.push_back(wd);
}
wd->flags.take_active = !app.no_activate;
wd->title = native_interface::window_caption(result.native_handle);
@ -542,10 +550,10 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd))
{
if(wd->other.category != category::root_tag::value)
if (category::flags::root != wd->other.category)
{
//Move child widgets
if(x != wd->pos_owner.x || y != wd->pos_owner.y)
if (x != wd->pos_owner.x || y != wd->pos_owner.y)
{
point delta{ x - wd->pos_owner.x, y - wd->pos_owner.y };
@ -562,8 +570,20 @@ namespace detail
return true;
}
}
else if(false == passive)
else if (!passive)
{
//Check if this root is a nested
if (wd->parent && (category::flags::root != wd->parent->other.category))
{
//The parent of the window is not a root, the position should
//be transformed to a position based on its parent.
x += wd->parent->pos_root.x;
y += wd->parent->pos_root.y;
}
native_interface::move_window(wd->root, x, y);
}
}
return false;
@ -602,22 +622,36 @@ namespace detail
}
else
{
::nana::rectangle root_r = r;
//Move event should not get called here,
//because the window is a root, the event will get called by system event handler.
//Check if this root is a nested
if (wd->parent && (category::flags::root != wd->parent->other.category))
{
//The parent of the window is not a root, the position should
//be transformed to a position based on its parent.
root_r.x += wd->parent->pos_root.x;
root_r.y += wd->parent->pos_root.y;
}
if(size_changed)
{
wd->dimension.width = r.width;
wd->dimension.height = r.height;
wd->dimension.width = root_r.width;
wd->dimension.height = root_r.height;
wd->drawer.graphics.make(wd->dimension);
wd->root_graph->make(wd->dimension);
native_interface::move_window(wd->root, r);
native_interface::move_window(wd->root, root_r);
arg_resized arg;
arg.window_handle = reinterpret_cast<window>(wd);
arg.width = r.width;
arg.height = r.height;
arg.width = root_r.width;
arg.height = root_r.height;
brock.emit(event_code::resized, wd, arg, true, brock.get_thread_context());
}
else
native_interface::move_window(wd->root, r.x, r.y);
native_interface::move_window(wd->root, root_r.x, root_r.y);
}
return (moved || size_changed);
@ -919,34 +953,37 @@ namespace detail
arg.receiver = wd->root;
brock.emit(event_code::focus, prev_focus, arg, true, brock.get_thread_context());
}
//Check the prev_focus again, because it may be closed in focus event
if (!impl_->wd_register.available(prev_focus))
prev_focus = nullptr;
}
else if(wd->root == native_interface::get_focus_window())
wd = nullptr; //no new focus_window
return prev_focus; //no new focus_window
if(wd)
{
if(wd->together.caret)
wd->together.caret->set_active(true);
arg.window_handle = reinterpret_cast<window>(wd);
arg.getting = true;
arg.receiver = wd->root;
brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context());
if(wd->together.caret)
wd->together.caret->set_active(true);
if (!root_has_been_focused)
native_interface::set_focus(root_wd->root);
arg.window_handle = reinterpret_cast<window>(wd);
arg.getting = true;
arg.receiver = wd->root;
brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context());
//A fix by Katsuhisa Yuasa
//The menubar token window will be redirected to the prev focus window when the new
//focus window is a menubar.
//The focus window will be restore to the prev focus which losts the focus becuase of
//memberbar.
if (wd == wd->root_widget->other.attribute.root->menubar)
wd = prev_focus;
if (!root_has_been_focused)
native_interface::set_focus(root_wd->root);
//A fix by Katsuhisa Yuasa
//The menubar token window will be redirected to the prev focus window when the new
//focus window is a menubar.
//The focus window will be restore to the prev focus which losts the focus becuase of
//memberbar.
if (prev_focus && (wd == wd->root_widget->other.attribute.root->menubar))
wd = prev_focus;
if (wd != wd->root_widget->other.attribute.root->menubar)
brock.set_menubar_taken(wd);
if (wd != wd->root_widget->other.attribute.root->menubar)
brock.set_menubar_taken(wd);
}
return prev_focus;
}
@ -1301,7 +1338,9 @@ namespace detail
void window_manager::_m_disengage(core_window_t* wd, core_window_t* for_new)
{
auto * const wdpa = wd->parent;
bool established = (for_new && wdpa != for_new);
bool established = (for_new && (wdpa != for_new));
decltype(for_new->root_widget->other.attribute.root) pa_root_attr = nullptr;
if (established)
@ -1443,14 +1482,26 @@ namespace detail
std::function<void(core_window_t*, const nana::point&)> set_pos_root;
set_pos_root = [&set_pos_root](core_window_t* wd, const nana::point& delta_pos)
{
wd->pos_root -= delta_pos;
for (auto child : wd->children)
{
child->root = wd->root;
child->root_graph = wd->root_graph;
child->root_widget = wd->root_widget;
set_pos_root(child, delta_pos);
if (category::flags::root == child->other.category)
{
auto pos = native_interface::window_position(child->root);
native_interface::parent_window(child->root, wd->root, false);
pos -= delta_pos;
native_interface::move_window(child->root, pos.x, pos.y);
}
else
{
child->root = wd->root;
child->root_graph = wd->root_graph;
child->root_widget = wd->root_widget;
set_pos_root(child, delta_pos);
}
}
wd->pos_root -= delta_pos;
};
set_pos_root(wd, delta_pos);
@ -1481,8 +1532,30 @@ namespace detail
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
//Delete the children widgets.
for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end; ++i)
_m_destroy(*i);
for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end;)
{
auto child = *i;
if (category::flags::root == child->other.category)
{
//closing a child root window erases itself from wd->children,
//to make sure the iterator is valid, it must be reloaded.
auto offset = std::distance(wd->children.rbegin(), i);
//!!!
//a potential issue is that if the calling thread is not same with child's thread,
//the child root window may not be erased from wd->children now.
native_interface::close_window(child->root);
i = wd->children.rbegin();
std::advance(i, offset);
end = wd->children.rend();
continue;
}
_m_destroy(child);
++i;
}
wd->children.clear();
@ -1508,7 +1581,7 @@ namespace detail
void window_manager::_m_move_core(core_window_t* wd, const point& delta)
{
if(wd->other.category != category::root_tag::value) //A root widget always starts at (0, 0) and its childs are not to be changed
if(category::flags::root != wd->other.category) //A root widget always starts at (0, 0) and its childs are not to be changed
{
wd->pos_root += delta;
if (category::flags::frame != wd->other.category)
@ -1525,6 +1598,11 @@ namespace detail
for (auto child : wd->children)
_m_move_core(child, delta);
}
else
{
auto pos = native_interface::window_position(wd->root) + delta;
native_interface::move_window(wd->root, pos.x, pos.y);
}
}
//_m_find

View File

@ -542,8 +542,8 @@ namespace API
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if(restrict::wd_manager().available(iwd))
return reinterpret_cast<window>(iwd->other.category == category::flags::root ? iwd->owner : iwd->parent);
if (restrict::wd_manager().available(iwd))
return reinterpret_cast<window>(iwd->parent);
return nullptr;
}

View File

@ -58,12 +58,12 @@ namespace nana
cell::cell(std::string text, const format& fmt)
: text(std::move(text)),
custom_format(new format{ fmt }) //make_unique
custom_format(std::make_unique<format>( fmt )) // or custom_format(new format{ fmt })
{}
cell::cell(std::string text, const ::nana::color& bgcolor, const ::nana::color& fgcolor)
: text(std::move(text)),
custom_format{ new format{ bgcolor, fgcolor } } //make_unique
custom_format{std::make_unique<format>( bgcolor, fgcolor ) } //custom_format{ new format{ bgcolor, fgcolor } }
{}
cell& cell::operator=(const cell& rhs)

View File

@ -528,17 +528,16 @@ namespace nana
auto index = state_.active;
for (auto & m : menu_->items)
{
if (0 == index--)
break;
if (m.flags.splitter)
{
pos.y += 2;
continue;
}
if (0 == index)
break;
pos.y += _m_item_height() + 1;
--index;
}
tmstamp = state_.active_timestamp;