Merge remote-tracking branch 'cnjinhao/develop' into develop

# Conflicts:
#	build/vc2017/nana.vcxproj.filters
This commit is contained in:
qPCR4vir 2017-12-03 00:55:27 +01:00
commit d5d1ba3c9e
36 changed files with 878 additions and 365 deletions

1
.gitignore vendored
View File

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

View File

@ -35,6 +35,9 @@ matrix:
- libx11-dev - libx11-dev
- libxft-dev - libxft-dev
- libboost-filesystem-dev - libboost-filesystem-dev
- libboost-system-dev
- libboost-thread-dev
- libboost-chrono-dev
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test

View File

@ -35,6 +35,7 @@ option(NANA_CMAKE_SHARED_LIB "Compile nana as a shared library." OFF)
option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." ON) option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." ON)
option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." OFF) option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." OFF)
option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF) option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF)
option(NANA_CLION "Activate some CLion specific workarounds" OFF)
# The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional. # The ISO C++ File System Technical Specification (ISO-TS, or STD) is optional.
# http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf
@ -64,11 +65,12 @@ if(POLICY CMP0004) # ignore leading space
cmake_policy(SET CMP0004 OLD) cmake_policy(SET CMP0004 OLD)
endif() endif()
set(CMAKE_DEBUG_POSTFIX "_d")
########### OS ########### OS
if(WIN32) if(WIN32)
add_definitions(-DWIN32) add_definitions(-DWIN32)
set(CMAKE_DEBUG_POSTFIX "_d")
#Global MSVC definitions. You may prefer the hand-tuned sln and projects from the nana repository. #Global MSVC definitions. You may prefer the hand-tuned sln and projects from the nana repository.
if(MSVC) if(MSVC)
option(MSVC_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON) option(MSVC_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON)
@ -139,10 +141,15 @@ endif(UNIX)
########### Compilers ########### Compilers
# #
# Using gcc: gcc 4.8 don't support C++14 and make_unique. You may want to update at least to 4.9. # Using gcc: gcc 4.8 don't support C++14 and make_unique. You may want to update at least to 4.9.
# In Windows, the gcc which come with CLion was 4.8 from MinGW. You may want to install MinGW-w64 from the
# TDM-GCC Compiler Suite for Windows which will update you to gcc 5.1.
# gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs # gcc 5.3 and 5.4 include filesytem, but you need to add the link flag: -lstdc++fs
# #
# In Windows, the gcc which come with CLion was 4.8 from MinGW.
# CLion was updated to MinGW with gcc 6.3 ? Allways check this in File/Settings.../toolchains
# You could install MinGW-w64 from the TDM-GCC Compiler Suite for Windows which will update you to gcc 5.1.
# It is posible to follow https://computingabdn.com/softech/mingw-howto-install-gcc-for-windows/
# and install MinGW with gcc 7.1 with has STD_THREADS and fs, from: https://sourceforge.net/projects/mingw-w64/files/
#
#
# see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html # see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU
@ -238,7 +245,7 @@ elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE)
add_definitions(-DSTD_FILESYSTEM_FORCE) add_definitions(-DSTD_FILESYSTEM_FORCE)
elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) add_definitions(-DBOOST_FILESYSTEM_FORCE)
endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
# https://cmake.org/cmake/help/git-master/module/FindBoost.html # https://cmake.org/cmake/help/git-master/module/FindBoost.html
# Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied,
@ -246,7 +253,7 @@ elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
# If using Boost::thread, then Thread::Thread will also be added automatically. # If using Boost::thread, then Thread::Thread will also be added automatically.
find_package(Boost COMPONENTS filesystem) find_package(Boost COMPONENTS filesystem)
if (Boost_FOUND) if (Boost_FOUND)
add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) add_definitions(-DBOOST_FILESYSTEM_AVAILABLE)
include_directories(SYSTEM "${Boost_INCLUDE_DIR}") include_directories(SYSTEM "${Boost_INCLUDE_DIR}")
list(APPEND NANA_LINKS ${Boost_LIBRARIES}) ###### FIRST !!!!!!!!!!!!!!!!! add is not first list(APPEND NANA_LINKS ${Boost_LIBRARIES}) ###### FIRST !!!!!!!!!!!!!!!!! add is not first
endif (Boost_FOUND) endif (Boost_FOUND)
@ -314,10 +321,20 @@ target_link_libraries(${PROJECT_NAME} ${NANA_LINKS})
# Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/ # Installing: the static "nana lib" will be in DESTDIR/CMAKE_INSTALL_PREFIX/lib/
# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ # and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/
# unfortunatelly install() is still ignored by CLion:
# https://intellij-support.jetbrains.com/hc/en-us/community/posts/205822949-CMake-install-isn-t-supported-
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
RUNTIME DESTINATION bin) RUNTIME DESTINATION bin)
# http://stackoverflow.com/questions/33788729/how-do-i-get-clion-to-run-an-install-target
if(NANA_CLION) # the Clion IDE don't reconize the install target
add_custom_target(install_${PROJECT_NAME}
$(MAKE) install
DEPENDS ${PROJECT_NAME}
COMMENT "Installing ${PROJECT_NAME}")
endif()
set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 )
if (NANA_CMAKE_SHARED_LIB) if (NANA_CMAKE_SHARED_LIB)
@ -347,6 +364,7 @@ if (NANA_CMAKE_SHARED_LIB)
endif (NANA_CMAKE_SHARED_LIB) endif (NANA_CMAKE_SHARED_LIB)
message ("") message ("")
message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib")
# Install the include directories too. # Install the include directories too.
if(NANA_CMAKE_INSTALL_INCLUDES) if(NANA_CMAKE_INSTALL_INCLUDES)
@ -370,6 +388,9 @@ message ( "NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR})
message ( "CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR}) message ( "CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR})
message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO}) message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO})
message ( "NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB}) message ( "NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB})
message ( "NANA_CLION = " ${NANA_CLION})
message ( "CMAKE_MAKE_PROGRAM = " ${CMAKE_MAKE_PROGRAM})
message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT})

View File

@ -252,6 +252,32 @@
<ClCompile Include="..\..\source\threads\pool.cpp" /> <ClCompile Include="..\..\source\threads\pool.cpp" />
<ClCompile Include="..\..\source\unicode_bidi.cpp" /> <ClCompile Include="..\..\source\unicode_bidi.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\any.hpp" />
<ClInclude Include="..\..\include\nana\basic_types.hpp" />
<ClInclude Include="..\..\include\nana\c++defines.hpp" />
<ClInclude Include="..\..\include\nana\charset.hpp" />
<ClInclude Include="..\..\include\nana\concepts.hpp" />
<ClInclude Include="..\..\include\nana\config.hpp" />
<ClInclude Include="..\..\include\nana\datetime.hpp" />
<ClInclude Include="..\..\include\nana\deploy.hpp" />
<ClInclude Include="..\..\include\nana\fwd.hpp" />
<ClInclude Include="..\..\include\nana\gui.hpp" />
<ClInclude Include="..\..\include\nana\internationalization.hpp" />
<ClInclude Include="..\..\include\nana\key_type.hpp" />
<ClInclude Include="..\..\include\nana\optional.hpp" />
<ClInclude Include="..\..\include\nana\stdc++.hpp" />
<ClInclude Include="..\..\include\nana\std_condition_variable.hpp" />
<ClInclude Include="..\..\include\nana\std_mutex.hpp" />
<ClInclude Include="..\..\include\nana\std_thread.hpp" />
<ClInclude Include="..\..\include\nana\traits.hpp" />
<ClInclude Include="..\..\include\nana\unicode_bidi.hpp" />
<ClInclude Include="..\..\include\nana\verbose_preprocessor.hpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\include\nana\pop_ignore_diagnostic" />
<None Include="..\..\include\nana\push_ignore_diagnostic" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -292,4 +292,74 @@
<Filter>Source Files\detail</Filter> <Filter>Source Files\detail</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\any.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\basic_types.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\c++defines.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\charset.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\concepts.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\config.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\datetime.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\deploy.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\fwd.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\internationalization.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\key_type.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\optional.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_condition_variable.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_mutex.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_thread.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\stdc++.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\traits.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\unicode_bidi.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\verbose_preprocessor.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\include\nana\pop_ignore_diagnostic">
<Filter>Header Files</Filter>
</None>
<None Include="..\..\include\nana\push_ignore_diagnostic">
<Filter>Header Files</Filter>
</None>
</ItemGroup>
</Project> </Project>

View File

@ -236,6 +236,73 @@
<ClCompile Include="..\..\source\threads\pool.cpp" /> <ClCompile Include="..\..\source\threads\pool.cpp" />
<ClCompile Include="..\..\source\unicode_bidi.cpp" /> <ClCompile Include="..\..\source\unicode_bidi.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\any.hpp" />
<ClInclude Include="..\..\include\nana\basic_types.hpp" />
<ClInclude Include="..\..\include\nana\c++defines.hpp" />
<ClInclude Include="..\..\include\nana\charset.hpp" />
<ClInclude Include="..\..\include\nana\concepts.hpp" />
<ClInclude Include="..\..\include\nana\config.hpp" />
<ClInclude Include="..\..\include\nana\datetime.hpp" />
<ClInclude Include="..\..\include\nana\deploy.hpp" />
<ClInclude Include="..\..\include\nana\fwd.hpp" />
<ClInclude Include="..\..\include\nana\gui.hpp" />
<ClInclude Include="..\..\include\nana\gui\animation.hpp" />
<ClInclude Include="..\..\include\nana\gui\basis.hpp" />
<ClInclude Include="..\..\include\nana\gui\dragger.hpp" />
<ClInclude Include="..\..\include\nana\gui\drawing.hpp" />
<ClInclude Include="..\..\include\nana\gui\effects.hpp" />
<ClInclude Include="..\..\include\nana\gui\element.hpp" />
<ClInclude Include="..\..\include\nana\gui\filebox.hpp" />
<ClInclude Include="..\..\include\nana\gui\layout_utility.hpp" />
<ClInclude Include="..\..\include\nana\gui\msgbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\notifier.hpp" />
<ClInclude Include="..\..\include\nana\gui\place.hpp" />
<ClInclude Include="..\..\include\nana\gui\programming_interface.hpp" />
<ClInclude Include="..\..\include\nana\gui\screen.hpp" />
<ClInclude Include="..\..\include\nana\gui\state_cursor.hpp" />
<ClInclude Include="..\..\include\nana\gui\timer.hpp" />
<ClInclude Include="..\..\include\nana\gui\tooltip.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\button.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\categorize.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\checkbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\combox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\date_chooser.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\float_listbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\form.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\frame.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\group.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\label.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\listbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\menu.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\menubar.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\panel.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\picture.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\progress.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\scroll.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\slider.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\spinbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\tabbar.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\textbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\toolbar.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\treebox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\widget.hpp" />
<ClInclude Include="..\..\include\nana\gui\wvl.hpp" />
<ClInclude Include="..\..\include\nana\internationalization.hpp" />
<ClInclude Include="..\..\include\nana\key_type.hpp" />
<ClInclude Include="..\..\include\nana\optional.hpp" />
<ClInclude Include="..\..\include\nana\stdc++.hpp" />
<ClInclude Include="..\..\include\nana\std_condition_variable.hpp" />
<ClInclude Include="..\..\include\nana\std_mutex.hpp" />
<ClInclude Include="..\..\include\nana\std_thread.hpp" />
<ClInclude Include="..\..\include\nana\traits.hpp" />
<ClInclude Include="..\..\include\nana\unicode_bidi.hpp" />
<ClInclude Include="..\..\include\nana\verbose_preprocessor.hpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\include\nana\pop_ignore_diagnostic" />
<None Include="..\..\include\nana\push_ignore_diagnostic" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -41,8 +41,14 @@
<Filter Include="Sources\threads"> <Filter Include="Sources\threads">
<UniqueIdentifier>{c1cdf46a-519f-422a-947f-39e173045414}</UniqueIdentifier> <UniqueIdentifier>{c1cdf46a-519f-422a-947f-39e173045414}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Headers"> <Filter Include="Include">
<UniqueIdentifier>{d87c71b7-71e7-4221-953e-783325beffe4}</UniqueIdentifier> <UniqueIdentifier>{d68bd89c-170f-445f-b79f-aa03c881ab6b}</UniqueIdentifier>
</Filter>
<Filter Include="Include\gui">
<UniqueIdentifier>{a5d87649-2cd1-4a8f-a1f9-7151eaf6c772}</UniqueIdentifier>
</Filter>
<Filter Include="Include\gui\widgets">
<UniqueIdentifier>{0e6a58ab-652c-45d7-b9aa-8d9f2fa80ea1}</UniqueIdentifier>
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -287,4 +293,197 @@
<Filter>Sources\gui</Filter> <Filter>Sources\gui</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\gui\widgets\spinbox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\group.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\treebox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\listbox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\menu.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\menubar.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\progress.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\widget.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\textbox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\toolbar.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\button.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\combox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\label.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\panel.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\picture.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\tabbar.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\categorize.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\scroll.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\slider.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\checkbox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\date_chooser.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\float_listbox.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\form.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\frame.hpp">
<Filter>Include\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\animation.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\basis.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\dragger.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\drawing.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\effects.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\element.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\filebox.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\layout_utility.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\msgbox.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\notifier.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\place.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\programming_interface.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\screen.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\state_cursor.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\timer.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\tooltip.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\wvl.hpp">
<Filter>Include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\any.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\basic_types.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\c++defines.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\charset.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\concepts.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\config.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\datetime.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\deploy.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\fwd.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\internationalization.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\key_type.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\optional.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_condition_variable.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_mutex.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_thread.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\stdc++.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\traits.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\unicode_bidi.hpp">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\verbose_preprocessor.hpp">
<Filter>Include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\include\nana\pop_ignore_diagnostic">
<Filter>Include</Filter>
</None>
<None Include="..\..\include\nana\push_ignore_diagnostic">
<Filter>Include</Filter>
</None>
</ItemGroup>
</Project> </Project>

View File

@ -312,7 +312,14 @@ namespace nana
/// @param lightness in range of [0, 1] /// @param lightness in range of [0, 1]
color& from_hsl(double hue, double saturation, double lightness); ///< immutable alpha channel color& from_hsl(double hue, double saturation, double lightness); ///< immutable alpha channel
color blend(const color& blending_color, double alpha) const; /// Blends color
/**
* Returns a color which is blended as this * (1 - fade_rate) + blending_color * fade_rate
* @param blending_color Color to blend
* @param fade_rate Blending rate for blending_color
* @return a blended color
*/
color blend(const color& blending_color, double fade_rate) const;
/// Determines whether the color is completely transparent. /// Determines whether the color is completely transparent.
bool invisible() const; bool invisible() const;

View File

@ -173,6 +173,7 @@
//Assume the std::thread is not implement on MinGW //Assume the std::thread is not implement on MinGW
//But some toolchains may implement std::thread. //But some toolchains may implement std::thread.
// it seems that MinGW 6.3 and 7.1 have std::thread
#ifdef NANA_MINGW #ifdef NANA_MINGW
# ifndef STD_THREAD_NOT_SUPPORTED # ifndef STD_THREAD_NOT_SUPPORTED
# define STD_THREAD_NOT_SUPPORTED # define STD_THREAD_NOT_SUPPORTED
@ -220,6 +221,9 @@
# if __has_include(<filesystem>) # if __has_include(<filesystem>)
# undef STD_FILESYSTEM_NOT_SUPPORTED # undef STD_FILESYSTEM_NOT_SUPPORTED
# endif # endif
# if __has_include(<mutex>)
# undef STD_THREAD_NOT_SUPPORTED
# endif
#endif #endif
#endif // NANA_CXX_DEFINES_INCLUDED #endif // NANA_CXX_DEFINES_INCLUDED

View File

@ -53,6 +53,7 @@
#undef NANA_USING_BOOST_FILESYSTEM #undef NANA_USING_BOOST_FILESYSTEM
#define NANA_USING_BOOST_FILESYSTEM 1 #define NANA_USING_BOOST_FILESYSTEM 1
# include <chrono>
# include <boost/filesystem.hpp> # include <boost/filesystem.hpp>
// add boost::filesystem into std::experimental::filesystem // add boost::filesystem into std::experimental::filesystem
@ -60,6 +61,20 @@ namespace std {
namespace experimental { namespace experimental {
namespace filesystem { namespace filesystem {
using namespace boost::filesystem; using namespace boost::filesystem;
using file_time_type = std::chrono::time_point<std::chrono::system_clock>;
enum class file_type {
none = boost::filesystem::file_type::status_unknown,
not_found = boost::filesystem::file_type::file_not_found,
regular = boost::filesystem::file_type::regular_file,
directory = boost::filesystem::file_type::directory_file,
symlink = boost::filesystem::file_type::symlink_file,
block = boost::filesystem::file_type::block_file,
character = boost::filesystem::file_type::character_file,
fifo = boost::filesystem::file_type::fifo_file,
socket = boost::filesystem::file_type::socket_file,
unknown = boost::filesystem::file_type::type_unknown,
};
} // filesystem } // filesystem
} // experimental } // experimental
} // std } // std

View File

@ -273,6 +273,7 @@ that return a corresponding nana::appearance with predefined values.
public: public:
virtual ~caret_interface() = default; virtual ~caret_interface() = default;
virtual bool activated() const = 0;
virtual void disable_throw() noexcept = 0; virtual void disable_throw() noexcept = 0;
virtual void effective_range(const rectangle& range) = 0; virtual void effective_range(const rectangle& range) = 0;

View File

@ -55,6 +55,7 @@ namespace detail
void dimension(const size& s) override; void dimension(const size& s) override;
void visible(bool visibility) override; void visible(bool visibility) override;
bool visible() const override; bool visible() const override;
bool activated() const override;
private: private:
basic_window * owner_; basic_window * owner_;
point position_; point position_;

View File

@ -1,7 +1,7 @@
/* /*
* Platform Implementation * Platform Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -66,11 +66,11 @@ namespace detail
static nana::point window_position(native_window_type); static nana::point window_position(native_window_type);
static void move_window(native_window_type, int x, int y); static void move_window(native_window_type, int x, int y);
static void move_window(native_window_type, const rectangle&); static bool move_window(native_window_type, const rectangle&);
static void bring_top(native_window_type, bool activated); static void bring_top(native_window_type, bool activated);
static void set_window_z_order(native_window_type, native_window_type wd_after, z_order_action action_if_no_wd_after); static void set_window_z_order(native_window_type, native_window_type wd_after, z_order_action action_if_no_wd_after);
static void window_size(native_window_type, const size&); static bool window_size(native_window_type, const size&);
static void get_window_rect(native_window_type, rectangle&); static void get_window_rect(native_window_type, rectangle&);
static void window_caption(native_window_type, const native_string_type&); static void window_caption(native_window_type, const native_string_type&);
static native_string_type window_caption(native_window_type); static native_string_type window_caption(native_window_type);

View File

@ -38,9 +38,9 @@ namespace nana
{ {
std::vector<std::shared_ptr<item_interface>> items; std::vector<std::shared_ptr<item_interface>> items;
std::size_t max_items{10}; // the number of items display. std::size_t max_items{ 10 }; // the number of items display.
mutable std::size_t index{::nana::npos}; // the result of the selection. mutable std::size_t index{ ::nana::npos }; // the result of the selection.
mutable bool have_selected; mutable bool have_selected{ false };
}; };
class item_renderer class item_renderer

View File

@ -36,7 +36,6 @@ namespace nana
void attached(widget_reference, graph_reference) override; void attached(widget_reference, graph_reference) override;
private: private:
void refresh(graph_reference) override; void refresh(graph_reference) override;
void _m_draw_background(unsigned,unsigned);
private: private:
implement * const impl_; implement * const impl_;
}; };

View File

@ -4,10 +4,10 @@
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/widgets/treebox.hpp * @file nana/gui/widgets/treebox.hpp
* @brief * @brief
* The treebox organizes the nodes by a key string. * The treebox organizes the nodes by a key string.
* The treebox would have a vertical scrollbar if there are too many nodes * The treebox would have a vertical scrollbar if there are too many nodes
@ -344,7 +344,7 @@ namespace nana
}//end namespace drawerbase }//end namespace drawerbase
/// \brief Displays a hierarchical list of items, such as the files and directories on a disk. /// \brief Displays a hierarchical list of items, such as the files and directories on a disk.
/// See also in [documentation](http://nanapro.org/en-us/help/widgets/treebox.htm) /// See also in [documentation](http://nanapro.org/en-us/documentation/widgets/treebox.htm)
class treebox class treebox
:public widget_object < category::widget_tag, drawerbase::treebox::trigger, drawerbase::treebox::treebox_events> :public widget_object < category::widget_tag, drawerbase::treebox::trigger, drawerbase::treebox::treebox_events>
{ {
@ -372,7 +372,7 @@ namespace nana
/// \brief The construct that creates a widget. /// \brief The construct that creates a widget.
/// @param wd A handle to the parent window of the widget being created. /// @param wd A handle to the parent window of the widget being created.
/// @param r the size and position of the widget in its parent window coordinate. /// @param r the size and position of the widget in its parent window coordinate.
/// @param visible specifying the visible after creating. /// @param visible specifying if visible after creating.
treebox(window, const nana::rectangle& = rectangle(), bool visible = true); treebox(window, const nana::rectangle& = rectangle(), bool visible = true);
template<typename ItemRenderer> template<typename ItemRenderer>
@ -397,18 +397,18 @@ namespace nana
/// ///
/// The treebox automatically redraws after certain operations, but, /// The treebox automatically redraws after certain operations, but,
/// under some circumstances, it is good to disable the automatic drawing mode, /// under some circumstances, it is good to disable the automatic drawing mode,
/// for example, before adding nodes in a loop, disable the mode to avoiding /// for example, before adding nodes in a loop, disable the mode avoiding
/// frequent and useless refresh for better performance, and then, after /// frequent and useless refresh for better performance, and then, after
/// the operations, enable the automatic redraw mode again. /// the operations, enable the automatic redraw mode again.
/// @param bool whether to enable. /// @param enable bool whether to enable.
void auto_draw(bool); void auto_draw(bool enable);
/// \brief Enable the checkboxs for each item of the widget. /// \brief Enable the checkboxs for each item of the widget.
/// @param bool indicates whether to show or hide the checkboxs. /// @param enable bool indicates whether to show or hide the checkboxs.
treebox & checkable(bool enable); treebox & checkable(bool enable);
bool checkable() const; ///< Determinte whether the checkboxs are enabled. bool checkable() const; ///< Are the checkboxs are enabled?
/// Clears the contents /// Clears the contents
void clear(); void clear();
@ -424,26 +424,30 @@ namespace nana
void icon_erase(const ::std::string& id); void icon_erase(const ::std::string& id);
item_proxy find(const ::std::string& keypath); ///< Find an item though a specified keypath. item_proxy find(const ::std::string& keypath); ///< Find an item through a specified keypath.
/// Inserts a new node to treebox, but if the keypath exists returns the existing node. /// Inserts a new node to treebox, but if the keypath exists change and returns the existing node.
item_proxy insert(const ::std::string& path_key, ///< specifies the node hierarchy item_proxy insert(const ::std::string& path_key, ///< specifies the node hierarchy
::std::string title ///< used for displaying ::std::string title ///< used for displaying
); );
/// Inserts a new node to treebox, but if the keypath exists returns the existing node. /// Inserts a new node to treebox, but if the keypath exists change and returns the existing node.
item_proxy insert( item_proxy pos, ///< the parent item node item_proxy insert( item_proxy pos, ///< the parent item node
const ::std::string& key, ///< specifies the new node const ::std::string& key, ///< specifies the new node
::std::string title ///< title used for displaying in the new node. ::std::string title ///< title used for displaying in the new node.
); );
item_proxy erase(item_proxy i); ///< Removes the node at pos and return the Item proxy following the removed node
item_proxy erase(item_proxy i); ///< Removes the node at i and return the Item proxy following the removed node
void erase(const ::std::string& keypath); ///< Removes the node by the key path. void erase(const ::std::string& keypath); ///< Removes the node by the key path.
::std::string make_key_path(item_proxy i, const ::std::string& splitter) const;///<returns the key path ::std::string make_key_path(item_proxy i, const ::std::string& splitter) const;///<returns the key path
item_proxy selected() const; ///< returns the selected node item_proxy selected() const; ///< returns the selected node
};//end class treebox };//end class treebox
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic> #include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -85,12 +85,14 @@ namespace nana
bool changed() const; ///< Returns true if the graphics object is operated bool changed() const; ///< Returns true if the graphics object is operated
bool empty() const; ///< Returns true if the graphics object does not refer to any resource. bool empty() const; ///< Returns true if the graphics object does not refer to any resource.
operator const void*() const; explicit operator bool() const noexcept;
drawable_type handle() const; drawable_type handle() const;
const void* pixmap() const; const void* pixmap() const;
const void* context() const; const void* context() const;
void swap(graphics& other) noexcept;
/// Creates a graphics/drawable resource /// Creates a graphics/drawable resource
/** /**
* @param sz The dimension of the graphics to be requested. If sz is empty, it performs as release(). * @param sz The dimension of the graphics to be requested. If sz is empty, it performs as release().

View File

@ -12,6 +12,9 @@
* @brief Implement the lack support of standard library. * @brief Implement the lack support of standard library.
*/ */
#ifndef NANA_STDCXX_INCLUDED
#define NANA_STDCXX_INCLUDED
#include "c++defines.hpp" #include "c++defines.hpp"
//Implement workarounds for GCC/MinGW which version is below 4.8.2 //Implement workarounds for GCC/MinGW which version is below 4.8.2
@ -153,4 +156,6 @@ namespace std
return (v < lo ? lo : (hi < v ? hi : v)); return (v < lo ? lo : (hi < v ? hi : v));
} }
} }
#endif #endif
#endif // NANA_STDCXX_INCLUDED

View File

@ -47,16 +47,6 @@ namespace detail
bool visible; bool visible;
}; };
struct move_window
{
enum { Pos = 1, Size = 2};
int x;
int y;
unsigned width;
unsigned height;
unsigned ignore; //determinate that pos or size would be ignored.
};
struct map_thread struct map_thread
{ {
rectangle update_area; rectangle update_area;
@ -77,7 +67,6 @@ namespace detail
async_set_focus, async_set_focus,
remote_flush_surface, remote_flush_surface,
remote_thread_destroy_window, remote_thread_destroy_window,
remote_thread_move_window,
operate_caret, //wParam: 1=Destroy, 2=SetPos operate_caret, //wParam: 1=Destroy, 2=SetPos
remote_thread_set_window_pos, remote_thread_set_window_pos,
remote_thread_set_window_text, remote_thread_set_window_text,

View File

@ -835,6 +835,19 @@ namespace detail
i->second->reinstate(); i->second->reinstate();
i->second->pos = pos; i->second->pos = pos;
} }
auto addr = i->second;
if(addr && addr->input_context) {
XPoint spot;
XVaNestedList list;
spot.x = pos.x;
spot.y = pos.y + addr->size.height;
list = ::XVaCreateNestedList(0, XNSpotLocation, &spot,
XNForeground, 0,
XNBackground, 0,
(void *)0);
::XSetICValues(addr->input_context, XNPreeditAttributes, list, NULL);
::XFree(list);
}
} }
void platform_spec::caret_visible(native_window_type wd, bool vis) void platform_spec::caret_visible(native_window_type wd, bool vis)

View File

@ -14,7 +14,13 @@
#include <nana/filesystem/filesystem_ext.hpp> #include <nana/filesystem/filesystem_ext.hpp>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <iomanip> //put_time
#include <nana/config.hpp>
#ifdef _enable_std_put_time
#include <nana/stdc++.hpp>
#else
#include <iomanip>
#endif
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include <windows.h> #include <windows.h>
@ -97,7 +103,13 @@ namespace nana
std::string pretty_file_date(const fs::path& path) // todo: move to .cpp std::string pretty_file_date(const fs::path& path) // todo: move to .cpp
{ {
try { try {
#if NANA_USING_BOOST_FILESYSTEM
// The return type of boost::filesystem::last_write_time isn't
// the same as in nana and std implementations of this function
auto ftime = std::chrono::system_clock::from_time_t(fs::last_write_time(path));
#else
auto ftime = fs::last_write_time(path); auto ftime = fs::last_write_time(path);
#endif
// crash: VS2015 will not read the time for some files (for example: C:/hiberfil.sys) // crash: VS2015 will not read the time for some files (for example: C:/hiberfil.sys)
// and will return file_time_type(-1) without throwing // and will return file_time_type(-1) without throwing

View File

@ -204,6 +204,11 @@ namespace nana
{ {
return (visible_state::invisible != visibility_); return (visible_state::invisible != visibility_);
} }
bool caret::activated() const
{
return (visible_state::displayed == visibility_);
}
//end class caret //end class caret
//struct basic_window //struct basic_window
@ -329,24 +334,18 @@ namespace nana
return false; return false;
} }
const basic_window* get_child_caret(const basic_window* wd, bool this_is_a_child)
{
if (this_is_a_child && wd->annex.caret_ptr)
return wd;
for (auto child : wd->children)
{
auto caret_wd = get_child_caret(child, true);
if (caret_wd)
return caret_wd;
}
return nullptr;
}
const basic_window * basic_window::child_caret() const const basic_window * basic_window::child_caret() const
{ {
return get_child_caret(this, false); for (auto child : children) {
//Only return the child who has activated caret.
if (child->annex.caret_ptr && child->annex.caret_ptr->activated())
return child;
auto caret = child->child_caret();
if (caret)
return caret;
}
return nullptr;
} }
bool basic_window::is_draw_through() const bool basic_window::is_draw_through() const

View File

@ -151,7 +151,8 @@ namespace nana
arg.window_handle = reinterpret_cast<window>(wd); arg.window_handle = reinterpret_cast<window>(wd);
if (emit(event_code::expose, wd, arg, false, get_thread_context())) if (emit(event_code::expose, wd, arg, false, get_thread_context()))
{ {
const core_window_t * caret_wd = (wd->annex.caret_ptr ? wd : wd->child_caret()); //Get the window who has the activated caret
const core_window_t * caret_wd = ((wd->annex.caret_ptr && wd->annex.caret_ptr->activated()) ? wd : wd->child_caret());
if (caret_wd) if (caret_wd)
{ {
if (exposed) if (exposed)

View File

@ -245,22 +245,31 @@ namespace detail
_m_event_filter(evt_code, wd, thrd); _m_event_filter(evt_code, wd, thrd);
} }
if(wd->other.upd_state == core_window_t::update_state::none) using update_state = basic_window::update_state;
wd->other.upd_state = core_window_t::update_state::lazy;
if(wd->other.upd_state == update_state::none)
wd->other.upd_state = update_state::lazy;
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal); _m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
//A child of wd may not be drawn if it was out of wd's range before wd resized, bool good_wd = false;
//so refresh all children of wd when a resized occurs. if(wd_manager().available(wd))
if(ask_update || (event_code::resized == evt_code))
{ {
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code)); //A child of wd may not be drawn if it was out of wd's range before wd resized,
//so refresh all children of wd when a resized occurs.
if(ask_update || (event_code::resized == evt_code) || (update_state::refreshed == wd->other.upd_state))
{
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code));
}
else
wd->other.upd_state = update_state::none;
good_wd = true;
} }
else if(wd_manager().available(wd))
wd->other.upd_state = core_window_t::update_state::none;
if(thrd) thrd->event_window = prev_wd; if(thrd) thrd->event_window = prev_wd;
return true; return good_wd;
} }
void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt) void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt)

View File

@ -601,40 +601,6 @@ namespace detail
::HeapFree(::GetProcessHeap(), 0, stru); ::HeapFree(::GetProcessHeap(), 0, stru);
} }
return true; return true;
case nana::detail::messages::remote_thread_move_window:
{
auto * mw = reinterpret_cast<nana::detail::messages::move_window*>(wParam);
::RECT r;
::GetWindowRect(wd, &r);
if(mw->ignore & mw->Pos)
{
mw->x = r.left;
mw->y = r.top;
}
else
{
HWND owner = ::GetWindow(wd, GW_OWNER);
if(owner)
{
::RECT owr;
::GetWindowRect(owner, &owr);
::POINT pos = {owr.left, owr.top};
::ScreenToClient(owner, &pos);
mw->x += (owr.left - pos.x);
mw->y += (owr.top - pos.y);
}
}
if(mw->ignore & mw->Size)
{
mw->width = r.right - r.left;
mw->height = r.bottom - r.top;
}
::MoveWindow(wd, mw->x, mw->y, mw->width, mw->height, true);
delete mw;
}
return true;
case nana::detail::messages::remote_thread_set_window_pos: case nana::detail::messages::remote_thread_set_window_pos:
::SetWindowPos(wd, reinterpret_cast<HWND>(wParam), 0, 0, 0, 0, static_cast<UINT>(lParam)); ::SetWindowPos(wd, reinterpret_cast<HWND>(wParam), 0, 0, 0, 0, static_cast<UINT>(lParam));
return true; return true;
@ -1652,18 +1618,21 @@ namespace detail
_m_event_filter(evt_code, wd, thrd); _m_event_filter(evt_code, wd, thrd);
} }
if (wd->other.upd_state == core_window_t::update_state::none) using update_state = basic_window::update_state;
wd->other.upd_state = core_window_t::update_state::lazy;
if (update_state::none == wd->other.upd_state)
wd->other.upd_state = update_state::lazy;
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal); _m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
bool good_wd = false; bool good_wd = false;
if (wd_manager().available(wd)) if (wd_manager().available(wd))
{ {
if (ask_update) //Ignore ask_update if update state is refreshed.
if (ask_update || (update_state::refreshed == wd->other.upd_state))
wd_manager().do_lazy_refresh(wd, false); wd_manager().do_lazy_refresh(wd, false);
else else
wd->other.upd_state = basic_window::update_state::none; wd->other.upd_state = update_state::none;
good_wd = true; good_wd = true;
} }

View File

@ -863,30 +863,27 @@ namespace nana{
void native_interface::move_window(native_window_type wd, int x, int y) void native_interface::move_window(native_window_type wd, int x, int y)
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
if(::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId()) ::RECT r;
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
if(owner)
{ {
nana::detail::messages::move_window * mw = new nana::detail::messages::move_window; ::RECT owner_rect;
mw->x = x; ::GetWindowRect(owner, &owner_rect);
mw->y = y; ::POINT pos = {owner_rect.left, owner_rect.top};
mw->ignore = mw->Size; ::ScreenToClient(owner, &pos);
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::remote_thread_move_window, reinterpret_cast<WPARAM>(mw), 0); x += (owner_rect.left - pos.x);
y += (owner_rect.top - pos.y);
} }
else
if (::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
{ {
::RECT r; nana::internal_revert_guard irg;
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
if(owner)
{
::RECT owner_rect;
::GetWindowRect(owner, &owner_rect);
::POINT pos = {owner_rect.left, owner_rect.top};
::ScreenToClient(owner, &pos);
x += (owner_rect.left - pos.x);
y += (owner_rect.top - pos.y);
}
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.right - r.left, r.bottom - r.top, true); ::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.right - r.left, r.bottom - r.top, true);
} }
else
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.right - r.left, r.bottom - r.top, true);
#elif defined(NANA_X11) #elif defined(NANA_X11)
Display * disp = restrict::spec.open_display(); Display * disp = restrict::spec.open_display();
@ -908,41 +905,36 @@ namespace nana{
#endif #endif
} }
void native_interface::move_window(native_window_type wd, const rectangle& r) bool native_interface::move_window(native_window_type wd, const rectangle& r)
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
if(::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
int x = r.x;
int y = r.y;
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
if(owner)
{ {
auto * mw = new nana::detail::messages::move_window; ::RECT owner_rect;
mw->x = r.x; ::GetWindowRect(owner, &owner_rect);
mw->y = r.y; ::POINT pos = {owner_rect.left, owner_rect.top};
mw->width = r.width; ::ScreenToClient(owner, &pos);
mw->height = r.height; x += (owner_rect.left - pos.x);
mw->ignore = 0; y += (owner_rect.top - pos.y);
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::remote_thread_move_window, reinterpret_cast<WPARAM>(mw), 0);
} }
else
{
int x = r.x;
int y = r.y;
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
if(owner)
{
::RECT owner_rect;
::GetWindowRect(owner, &owner_rect);
::POINT pos = {owner_rect.left, owner_rect.top};
::ScreenToClient(owner, &pos);
x += (owner_rect.left - pos.x);
y += (owner_rect.top - pos.y);
}
RECT client, wd_area; RECT client, wd_area;
::GetClientRect(reinterpret_cast<HWND>(wd), &client); ::GetClientRect(reinterpret_cast<HWND>(wd), &client);
::GetWindowRect(reinterpret_cast<HWND>(wd), &wd_area); ::GetWindowRect(reinterpret_cast<HWND>(wd), &wd_area);
unsigned ext_w = (wd_area.right - wd_area.left) - client.right; unsigned ext_w = (wd_area.right - wd_area.left) - client.right;
unsigned ext_h = (wd_area.bottom - wd_area.top) - client.bottom; unsigned ext_h = (wd_area.bottom - wd_area.top) - client.bottom;
::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.width + ext_w, r.height + ext_h, true);
if (::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
{
nana::internal_revert_guard irg;
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.width + ext_w, r.height + ext_h, true));
} }
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), x, y, r.width + ext_w, r.height + ext_h, true));
#elif defined(NANA_X11) #elif defined(NANA_X11)
Display * disp = restrict::spec.open_display(); Display * disp = restrict::spec.open_display();
long supplied; long supplied;
@ -984,6 +976,7 @@ namespace nana{
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints); ::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height); ::XMoveResizeWindow(disp, reinterpret_cast<Window>(wd), x, y, r.width, r.height);
return true;
#endif #endif
} }
@ -1062,32 +1055,28 @@ namespace nana{
#endif #endif
} }
void native_interface::window_size(native_window_type wd, const size& sz) bool native_interface::window_size(native_window_type wd, const size& sz)
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
if(::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId()) ::RECT r;
::GetWindowRect(reinterpret_cast<HWND>(wd), &r);
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
HWND parent = ::GetParent(reinterpret_cast<HWND>(wd));
if(parent && (parent != owner))
{ {
auto * mw = new nana::detail::messages::move_window; ::POINT pos = {r.left, r.top};
mw->width = sz.width; ::ScreenToClient(parent, &pos);
mw->height = sz.height; r.left = pos.x;
mw->ignore = mw->Pos; r.top = pos.y;
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::remote_thread_move_window, reinterpret_cast<WPARAM>(mw), 0);
} }
else
if (::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), 0) != ::GetCurrentThreadId())
{ {
::RECT r; nana::internal_revert_guard irg;
::GetWindowRect(reinterpret_cast<HWND>(wd), &r); return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), r.left, r.top, static_cast<int>(sz.width), static_cast<int>(sz.height), true));
HWND owner = ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER);
HWND parent = ::GetParent(reinterpret_cast<HWND>(wd));
if(parent && (parent != owner))
{
::POINT pos = {r.left, r.top};
::ScreenToClient(parent, &pos);
r.left = pos.x;
r.top = pos.y;
}
::MoveWindow(reinterpret_cast<HWND>(wd), r.left, r.top, static_cast<int>(sz.width), static_cast<int>(sz.height), true);
} }
return (FALSE != ::MoveWindow(reinterpret_cast<HWND>(wd), r.left, r.top, static_cast<int>(sz.width), static_cast<int>(sz.height), true));
#elif defined(NANA_X11) #elif defined(NANA_X11)
auto disp = restrict::spec.open_display(); auto disp = restrict::spec.open_display();
nana::detail::platform_scope_guard psg; nana::detail::platform_scope_guard psg;
@ -1104,6 +1093,7 @@ namespace nana{
::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints); ::XSetWMNormalHints(disp, reinterpret_cast<Window>(wd), &hints);
} }
::XResizeWindow(disp, reinterpret_cast<Window>(wd), sz.width, sz.height); ::XResizeWindow(disp, reinterpret_cast<Window>(wd), sz.width, sz.height);
return true;
#endif #endif
} }

View File

@ -219,8 +219,6 @@ namespace detail
Key first; Key first;
Value second; Value second;
key_value_rep() = default;
key_value_rep(const Key& k) key_value_rep(const Key& k)
: first(k), second{} : first(k), second{}
{ {
@ -258,15 +256,7 @@ namespace detail
std::vector<key_value_rep> table_; std::vector<key_value_rep> table_;
}; };
//class window_manager //class window_manager
struct window_handle_deleter
{
void operator()(basic_window* wd) const
{
delete wd;
}
};
//struct wdm_private_impl //struct wdm_private_impl
struct window_manager::wdm_private_impl struct window_manager::wdm_private_impl
{ {
@ -506,7 +496,7 @@ namespace detail
if (impl_->wd_register.available(owner)) if (impl_->wd_register.available(owner))
{ {
if (owner->flags.destroying) if (owner->flags.destroying)
throw std::runtime_error("the specified owner is destory"); throw std::runtime_error("the specified owner is destoryed");
#ifndef WIDGET_FRAME_DEPRECATED #ifndef WIDGET_FRAME_DEPRECATED
native = (category::flags::frame == owner->other.category ? native = (category::flags::frame == owner->other.category ?
@ -953,24 +943,46 @@ namespace detail
if (wd->dimension == sz) if (wd->dimension == sz)
return false; return false;
//Before resiz the window, creates the new graphics
paint::graphics graph;
paint::graphics root_graph;
if (category::flags::lite_widget != wd->other.category)
{
//If allocation fails, here throws std::bad_alloc.
graph.make(sz);
graph.typeface(wd->drawer.graphics.typeface());
if (category::flags::root == wd->other.category)
root_graph.make(sz);
}
auto pre_sz = wd->dimension;
wd->dimension = sz; wd->dimension = sz;
if(category::flags::lite_widget != wd->other.category) if(category::flags::lite_widget != wd->other.category)
{ {
bool graph_state = wd->drawer.graphics.empty(); bool graph_state = wd->drawer.graphics.empty();
wd->drawer.graphics.make(sz); wd->drawer.graphics.swap(graph);
//It shall make a typeface_changed() call when the graphics state is changing. //It shall make a typeface_changed() call when the graphics state is changing.
//Because when a widget is created with zero-size, it may get some wrong result in typeface_changed() call //Because when a widget is created with zero-size, it may get some wrong results in typeface_changed() call
//due to the invaliable graphics object. //due to the invaliable graphics object.
if(graph_state != wd->drawer.graphics.empty()) if(graph_state != wd->drawer.graphics.empty())
wd->drawer.typeface_changed(); wd->drawer.typeface_changed();
if(category::flags::root == wd->other.category) if(category::flags::root == wd->other.category)
{ {
wd->root_graph->make(sz); //wd->root_graph->make(sz);
wd->root_graph->swap(root_graph);
if(false == passive) if(false == passive)
native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)); if (!native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)))
{
wd->dimension = pre_sz;
wd->drawer.graphics.swap(graph);
wd->root_graph->swap(root_graph);
wd->drawer.typeface_changed();
return false;
}
} }
#ifndef WIDGET_FRAME_DEPRECATED #ifndef WIDGET_FRAME_DEPRECATED
else if(category::flags::frame == wd->other.category) else if(category::flags::frame == wd->other.category)

View File

@ -505,21 +505,18 @@ namespace nana
auto fpath = i->path().native(); auto fpath = i->path().native();
auto fattr = fs::status(fpath); auto fattr = fs::status(fpath);
auto ftype = static_cast<fs::file_type>(fattr.type());
item_fs m; item_fs m;
m.name = name; m.name = name;
m.directory = fs::is_directory(fattr); m.directory = fs::is_directory(fattr);
switch(fattr.type()) if (ftype == fs::file_type::not_found ||
{ ftype == fs::file_type::unknown ||
case fs::file_type::not_found: ftype == fs::file_type::directory)
case fs::file_type::unknown:
case fs::file_type::directory:
m.bytes = 0; m.bytes = 0;
break; else
default:
m.bytes = fs::file_size(fpath); m.bytes = fs::file_size(fpath);
}
fs_ext::modified_file_time(fpath, m.modified_time); fs_ext::modified_file_time(fpath, m.modified_time);
@ -692,13 +689,12 @@ namespace nana
return; return;
} }
using file_type = fs::file_type;
fs::path fspath(fb_.addr_.filesystem + path); fs::path fspath(fb_.addr_.filesystem + path);
auto fst = fs::status(fspath); auto fattr = fs::status(fspath);
auto ftype = static_cast<fs::file_type>(fattr.type());
if(fst.type() != file_type::not_found && fst.type() != file_type::none) if(ftype != fs::file_type::not_found && ftype != fs::file_type::none)
{ {
mb<<i18n("NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_EXISTING"); mb<<i18n("NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_EXISTING");
mb(); mb();
@ -800,6 +796,7 @@ namespace nana
tar = addr_.filesystem + file; tar = addr_.filesystem + file;
auto fattr = fs::status(tar); auto fattr = fs::status(tar);
auto ftype = static_cast<fs::file_type>(fattr.type());
//Check if the selected name is a directory //Check if the selected name is a directory
auto is_dir = fs::is_directory(fattr); auto is_dir = fs::is_directory(fattr);
@ -808,6 +805,7 @@ namespace nana
{ {
//Add the extension, then check if it is a directory again. //Add the extension, then check if it is a directory again.
fattr = fs::status(tar); fattr = fs::status(tar);
ftype = static_cast<fs::file_type>(fattr.type());
is_dir = fs::is_directory(fattr); is_dir = fs::is_directory(fattr);
} }
@ -820,7 +818,7 @@ namespace nana
if(io_read_) if(io_read_)
{ {
if(fs::file_type::not_found == fattr.type()) if(fs::file_type::not_found == ftype)
{ {
msgbox mb(*this, caption()); msgbox mb(*this, caption());
mb.icon(msgbox::icon_information); mb.icon(msgbox::icon_information);
@ -832,7 +830,7 @@ namespace nana
} }
else else
{ {
if(fs::file_type::not_found != fattr.type()) if(fs::file_type::not_found != ftype)
{ {
msgbox mb(*this, caption(), msgbox::yes_no); msgbox mb(*this, caption(), msgbox::yes_no);
mb.icon(msgbox::icon_question); mb.icon(msgbox::icon_question);

View File

@ -58,7 +58,7 @@ namespace nana
{ {
div_start, div_end, splitter, div_start, div_end, splitter,
identifier, dock, fit, hfit, vfit, vert, grid, number, array, reparray, identifier, dock, fit, hfit, vfit, vert, grid, number, array, reparray,
weight, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible, weight, width, height, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible,
collapse, parameters, collapse, parameters,
equal, equal,
eof, error eof, error
@ -235,15 +235,21 @@ namespace nana
idstr_.assign(idstart, sp_); idstr_.assign(idstart, sp_);
if ("weight" == idstr_ || "min" == idstr_ || "max" == idstr_) if ( "weight" == idstr_
|| "min" == idstr_
|| "max" == idstr_
|| "width" == idstr_
|| "height" == idstr_
)
{ {
auto ch = idstr_[1]; auto c3 = idstr_[2], c1 =idstr_[0];
_m_attr_number_value(); _m_attr_number_value();
switch (ch) switch (c3)
{ {
case 'e': return token::weight; case 'i': return c1=='w'? token::weight : token::height;
case 'i': return token::min_px; case 'n': return token::min_px;
case 'a': return token::max_px; case 'x': return token::max_px;
case 'd': return token::width;
} }
} }
else if ("dock" == idstr_) else if ("dock" == idstr_)
@ -742,6 +748,7 @@ namespace nana
{ {
public: public:
enum class kind{ arrange, vertical_arrange, grid, splitter, dock, dockpane}; enum class kind{ arrange, vertical_arrange, grid, splitter, dock, dockpane};
using token = place_parts::tokenizer::token;
division(kind k, std::string&& n) noexcept division(kind k, std::string&& n) noexcept
: kind_of_division(k), : kind_of_division(k),
@ -1082,6 +1089,7 @@ namespace nana
::nana::rectangle field_area; ::nana::rectangle field_area;
number_t weight; number_t weight;
token weigth_type=token::weight;
number_t min_px, max_px; number_t min_px, max_px;
place_parts::margin margin; place_parts::margin margin;
@ -2616,10 +2624,10 @@ namespace nana
auto place::implement::scan_div(place_parts::tokenizer& tknizer) -> std::unique_ptr<division> auto place::implement::scan_div(place_parts::tokenizer& tknizer) -> std::unique_ptr<division>
{ {
typedef place_parts::tokenizer::token token; using token = place_parts::tokenizer::token ;
std::unique_ptr<division> div; std::unique_ptr<division> div;
token div_type = token::eof; token div_type = token::eof , weight_type=token::weight;
auto fit = fit_policy::none; auto fit = fit_policy::none;
place_parts::repeated_array fit_parameters; place_parts::repeated_array fit_parameters;
@ -2726,7 +2734,7 @@ namespace nana
} }
} }
break; break;
case token::weight: case token::min_px: case token::max_px: case token::weight: case token::min_px: case token::max_px: case token::width: case token::height:
{ {
auto n = tknizer.number(); auto n = tknizer.number();
//If n is the type of real, convert it to integer. //If n is the type of real, convert it to integer.
@ -2736,7 +2744,9 @@ namespace nana
switch (tk) switch (tk)
{ {
case token::weight: weight = n; break; case token::weight: weight = n; weight_type = token::weight; break; // we could detect errors here (redefinitions and duplicates)
case token::width : weight = n; weight_type = token::width ; break;
case token::height: weight = n; weight_type = token::height; break;
case token::min_px: min_px = n; break; case token::min_px: min_px = n; break;
case token::max_px: max_px = n; break; case token::max_px: max_px = n; break;
default: break; //Useless default: break; //Useless
@ -2805,10 +2815,16 @@ namespace nana
} }
} }
token unmatch = token::width;
switch (div_type) switch (div_type)
{ {
case token::eof: case token::eof: unmatch = token::height; // "horitontal" div
case token::vert: case token::vert: // "vertical" div
for (auto& ch : children)
if (ch->weigth_type == unmatch)
throw std::invalid_argument("nana.place: unmatch vertical-heigth/horizontal-width betwen division '"
+name+"' and children division '" + ch->name);
div.reset(new div_arrange(token::vert == div_type, std::move(name), std::move(arrange))); div.reset(new div_arrange(token::vert == div_type, std::move(name), std::move(arrange)));
break; break;
case token::grid: case token::grid:
@ -2837,6 +2853,7 @@ namespace nana
default: default:
throw std::invalid_argument("nana.place: invalid division type."); throw std::invalid_argument("nana.place: invalid division type.");
} }
div->weigth_type = weight_type;
//Requirements for min/max //Requirements for min/max
//1, min and max != negative //1, min and max != negative

View File

@ -1183,6 +1183,13 @@ namespace API
auto caret = _m_caret(); auto caret = _m_caret();
return (caret && caret->visible()); return (caret && caret->visible());
} }
bool activated() const override
{
internal_scope_guard lock;
auto caret = _m_caret();
return (caret && caret->activated());
}
private: private:
caret_interface* _m_caret() const caret_interface* _m_caret() const
{ {

View File

@ -14,6 +14,7 @@
#include <nana/gui/widgets/scroll.hpp> #include <nana/gui/widgets/scroll.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <nana/gui/screen.hpp>
namespace nana namespace nana
{ {
@ -198,16 +199,14 @@ namespace nana
return widget_; return widget_;
} }
void attach(widget* wd, nana::paint::graphics* graph) void attach(widget& wd, nana::paint::graphics& graph)
{ {
if(wd) widget_ = &wd;
{ wd.events().mouse_wheel.connect_unignorable([this](const arg_wheel& arg){
widget_ = wd; scroll_items(arg.upwards);
wd->events().mouse_wheel.connect_unignorable([this](const arg_wheel& arg){ });
scroll_items(arg.upwards);
}); graph_ = &graph;
}
if(graph) graph_ = graph;
} }
void detach() void detach()
@ -219,9 +218,46 @@ namespace nana
{ {
if(module_) if(module_)
{ {
std::size_t items = (module_->max_items <= module_->items.size() ? module_->max_items : module_->items.size());
std::size_t h = items * state_.renderer->item_pixels(*graph_); auto const items = (module_->max_items <= module_->items.size() ? module_->max_items : module_->items.size());
widget_->size(size{ widget_->size().width, static_cast<unsigned>(h + 4) });
rectangle list_r{
0, 0,
widget_->size().width,
static_cast<unsigned>(items * state_.renderer->item_pixels(*graph_)) + 4
};
//Test if the listbox excesses the screen
screen scr;
auto & disp = scr.from_window(*widget_);
auto disp_r = disp.area();
point pos;
API::calc_screen_point(*widget_, pos);
list_r.position(pos);
if (widget_->size().width >= disp_r.width)
{
pos.x = 0;
list_r.width = disp_r.width;
}
else if (list_r.right() > disp_r.right())
pos.x = disp_r.right() - static_cast<int>(list_r.width);
if (list_r.height >= disp_r.height)
{
pos.y = 0;
list_r.height = disp_r.height;
}
else if (list_r.bottom() > disp_r.bottom())
pos.y = disp_r.bottom() - static_cast<int>(list_r.height);
API::calc_window_point(API::get_owner_window(*widget_), pos);
list_r.position(pos);
widget_->move(list_r);
} }
} }
@ -312,36 +348,37 @@ namespace nana
void _m_open_scrollbar(widget_reference wd, bool v) void _m_open_scrollbar(widget_reference wd, bool v)
{ {
if(v) if (!v)
{ {
if(scrollbar_.empty() && module_)
{
scrollbar_.create(wd, rectangle(static_cast<int>(wd.size().width - 18), 2, 16, wd.size().height - 4));
scrollbar_.amount(module_->items.size());
scrollbar_.range(module_->max_items);
scrollbar_.value(state_.offset_y);
auto & events = scrollbar_.events();
events.mouse_wheel.connect([this](const arg_wheel& arg)
{
scroll_items(arg.upwards);
});
auto fn = [this](const arg_mouse& arg)
{
if (arg.is_left_button() && (scrollbar_.value() != state_.offset_y))
{
state_.offset_y = static_cast<unsigned>(scrollbar_.value());
draw();
API::update_window(*widget_);
}
};
events.mouse_move.connect(fn);
events.mouse_up.connect(fn);
}
}
else
scrollbar_.close(); scrollbar_.close();
return;
}
if(scrollbar_.empty() && module_)
{
scrollbar_.create(wd, rectangle(static_cast<int>(wd.size().width - 18), 2, 16, wd.size().height - 4));
scrollbar_.amount(module_->items.size());
scrollbar_.range(module_->max_items);
scrollbar_.value(state_.offset_y);
auto & events = scrollbar_.events();
events.mouse_wheel.connect([this](const arg_wheel& arg)
{
scroll_items(arg.upwards);
});
auto fn = [this](const arg_mouse& arg)
{
if (arg.is_left_button() && (scrollbar_.value() != state_.offset_y))
{
state_.offset_y = static_cast<unsigned>(scrollbar_.value());
draw();
API::update_window(*widget_);
}
};
events.mouse_move.connect(fn);
events.mouse_up.connect(fn);
}
} }
private: private:
widget * widget_{nullptr}; widget * widget_{nullptr};
@ -393,7 +430,7 @@ namespace nana
void trigger::attached(widget_reference widget, graph_reference graph) void trigger::attached(widget_reference widget, graph_reference graph)
{ {
drawer_->attach(&widget, &graph); drawer_->attach(widget, graph);
} }
void trigger::detached() void trigger::detached()

View File

@ -3931,6 +3931,11 @@ namespace nana
essence_->content_view.reset(new widgets::skeletons::content_view{ widget.handle() }); essence_->content_view.reset(new widgets::skeletons::content_view{ widget.handle() });
essence_->resize_disp_area(); essence_->resize_disp_area();
//Set the content_view wheel speed with the listbox scheme.
essence_->content_view->set_wheel_speed([this] {
return essence_->scheme_ptr->mouse_wheel.lines;
});
essence_->content_view->events().hover_outside = [this](const point& cur_pos) { essence_->content_view->events().hover_outside = [this](const point& cur_pos) {
essence_->update_mouse_selection(cur_pos); essence_->update_mouse_selection(cur_pos);
}; };
@ -4166,16 +4171,17 @@ namespace nana
{ {
if (item_ptr->flags.selected != sel) if (item_ptr->flags.selected != sel)
{ {
item_ptr->flags.selected = sel; if (sel)
lister.emit_cs(abs_item_pos, true);
if (item_ptr->flags.selected)
{ {
//Deselects the previously selected item.
lister.cancel_others_if_single_enabled(true, abs_item_pos); lister.cancel_others_if_single_enabled(true, abs_item_pos);
essence_->lister.latest_selected_abs = abs_item_pos; essence_->lister.latest_selected_abs = abs_item_pos;
} }
else if (essence_->lister.latest_selected_abs == abs_item_pos) else if (essence_->lister.latest_selected_abs == abs_item_pos)
essence_->lister.latest_selected_abs.set_both(npos); essence_->lister.latest_selected_abs.set_both(npos);
item_ptr->flags.selected = sel;
lister.emit_cs(abs_item_pos, true);
} }
} }
else else

View File

@ -29,7 +29,6 @@ namespace nana
struct implement struct implement
{ {
widget* wdg_ptr{nullptr}; widget* wdg_ptr{nullptr};
paint::graphics* graph_ptr{nullptr};
std::unique_ptr<content_measurer> measurer; std::unique_ptr<content_measurer> measurer;
struct gradual_bground_tag struct gradual_bground_tag
@ -48,6 +47,23 @@ namespace nana
std::unique_ptr<element::bground> bground; //If it is not a null ptr, the widget is stretchable mode std::unique_ptr<element::bground> bground; //If it is not a null ptr, the widget is stretchable mode
bool stretchable{ false }; //If it is true, the widget is stretchable mode without changing aspect ratio. bool stretchable{ false }; //If it is true, the widget is stretchable mode without changing aspect ratio.
}backimg; }backimg;
void draw_background(paint::graphics& graph, const size& dimension)
{
if (!API::dev::copy_transparent_background(*wdg_ptr, graph))
{
auto const graph_size = graph.size();
if (dimension.width < graph_size.width || dimension.height < graph_size.height || backimg.image.alpha())
{
if (gradual_bground.gradual_from.invisible() || gradual_bground.gradual_to.invisible())
graph.rectangle(true, wdg_ptr->bgcolor());
else if (gradual_bground.gradual_from == gradual_bground.gradual_to)
graph.rectangle(true, gradual_bground.gradual_from);
else
graph.gradual_rectangle(::nana::rectangle{graph_size }, gradual_bground.gradual_from, gradual_bground.gradual_to, !gradual_bground.horizontal);
}
}
}
}; };
class content_measurer class content_measurer
@ -88,32 +104,36 @@ namespace nana
delete impl_; delete impl_;
} }
void drawer::attached(widget_reference& wdg, graph_reference graph) void drawer::attached(widget_reference& wdg, graph_reference)
{ {
impl_->wdg_ptr = &wdg; impl_->wdg_ptr = &wdg;
impl_->graph_ptr = &graph;
API::dev::set_measurer(wdg, impl_->measurer.get()); API::dev::set_measurer(wdg, impl_->measurer.get());
} }
void drawer::refresh(graph_reference graph) void drawer::refresh(graph_reference graph)
{ {
if (!graph.changed()) auto const graphsize = graph.size();
return;
auto graphsize = graph.size();
auto & backimg = impl_->backimg; auto & backimg = impl_->backimg;
if (!backimg.bground) if (!backimg.bground)
{ {
if (backimg.image.empty())
{
impl_->draw_background(graph, {});
return;
}
auto valid_area = backimg.valid_area; auto valid_area = backimg.valid_area;
if (valid_area.empty()) if (valid_area.empty())
valid_area.dimension(backimg.image.size()); valid_area.dimension(backimg.image.size());
//The position where the image to be drawn.
::nana::point pos;
if (backimg.stretchable) if (backimg.stretchable)
{ {
auto fit_size = fit_zoom({ valid_area.width, valid_area.height }, graphsize); auto fit_size = fit_zoom(valid_area.dimension(), graphsize);
::nana::point pos;
if (fit_size.width != graphsize.width) if (fit_size.width != graphsize.width)
{ {
@ -142,15 +162,12 @@ namespace nana
} }
} }
_m_draw_background(fit_size.width, fit_size.height); impl_->draw_background(graph, fit_size);
backimg.image.stretch(valid_area, graph, ::nana::rectangle{ pos, fit_size }); backimg.image.stretch(valid_area, graph, ::nana::rectangle{ pos, fit_size });
} }
else else
{ {
//The point in which position the image to be drawn.
::nana::point pos;
switch (backimg.align_horz) switch (backimg.align_horz)
{ {
case ::nana::align::left: break; case ::nana::align::left: break;
@ -173,15 +190,14 @@ namespace nana
break; break;
} }
_m_draw_background(valid_area.width, valid_area.height); impl_->draw_background(graph, valid_area.dimension());
if ( ! backimg.image.empty()) backimg.image.paste(valid_area, graph, pos);
backimg.image.paste(valid_area, graph, pos);
} }
} }
else else
{ {
_m_draw_background(graphsize.width, graphsize.height); impl_->draw_background(graph, graphsize);
color invalid_clr_for_call; color invalid_clr_for_call;
backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, rectangle{ graphsize }, element_state::normal); backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, rectangle{ graphsize }, element_state::normal);
@ -189,25 +205,6 @@ namespace nana
graph.setsta(); graph.setsta();
} }
void drawer::_m_draw_background(unsigned w, unsigned h)
{
auto graph = impl_->graph_ptr;
if (graph && (!API::dev::copy_transparent_background(*impl_->wdg_ptr, *graph)))
{
if (w < graph->size().width || h < graph->size().height || impl_->backimg.image.alpha())
{
auto & bground = impl_->gradual_bground;
if (bground.gradual_from.invisible() || bground.gradual_to.invisible())
graph->rectangle(true, impl_->wdg_ptr->bgcolor());
else if (bground.gradual_from == bground.gradual_to)
graph->rectangle(true, bground.gradual_from);
else
graph->gradual_rectangle(::nana::rectangle{ graph->size() }, bground.gradual_from, bground.gradual_to, !bground.horizontal);
}
}
}
//end class drawer //end class drawer
}//end namespace picture }//end namespace picture
}//end namespace drawerbase }//end namespace drawerbase
@ -233,11 +230,7 @@ namespace nana
if (backimg.bground) if (backimg.bground)
backimg.bground->image(backimg.image, true, valid_area); backimg.bground->image(backimg.image, true, valid_area);
if (handle()) API::refresh_window(*this);
{
get_drawer_trigger().impl_->graph_ptr->set_changed();
API::refresh_window(*this);
}
} }
void picture::align(::nana::align horz, align_v vert) void picture::align(::nana::align horz, align_v vert)
@ -252,18 +245,11 @@ namespace nana
backimg.align_horz = horz; backimg.align_horz = horz;
backimg.align_vert = vert; backimg.align_vert = vert;
if (handle()) API::refresh_window(*this);
{
get_drawer_trigger().impl_->graph_ptr->set_changed();
API::refresh_window(*this);
}
} }
void picture::stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom) void picture::stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom)
{ {
if (!handle())
return;
internal_scope_guard lock; internal_scope_guard lock;
auto & backimg = get_drawer_trigger().impl_->backimg; auto & backimg = get_drawer_trigger().impl_->backimg;
if (!backimg.bground) if (!backimg.bground)
@ -275,11 +261,8 @@ namespace nana
backimg.bground->stretch_parts(left, top, right, bottom); backimg.bground->stretch_parts(left, top, right, bottom);
backimg.stretchable = false; backimg.stretchable = false;
if (handle())
{ API::refresh_window(*this);
get_drawer_trigger().impl_->graph_ptr->set_changed();
API::refresh_window(*this);
}
} }
void picture::stretchable(bool enables) void picture::stretchable(bool enables)
@ -290,11 +273,7 @@ namespace nana
backimg.bground.reset(); backimg.bground.reset();
backimg.stretchable = enables; backimg.stretchable = enables;
if (handle()) API::refresh_window(*this);
{
get_drawer_trigger().impl_->graph_ptr->set_changed();
API::refresh_window(*this);
}
} }
void picture::set_gradual_background(const ::nana::color& from, const ::nana::color& to, bool horizontal) void picture::set_gradual_background(const ::nana::color& from, const ::nana::color& to, bool horizontal)
@ -303,11 +282,8 @@ namespace nana
bground.gradual_from = from; bground.gradual_from = from;
bground.gradual_to = to; bground.gradual_to = to;
bground.horizontal = horizontal; bground.horizontal = horizontal;
if (handle())
{ API::refresh_window(*this);
get_drawer_trigger().impl_->graph_ptr->set_changed();
API::refresh_window(*this);
}
} }
void picture::transparent(bool enabled) void picture::transparent(bool enabled)

View File

@ -91,19 +91,26 @@ namespace nana
{ {
return value_px_; return value_px_;
} }
bool value_px_sync()
{
if (widget_)
{
auto value_px = (widget_->size().width - border_px * 2) * value_ / max_;
if (value_px != value_px_)
{
value_px_ = value_px;
return true;
}
}
return false;
}
private: private:
void _m_try_refresh() void _m_try_refresh()
{ {
if (nullptr == widget_) if (value_px_sync())
return;
auto value_px = (widget_->size().width - border_px * 2) * value_ / max_;
if (value_px != value_px_)
{
value_px_ = value_px;
API::refresh_window(*widget_); API::refresh_window(*widget_);
}
} }
private: private:
nana::progress * widget_{ nullptr }; nana::progress * widget_{ nullptr };
@ -144,6 +151,9 @@ namespace nana
auto rt_bground = rt_val; auto rt_bground = rt_val;
if (false == progress_->unknown(nullptr)) if (false == progress_->unknown(nullptr))
{ {
//Sync the value_px otherwise the progress is incorrect when it is resized.
progress_->value_px_sync();
rt_bground.x = static_cast<int>(progress_->value_px()) + static_cast<int>(border_px); rt_bground.x = static_cast<int>(progress_->value_px()) + static_cast<int>(border_px);
rt_bground.width -= progress_->value_px(); rt_bground.width -= progress_->value_px();

View File

@ -15,7 +15,12 @@
#include <nana/gui/detail/bedrock.hpp> #include <nana/gui/detail/bedrock.hpp>
#include <nana/std_thread.hpp> #include <nana/std_thread.hpp>
#include <iostream> #include <iostream>
#include <chrono>
#ifdef STD_THREAD_NOT_SUPPORTED
# include <boost/chrono.hpp>
#else
# include <chrono>
#endif
//#define NANA_AUTOMATIC_GUI_TESTING //#define NANA_AUTOMATIC_GUI_TESTING
namespace nana namespace nana

View File

@ -269,9 +269,9 @@ namespace paint
return (!impl_->handle); return (!impl_->handle);
} }
graphics::operator const void *() const graphics::operator bool() const noexcept
{ {
return impl_->handle; return (impl_->handle != nullptr);
} }
drawable_type graphics::handle() const drawable_type graphics::handle() const
@ -291,9 +291,15 @@ namespace paint
return (impl_->handle ? impl_->handle->context : nullptr); return (impl_->handle ? impl_->handle->context : nullptr);
} }
void graphics::swap(graphics& other) noexcept
{
if (context() != other.context())
impl_.swap(other.impl_);
}
void graphics::make(const ::nana::size& sz) void graphics::make(const ::nana::size& sz)
{ {
if(impl_->handle == nullptr || impl_->size != sz) if (impl_->handle == nullptr || impl_->size != sz)
{ {
if (sz.empty()) if (sz.empty())
{ {
@ -302,9 +308,10 @@ namespace paint
} }
//The object will be delete while dwptr_ is performing a release. //The object will be delete while dwptr_ is performing a release.
drawable_type dw = new nana::detail::drawable_impl_type; std::shared_ptr<nana::detail::drawable_impl_type> dw{ new nana::detail::drawable_impl_type, detail::drawable_deleter{} };
//Reuse the old font //Reuse the old font
if(impl_->platform_drawable) if (impl_->platform_drawable)
{ {
drawable_type reuse = impl_->platform_drawable.get(); drawable_type reuse = impl_->platform_drawable.get();
dw->font = reuse->font; dw->font = reuse->font;
@ -314,8 +321,13 @@ namespace paint
dw->font = impl_->font_shadow.impl_->real_font; dw->font = impl_->font_shadow.impl_->real_font;
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
HDC hdc = ::GetDC(0); HDC hdc = ::GetDC(nullptr);
HDC cdc = ::CreateCompatibleDC(hdc); HDC cdc = ::CreateCompatibleDC(hdc);
if (nullptr == cdc)
{
::ReleaseDC(nullptr, hdc);
throw std::bad_alloc{};
}
BITMAPINFO bmi; BITMAPINFO bmi;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@ -328,34 +340,60 @@ namespace paint
HBITMAP bmp = ::CreateDIBSection(cdc, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&(dw->pixbuf_ptr)), 0, 0); HBITMAP bmp = ::CreateDIBSection(cdc, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&(dw->pixbuf_ptr)), 0, 0);
if(bmp) if (nullptr == bmp)
{
::DeleteObject((HBITMAP)::SelectObject(cdc, bmp));
::DeleteObject(::SelectObject(cdc, dw->font->native_handle()));
dw->context = cdc;
dw->pixmap = bmp;
::SetBkMode(cdc, TRANSPARENT);
}
else
{ {
::DeleteDC(cdc); ::DeleteDC(cdc);
delete dw; ::ReleaseDC(nullptr, hdc);
dw = nullptr; throw std::bad_alloc{};
release();
} }
::DeleteObject((HBITMAP)::SelectObject(cdc, bmp));
::DeleteObject(::SelectObject(cdc, dw->font->native_handle()));
dw->context = cdc;
dw->pixmap = bmp;
::SetBkMode(cdc, TRANSPARENT);
::ReleaseDC(0, hdc); ::ReleaseDC(0, hdc);
#elif defined(NANA_X11) #elif defined(NANA_X11)
auto & spec = nana::detail::platform_spec::instance(); auto & spec = nana::detail::platform_spec::instance();
Display* disp = spec.open_display(); {
int screen = DefaultScreen(disp); nana::detail::platform_scope_guard psg;
Window root = ::XRootWindow(disp, screen);
dw->pixmap = ::XCreatePixmap(disp, root, sz.width, sz.height, DefaultDepth(disp, screen)); spec.set_error_handler();
dw->context = ::XCreateGC(disp, dw->pixmap, 0, 0);
#if defined(NANA_USE_XFT) Display* disp = spec.open_display();
dw->xftdraw = ::XftDrawCreate(disp, dw->pixmap, spec.screen_visual(), spec.colormap()); int screen = DefaultScreen(disp);
#endif Window root = ::XRootWindow(disp, screen);
auto pixmap = ::XCreatePixmap(disp, root, sz.width, sz.height, DefaultDepth(disp, screen));
if(spec.error_code)
{
spec.rev_error_handler();
throw std::bad_alloc();
}
auto context = ::XCreateGC(disp, pixmap, 0, 0);
if (spec.error_code)
{
::XFreePixmap(disp, pixmap);
spec.rev_error_handler();
throw std::bad_alloc();
}
# if defined(NANA_USE_XFT)
auto xftdraw = ::XftDrawCreate(disp, pixmap, spec.screen_visual(), spec.colormap());
if (spec.error_code)
{
::XFreeGC(disp, context);
::XFreePixmap(disp, pixmap);
spec.rev_error_handler();
throw std::bad_alloc();
}
dw->xftdraw = xftdraw;
# endif
dw->pixmap = pixmap;
dw->context = context;
}
#endif #endif
if(dw) if(dw)
{ {
@ -366,8 +404,8 @@ namespace paint
#else #else
dw->update_text_color(); dw->update_text_color();
#endif #endif
impl_->platform_drawable.reset(dw, detail::drawable_deleter{}); impl_->platform_drawable = dw;
impl_->handle = dw; impl_->handle = dw.get();
impl_->size = sz; impl_->size = sz;
impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width; impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;