Merge branch 'hotfix-1.3' into develop

This commit is contained in:
Jinhao 2016-04-18 15:16:03 +08:00
commit 116787072f
116 changed files with 2343 additions and 1004 deletions

1
.gitignore vendored
View File

@ -24,6 +24,7 @@ build/makefile-bkl/*
*.ilk *.ilk
*.log *.log
[Bb]in [Bb]in
[Bb]in/
[Dd]ebug*/ [Dd]ebug*/
*.lib *.lib
*.a *.a

View File

@ -20,6 +20,7 @@ matrix:
- alsa-oss - alsa-oss
- libx11-dev - libx11-dev
- libxft-dev - libxft-dev
- libboost-filesystem-dev
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- env: CXX=g++-4.9 CC=gcc-4.9 - env: CXX=g++-4.9 CC=gcc-4.9
@ -55,7 +56,7 @@ matrix:
- llvm-toolchain-precise - llvm-toolchain-precise
before_install: before_install:
- git clone --depth=50 --branch=stable https://github.com/qPCR4vir/nana-demo.git nana-demo - git clone --depth=1 --branch=dev_nana_in_examples https://github.com/qPCR4vir/nana-demo.git nana-demo
- export PATH="$HOME/bin:$PATH" - export PATH="$HOME/bin:$PATH"
- mkdir ~/bin - mkdir ~/bin
- wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true
@ -65,10 +66,71 @@ install:
- /tmp/tools/cmake --prefix="$HOME" --exclude-subdir - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir
before_script : before_script :
- mkdir bld # travis dont have a fisical monitor. We need to instal an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/
- cd bld - "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
# we have: qPCR4vir/nana/nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples)
#- cd nana-demo
- mkdir bin
- cd bin
script: script:
- cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON -DENABLE_PNG=OFF -DBUILD_NANA_DEMOS=ON -DENABLE_AUDIO=OFF - cmake -G"Unix Makefiles" .. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON
- make - make
- cd ..
- mv -v bin/ nana-demo/
- cd nana-demo/bin
- ls
- ./a_group_impl
- ./animate-bmp
- ./audio_player
- ./background-effects
#- ./calculator
- ./categ
- ./clicked
- ./decore
- ./dock
- ./drag-button
- ./draw
- ./file_explorer
#- ./example_menu
- ./example_listbox
#- ./example_combox
- ./example.button
#- ./folder_tree_nana
#- ./folder_tree_std
- ./framework_design_1
- ./framework_design_2
- ./framework_design_3
- ./group
- ./HelloWord
#- ./helloword_quit
#- ./inputbox
- ./label_listener
#- ./lambda_event.cpp11
- ./listbox_inline_widget
- ./listbox_Resolver
- ./loader_1
#- ./loader_2
- ./mbox
- ./menu_debug
#- ./MontiHall
#- ./helloworld_demo
#- ./notepad
- ./menu_debug
- ./menu_popuper
#- ./modal_form
#- ./widget_show2
#- ./widget_show
- ./place_login
- ./png
#- ./screen
- ./stretch_image
- ./threading
#- ./thread-pool
- ./various_events
#- ./window-dragger
- ./windows-subclassing

View File

@ -1,7 +1,8 @@
# CMake configuration for Nana # CMake configuration for Nana
# Author: Andrew Kornilov(https://github.com/ierofant) # Author: Andrew Kornilov(https://github.com/ierofant)
# Contributor: # Contributors:
# Robert Hauck - Enable support for PNG/Freetype # Jinhao
# Robert Hauck - Enable support for PNG/Freetype
# Qiangqiang Wu - Add biicode support # Qiangqiang Wu - Add biicode support
# Ariel Vina-Rodriguez (qPCR4vir) # Ariel Vina-Rodriguez (qPCR4vir)
@ -9,16 +10,30 @@
#https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption #https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption
# use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir # use CACHE FORCE or set(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ ON) or delete CMakecache.txt or the entirely build dir
# if your changes don't execute # if your changes don't execute
option(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF)
option(ENABLE_PNG "Enable the use of PNG" OFF) # It seems that project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES.
option(LIBPNG_FROM_OS "Use libpng from operating system." ON) # https://bbs.archlinux.org/viewtopic.php?id=84967
option(ENABLE_JPEG "Enable the use of JPEG" OFF) project(nana)
option(LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) cmake_minimum_required(VERSION 2.8)
option(ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF)
option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) set(NANA_LINKS)
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(NANA_CMAKE_INSTALL_INCLUDES "Install nana includes when compile the library" ON)
# The ISO C++ File System Technical Specification is optional. option(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ "replaced boost.thread with meganz's mingw-std-threads." OFF)
option(NANA_CMAKE_ENABLE_PNG "Enable the use of PNG" OFF)
option(NANA_CMAKE_LIBPNG_FROM_OS "Use libpng from operating system." ON)
option(NANA_CMAKE_ENABLE_JPEG "Enable the use of JPEG" OFF)
option(NANA_CMAKE_LIBJPEG_FROM_OS "Use libjpeg from operating system." ON)
option(NANA_CMAKE_ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF)
option(NANA_CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF)
option(NANA_CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON)
option(NANA_CMAKE_BUILD_DEMOS "Build all the demos form the nana_demo repository." OFF)
option(NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS "" ON)
option(NANA_CMAKE_AUTOMATIC_GUI_TESTING "Activate automatic GUI testing?" OFF)
option(NANA_CMAKE_BUILD_FreeMe "Build FreeMe (currently broken)?" OFF)
# 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
# This is not a workaround, but an user option. # This is not a workaround, but an user option.
# The library maybe available in the std library in use or from Boost (almost compatible) # The library maybe available in the std library in use or from Boost (almost compatible)
@ -26,31 +41,51 @@ option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF
# or you can choose to use the (partial, but functional) implementation provided by nana. # or you can choose to use the (partial, but functional) implementation provided by nana.
# If you include the file <nana/filesystem/filesystem_selector.hpp> # If you include the file <nana/filesystem/filesystem_selector.hpp>
# The selected option will be set by nana into std::experimental::filesystem # The selected option will be set by nana into std::experimental::filesystem
# By default Nana will use the ISO TS if available, or nana if not. # By default Nana will try to use the STD. If not available will try
# Boost will be use only if you change one of the following: # to use boost if available. Nana own implementation will be use only none of them are available.
option(CMAKE_BOOST_FILESYSTEM_AVAILABLE "Is Boost filesystem available?" OFF) # You can change that default if you change one of the following
option(NANA_BOOST_FILESYSTEM_PREFERRED "Is Boost filesystem preferred over nana?" OFF) # (please don't define more than one of the _XX_FORCE options):
option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over ISO)?" OFF) option(NANA_CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" ON)
option(CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find <boost/filesystem.hpp>?" "../") option(NANA_CMAKE_NANA_FILESYSTEM_FORCE "Force nana filesystem over ISO and boost?" OFF)
option(CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") option(NANA_CMAKE_STD_FILESYSTEM_FORCE "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF)
option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over STD)?" OFF)
# cmake will find the package self, if don't works set the following (please find the correct values):
#option(NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find <boost/filesystem.hpp>?" "../")
#option(NANA_CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs")
#include_directories("${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}")
#list(APPEND NANA_LINKS "${NANA_CMAKE_BOOST_FILESYSTEM_LIB}" )
set(NANA_LINKS)
if (CMAKE_BOOST_FILESYSTEM_AVAILABLE) if (NANA_CMAKE_NANA_FILESYSTEM_FORCE)
if (CMAKE_BOOST_FILESYSTEM_PREFERED OR CMAKE_BOOST_FILESYSTEM_FORCE) add_definitions(-DNANA_FILESYSTEM_FORCE)
elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE)
add_definitions(-DSTD_FILESYSTEM_FORCE)
elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE)
endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
# 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,
# even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries.
# If using Boost::thread, then Thread::Thread will also be added automatically.
find_package(Boost COMPONENTS filesystem)
if (Boost_FOUND)
add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE) add_definitions(-DNANA_BOOST_FILESYSTEM_AVAILABLE)
if (CMAKE_BOOST_FILESYSTEM_FORCE) include_directories(SYSTEM "${Boost_INCLUDE_DIR}")
add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) list(APPEND NANA_LINKS "${Boost_LIBRARIES}")
else() endif (Boost_FOUND)
add_definitions(-DNANA_BOOST_FILESYSTEM_PREFERED)
endif() set(Boost_USE_STATIC_LIBS ON)
include_directories("${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") set(Boost_USE_STATIC_RUNTIME ON) # ??
list(APPEND NANA_LINKS "${CMAKE_BOOST_FILESYSTEM_LIB}") #set(Boost_USE_MULTITHREADED ON)
endif (CMAKE_BOOST_FILESYSTEM_PREFERED OR CMAKE_BOOST_FILESYSTEM_FORCE)
endif (CMAKE_BOOST_FILESYSTEM_AVAILABLE) endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE)
project(nana)
cmake_minimum_required(VERSION 2.8)
# Compatibility with CMake 3.1 # Compatibility with CMake 3.1
if(POLICY CMP0054) if(POLICY CMP0054)
@ -73,12 +108,11 @@ if(WIN32)
endif(MSVC) endif(MSVC)
if(MINGW) if(MINGW)
if(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) if(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
add_definitions(-DSTD_THREAD_NOT_SUPPORTED)
add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
endif(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
endif(MINGW) endif(MINGW)
elseif(WIN32)
set(BUILD_FreeMe OFF)
endif(WIN32) endif(WIN32)
if(APPLE) if(APPLE)
@ -103,34 +137,34 @@ if(UNIX)
endif(UNIX) endif(UNIX)
#Find PNG #Find PNG
if(ENABLE_PNG) if(NANA_CMAKE_ENABLE_PNG)
add_definitions(-DNANA_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG)
#set(NANA_PNG_LIB "png") #set(NANA_PNG_LIB "png")
list(APPEND NANA_LINKS -lpng ) list(APPEND NANA_LINKS -lpng )
if(LIBPNG_FROM_OS) if(NANA_CMAKE_LIBPNG_FROM_OS)
find_package(PNG) find_package(PNG)
if (PNG_FOUND) if (PNG_FOUND)
include_directories( ${PNG_INCLUDE_DIRS}) include_directories( ${PNG_INCLUDE_DIRS})
add_definitions(-DUSE_LIBPNG_FROM_OS) add_definitions(-DUSE_LIBPNG_FROM_OS)
endif(PNG_FOUND) endif(PNG_FOUND)
endif(LIBPNG_FROM_OS) endif(NANA_CMAKE_LIBPNG_FROM_OS)
endif(ENABLE_PNG) endif(NANA_CMAKE_ENABLE_PNG)
#Find JPEG #Find JPEG
if(ENABLE_JPEG) if(NANA_CMAKE_ENABLE_JPEG)
add_definitions(-DNANA_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG)
#set(NANA_JPEG_LIB "jpeg") #set(NANA_JPEG_LIB "jpeg")
list(APPEND NANA_LINKS -ljpeg ) list(APPEND NANA_LINKS -ljpeg )
if(LIBJPEG_FROM_OS) if(NANA_CMAKE_LIBJPEG_FROM_OS)
find_package(JPEG) find_package(JPEG)
if (JPEG_FOUND) if (JPEG_FOUND)
include_directories( ${JPEG_INCLUDE_DIRS}) include_directories( ${JPEG_INCLUDE_DIRS})
add_definitions(-DUSE_LIBJPEG_FROM_OS) add_definitions(-DUSE_LIBJPEG_FROM_OS)
endif(JPEG_FOUND) endif(JPEG_FOUND)
endif(LIBJPEG_FROM_OS) endif(NANA_CMAKE_LIBJPEG_FROM_OS)
endif(ENABLE_JPEG) endif(NANA_CMAKE_ENABLE_JPEG)
if(ENABLE_AUDIO) if(NANA_CMAKE_ENABLE_AUDIO)
add_definitions(-DNANA_ENABLE_AUDIO) add_definitions(-DNANA_ENABLE_AUDIO)
if(UNIX) if(UNIX)
find_package(ASOUND) find_package(ASOUND)
@ -141,12 +175,11 @@ if(ENABLE_AUDIO)
message(FATAL_ERROR "libasound is not found") message(FATAL_ERROR "libasound is not found")
endif(ASOUND_FOUND) endif(ASOUND_FOUND)
endif(UNIX) endif(UNIX)
endif(ENABLE_AUDIO) endif(NANA_CMAKE_ENABLE_AUDIO)
#Unicode if(NANA_CMAKE_VERBOSE_PREPROCESSOR)
if(CMAKE_VERBOSE_PREPROCESSOR)
add_definitions(-DVERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR)
endif(CMAKE_VERBOSE_PREPROCESSOR) endif(NANA_CMAKE_VERBOSE_PREPROCESSOR)
set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source)
@ -164,7 +197,7 @@ aux_source_directory(${NANA_SOURCE_DIR}/paint NANA_PAINT_SOURCE)
aux_source_directory(${NANA_SOURCE_DIR}/paint/detail NANA_PAINT_DETAIL_SOURCE) 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}/system NANA_SYSTEM_SOURCE)
aux_source_directory(${NANA_SOURCE_DIR}/threads NANA_THREADS_SOURCE) aux_source_directory(${NANA_SOURCE_DIR}/threads NANA_THREADS_SOURCE)
if(ENABLE_AUDIO) if(NANA_CMAKE_ENABLE_AUDIO)
aux_source_directory(${NANA_SOURCE_DIR}/audio NANA_AUDIO_SOURCE) aux_source_directory(${NANA_SOURCE_DIR}/audio NANA_AUDIO_SOURCE)
aux_source_directory(${NANA_SOURCE_DIR}/audio/detail NANA_AUDIO_DETAIL_SOURCE) aux_source_directory(${NANA_SOURCE_DIR}/audio/detail NANA_AUDIO_DETAIL_SOURCE)
endif() endif()
@ -186,185 +219,86 @@ add_library(${PROJECT_NAME} ${NANA_SOURCE}
${NANA_SYSTEM_SOURCE} ${NANA_SYSTEM_SOURCE}
${NANA_THREADS_SOURCE}) ${NANA_THREADS_SOURCE})
#Headers: use INCLUDE_DIRECTORIES # Headers: use INCLUDE_DIRECTORIES
# Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES)
target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) target_link_libraries(${PROJECT_NAME} ${NANA_LINKS})
install(TARGETS ${PROJECT_NAME} install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib) LIBRARY DESTINATION lib)
# ??
install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) # Install include directories too.
if(NANA_CMAKE_INSTALL_INCLUDES)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/nana
DESTINATION include)
endif(NANA_CMAKE_INSTALL_INCLUDES)
set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 )
# TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file
if (BUILD_NANA_DEMOS) if (NANA_CMAKE_BUILD_DEMOS)
set (CMAKE_INSTALL_PREFIX ${DEMO_BIN})
set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin)
set(CMAKE_INSTALL_PREFIX )
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})
if (BUILD_FreeMe) if(NANA_CMAKE_AUTOMATIC_GUI_TESTING)
add_executable(FreeMe ../nana-demo/FreeMe.cpp) add_definitions(-DNANA_AUTOMATIC_GUI_TESTING)
set_property( TARGET FreeMe PROPERTY CXX_STANDARD 14 ) enable_testing ()
target_link_libraries(FreeMe ${PROJECT_NAME} ) endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING)
install(TARGETS FreeMe RUNTIME DESTINATION &{DEMO_BIN})
endif (BUILD_FreeMe)
add_executable(notepad ../nana-demo/notepad.cpp) set (demos calculator file_explorer helloworld_demo notepad )
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) foreach ( demo ${demos})
set_property( TARGET widget_show PROPERTY CXX_STANDARD 14 ) add_executable(${demo} "../nana-demo/${demo}.cpp")
target_link_libraries(widget_show ${PROJECT_NAME}) set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 )
install(TARGETS widget_show RUNTIME DESTINATION &{DEMO_BIN}) target_link_libraries(${demo} ${PROJECT_NAME})
#if(NANA_CMAKE_AUTOMATIC_GUI_TESTING)
#add_custom_command( TARGET ${demo} POST_BUILD COMMAND ${demo} )
#add_custom_target(do_always_${demo} ALL COMMAND ${demo})
#add_test(${demo} COMMAND ${demo})
#endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING)
install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/")
message("... to build: ../nana-demo/${demo}.cpp" )
endforeach( demo ${demos})
add_executable(widget_show2 ../nana-demo/widget_show2.cpp) set (demos widget_show widget_show2 )
set_property( TARGET widget_show2 PROPERTY CXX_STANDARD 14 )
target_link_libraries(widget_show2 ${PROJECT_NAME})
install(TARGETS widget_show2 RUNTIME DESTINATION &{DEMO_BIN})
if (OFF) # temporal: we need to adapt the use of filesystem to nana v1.03 (no file iterator) if (NANA_CMAKE_BUILD_FreeMe)
add_definitions(-DBUILD_FreeMe)
endif (NANA_CMAKE_BUILD_FreeMe)
add_executable(file_explorer ../nana-demo/file_explorer.cpp) if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS)
set_property( TARGET file_explorer PROPERTY CXX_STANDARD 14 ) list(APPEND demos FreeMe) # ??
target_link_libraries(file_explorer ${PROJECT_NAME} ) endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS)
install(TARGETS file_explorer RUNTIME DESTINATION &{DEMO_BIN}) # Pending: FreeMe (added but really completelly compiled if defined BUILD_FreeMe )
foreach ( demo ${demos})
add_executable(${demo} "../nana-demo/${demo}.cpp")
set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 )
target_link_libraries(${demo} ${PROJECT_NAME})
install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/")
message("... to build: ../nana-demo/${demo}.cpp" )
endforeach( demo ${demos})
endif(OFF)
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 (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked
set_property( TARGET animate-bmp PROPERTY CXX_STANDARD 14 ) decore dock drag-button draw example.button example_combox example_listbox example_menu
target_link_libraries(animate-bmp ${PROJECT_NAME}) filebox-txt folder_tree folder_tree_nana folder_tree_std framework_design_1 framework_design_2 framework_design_3
group HelloWord helloword_quit inputbox label_listener lambda_event.Cpp11 listbox_inline_widget listbox_Resolver loader_1 loader_2
main mbox menu_debug menu_popuper modal_form MontiHall place_login png screen stretch_image
threading thread-pool various_events window-dragger windows-subclassing
)
# Pending:
foreach ( demo ${demos})
add_executable(${demo} "../nana-demo/Examples/${demo}.cpp")
set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 )
target_link_libraries(${demo} ${PROJECT_NAME})
install(TARGETS ${demo} RUNTIME DESTINATION "../nana-demo/Examples/")
message("... to build: ../nana-demo/Examples/${demo}.cpp" )
endforeach( demo ${demos})
add_executable(background-effects ../nana-demo/Examples/background-effects.cpp)
set_property( TARGET background-effects PROPERTY CXX_STANDARD 14 )
target_link_libraries(background-effects ${PROJECT_NAME})
add_executable(categ ../nana-demo/Examples/categ.cpp) endif (NANA_CMAKE_BUILD_DEMOS)
set_property( TARGET categ PROPERTY CXX_STANDARD 14 )
target_link_libraries(categ ${PROJECT_NAME})
add_executable(clicked ../nana-demo/Examples/clicked.cpp)
set_property( TARGET clicked PROPERTY CXX_STANDARD 14 )
target_link_libraries(clicked ${PROJECT_NAME})
add_executable(decore ../nana-demo/Examples/decore.cpp)
set_property( TARGET decore PROPERTY CXX_STANDARD 14 )
target_link_libraries(decore ${PROJECT_NAME})
add_executable(dock ../nana-demo/Examples/dock.cpp)
set_property( TARGET dock PROPERTY CXX_STANDARD 14 )
target_link_libraries(dock ${PROJECT_NAME})
add_executable(drag-button ../nana-demo/Examples/drag-button.cpp)
set_property( TARGET drag-button PROPERTY CXX_STANDARD 14 )
target_link_libraries(drag-button ${PROJECT_NAME})
add_executable(draw ../nana-demo/Examples/draw.cpp)
set_property( TARGET draw PROPERTY CXX_STANDARD 14 )
target_link_libraries(draw ${PROJECT_NAME})
add_executable(example_combox ../nana-demo/Examples/example_combox.cpp)
set_property( TARGET example_combox PROPERTY CXX_STANDARD 14 )
target_link_libraries(example_combox ${PROJECT_NAME})
add_executable(example_listbox ../nana-demo/Examples/example_listbox.cpp)
set_property( TARGET example_listbox PROPERTY CXX_STANDARD 14 )
target_link_libraries(example_listbox ${PROJECT_NAME})
add_executable(example_menu ../nana-demo/Examples/example_menu.cpp)
set_property( TARGET example_menu PROPERTY CXX_STANDARD 14 )
target_link_libraries(example_menu ${PROJECT_NAME})
add_executable(filebox-txt ../nana-demo/Examples/filebox-txt.cpp)
set_property( TARGET filebox-txt PROPERTY CXX_STANDARD 14 )
target_link_libraries(filebox-txt ${PROJECT_NAME})
add_executable(folder_tree ../nana-demo/Examples/folder_tree.cpp)
set_property( TARGET folder_tree PROPERTY CXX_STANDARD 14 )
target_link_libraries(folder_tree ${PROJECT_NAME})
add_executable(folder_tree_nana ../nana-demo/Examples/folder_tree_nana.cpp)
set_property( TARGET folder_tree_nana PROPERTY CXX_STANDARD 14 )
target_link_libraries(folder_tree_nana ${PROJECT_NAME})
add_executable(folder_tree_std ../nana-demo/Examples/folder_tree_std.cpp)
set_property( TARGET folder_tree_std PROPERTY CXX_STANDARD 14 )
target_link_libraries(folder_tree_std ${PROJECT_NAME})
add_executable(listbox_Resolver ../nana-demo/Examples/listbox_Resolver.cpp)
set_property( TARGET listbox_Resolver PROPERTY CXX_STANDARD 14 )
target_link_libraries(listbox_Resolver ${PROJECT_NAME})
add_executable(framework_design_2 ../nana-demo/Examples/framework_design_2.cpp)
set_property( TARGET framework_design_2 PROPERTY CXX_STANDARD 14 )
target_link_libraries(framework_design_2 ${PROJECT_NAME})
add_executable(framework_design_3 ../nana-demo/Examples/framework_design_3.cpp)
set_property( TARGET framework_design_3 PROPERTY CXX_STANDARD 14 )
target_link_libraries(framework_design_3 ${PROJECT_NAME})
add_executable(group ../nana-demo/Examples/group.cpp)
set_property( TARGET group PROPERTY CXX_STANDARD 14 )
target_link_libraries(group ${PROJECT_NAME})
add_executable(HelloWord ../nana-demo/Examples/HelloWord.cpp)
set_property( TARGET HelloWord PROPERTY CXX_STANDARD 14 )
target_link_libraries(HelloWord ${PROJECT_NAME})
add_executable(listbox_inline_widget ../nana-demo/Examples/listbox_inline_widget.cpp)
set_property( TARGET listbox_inline_widget PROPERTY CXX_STANDARD 14 )
target_link_libraries(listbox_inline_widget ${PROJECT_NAME})
add_executable(inputbox ../nana-demo/Examples/inputbox.cpp)
set_property( TARGET inputbox PROPERTY CXX_STANDARD 14 )
target_link_libraries(inputbox ${PROJECT_NAME})
add_executable(label_listener ../nana-demo/Examples/label_listener.cpp)
set_property( TARGET label_listener PROPERTY CXX_STANDARD 14 )
target_link_libraries(label_listener ${PROJECT_NAME})
add_executable(lambda_event.Cpp11 ../nana-demo/Examples/lambda_event.Cpp11.cpp)
set_property( TARGET lambda_event.Cpp11 PROPERTY CXX_STANDARD 14 )
target_link_libraries(lambda_event.Cpp11 ${PROJECT_NAME})
if (ENABLE_AUDIO)
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} )
endif(ENABLE_AUDIO)
# TODO: make it automatic to select each demo and example and build each.
#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} )# X11 Xft ${NANA_JPEG_LIB} ${NANA_PNG_LIB})
#endforeach( demofile ${DEMO_SOURCES} )
endif(BUILD_NANA_DEMOS)
# set compile flags # set compile flags
@ -393,5 +327,15 @@ message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG})
message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX})
message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS})
message ( "DESTDIR = " ${DESTDIR})
message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX})
message ( "NANA_LINKS = " ${NANA_LINKS}) message ( "NANA_LINKS = " ${NANA_LINKS})
message ( "ENABLE_AUDIO = " ${ENABLE_AUDIO}) message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO})
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_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB})
message ( "NANA_CMAKE_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_AUTOMATIC_GUI_TESTING})
message ( "NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING})

View File

@ -1,7 +1,7 @@
# Nana C++ Library # Nana C++ Library
[Linux (gcc 5, including demos) ![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) [Linux (gcc 5.2.1 and 4.9.2)![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) including [(nana-demos)](https://github.com/qPCR4vir/nana-demo)
[Windows (VC2015) ![AppVeyor uild status](https://ci.appveyor.com/api/projects/status/5j79p9fi887usv7h?svg=true)](https://ci.appveyor.com/project/qPCR4vir/nana) [Windows (Microsoft (R) Build Engine version 14.0.24720.0) ![AppVeyor uild status](https://ci.appveyor.com/api/projects/status/5j79p9fi887usv7h?svg=true)](https://ci.appveyor.com/project/qPCR4vir/nana)
[![Licence](https://img.shields.io/badge/license-BSL-blue.svg?style=flat)](LICENSE_1_0.txt) [![Licence](https://img.shields.io/badge/license-BSL-blue.svg?style=flat)](LICENSE_1_0.txt)

View File

@ -1,8 +1,8 @@
Building Nana C++ Library # Building Nana C++ Library directly with make
requires: If you are using make directly, it require:
X11, pthread, Xpm, rt, dl, freetype2, Xft, fontconfig, ALSA X11, pthread, Xpm, rt, dl, freetype2, Xft, fontconfig, ALSA
Writing a makefile for creating applications with Nana C++ Library Example of writing a makefile for creating applications with Nana C++ Library
------------------- -------------------
``` ```
GCC = g++ GCC = g++

View File

@ -249,6 +249,9 @@
<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\filesystem\filesystem_selector.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -49,6 +49,9 @@
<Filter Include="Source Files\paint\detail"> <Filter Include="Source Files\paint\detail">
<UniqueIdentifier>{53feb93f-2b86-4bf5-b2f3-f60ef1bbbf76}</UniqueIdentifier> <UniqueIdentifier>{53feb93f-2b86-4bf5-b2f3-f60ef1bbbf76}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\filesystem">
<UniqueIdentifier>{6caffbf6-c023-4dbf-ba69-cdb49feddb5d}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\source\any.cpp"> <ClCompile Include="..\..\source\any.cpp">
@ -280,4 +283,9 @@
<Filter>Source Files\gui\detail</Filter> <Filter>Source Files\gui\detail</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\filesystem\filesystem_selector.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>
</ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,6 @@
#ifndef NANA_AUDIO_PLAYER_HPP #ifndef NANA_AUDIO_PLAYER_HPP
#define NANA_AUDIO_PLAYER_HPP #define NANA_AUDIO_PLAYER_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/deploy.hpp> #include <nana/deploy.hpp>
#ifdef NANA_ENABLE_AUDIO #ifdef NANA_ENABLE_AUDIO
@ -31,4 +31,7 @@ namespace nana{ namespace audio
}//end namespace nana }//end namespace nana
#endif //NANA_ENABLE_AUDIO #endif //NANA_ENABLE_AUDIO
#endif
#include <nana/pop_ignore_diagnostic>
#endif

View File

@ -15,6 +15,7 @@
#include <nana/deploy.hpp> #include <nana/deploy.hpp>
#include <cctype> #include <cctype>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -337,9 +338,9 @@ namespace nana
bool operator==(const color& other) const; bool operator==(const color& other) const;
bool operator!=(const color& other) const; bool operator!=(const color& other) const;
private: private:
double r_; double r_{ 0.0 };
double g_; double g_{ 0.0 };
double b_; double b_{ 0.0 };
double a_{ 0.0 }; //invisible double a_{ 0.0 }; //invisible
}; };
@ -484,7 +485,7 @@ namespace nana
southeast southeast
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -31,6 +31,7 @@
* - _SCL_SECURE_NO_WARNNGS, _CRT_SECURE_NO_DEPRECATE (VC) * - _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_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_THREAD_NOT_SUPPORTED (GCC < 4.8.1)
* - STD_put_time_NOT_SUPPORTED (GCC < 5)
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1)
* - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (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) * - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8)
@ -133,9 +134,14 @@
#endif #endif
#endif #endif
#if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
#undef STD_FILESYSTEM_NOT_SUPPORTED #if ((__GNUC__ < 5) )
#endif # define STD_put_time_NOT_SUPPORTED
#endif
#if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) )
# undef STD_FILESYSTEM_NOT_SUPPORTED
#endif
#if (__GNUC__ == 4) #if (__GNUC__ == 4)
#if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) #if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1))
@ -147,8 +153,10 @@
#endif #endif
#if defined(NANA_MINGW) #if defined(NANA_MINGW)
//It's a knonwn issue under MinGW #ifndef __MINGW64_VERSION_MAJOR
#define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED //It's a knonwn issue under MinGW(except MinGW-W64)
#define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
#endif
#endif #endif
#if (__GNUC_MINOR__ < 8) #if (__GNUC_MINOR__ < 8)

View File

@ -46,7 +46,31 @@ namespace nana
class charset_encoding_interface; class charset_encoding_interface;
} }
/// An intelligent charset class for character code conversion. /*!\class charset
\brief An intelligent charset class for character code conversion.
Example:
1. A UTF-8 string from the socket.
int len = ::recv(sd, buf, buflen, 0);
textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8));
2. Send the string in text to the socket as UTF-8.
std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8);
::send(sd, utf8str.c_str(), utf8str.size(), 0);
3, Convert a string to the specified multi-byte character code.
// Convert to a multibytes string through default system language.
std::string mbstr = nana::charset(a_wstring);
// If the default system language is English and convert
// a Chinese unicode string to multibytes string through GB2312
std::setlocale(LC_CTYPE, "zh_CN.GB2312");
//set::setlocale(LC_CTYPE, ".936"); call it in Windows
std::string mbstr = nana::charset(a_wstring_with_chinese);
*/
class charset class charset
{ {
public: public:
@ -74,27 +98,3 @@ namespace nana
}//end namespace nana }//end namespace nana
#endif #endif
/*!\class charset
Example
1. A UTF-8 string from the socket.
int len = ::recv(sd, buf, buflen, 0);
textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8));
2. Send the string in text to the socket as UTF-8.
std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8);
::send(sd, utf8str.c_str(), utf8str.size(), 0);
3, Convert a string to the specified multi-byte character code.
//Convert to a multibytes string through default system language.
std::string mbstr = nana::charset(a_wstring);
//If the default system language is English and convert
//a Chinese unicode string to multibytes string through GB2312
std::setlocale(LC_CTYPE, "zh_CN.GB2312");
//set::setlocale(LC_CTYPE, ".936"); call it in Windows
std::string mbstr = nana::charset(a_wstring_with_chinese);
*/

View File

@ -39,20 +39,30 @@
// https://github.com/meganz/mingw-std-threads // https://github.com/meganz/mingw-std-threads
//#define NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ //#define NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ
//////////////////////////// //# The ISO C++ File System Technical Specification(ISO - TS, or STD) is optional.
// The ISO C++ File System Technical Specification 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 //# This is not a workaround, but an user option.
// This is not a workaround, but an user option. //# The library maybe available in the std library in use or from Boost(almost compatible)
// The library maybe available in the std library in use or from Boost (almost compatible) //# http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm
// http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm //# or you can choose to use the(partial, but functional) implementation provided by nana.
// or you can choose to use the (partial, but functional) implementation provided by nana. //# If you include the file <nana/filesystem/filesystem_selector.hpp>
// If you include the file <nana/filesystem/filesystem_selector.hpp> //# the selected option will be set by nana into std::experimental::filesystem
// The selected option will be set by nana into std::experimental::filesystem //# By default Nana will try to use the STD.If not available will try
// By default Nana will use the ISO TS if available, or nana if not. //# to use boost if available.Nana own implementation will be use only none of them are available.
// Boost will be use only if you change one of the following (set the includes and link correspondly): //# You can change that default if you change one of the following
//#define NANA_BOOST_FILESYSTEM_AVAILABLE // "Is Boost filesystem available?" //# (please don't define more than one of the _XX_FORCE options):
//#define NANA_BOOST_FILESYSTEM_PREFERRED // "Is Boost filesystem preferred over nana?" //
//#define NANA_BOOST_FILESYSTEM_FORCE // "Force use of Boost filesystem if available (over ISO)? //#define BOOST_FILESYSTEM_AVAILABLE // "Is Boost filesystem available?"
//#define BOOST_FILESYSTEM_FORCE // "Force use of Boost filesystem if available (over ISO and nana)
//#define STD_FILESYSTEM_FORCE // "Use of STD filesystem?(a compilation error will ocurre if not available)" OFF)
//#define NANA_FILESYSTEM_FORCE // "Force nana filesystem over ISO and boost?" OFF)
//
// Make sure you (cmake?) provide the following where correspond (please find the correct values):
// set CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find <boost/filesystem.hpp>?" "../")
// set CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs")
// include_directories CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT
// APPEND flag LINKS CMAKE_BOOST_FILESYSTEM_LIB
/////////////////// ///////////////////
// Support of PCM playback // Support of PCM playback
@ -83,6 +93,17 @@
#endif #endif
#endif #endif
///////////////////
// Support for NANA_AUTOMATIC_GUI_TESTING
// Will cause the program to self-test the GUI. A default automatic GUI test
// will be added to all programs which don't have yet one defined. This default test will simple
// wait 10 sec. (time to construct, show and execute the GUI) and then exit normally.
//
//#define NANA_AUTOMATIC_GUI_TESTING
#if !defined(VERBOSE_PREPROCESSOR) #if !defined(VERBOSE_PREPROCESSOR)
//#define VERBOSE_PREPROCESSOR //#define VERBOSE_PREPROCESSOR
#endif #endif

View File

@ -14,6 +14,7 @@
#ifndef NANA_DEPLOY_HPP #ifndef NANA_DEPLOY_HPP
#define NANA_DEPLOY_HPP #define NANA_DEPLOY_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/config.hpp> #include <nana/config.hpp>
#if defined(VERBOSE_PREPROCESSOR) #if defined(VERBOSE_PREPROCESSOR)
@ -92,14 +93,57 @@ namespace std
} }
#endif #endif
#ifdef STD_put_time_NOT_SUPPORTED
#include <ctime>
namespace std
{
//Workaround for no implemenation of std::put_time in gcc < 5.
/* std unspecified return type */
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
//template< >
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt);
//Defined in header <ctime>
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
//template<>
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
}
#endif // STD_put_time_NOT_SUPPORTED
namespace nana namespace nana
{ {
/// move to *.h ??
struct utf8_Error : std::runtime_error
{
static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ?
using std::runtime_error::runtime_error;
#if defined(_MSC_VER)
# if (_MSC_VER < 1900)
//A workaround for lack support of C++11 inheriting constructors for VC2013
explicit utf8_Error(const std::string& msg);
# endif
#endif
void emit();
};
/// Checks whether a specified text is utf8 encoding /// Checks whether a specified text is utf8 encoding
bool is_utf8(const char* str, std::size_t len); bool is_utf8(const char* str, std::size_t len);
void throw_not_utf8(const std::string& text); void throw_not_utf8(const std::string& text);
void throw_not_utf8(const char*, std::size_t len); void throw_not_utf8(const char*, std::size_t len);
void throw_not_utf8(const char*); void throw_not_utf8(const char*);
/// this text needed change, it needed review ??
bool review_utf8(const std::string& text);
/// this text needed change, it needed review ??
bool review_utf8(std::string& text);
const std::string& to_utf8(const std::string&); const std::string& to_utf8(const std::string&);
std::string to_utf8(const std::wstring&); std::string to_utf8(const std::wstring&);
@ -190,5 +234,5 @@ namespace std {
make_unique(Args&&...) = delete; make_unique(Args&&...) = delete;
} }
#endif //STD_make_unique_NOT_SUPPORTED #endif //STD_make_unique_NOT_SUPPORTED
#include <nana/pop_ignore_diagnostic>
#endif //NANA_MACROS_HPP #endif //NANA_DEPLOY_HPP

View File

@ -18,6 +18,8 @@
#ifndef NANA_DETAIL_PLATFORM_SPEC_HPP #ifndef NANA_DETAIL_PLATFORM_SPEC_HPP
#define NANA_DETAIL_PLATFORM_SPEC_HPP #define NANA_DETAIL_PLATFORM_SPEC_HPP
#include <nana/push_ignore_diagnostic>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <memory> #include <memory>
@ -60,6 +62,8 @@ namespace detail
class charset_conv class charset_conv
{ {
charset_conv(const charset_conv&) = delete;
charset_conv& operator=(const charset_conv*) = delete;
public: public:
charset_conv(const char* tocode, const char* fromcode); charset_conv(const char* tocode, const char* fromcode);
~charset_conv(); ~charset_conv();
@ -118,6 +122,9 @@ namespace detail
void update_color(); void update_color();
void update_text_color(); void update_text_color();
private: private:
drawable_impl_type(const drawable_impl_type&) = delete;
drawable_impl_type& operator=(const drawable_impl_type&) = delete;
unsigned current_color_{ 0xFFFFFF }; unsigned current_color_{ 0xFFFFFF };
unsigned color_{ 0xFFFFFFFF }; unsigned color_{ 0xFFFFFFFF };
unsigned text_color_{ 0xFFFFFFFF }; unsigned text_color_{ 0xFFFFFFFF };
@ -188,8 +195,8 @@ namespace detail
native_window_type owner; native_window_type owner;
std::vector<native_window_type> * owned; std::vector<native_window_type> * owned;
}; };
public: public:
int error_code; int error_code;
public: public:
typedef drawable_impl_type::font_ptr_t font_ptr_t; typedef drawable_impl_type::font_ptr_t font_ptr_t;
typedef void (*timer_proc_type)(unsigned tid); typedef void (*timer_proc_type)(unsigned tid);
@ -197,6 +204,8 @@ namespace detail
typedef ::nana::event_code event_code; typedef ::nana::event_code event_code;
typedef ::nana::native_window_type native_window_type; typedef ::nana::native_window_type native_window_type;
platform_spec(const platform_spec&) = delete;
platform_spec& operator=(const platform_spec&) = delete;
platform_spec(); platform_spec();
~platform_spec(); ~platform_spec();
@ -327,6 +336,7 @@ namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
// .h ward // .h ward
#endif #endif

View File

@ -1,15 +1,15 @@
/* /**
* Selector of Platform Specification * Selector of Platform Specification
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/detail/platform_spec_selector.hpp * @file nana/detail/platform_spec_selector.hpp
* *
* Selects the proper platform_spec header file for the current platform * @brief Selects the proper platform_spec header file for the current platform
*/ */
#include <nana/config.hpp> #include <nana/config.hpp>

View File

@ -1,7 +1,7 @@
/* /*
* Platform Specification Implementation * Platform Specification Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -25,6 +25,7 @@
#include <windows.h> #include <windows.h>
#include <map> #include <map>
#include <memory> #include <memory>
#include <functional>
namespace nana namespace nana
{ {
@ -63,9 +64,15 @@ namespace detail
bool forced; bool forced;
}; };
struct arg_affinity_execute
{
const std::function<void()> * function_ptr;
};
enum enum
{ {
tray = 0x501, tray = 0x501,
async_activate, async_activate,
async_set_focus, async_set_focus,
remote_flush_surface, remote_flush_surface,
@ -74,6 +81,10 @@ namespace detail
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,
//Execute a function in a thread with is associated with a specified native window
affinity_execute,
user, user,
}; };
}; };
@ -142,6 +153,9 @@ namespace detail
unsigned whitespace_pixels; unsigned whitespace_pixels;
}string; }string;
drawable_impl_type(const drawable_impl_type&) = delete;
drawable_impl_type& operator=(const drawable_impl_type&) = delete;
drawable_impl_type(); drawable_impl_type();
~drawable_impl_type(); ~drawable_impl_type();

View File

@ -1,4 +1,4 @@
/* /**
* A ISO C++ filesystem Implementation * A ISO C++ filesystem 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-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,17 +7,17 @@
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/filesystem/filesystem.hpp * @file nana/filesystem/filesystem.hpp
* Modiffied by Ariel Vina-Rodriguez: * @author Jinhao, conributed: Ariel Vina-Rodriguez
* Now mimic std::experimental::filesystem::v1 (boost v3) * @brief Mimic std::experimental::filesystem::v1 (boost v3)
* and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013 * and need VC2015 or a C++11 compiler. With a few correction can be compiler by VC2013
*/ */
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 <filesystem> 2014-07-04
// http://en.cppreference.com/w/cpp/experimental/fs // http://en.cppreference.com/w/cpp/experimental/fs
// http://cpprocks.com/introduction-to-tr2-filesystem-library-in-vs2012/ --- TR2 filesystem in VS2012 // http://cpprocks.com/introduction-to-tr2-filesystem-library-in-vs2012/ --- TR2 filesystem in VS2012
// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.140%29.aspx --- C++ 14, the <filesystem> header VS2015 // https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.140%29.aspx --- C++ 14, the <filesystem> header VS2015
// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- <filesystem> header VS2013 // https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- <filesystem> header VS2013
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 2014-07-04
// http://cplusplus.github.io/filesystem-ts/working-draft.html --- in html format // http://cplusplus.github.io/filesystem-ts/working-draft.html --- in html format
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html --- in html format // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html --- in html format
// http://article.gmane.org/gmane.comp.lib.boost.devel/256220 --- The filesystem TS unanimously approved by ISO. // http://article.gmane.org/gmane.comp.lib.boost.devel/256220 --- The filesystem TS unanimously approved by ISO.
@ -29,6 +29,9 @@
#ifndef NANA_FILESYSTEM_HPP #ifndef NANA_FILESYSTEM_HPP
#define NANA_FILESYSTEM_HPP #define NANA_FILESYSTEM_HPP
#include <nana/push_ignore_diagnostic>
#include <string> #include <string>
#include <system_error> #include <system_error>
#include <iterator> #include <iterator>
@ -40,18 +43,14 @@
#include <nana/deploy.hpp> #include <nana/deploy.hpp>
// namespace std { namespace experimental { namespace filesystem { inline namespace v1 { namespace nana { namespace experimental { namespace filesystem
namespace nana { namespace experimental {
#ifndef CXX_NO_INLINE_NAMESPACE
inline namespace v1
{ {
#ifndef CXX_NO_INLINE_NAMESPACE
inline namespace v1
{
#endif #endif
namespace filesystem enum class file_type
{
enum class file_type
{ {
none = 0, ///< has not been determined or an error occurred while trying to determine none = 0, ///< has not been determined or an error occurred while trying to determine
not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error
@ -82,7 +81,7 @@ namespace filesystem
uintmax_t available; uintmax_t available;
}; };
using file_time_type = std::chrono::time_point<std::chrono::system_clock>;// trivial-clock> ; using file_time_type = std::chrono::time_point<std::chrono::system_clock>; ///< trivial-clock> ;
class file_status class file_status
{ {
@ -116,7 +115,7 @@ namespace filesystem
public: public:
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
using value_type = wchar_t; using value_type = wchar_t;
const static value_type preferred_separator = '\\'; const static value_type preferred_separator = L'\\';
#else #else
using value_type = char; using value_type = char;
const static value_type preferred_separator = '/'; const static value_type preferred_separator = '/';
@ -131,23 +130,41 @@ namespace filesystem
_m_assign(source); _m_assign(source);
} }
// modifiers
//void clear() noexcept;
path& make_preferred();
path& remove_filename();
//path& replace_filename(const path& replacement);
//path& replace_extension(const path& replacement = path());
//void swap(path& rhs) noexcept;
// decomposition
//path root_name() const;
//path root_directory() const;
//path root_path() const;
//path relative_path() const;
path parent_path() const;
path filename() const;
//path stem() const;
path extension() const;
// query
bool empty() const noexcept;
//bool has_root_name() const;
//bool has_root_directory() const;
//bool has_root_path() const;
//bool has_relative_path() const;
bool has_parent_path() const { return !parent_path().string().empty(); }; // temp;;
bool has_filename() const { return !filename().string().empty(); }; // temp;
//bool has_stem() const;
bool has_extension() const { return !extension().string().empty(); }; // temp
//bool is_absolute() const;
//bool is_relative() const;
int compare(const path& other) const; int compare(const path& other) const;
bool empty() const;
path extension() const;
path parent_path() const;
file_type what() const; file_type what() const;
//decomposition
path filename() const;
//modifiers
path& remove_filename();
const value_type*c_str() const; const value_type*c_str() const;
const string_type& native() const; const string_type& native() const;
operator string_type() const; operator string_type() const;
@ -203,8 +220,9 @@ namespace filesystem
filesystem_error(const std::string& msg, const path& path1, std::error_code err); filesystem_error(const std::string& msg, const path& path1, std::error_code err);
filesystem_error(const std::string& msg, const path& path1, const path& path2, std::error_code err); filesystem_error(const std::string& msg, const path& path1, const path& path2, std::error_code err);
const path& path1() const; //noexcept const path& path1() const noexcept;
const path& path2() const; //noexcept const path& path2() const noexcept;
// const char* what() const noexcept;
private: private:
path path1_; path path1_;
path path2_; path path2_;
@ -229,33 +247,23 @@ namespace filesystem
filesystem::path path_; filesystem::path path_;
}; };
/// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator /// InputIterator that iterate over the sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator
//template<typename FileInfo>
class directory_iterator :public std::iterator<std::input_iterator_tag, directory_entry> class directory_iterator :public std::iterator<std::input_iterator_tag, directory_entry>
{ {
using find_handle = void*; using find_handle = void*;
public: public:
using value_type = directory_entry ;
typedef ptrdiff_t difference_type;
typedef const directory_entry* pointer;
typedef const directory_entry& reference;
typedef std::input_iterator_tag iterator_category;
directory_iterator(); directory_iterator() noexcept;
directory_iterator(const path& file_path); explicit directory_iterator(const path& dir);
const value_type& operator*() const; const value_type& operator*() const;
const value_type* operator->() const; const value_type* operator->() const;
directory_iterator& operator++(); directory_iterator& operator++();
directory_iterator operator++(int); directory_iterator operator++(int); ///< extention
bool equal(const directory_iterator& x) const; bool equal(const directory_iterator& x) const;
// enable directory_iterator range-based for statements
directory_iterator begin();
directory_iterator end();
private: private:
template<typename Char> template<typename Char>
static bool _m_ignore(const Char * p) static bool _m_ignore(const Char * p)
@ -275,6 +283,16 @@ namespace filesystem
find_handle handle_{nullptr}; find_handle handle_{nullptr};
value_type value_; value_type value_;
}; };
/// enable directory_iterator range-based for statements
inline directory_iterator begin( directory_iterator iter) noexcept
{
return iter;
}
inline directory_iterator end( const directory_iterator&) noexcept
{
return {};
}
//class recursive_directory_iterator; //class recursive_directory_iterator;
@ -301,15 +319,23 @@ namespace filesystem
std::uintmax_t file_size(const path& p); std::uintmax_t file_size(const path& p);
//uintmax_t file_size(const path& p, error_code& ec) noexcept; //uintmax_t file_size(const path& p, error_code& ec) noexcept;
inline bool is_directory(file_status s) { return s.type() == file_type::directory ;} inline bool is_directory(file_status s) noexcept
{ return s.type() == file_type::directory ;}
bool is_directory(const path& p); bool is_directory(const path& p);
inline bool is_directory(const directory_entry& d)
{
return is_directory(d.status());
}
//bool is_directory(const path& p, error_code& ec) noexcept; //bool is_directory(const path& p, error_code& ec) noexcept;
//bool is_regular_file(file_status s) noexcept; inline bool is_regular_file(file_status s) noexcept
{
return s.type() == file_type::regular;
}
inline bool is_regular_file(const path& p)
{
return is_regular_file(status(p));
}
// bool is_regular_file(const path& p, error_code& ec) noexcept;
// Returns: is_regular_file(status(p, ec)).Returns false if an error occurs.
inline bool is_empty(const path& p) inline bool is_empty(const path& p)
{ {
@ -320,7 +346,7 @@ namespace filesystem
return (file_size(p) == 0); return (file_size(p) == 0);
} }
//bool is_empty(const path& p, error_code& ec) noexcept; // bool is_empty(const path& p, error_code& ec) noexcept;
bool create_directories(const path& p); bool create_directories(const path& p);
@ -330,16 +356,21 @@ namespace filesystem
bool create_directory(const path& p, const path& attributes); bool create_directory(const path& p, const path& attributes);
//bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept; //bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept;
bool modified_file_time(const path& p, struct tm&); bool modified_file_time(const path& p, struct tm&); ///< extention ?
/// The time of last data modification of p, determined as if by the value of the POSIX
/// stat structure member st_mtime obtained as if by POSIX stat().
file_time_type last_write_time(const path& p);
/// returns file_time_type::min() if an error occurs
//file_time_type last_write_time(const path& p, error_code& ec) noexcept;
path path_user(); ///< extention ?
path path_user();
path current_path(); path current_path();
//path current_path(error_code& ec); //path current_path(error_code& ec);
void current_path(const path& p); void current_path(const path& p); ///< chdir
//void current_path(const path& p, error_code& ec) noexcept; //void current_path(const path& p, error_code& ec) noexcept;
bool remove(const path& p); bool remove(const path& p);
bool remove(const path& p, std::error_code& ec); // noexcept; bool remove(const path& p, std::error_code& ec); // noexcept;
@ -381,4 +412,5 @@ namespace filesystem
//namespace filesystem = experimental::filesystem; //namespace filesystem = experimental::filesystem;
} //end namespace nana } //end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -0,0 +1,162 @@
/**
* 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\filesystem\filesystem_ext.hpp
* @autor by Ariel Vina-Rodriguez:
* @brief Some convenient extensions to the filesystem library.
*
*/
#ifndef NANA_FILESYSTEM_EXT_HPP
#define NANA_FILESYSTEM_EXT_HPP
#include <iomanip>
#include <nana/filesystem/filesystem_selector.hpp>
namespace nana {namespace experimental {namespace filesystem {namespace ext {
#if defined(NANA_WINDOWS)
constexpr auto def_root = "C:";
constexpr auto def_rootstr = "C:\\";
constexpr auto def_rootname = "Local Drive(C:)";
#elif defined(NANA_LINUX)
constexpr auto def_root = "/";
constexpr auto def_rootstr = "/";
constexpr auto def_rootname = "Root/";
#endif
// nana::experimental::filesystem::path_user());
inline bool is_directory(const std::experimental::filesystem::directory_entry& dir) noexcept
{
return is_directory(dir.status());
}
//template<class DI> // DI = directory_iterator from std, boost, or nana : return directory_entry
class directory_only_iterator : public std::experimental::filesystem::directory_iterator
{
using DI = std::experimental::filesystem::directory_iterator;
directory_only_iterator& find_first()
{
auto end = directory_only_iterator{};
while (*this != end)
{
if (is_directory((**this).status()))
return *this;
this->DI::operator++();
}
return *this;
}
public:
template <class... Arg>
directory_only_iterator(Arg&&... arg ): DI(std::forward<Arg>(arg)...)
{
find_first();
}
directory_only_iterator( ) {}
directory_only_iterator& operator++()
{
this->DI::operator++();
return find_first();
}
};
inline directory_only_iterator begin(directory_only_iterator iter) noexcept
{
return iter;
}
inline directory_only_iterator end(const directory_only_iterator&) noexcept
{
return{};
}
//template<class DI> // DI = directory_iterator from std, boost, or nana : value_type directory_entry
class regular_file_only_iterator : public std::experimental::filesystem::directory_iterator
{
using DI = std::experimental::filesystem::directory_iterator;
regular_file_only_iterator& find_first()
{
while(( (*this) != DI{}) && !is_regular_file((**this).status()))
this->DI::operator++();
return (*this);
}
public:
template <class... Arg>
regular_file_only_iterator(Arg&&... arg ): DI(std::forward<Arg>(arg)...)
{
find_first();
}
regular_file_only_iterator() : DI() {}
regular_file_only_iterator& operator++()
{
this->DI::operator++();
return find_first();
}
};
inline regular_file_only_iterator begin(regular_file_only_iterator iter) noexcept
{
return iter;
}
inline regular_file_only_iterator end(const regular_file_only_iterator&) noexcept
{
return{};
}
inline std::string pretty_file_size(const std::experimental::filesystem::path& path) // todo: move to .cpp
{
try {
std::size_t bytes = std::experimental::filesystem::file_size ( path );
const char * ustr[] = { " KB", " MB", " GB", " TB" };
std::stringstream ss;
if (bytes < 1024)
ss << bytes << " Bytes";
else
{
double cap = bytes / 1024.0;
std::size_t uid = 0;
while ((cap >= 1024.0) && (uid < sizeof(ustr) / sizeof(char *)))
{
cap /= 1024.0;
++uid;
}
ss << cap;
auto s = ss.str();
auto pos = s.find('.');
if (pos != s.npos)
{
if (pos + 2 < s.size())
s.erase(pos + 2);
}
return s + ustr[uid];
}
return ss.str();
}
catch (...) {}
return {};
}
inline std::string pretty_file_date(const std::experimental::filesystem::path& path) // todo: move to .cpp
{
try {
auto ftime = std::experimental::filesystem::last_write_time(path);
std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime);
std::stringstream tm;
tm << std::put_time(std::localtime(&cftime), "%Y-%m-%d, %H:%M:%S");
return tm.str();
}
catch (...) {
return {};
}
}
}}}}
#endif //NANA_FILESYSTEM_EXT_HPP

View File

@ -0,0 +1,77 @@
/**
* 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\filesystem\filesystem_selector.hpp
* @autor by Ariel Vina-Rodriguez:
* @brief A "ISO C++" filesystem Implementation selector
*
* 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
* This is not a workaround, but an user option.
* The library maybe available in the std library in use or from Boost(almost compatible)
* http://www.boost.org/doc/libs/1_60_0/libs/filesystem/doc/index.htm
* or you can choose to use the(partial, but functional) implementation provided by nana.
* If you include the file <nana/filesystem/filesystem_selector.hpp>
* the selected option will be set by nana into std::experimental::filesystem
* By default Nana will try to use the STD. If not available will try
* to use boost if available. Nana own implementation will be use only if none of them are available.
* nana Now mimic std::experimental::filesystem::v1 (boost v3)
*
*/
#ifndef NANA_FILESYSTEM_SELECTOR
#define NANA_FILESYSTEM_SELECTOR
#include <nana/config.hpp>
#if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) )
# include <nana/filesystem/filesystem.hpp>
namespace std {
namespace experimental {
namespace filesystem {
# ifdef CXX_NO_INLINE_NAMESPACE
using namespace nana::experimental::filesystem;
# else
using namespace nana::experimental::filesystem::v1;
# endif
} // filesystem
} // experimental
} // std
#elif (defined(BOOST_FILESYSTEM_AVAILABLE) && ( defined(BOOST_FILESYSTEM_FORCE) || ( defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(STD_FILESYSTEM_FORCE) ) ))
# include <boost/filesystem.hpp>
// add boost::filesystem into std::experimental::filesystem
namespace std {
namespace experimental {
namespace filesystem {
using namespace boost::filesystem;
} // filesystem
} // experimental
} // std
#else
# include <experimental/filesystem>
#endif
#ifndef __cpp_lib_experimental_filesystem
# define __cpp_lib_experimental_filesystem 1
#endif
#endif // NANA_FILESYSTEM_SELECTOR

View File

@ -12,7 +12,7 @@
#ifndef NANA_GUI_ANIMATION_HPP #ifndef NANA_GUI_ANIMATION_HPP
#define NANA_GUI_ANIMATION_HPP #define NANA_GUI_ANIMATION_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/paint/image.hpp> #include <nana/paint/image.hpp>
#include <functional> #include <functional>
@ -82,4 +82,5 @@ namespace nana
impl * impl_; impl * impl_;
}; };
} //end namespace nana } //end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_GUI_ANIMATION_HPP #endif //NANA_GUI_ANIMATION_HPP

View File

@ -1,20 +1,22 @@
/* /**
* \file basis.hpp
* \brief This file provides basis class and data structures required by the GUI
*
* Basis Implementation * Basis Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/basis.hpp
*
* This file provides basis class and data structrue that required by gui
*/ */
#ifndef NANA_GUI_BASIS_HPP #ifndef NANA_GUI_BASIS_HPP
#define NANA_GUI_BASIS_HPP #define NANA_GUI_BASIS_HPP
#include <nana/push_ignore_diagnostic>
#include "../basic_types.hpp" #include "../basic_types.hpp"
#include "../traits.hpp" //metacomp::fixed_type_set #include "../traits.hpp" //metacomp::fixed_type_set
@ -59,9 +61,9 @@ namespace nana
}; };
//wait for constexpr //wait for constexpr
struct widget_tag{ static const flags value = flags::widget; }; struct widget_tag{ static const flags value = flags::widget; };
struct lite_widget_tag : widget_tag{ static const flags value = flags::lite_widget;}; struct lite_widget_tag : public widget_tag{ static const flags value = flags::lite_widget; };
struct root_tag : widget_tag{ static const flags value = flags::root; }; struct root_tag : public widget_tag{ static const flags value = flags::root; };
struct frame_tag: widget_tag{ static const flags value = flags::frame; }; struct frame_tag : public widget_tag{ static const flags value = flags::frame; };
}// end namespace category }// end namespace category
using native_window_type = detail::native_window_handle_impl*; using native_window_type = detail::native_window_handle_impl*;
@ -152,7 +154,25 @@ namespace nana
appearance(); appearance();
appearance(bool has_decoration, bool taskbar, bool floating, bool no_activate, bool min, bool max, bool sizable); appearance(bool has_decoration, bool taskbar, bool floating, bool no_activate, bool min, bool max, bool sizable);
}; };
/// Provided to generate an appearance object with better readability and understandability
/** @brief Provided to generate an appearance object with better readability and understandability
A window has an appearance. This appearance can be specified when a window is being created.
To determine the appearance of a window there is a structure named nana::appearance with
a bool member for each feature with can be included or excluded in the "apereance" of the windows form.
But in practical development is hard to describe the style of the appearance using the struct nana::appearance.
If a form would to be defined without min/max button and sizable border, then
\code{.CPP}
nana::form form(x, y, width, height, nana::appearance(false, false, false, true, false));
\endcode
This piece of code may be confusing because of the 5 parameters of the constructor of `nana::form`. So the library provides a helper class for making it easy.
For better readability and understandability Nana provides three templates classes to generate an appearance object:
nana::appear::decorate, nana::appear::bald and nana::appear::optional. Each provide an operator
that return a corresponding nana::appearance with predefined values.
*/
struct appear struct appear
{ {
struct minimize{}; struct minimize{};
@ -161,7 +181,20 @@ namespace nana
struct taskbar{}; struct taskbar{};
struct floating{}; struct floating{};
struct no_activate{}; struct no_activate{};
/// Create an appearance of a window with "decoration"
/** @brief Create an appearance of a window with "decoration" in non-client area, such as title bar
*
* We can create a form without min/max button and sizable border like this:
* \code{.CPP}
* using nana::appear;
* nana::form form(x, y, width, height, appear::decorate<appear::taskbar>());
* \endcode
* The appearance created by appear::decorate<>() has a titlebar and borders that are draw by the
* platform- window manager. If a window needs a minimize button, it should be:
* \code{.CPP}
* appear::decorate<appear::minimize, appear::taskbar>()
* \endcode
*/
template< typename Minimize = null_type, template< typename Minimize = null_type,
typename Maximize = null_type, typename Maximize = null_type,
typename Sizable = null_type, typename Sizable = null_type,
@ -182,7 +215,8 @@ namespace nana
); );
} }
}; };
/// Create an appearance of a window without "decoration"
/// Create an appearance of a window without "decoration" with no titlebar and no 3D-look borders.
template < typename Taskbar = null_type, template < typename Taskbar = null_type,
typename Floating = null_type, typename Floating = null_type,
typename NoActive = null_type, typename NoActive = null_type,
@ -227,4 +261,6 @@ namespace nana
}; };
};//end namespace apper };//end namespace apper
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -1,4 +1,4 @@
/* /**
* A Basic Window Widget Definition * A Basic Window Widget Definition
* 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-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,11 +7,13 @@
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/detail/basic_window.hpp * @file nana/gui/detail/basic_window.hpp
* @brief A Basic Window Widget Definition
*/ */
#ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP #ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP
#define NANA_GUI_DETAIL_BASIC_WINDOW_HPP #define NANA_GUI_DETAIL_BASIC_WINDOW_HPP
#include <nana/push_ignore_diagnostic>
#include "drawer.hpp" #include "drawer.hpp"
#include "events_holder.hpp" #include "events_holder.hpp"
#include "widget_colors.hpp" #include "widget_colors.hpp"
@ -57,20 +59,18 @@ namespace detail
::nana::rectangle effective_range_; ::nana::rectangle effective_range_;
};//end class caret_descriptor };//end class caret_descriptor
//tab_type /// Define some constant about tab category, these flags can be combine with operator |
//@brief: Define some constant about tab category, these flags can be combine with operator |
struct tab_type struct tab_type
{ {
enum t enum t
{ {
none, //process by nana none, ///< process by nana
tabstop, //move to the next tabstop window tabstop, ///< move to the next tabstop window
eating, //process by current window eating, ///< process by current window
}; };
}; };
//struct basic_window /// a window data structure descriptor
//@brief: a window data structure descriptor
struct basic_window struct basic_window
: public events_holder : public events_holder
{ {
@ -87,8 +87,7 @@ namespace detail
bool rendered; bool rendered;
}; };
//basic_window /// constructor for the root window
//@brief: constructor for the root window
basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&&, category::root_tag**); basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&&, category::root_tag**);
template<typename Category> template<typename Category>
@ -105,8 +104,7 @@ namespace detail
~basic_window(); ~basic_window();
//bind_native_window /// bind a native window and baisc_window
//@brief: bind a native window and baisc_window
void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&); void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&);
void frame_window(native_window_type); void frame_window(native_window_type);
@ -115,13 +113,13 @@ namespace detail
bool visible_parents() const; bool visible_parents() const;
bool displayed() const; bool displayed() const;
bool belong_to_lazy() const; bool belong_to_lazy() const;
const basic_window * child_caret() const; //Returns a child which owns a caret const basic_window * child_caret() const; ///< Returns the child which owns the caret
bool is_draw_through() const; ///< Determines whether it is a draw-through window. bool is_draw_through() const; ///< Determines whether it is a draw-through window.
basic_window * seek_non_lite_widget_ancestor() const; basic_window * seek_non_lite_widget_ancestor() const;
public: public:
//Override event_holder /// Override event_holder
bool set_events(const std::shared_ptr<general_events>&) override; bool set_events(const std::shared_ptr<general_events>&) override;
general_events * get_events() const override; general_events * get_events() const override;
private: private:
@ -131,7 +129,7 @@ namespace detail
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_LINUX) || defined(NANA_MACOS)
point pos_native; point pos_native;
#endif #endif
point pos_root; //coordinate for root window point pos_root; ///< coordinates of the root window
point pos_owner; point pos_owner;
size dimension; size dimension;
::nana::size min_track_size; ::nana::size min_track_size;
@ -146,9 +144,9 @@ namespace detail
basic_window *owner; basic_window *owner;
native_string_type title; native_string_type title;
::nana::detail::drawer drawer; //Self Drawer with owen graphics ::nana::detail::drawer drawer; ///< Self Drawer with owen graphics
basic_window* root_widget; //A pointer refers to the root basic window, if the window is a root, the pointer refers to itself. basic_window* root_widget; ///< A pointer refers to the root basic window, if the window is a root, the pointer refers to itself.
paint::graphics* root_graph; //Refer to the root buffer graphics paint::graphics* root_graph; ///< Refer to the root buffer graphics
cursor predef_cursor; cursor predef_cursor;
std::unique_ptr<widget_notifier_interface> widget_notifier; std::unique_ptr<widget_notifier_interface> widget_notifier;
@ -156,20 +154,20 @@ namespace detail
{ {
bool enabled :1; bool enabled :1;
bool dbl_click :1; bool dbl_click :1;
bool captured :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle bool captured :1; ///< if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
bool modal :1; bool modal :1;
bool take_active:1; //If take_active is false, other.active_window still keeps the focus. bool take_active:1; ///< If take_active is false, other.active_window still keeps the focus.
bool refreshing :1; bool refreshing :1;
bool destroying :1; bool destroying :1;
bool dropable :1; //Whether the window has make mouse_drop event. bool dropable :1; ///< Whether the window has make mouse_drop event.
bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen. bool fullscreen :1; ///< When the window is maximizing whether it fit for fullscreen.
bool borderless :1; bool borderless :1;
bool make_bground_declared : 1; //explicitly make bground for bground effects bool make_bground_declared : 1; ///< explicitly make bground for bground effects
bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus. bool ignore_menubar_focus : 1; ///< A flag indicates whether the menubar sets the focus.
bool ignore_mouse_focus : 1; //A flag indicates whether the widget accepts focus when clicking on it bool ignore_mouse_focus : 1; ///< A flag indicates whether the widget accepts focus when clicking on it
bool space_click_enabled : 1; //A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key. bool space_click_enabled : 1; ///< A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key.
unsigned Reserved :18; unsigned Reserved :18;
unsigned char tab; //indicate a window that can receive the keyboard TAB unsigned char tab; ///< indicate a window that can receive the keyboard TAB
mouse_action action; mouse_action action;
}flags; }flags;
@ -198,7 +196,7 @@ namespace detail
struct attr_root_tag struct attr_root_tag
{ {
container frames; //initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame container frames; ///< initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame
container tabstop; container tabstop;
std::vector<edge_nimbus_action> effects_edge_nimbus; std::vector<edge_nimbus_action> effects_edge_nimbus;
basic_window* focus{nullptr}; basic_window* focus{nullptr};
@ -210,13 +208,13 @@ namespace detail
cursor state_cursor{nana::cursor::arrow}; cursor state_cursor{nana::cursor::arrow};
basic_window* state_cursor_window{ nullptr }; basic_window* state_cursor_window{ nullptr };
std::function<void()> draw_through; // A draw through renderer for root widgets. std::function<void()> draw_through; ///< A draw through renderer for root widgets.
}; };
const category::flags category; const category::flags category;
basic_window *active_window; //if flags.take_active is false, the active_window still keeps the focus, basic_window *active_window; ///< if flags.take_active is false, the active_window still keeps the focus,
//if the active_window is null, the parent of this window keeps focus. ///< if the active_window is null, the parent of this window keeps focus.
paint::graphics glass_buffer; //if effect.bground is avaiable. Refer to window_layout::make_bground. paint::graphics glass_buffer; ///< if effect.bground is avaiable. Refer to window_layout::make_bground.
update_state upd_state; update_state upd_state;
union union
@ -229,13 +227,14 @@ namespace detail
~other_tag(); ~other_tag();
}other; }other;
native_window_type root; //root Window handle native_window_type root; ///< root Window handle
unsigned thread_id; //the identifier of the thread that created the window. unsigned thread_id; ///< the identifier of the thread that created the window.
unsigned index; unsigned index;
container children; container children;
}; };
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -1,4 +1,4 @@
/* /**
* A Bedrock Implementation * A Bedrock 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-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,7 +7,9 @@
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/detail/bedrock.hpp * @file nana/gui/detail/bedrock.hpp
*
* @brief A Bedrock Implementation
*/ */
#ifndef NANA_GUI_DETAIL_BEDROCK_HPP #ifndef NANA_GUI_DETAIL_BEDROCK_HPP
@ -25,12 +27,14 @@ namespace detail
struct basic_window; struct basic_window;
class window_manager; class window_manager;
//class bedrock
//@brief: bedrock is a fundamental core component, it provides a abstract to the OS platform /// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions.
// and some basic functions.
class bedrock class bedrock
{ {
bedrock(); bedrock();
bedrock(const bedrock&) = delete;
bedrock& operator=(const bedrock&) = delete;
public: public:
using core_window_t = basic_window; using core_window_t = basic_window;

View File

@ -1,6 +1,8 @@
#ifndef NANA_DETAIL_BEDROCK_PI_DATA_HPP #ifndef NANA_DETAIL_BEDROCK_PI_DATA_HPP
#define NANA_DETAIL_BEDROCK_PI_DATA_HPP #define NANA_DETAIL_BEDROCK_PI_DATA_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/gui/detail/bedrock.hpp> #include <nana/gui/detail/bedrock.hpp>
#include "color_schemes.hpp" #include "color_schemes.hpp"
#include "events_operation.hpp" #include "events_operation.hpp"
@ -30,4 +32,7 @@ namespace nana
}; };
} }
} }
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -13,6 +13,7 @@
#ifndef NANA_GUI_DETAIL_DRAWER_HPP #ifndef NANA_GUI_DETAIL_DRAWER_HPP
#define NANA_GUI_DETAIL_DRAWER_HPP #define NANA_GUI_DETAIL_DRAWER_HPP
#include <nana/push_ignore_diagnostic>
#include <vector> #include <vector>
#include "general_events.hpp" #include "general_events.hpp"
#include <nana/paint/graphics.hpp> #include <nana/paint/graphics.hpp>
@ -170,4 +171,6 @@ namespace nana
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -15,9 +15,13 @@
#include <nana/gui/element.hpp> #include <nana/gui/element.hpp>
#include <nana/pat/cloneable.hpp> #include <nana/pat/cloneable.hpp>
#include <map> #include <map>
#include <string> #include <string>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
namespace detail namespace detail
@ -48,5 +52,6 @@ namespace detail
}; };
}//end namespace detail }//end namespace detail
} }
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,8 @@
#ifndef NANA_DETAIL_GENERAL_EVENTS_HPP #ifndef NANA_DETAIL_GENERAL_EVENTS_HPP
#define NANA_DETAIL_GENERAL_EVENTS_HPP #define NANA_DETAIL_GENERAL_EVENTS_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/gui/basis.hpp> #include <nana/gui/basis.hpp>
#include "event_code.hpp" #include "event_code.hpp"
#include "internal_scope_guard.hpp" #include "internal_scope_guard.hpp"
@ -84,7 +86,7 @@ namespace nana
}; };
}//end namespace detail }//end namespace detail
/// base clase for all event argument types /// base class for all event argument types
class event_arg class event_arg
{ {
public: public:
@ -99,7 +101,14 @@ namespace nana
struct general_events; struct general_events;
/// the type of the members of general_events /** @brief the type of the members of general_events.
*
* It connect the functions to be called as response to the event and manages that chain of responses
* It is a functor, that get called to connect a "normal" response function, with normal "priority".
* If a response function need another priority (unignorable or called first) it will need to be connected with
* the specific connect function not with the operator()
* It also permit to "emit" that event, calling all the active responders.
*/
template<typename Arg> template<typename Arg>
class basic_event : public detail::event_base class basic_event : public detail::event_base
{ {
@ -108,7 +117,8 @@ namespace nana
private: private:
struct docker struct docker
: public detail::docker_base : public detail::docker_base
{ {
/// the callback/response function taking the typed argument
std::function<void(arg_reference)> invoke; std::function<void(arg_reference)> invoke;
docker(basic_event * evt, std::function<void(arg_reference)> && ivk, bool unignorable_flag) docker(basic_event * evt, std::function<void(arg_reference)> && ivk, bool unignorable_flag)
@ -125,10 +135,10 @@ namespace nana
event_handle connect_front(Function && fn) event_handle connect_front(Function && fn)
{ {
using prototype = typename std::remove_reference<Function>::type; using prototype = typename std::remove_reference<Function>::type;
return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true); return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true);
} }
/// It will not get called if stop_propagation() was called.
event_handle connect(void (*fn)(arg_reference)) event_handle connect(void (*fn)(arg_reference))
{ {
return connect([fn](arg_reference arg){ return connect([fn](arg_reference arg){
@ -136,12 +146,11 @@ namespace nana
}); });
} }
/// It will not get called if stop_propagation() was called. /// It will not get called if stop_propagation() was called, because it is set at the end of the chain..
template<typename Function> template<typename Function>
event_handle connect(Function && fn) event_handle connect(Function && fn)
{ {
using prototype = typename std::remove_reference<Function>::type; using prototype = typename std::remove_reference<Function>::type;
return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false); return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false);
} }
@ -193,7 +202,6 @@ namespace nana
continue; continue;
static_cast<docker*>(*i)->invoke(arg); static_cast<docker*>(*i)->invoke(arg);
if (window_handle && (!detail::check_window(window_handle))) if (window_handle && (!detail::check_window(window_handle)))
break; break;
} }
@ -378,11 +386,11 @@ namespace nana
} }
}; };
}; };
struct arg_mouse struct arg_mouse
: public event_arg : public event_arg
{ {
event_code evt_code; ///< event_code evt_code; ///< what kind of mouse event?
::nana::window window_handle; ///< A handle to the event window ::nana::window window_handle; ///< A handle to the event window
::nana::point pos; ///< cursor position in the event window ::nana::point pos; ///< cursor position in the event window
::nana::mouse button; ///< indicates a button which triggers the event ::nana::mouse button; ///< indicates a button which triggers the event
@ -401,7 +409,8 @@ namespace nana
} }
}; };
/// in arg_wheel event_code is event_code::mouse_wheel /// \brief in arg_wheel event_code is event_code::mouse_wheel
/// The type arg_wheel is derived from arg_mouse, a handler /// The type arg_wheel is derived from arg_mouse, a handler
/// with prototype void(const arg_mouse&) can be set for mouse_wheel. /// with prototype void(const arg_mouse&) can be set for mouse_wheel.
struct arg_wheel : public arg_mouse struct arg_wheel : public arg_mouse
@ -487,11 +496,11 @@ namespace nana
{ {
::nana::window window_handle; ///< A handle to the event window ::nana::window window_handle; ///< A handle to the event window
}; };
/// a higher level event argument than just mouse down
struct arg_click : public event_arg struct arg_click : public event_arg
{ {
::nana::window window_handle; ///< A handle to the event window ::nana::window window_handle; ///< A handle to the event window
const arg_mouse* mouse_args; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise. const arg_mouse* mouse_args{}; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise.
}; };
/// provides some fundamental events that every widget owns. /// provides some fundamental events that every widget owns.
@ -531,4 +540,6 @@ namespace nana
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -25,6 +25,8 @@
#include <map> #include <map>
#include <iterator> #include <iterator>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -288,4 +290,6 @@ namespace nana
};//end class handle_manager };//end class handle_manager
}//end namespace detail }//end namespace detail
}// end namespace nana }// end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -14,6 +14,7 @@
#ifndef NANA_GUI_INNER_FWD_IMPLEMENT_HPP #ifndef NANA_GUI_INNER_FWD_IMPLEMENT_HPP
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP #define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
#include <nana/push_ignore_diagnostic>
#include "inner_fwd.hpp" #include "inner_fwd.hpp"
#include "basic_window.hpp" #include "basic_window.hpp"
#include "../../paint/graphics.hpp" #include "../../paint/graphics.hpp"
@ -173,4 +174,7 @@ namespace nana{
}; };
} }
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_GUI_INNER_FWD_IMPLEMENT_HPP #endif //NANA_GUI_INNER_FWD_IMPLEMENT_HPP

View File

@ -1,7 +1,7 @@
/* /*
* Forward Declaration of Internal Scope Guard * Forward Declaration of Internal Scope Guard
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -26,6 +26,18 @@ namespace nana
internal_scope_guard(); internal_scope_guard();
~internal_scope_guard(); ~internal_scope_guard();
}; };
class internal_revert_guard
{
internal_revert_guard(const internal_revert_guard&) = delete;
internal_revert_guard(internal_revert_guard&&) = delete;
internal_revert_guard& operator=(const internal_revert_guard&) = delete;
internal_revert_guard& operator=(internal_revert_guard&&) = delete;
public:
internal_revert_guard();
~internal_revert_guard();
};
} }
#endif #endif

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-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -36,6 +36,9 @@ namespace detail
using native_string_type = ::nana::detail::native_string_type; using native_string_type = ::nana::detail::native_string_type;
//Execute a function in a thread which is associated with the specified native window.
static void affinity_execute(native_window_type, const std::function<void()>&);
static nana::size primary_monitor_size(); static nana::size primary_monitor_size();
static rectangle screen_area_from_point(const point&); static rectangle screen_area_from_point(const point&);
static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&); static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&);

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP #ifndef NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP
#define NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP #define NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/gui/basis.hpp> #include <nana/gui/basis.hpp>
#include <vector> #include <vector>
@ -84,5 +85,7 @@ namespace detail
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP #endif //NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP

View File

@ -1,7 +1,7 @@
/* /*
* Window Manager Implementation * Window Manager Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -18,6 +18,8 @@
#ifndef NANA_GUI_DETAIL_WINDOW_MANAGER_HPP #ifndef NANA_GUI_DETAIL_WINDOW_MANAGER_HPP
#define NANA_GUI_DETAIL_WINDOW_MANAGER_HPP #define NANA_GUI_DETAIL_WINDOW_MANAGER_HPP
#include <nana/push_ignore_diagnostic>
#include <vector> #include <vector>
#include "window_layout.hpp" #include "window_layout.hpp"
#include "event_code.hpp" #include "event_code.hpp"
@ -129,7 +131,7 @@ namespace detail
bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr); bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr);
void refresh_tree(core_window_t*); void refresh_tree(core_window_t*);
bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen); bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen, bool refresh_tree = false);
bool get_graphics(core_window_t*, nana::paint::graphics&); bool get_graphics(core_window_t*, nana::paint::graphics&);
bool get_visual_rectangle(core_window_t*, nana::rectangle&); bool get_visual_rectangle(core_window_t*, nana::rectangle&);
@ -195,4 +197,7 @@ namespace detail
};//end class window_manager };//end class window_manager
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_DRAGGER_HPP #ifndef NANA_GUI_DRAGGER_HPP
#define NANA_GUI_DRAGGER_HPP #define NANA_GUI_DRAGGER_HPP
#include <nana/push_ignore_diagnostic>
#include "basis.hpp" #include "basis.hpp"
#include "../basic_types.hpp" #include "../basic_types.hpp"
#include "../traits.hpp" #include "../traits.hpp"
@ -44,4 +45,5 @@ namespace nana
dragger_impl_t * impl_; dragger_impl_t * impl_;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -11,6 +11,8 @@
*/ */
#ifndef NANA_GUI_DRAWING_HPP #ifndef NANA_GUI_DRAWING_HPP
#define NANA_GUI_DRAWING_HPP #define NANA_GUI_DRAWING_HPP
#include <nana/push_ignore_diagnostic>
#include "widgets/widget.hpp" #include "widgets/widget.hpp"
#include "../traits.hpp" #include "../traits.hpp"
namespace nana namespace nana
@ -46,4 +48,6 @@ namespace nana
window handle_; window handle_;
};//end class drawing };//end class drawing
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_ELEMENT_HPP #ifndef NANA_GUI_ELEMENT_HPP
#define NANA_GUI_ELEMENT_HPP #define NANA_GUI_ELEMENT_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/paint/graphics.hpp> #include <nana/paint/graphics.hpp>
#include <nana/pat/cloneable.hpp> #include <nana/pat/cloneable.hpp>
#include <vector> #include <vector>
@ -348,4 +349,5 @@ namespace nana
}//end namespace element }//end namespace element
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_GUI_ELEMENT_HPP #endif //NANA_GUI_ELEMENT_HPP

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_MSGBOX_HPP #ifndef NANA_GUI_MSGBOX_HPP
#define NANA_GUI_MSGBOX_HPP #define NANA_GUI_MSGBOX_HPP
#include <nana/push_ignore_diagnostic>
#include <sstream> #include <sstream>
@ -253,5 +254,6 @@ namespace nana
::nana::rectangle valid_areas_[4]; ::nana::rectangle valid_areas_[4];
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -14,6 +14,7 @@
#define NANA_GUI_NOTIFIER_HPP #define NANA_GUI_NOTIFIER_HPP
#include <nana/gui/basis.hpp> #include <nana/gui/basis.hpp>
#include <nana/gui/detail/general_events.hpp> #include <nana/gui/detail/general_events.hpp>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -65,4 +66,5 @@ namespace nana
implement * impl_; implement * impl_;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -15,6 +15,7 @@
#ifndef NANA_GUI_PLACE_HPP #ifndef NANA_GUI_PLACE_HPP
#define NANA_GUI_PLACE_HPP #define NANA_GUI_PLACE_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/gui/basis.hpp> #include <nana/gui/basis.hpp>
#include <utility> #include <utility>
#include <memory> #include <memory>
@ -145,5 +146,6 @@ namespace nana
implement * impl_; implement * impl_;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //#ifndef NANA_GUI_PLACE_HPP #endif //#ifndef NANA_GUI_PLACE_HPP

View File

@ -60,6 +60,8 @@ namespace API
//@brief: The interfaces defined in namespace dev are used for developing the nana.gui //@brief: The interfaces defined in namespace dev are used for developing the nana.gui
namespace dev namespace dev
{ {
void affinity_execute(window window_handle, const std::function<void()>&);
bool set_events(window, const std::shared_ptr<general_events>&); bool set_events(window, const std::shared_ptr<general_events>&);
template<typename Scheme> template<typename Scheme>
@ -153,9 +155,17 @@ namespace API
}; };
}//end namespace detail }//end namespace detail
void exit(); void exit(); ///< close all windows in current thread
void exit_all(); ///< close all windows
std::string transform_shortkey_text(std::string text, wchar_t &shortkey, std::string::size_type *skpos); /// @brief Searchs whether the text contains a '&' and removes the character for transforming.
/// If the text contains more than one '&' charachers, the others are ignored. e.g
/// text = "&&a&bcd&ef", the result should be "&abcdef", shortkey = 'b', and pos = 2.
std::string transform_shortkey_text
( std::string text, ///< the text is transformed
wchar_t &shortkey, ///< the character which indicates a short key.
std::string::size_type *skpos ///< retrives the shortkey position if it is not a null_ptr;
);
bool register_shortkey(window, unsigned long); bool register_shortkey(window, unsigned long);
void unregister_shortkey(window); void unregister_shortkey(window);

View File

@ -16,6 +16,7 @@
#ifndef NANA_GUI_TIMER_HPP #ifndef NANA_GUI_TIMER_HPP
#define NANA_GUI_TIMER_HPP #define NANA_GUI_TIMER_HPP
#include <nana/gui/detail/general_events.hpp> #include <nana/gui/detail/general_events.hpp>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -58,4 +59,5 @@ namespace nana
implement * const impl_; implement * const impl_;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -14,6 +14,8 @@
#define NANA_GUI_WIDGET_BUTTON_HPP #define NANA_GUI_WIDGET_BUTTON_HPP
#include "widget.hpp" #include "widget.hpp"
#include <nana/gui/element.hpp> #include <nana/gui/element.hpp>
#include <nana/push_ignore_diagnostic>
namespace nana{ namespace nana{
namespace drawerbase namespace drawerbase
@ -105,5 +107,7 @@ namespace nana{
void _m_caption(native_string_type&&) override; void _m_caption(native_string_type&&) override;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -16,6 +16,7 @@
#include <nana/gui/widgets/widget.hpp> #include <nana/gui/widgets/widget.hpp>
#include <nana/pat/cloneable.hpp> #include <nana/pat/cloneable.hpp>
#include <nana/any.hpp> #include <nana/any.hpp>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -141,7 +142,7 @@ namespace nana
void mouse_leave(graph_reference, const arg_mouse&) override; void mouse_leave(graph_reference, const arg_mouse&) override;
private: private:
std::unique_ptr<event_agent_interface> event_agent_; std::unique_ptr<event_agent_interface> event_agent_;
scheme * scheme_; scheme * scheme_{nullptr};
}; };
}//end namespace categorize }//end namespace categorize
}//end namespace drawerbase }//end namespace drawerbase
@ -258,5 +259,5 @@ namespace nana
} }
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,8 @@
#ifndef NANA_GUI_WIDGET_CHECKBOX_HPP #ifndef NANA_GUI_WIDGET_CHECKBOX_HPP
#define NANA_GUI_WIDGET_CHECKBOX_HPP #define NANA_GUI_WIDGET_CHECKBOX_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -106,5 +108,6 @@ namespace drawerbase
std::vector<element_tag> ui_container_; std::vector<element_tag> ui_container_;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_WIDGETS_COMBOX_HPP #ifndef NANA_GUI_WIDGETS_COMBOX_HPP
#define NANA_GUI_WIDGETS_COMBOX_HPP #define NANA_GUI_WIDGETS_COMBOX_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include "float_listbox.hpp" #include "float_listbox.hpp"
#include "skeletons/text_editor_part.hpp" #include "skeletons/text_editor_part.hpp"
@ -227,4 +228,5 @@ namespace nana
nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override; nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override;
}; };
} }
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,7 +12,7 @@
#ifndef NANA_GUI_WIDGETS_DATE_CHOOSER_HPP #ifndef NANA_GUI_WIDGETS_DATE_CHOOSER_HPP
#define NANA_GUI_WIDGETS_DATE_CHOOSER_HPP #define NANA_GUI_WIDGETS_DATE_CHOOSER_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include <nana/datetime.hpp> #include <nana/datetime.hpp>
@ -79,5 +79,6 @@ namespace nana
void weekstr(unsigned index, ::std::string);///<Set the week strings which will be displayed for day, index is in range of [0, 6] void weekstr(unsigned index, ::std::string);///<Set the week strings which will be displayed for day, index is in range of [0, 6]
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP #ifndef NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP
#define NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP #define NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP
#include <stack> #include <stack>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -515,4 +516,6 @@ namespace detail
}//end namespace detail }//end namespace detail
}//end namespace widgets }//end namespace widgets
}//end namesace nana }//end namesace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP #ifndef NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP
#define NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP #define NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include <vector> #include <vector>
@ -101,5 +102,6 @@ namespace nana
std::size_t index() const; std::size_t index() const;
}; };
} }
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,8 +12,9 @@
#ifndef NANA_GUI_WIDGET_LABEL_HPP #ifndef NANA_GUI_WIDGET_LABEL_HPP
#define NANA_GUI_WIDGET_LABEL_HPP #define NANA_GUI_WIDGET_LABEL_HPP
#include "widget.hpp"
#include "widget.hpp"
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -80,4 +81,6 @@ namespace nana
void _m_caption(native_string_type&&) override; void _m_caption(native_string_type&&) override;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -17,6 +17,8 @@
#ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP
#define NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include "detail/inline_widget.hpp" #include "detail/inline_widget.hpp"
#include <nana/pat/abstract_factory.hpp> #include <nana/pat/abstract_factory.hpp>
@ -295,7 +297,18 @@ namespace nana
throw std::runtime_error("listbox::item_proxy.value<T>() invalid type of value"); throw std::runtime_error("listbox::item_proxy.value<T>() invalid type of value");
return *p; return *p;
} }
template<typename T>
T & value()
{
auto * pany = _m_value();
if (nullptr == pany)
throw std::runtime_error("listbox::item_proxy.value<T>() is empty");
T * p = any_cast<T>(_m_value(false));
if (nullptr == p)
throw std::runtime_error("listbox::item_proxy.value<T>() invalid type of value");
return *p;
}
template<typename T> template<typename T>
item_proxy & value(T&& t) item_proxy & value(T&& t)
{ {
@ -503,9 +516,7 @@ namespace nana
{ {
basic_event<arg_listbox> checked; basic_event<arg_listbox> checked;
basic_event<arg_listbox> selected; basic_event<arg_listbox> selected;
basic_event<arg_listbox_category> category_dbl_click; ///< An event occurs when a listbox category is double clicking.
/// An event occurs when a listbox category is double clicking.
basic_event<arg_listbox_category> category_dbl_click;
}; };
struct scheme struct scheme
@ -516,26 +527,40 @@ namespace nana
color_proxy header_floated{ static_cast<color_rgb>(0xBABBBC)}; color_proxy header_floated{ static_cast<color_rgb>(0xBABBBC)};
color_proxy item_selected{ static_cast<color_rgb>(0xD5EFFC) }; color_proxy item_selected{ static_cast<color_rgb>(0xD5EFFC) };
unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ?? /// \todo how to implement some geometrical parameters ??
ext_w = 5; unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this
unsigned min_header_width{ 20 }; ///< non counting suspension_width
unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...")
unsigned ext_w { 5 }; ///< ??
unsigned header_height { 20 }; ///< header height header_size
unsigned text_height { 0 }; ///< the trigger will set this to the height of the text font
unsigned item_height_ex { 6 }; ///< 6? item_height = text_height + item_height_ex
unsigned item_height { 0 }; ///< the trigger will set this TO item_height = text_height + item_height_ex
unsigned header_mouse_spliter_area_before{ 2 };
unsigned header_mouse_spliter_area_after { 3 };
}; };
} }
}//end namespace drawerbase }//end namespace drawerbase
/*! \class listbox /*! \class listbox
\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. \brief A rectangle containing a list of strings from which the user can select.
A category is a text with can be \a selected, \a checked and \a expanded to show the items. This widget contain a list of \a categories, with in turn contain a list of \a items.
An item is formed by \a column-fields, each corresponding to one of the \a headers. A \a category is a text with can be \a selected, \a checked and \a expanded to show the \a items.
An item can be \a selected and \a checked. An \a item is formed by \a column-fields, each corresponding to one of the \a headers.
An \a item can be \a selected and \a checked.
The user can \a drag the header to \a resize it or to \a reorganize it. The user can \a drag the header to \a resize it or to \a reorganize it.
By \a clicking on one header the list get \a reordered, first up, and then down alternatively. By \a clicking on one header the list get \a reordered, first up, and then down alternatively.
1. The resolver is used to resolute an object of the specified type for a listbox item. 1. The resolver is used to resolute an object of the specified type into (or back from) a listbox item.
3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. 3. nana::listbox creates the category 0 by default.
This is an special category, becouse it is invisible, while the associated items are visible.
The optional, user-created categories begin at index 1 and are visibles.
The member functions without the categ parameter operate the items that belong to category 0.
4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: 4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement:
Irreflexivity (comp(x, x) returns false) Irreflexivity (comp(x, x) returns false)
and and
antisymmetry(comp(a, b) != comp(b, a) returns true) Antisymmetry(comp(a, b) != comp(b, a) returns true)
A simple example. A simple example.
bool sort_compare( const std::string& s1, nana::any*, bool sort_compare( const std::string& s1, nana::any*,
const std::string& s2, nana::any*, bool reverse) const std::string& s2, nana::any*, bool reverse)
@ -550,10 +575,10 @@ By \a clicking on one header the list get \a reordered, first up, and then down
{ {
if(o1 && o2) //some items may not attach a customer object. if(o1 && o2) //some items may not attach a customer object.
{ {
int * i1 = o1->get<int>(); int * i1 = any_cast<int>(*o1);
int * i2 = o2->get<int>(); int * i2 = any_cast<int>(*o2);
return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2)); return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2));
;//some types may not be int. // ^ some types may not be int.
} }
return false; return false;
} }
@ -697,7 +722,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down
size_type size_categ() const; ///<Get the number of categories size_type size_categ() const; ///<Get the number of categories
size_type size_item() const; ///<The number of items in the default category size_type size_item() const; ///<The number of items in the default category
size_type size_item(size_type cat) const; ///<The number of items in category "cat" size_type size_item(size_type cat) const; ///<The number of items in category "cat"
void enable_single(bool for_selection, bool category_limited); void enable_single(bool for_selection, bool category_limited);
void disable_single(bool for_selection); void disable_single(bool for_selection);
@ -709,4 +734,6 @@ By \a clicking on one header the list get \a reordered, first up, and then down
void _m_erase_key(nana::detail::key_interface*); void _m_erase_key(nana::detail::key_interface*);
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -17,6 +17,8 @@
#include <nana/gui/timer.hpp> #include <nana/gui/timer.hpp>
#include <nana/pat/cloneable.hpp> #include <nana/pat/cloneable.hpp>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
namespace drawerbase namespace drawerbase
@ -198,4 +200,6 @@ namespace nana
detail::popuper menu_popuper(menu&, mouse = mouse::right_button); detail::popuper menu_popuper(menu&, mouse = mouse::right_button);
detail::popuper menu_popuper(menu&, window owner, const point&, mouse = mouse::right_button); detail::popuper menu_popuper(menu&, window owner, const point&, mouse = mouse::right_button);
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -14,6 +14,7 @@
#define NANA_GUI_WIDGETS_MENUBAR_HPP #define NANA_GUI_WIDGETS_MENUBAR_HPP
#include "widget.hpp" #include "widget.hpp"
#include "menu.hpp" #include "menu.hpp"
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -117,4 +118,6 @@ namespace nana
::nana::event_handle evt_resized_{nullptr}; ::nana::event_handle evt_resized_{nullptr};
};//end class menubar };//end class menubar
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -13,6 +13,8 @@
*/ */
#ifndef NANA_GUI_WIDGET_PICTURE_HPP #ifndef NANA_GUI_WIDGET_PICTURE_HPP
#define NANA_GUI_WIDGET_PICTURE_HPP #define NANA_GUI_WIDGET_PICTURE_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
namespace nana namespace nana
@ -67,4 +69,6 @@ namespace nana
bool transparent() const; bool transparent() const;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -15,6 +15,7 @@
#include "widget.hpp" #include "widget.hpp"
#include <nana/gui/timer.hpp> #include <nana/gui/timer.hpp>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -502,4 +503,5 @@ namespace nana
} }
};//end class scroll };//end class scroll
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -13,6 +13,8 @@
#ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP #ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
#define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP #define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
#include <nana/push_ignore_diagnostic>
#include "textbase.hpp" #include "textbase.hpp"
#include "text_editor_part.hpp" #include "text_editor_part.hpp"
#include <nana/gui/widgets/scroll.hpp> #include <nana/gui/widgets/scroll.hpp>
@ -218,7 +220,7 @@ namespace nana{ namespace widgets
void set_end_caret(); void set_end_caret();
bool hit_text_area(const point&) const; bool hit_text_area(const point&) const;
bool hit_select_area(nana::upoint pos) const; bool hit_select_area(nana::upoint pos, bool ignore_when_select_all) const;
bool move_select(); bool move_select();
bool mask(wchar_t); bool mask(wchar_t);
@ -358,12 +360,11 @@ namespace nana{ namespace widgets
struct selection struct selection
{ {
enum class mode{ no_selected, mouse_selected, method_selected }; enum class mode{ no_selected, mouse_selected, method_selected, move_selected };
text_focus_behavior behavior; text_focus_behavior behavior;
bool move_to_end; bool move_to_end;
mode mode_selection; mode mode_selection;
bool dragged;
bool ignore_press; bool ignore_press;
nana::upoint a, b; nana::upoint a, b;
}select_; }select_;
@ -380,5 +381,7 @@ namespace nana{ namespace widgets
}//end namespace widgets }//end namespace widgets
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -21,6 +21,8 @@
#include <stack> #include <stack>
#include <stdexcept> #include <stdexcept>
#include <nana/push_ignore_diagnostic>
namespace nana{ namespace widgets{ namespace skeletons namespace nana{ namespace widgets{ namespace skeletons
{ {
//The tokens are defined for representing a text, the tokens are divided //The tokens are defined for representing a text, the tokens are divided
@ -177,13 +179,24 @@ namespace nana{ namespace widgets{ namespace skeletons
return token::tag_begin; return token::tag_begin;
} }
//Escape //Escape
if(ch == '\\') if(this->format_enabled_ && (ch == '\\'))
{ {
if(iptr_ + 1 < endptr_) if(iptr_ + 1 < endptr_)
{ {
ch = *(iptr_ + 1); ch = *(iptr_ + 1);
iptr_ += 2;
if ('<' == ch || '>' == ch) //two characters need to be escaped.
{
iptr_ += 2;
}
else
{
//ignore escape
ch = '\\';
iptr_++;
}
} }
else else
{ {
@ -191,8 +204,8 @@ namespace nana{ namespace widgets{ namespace skeletons
return token::eof; return token::eof;
} }
} }
else
++iptr_; ++iptr_;
idstr_.clear(); idstr_.clear();
idstr_.append(1, ch); idstr_.append(1, ch);
@ -260,6 +273,8 @@ namespace nana{ namespace widgets{ namespace skeletons
return token::eof; return token::eof;
} }
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || '_' == ch) if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || '_' == ch)
{ {
--iptr_; --iptr_;
@ -926,4 +941,5 @@ namespace nana{ namespace widgets{ namespace skeletons
}//end namespace skeletons }//end namespace skeletons
}//end namespace widgets }//end namespace widgets
}//end namepsace nana }//end namepsace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM #endif //NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM

View File

@ -13,6 +13,7 @@
#ifndef NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP #ifndef NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP
#define NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP #define NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/charset.hpp> #include <nana/charset.hpp>
#include <nana/basic_types.hpp> #include <nana/basic_types.hpp>
@ -536,4 +537,6 @@ namespace skeletons
}//end namespace detail }//end namespace detail
}//end namespace widgets }//end namespace widgets
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -11,6 +11,9 @@
*/ */
#ifndef NANA_GUI_WIDGETS_SLIDER_HPP #ifndef NANA_GUI_WIDGETS_SLIDER_HPP
#define NANA_GUI_WIDGETS_SLIDER_HPP #define NANA_GUI_WIDGETS_SLIDER_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include <nana/pat/cloneable.hpp> #include <nana/pat/cloneable.hpp>
@ -111,7 +114,7 @@ namespace nana
}; };
}//end namespace slider }//end namespace slider
}//end namespace drawerbase }//end namespace drawerbase
/// A slider widget wich the user can drag for tracking /// A slider widget wich the user can drag for tracking \todo add scheme ?
class slider class slider
: public widget_object<category::widget_tag, drawerbase::slider::trigger, drawerbase::slider::slider_events> : public widget_object<category::widget_tag, drawerbase::slider::trigger, drawerbase::slider::slider_events>
{ {
@ -141,5 +144,6 @@ namespace nana
bool transparent() const; bool transparent() const;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,8 @@
#ifndef NANA_GUI_WIDGET_SPINBOX_HPP #ifndef NANA_GUI_WIDGET_SPINBOX_HPP
#define NANA_GUI_WIDGET_SPINBOX_HPP #define NANA_GUI_WIDGET_SPINBOX_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include "skeletons/text_editor_part.hpp" #include "skeletons/text_editor_part.hpp"
@ -68,7 +70,7 @@ namespace nana
private: private:
implementation * const impl_; implementation * const impl_;
}; };
}; }
}//end namespace drawerbase }//end namespace drawerbase
/// Spinbox Widget /// Spinbox Widget
@ -110,5 +112,5 @@ namespace nana
void _m_caption(native_string_type&&); void _m_caption(native_string_type&&);
}; //end class spinbox }; //end class spinbox
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_GUI_WIDGET_SPINBOX_HPP #endif //NANA_GUI_WIDGET_SPINBOX_HPP

View File

@ -13,6 +13,8 @@
*/ */
#ifndef NANA_GUI_WIDGET_TABBAR_HPP #ifndef NANA_GUI_WIDGET_TABBAR_HPP
#define NANA_GUI_WIDGET_TABBAR_HPP #define NANA_GUI_WIDGET_TABBAR_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include <nana/pat/cloneable.hpp> #include <nana/pat/cloneable.hpp>
#include <nana/any.hpp> #include <nana/any.hpp>
@ -410,5 +412,6 @@ namespace nana
void erase(std::size_t pos, bool close_attached = true); void erase(std::size_t pos, bool close_attached = true);
}; };
} }
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -11,6 +11,8 @@
*/ */
#ifndef NANA_GUI_WIDGET_TEXTBOX_HPP #ifndef NANA_GUI_WIDGET_TEXTBOX_HPP
#define NANA_GUI_WIDGET_TEXTBOX_HPP #define NANA_GUI_WIDGET_TEXTBOX_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/gui/widgets/widget.hpp> #include <nana/gui/widgets/widget.hpp>
#include "skeletons/textbase_export_interface.hpp" #include "skeletons/textbase_export_interface.hpp"
#include "skeletons/text_editor_part.hpp" #include "skeletons/text_editor_part.hpp"
@ -224,4 +226,6 @@ namespace nana
void _m_typeface(const paint::font&) override; void _m_typeface(const paint::font&) override;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -12,6 +12,7 @@
#ifndef NANA_GUI_WIDGET_TOOLBAR_HPP #ifndef NANA_GUI_WIDGET_TOOLBAR_HPP
#define NANA_GUI_WIDGET_TOOLBAR_HPP #define NANA_GUI_WIDGET_TOOLBAR_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
@ -101,4 +102,6 @@ namespace nana
bool detached_; bool detached_;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -17,6 +17,8 @@
#ifndef NANA_GUI_WIDGETS_TREEBOX_HPP #ifndef NANA_GUI_WIDGETS_TREEBOX_HPP
#define NANA_GUI_WIDGETS_TREEBOX_HPP #define NANA_GUI_WIDGETS_TREEBOX_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
#include "detail/compset.hpp" #include "detail/compset.hpp"
#include "detail/tree_cont.hpp" #include "detail/tree_cont.hpp"
@ -307,14 +309,14 @@ namespace nana
{ {
_m_value() = t; _m_value() = t;
return *this; return *this;
}; }
template<typename T> template<typename T>
item_proxy & value(T&& t) item_proxy & value(T&& t)
{ {
_m_value() = std::move(t); _m_value() = std::move(t);
return *this; return *this;
}; }
// Undocumentated methods for internal use // Undocumentated methods for internal use
trigger::node_type * _m_node() const; trigger::node_type * _m_node() const;
@ -452,4 +454,6 @@ namespace nana
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>
#endif #endif

View File

@ -12,6 +12,8 @@
#ifndef NANA_GUI_WIDGET_HPP #ifndef NANA_GUI_WIDGET_HPP
#define NANA_GUI_WIDGET_HPP #define NANA_GUI_WIDGET_HPP
#include <nana/push_ignore_diagnostic>
#include "../basis.hpp" #include "../basis.hpp"
#include "../programming_interface.hpp" #include "../programming_interface.hpp"
#include <nana/internationalization.hpp> #include <nana/internationalization.hpp>
@ -481,4 +483,6 @@ namespace nana
std::unique_ptr<scheme_type> scheme_; std::unique_ptr<scheme_type> scheme_;
};//end class widget_object<category::frame_tag> };//end class widget_object<category::frame_tag>
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -1,14 +1,14 @@
/* /**
* Nana GUI Library Definition * Nana GUI Library Definition
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/wvl.hpp * @file nana/gui/wvl.hpp
* @description: * @description
* the header file contains the files required for running of Nana.GUI * the header file contains the files required for running of Nana.GUI
*/ */
@ -22,6 +22,7 @@
#include "msgbox.hpp" #include "msgbox.hpp"
#include "place.hpp" #include "place.hpp"
namespace nana namespace nana
{ {
namespace detail namespace detail
@ -58,6 +59,25 @@ namespace nana
template<typename Form, bool IsVisible = true> template<typename Form, bool IsVisible = true>
using form_loader = detail::form_loader<Form, IsVisible>; using form_loader = detail::form_loader<Form, IsVisible>;
void exec(); /// @brief Take control of the GUI and optionaly automaticaly tests it.
///
/// @detail It transfers to nana the program flow control, which begin pumping messages
/// from the underlying OS, interpreting and sending it with suitable arguments
/// to the nana widgets that registered a response in the corresponding event.
/// It also accept arguments to be used in case of automatic GUI testing.
/// Other Way the arguments are ignored.
void exec(
unsigned wait = 1, ///< for the GUI to be constructed, in seconds
unsigned wait_end = 1, ///< for the GUI to be destructed, in seconds
std::function<void()> = {} ///< emit events to mimics user actions and may asert results
);
/// send a click message to this widget - useffull in GUI testing
void click(widget& w);
/// in seconds
void Wait(unsigned wait = 0);
}//end namespace nana }//end namespace nana
#endif #endif

View File

@ -13,6 +13,7 @@
#ifndef NANA_PAT_CLONEABLE_HPP #ifndef NANA_PAT_CLONEABLE_HPP
#define NANA_PAT_CLONEABLE_HPP #define NANA_PAT_CLONEABLE_HPP
#include <nana/push_ignore_diagnostic>
#include <nana/c++defines.hpp> #include <nana/c++defines.hpp>
#include <cstddef> #include <cstddef>
#include <type_traits> #include <type_traits>
@ -97,9 +98,7 @@ namespace nana{ namespace pat{
typedef int inner_bool::* operator_bool_t; typedef int inner_bool::* operator_bool_t;
template<typename U> template<typename U>
struct member_enabled using member_enabled = std::enable_if<(!std::is_base_of<cloneable, typename std::remove_reference<U>::type>::value) && std::is_base_of<base_t, typename std::remove_reference<U>::type>::value, int>;
: public std::enable_if<(!std::is_base_of<cloneable, typename std::remove_reference<U>::type>::value) && std::is_base_of<base_t, typename std::remove_reference<U>::type>::value, int>
{};
public: public:
cloneable() noexcept = default; cloneable() noexcept = default;
@ -207,5 +206,5 @@ namespace nana{ namespace pat{
using mutable_cloneable = cloneable<T, true>; using mutable_cloneable = cloneable<T, true>;
}//end namespace pat }//end namespace pat
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -0,0 +1,5 @@
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
# pragma GCC diagnostic pop
#endif

View File

@ -0,0 +1,4 @@
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Weffc++"
#endif

View File

@ -8,12 +8,12 @@
#include <windows.h> #include <windows.h>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <thread> //#include <thread>
#include <pthread.h> //#include <pthread.h>
#include <errno.h> #include <errno.h>
#include <cstdio> #include <cstdio>
// http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno.h#L53 // http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno.h#L53
#define EPROTO 71 /* Protocol error */ //#define EPROTO 71 /* Protocol error */
#include <mingw.thread.h> #include <mingw.thread.h>
#include <mingw.mutex.h> #include <mingw.mutex.h>
#else #else

View File

@ -5,6 +5,7 @@
#if defined(STD_THREAD_NOT_SUPPORTED) #if defined(STD_THREAD_NOT_SUPPORTED)
#if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
#include <mingw.thread.h> #include <mingw.thread.h>
#else #else
#include <boost/thread.hpp> #include <boost/thread.hpp>
@ -13,5 +14,11 @@ namespace std
typedef boost::thread thread; typedef boost::thread thread;
} }
#endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
#else
#include <thread>
#endif // (STD_THREAD_NOT_SUPPORTED) #endif // (STD_THREAD_NOT_SUPPORTED)
#endif // NANA_STD_THREAD_HPP #endif // NANA_STD_THREAD_HPP

View File

@ -30,7 +30,7 @@ namespace system
typedef void* module_t; typedef void* module_t;
void* symbols(module_t handle, const char* symbol); void* symbols(module_t handle, const char* symbol);
}; //end struct shared_helper } //end namespace shared_helper
}//end namespace detail }//end namespace detail
class shared_wrapper class shared_wrapper

View File

@ -1,6 +1,8 @@
#ifndef NANA_UNICODE_BIDI_HPP #ifndef NANA_UNICODE_BIDI_HPP
#define NANA_UNICODE_BIDI_HPP #define NANA_UNICODE_BIDI_HPP
#include <vector> #include <vector>
#include <nana/push_ignore_diagnostic>
namespace nana namespace nana
{ {
@ -60,7 +62,7 @@ namespace nana
void _m_resolve_weak_types(); void _m_resolve_weak_types();
void _m_resolve_neutral_types(); void _m_resolve_neutral_types();
void _m_resolve_implicit_levels(); void _m_resolve_implicit_levels();
void _m_reordering_resolved_levels(const char_type*, std::vector<entity> & reordered); void _m_reordering_resolved_levels(std::vector<entity> & reordered);
static bidi_category _m_bidi_category(bidi_char); static bidi_category _m_bidi_category(bidi_char);
static bidi_char _m_char_dir(char_type); static bidi_char _m_char_dir(char_type);
private: private:
@ -71,5 +73,6 @@ namespace nana
}; };
} }
#include <nana/pop_ignore_diagnostic>
#endif #endif

View File

@ -1,5 +1,8 @@
#include <nana/push_ignore_diagnostic>
#include <nana/audio/player.hpp> #include <nana/audio/player.hpp>
#ifdef NANA_ENABLE_AUDIO #ifdef NANA_ENABLE_AUDIO
#include <nana/audio/detail/audio_stream.hpp> #include <nana/audio/detail/audio_stream.hpp>
@ -67,4 +70,4 @@ namespace nana{ namespace audio
}//end namespace audio }//end namespace audio
}//end namespace nana }//end namespace nana
#endif //NANA_ENABLE_AUDIO #endif //NANA_ENABLE_AUDIO

View File

@ -1,4 +1,4 @@
/* /**
* A Character Encoding Set Implementation * A Character Encoding Set 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-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,9 +7,9 @@
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/charset.cpp * @file nana/charset.cpp
* @brief: A conversion between unicode characters and multi bytes characters * @brief A conversion between unicode characters and multi bytes characters
* @contributions: * @contributions
* UTF16 4-byte decoding issue by Renke Yan. * UTF16 4-byte decoding issue by Renke Yan.
* Pr0curo(pr#98) * Pr0curo(pr#98)
*/ */
@ -20,6 +20,7 @@
#include <cwchar> #include <cwchar>
#include <clocale> #include <clocale>
#include <cstring> //Added by Pr0curo(pr#98) #include <cstring> //Added by Pr0curo(pr#98)
#include <memory>
//GCC 4.7.0 does not implement the <codecvt> and codecvt_utfx classes //GCC 4.7.0 does not implement the <codecvt> and codecvt_utfx classes
#ifndef STD_CODECVT_NOT_SUPPORTED #ifndef STD_CODECVT_NOT_SUPPORTED
@ -34,6 +35,7 @@ namespace nana
{ {
namespace utf namespace utf
{ {
/// return a pointer to the code unit of the character at pos
const char* char_ptr(const char* text, unsigned pos) const char* char_ptr(const char* text, unsigned pos)
{ {
auto ustr = reinterpret_cast<const unsigned char*>(text); auto ustr = reinterpret_cast<const unsigned char*>(text);
@ -48,10 +50,10 @@ namespace nana
continue; continue;
} }
if (uch < 0xC0) if (uch < 0xC0) // use police ?
return nullptr; return nullptr;
if ((uch < 0xE0) && (ustr + 1 < end)) if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0
ustr += 2; ustr += 2;
else if (uch < 0xF0 && (ustr + 2 <= end)) else if (uch < 0xF0 && (ustr + 2 <= end))
ustr += 3; ustr += 3;
@ -64,6 +66,7 @@ namespace nana
return reinterpret_cast<const char*>(ustr); return reinterpret_cast<const char*>(ustr);
} }
/// return a pointer to the code unit of the character at pos - reuse ^ ?
const char* char_ptr(const std::string& text_utf8, unsigned pos) const char* char_ptr(const std::string& text_utf8, unsigned pos)
{ {
auto ustr = reinterpret_cast<const unsigned char*>(text_utf8.c_str()); auto ustr = reinterpret_cast<const unsigned char*>(text_utf8.c_str());
@ -94,6 +97,7 @@ namespace nana
return reinterpret_cast<const char*>(ustr); return reinterpret_cast<const char*>(ustr);
} }
/// return a code point (max 16 bits?) and the len in code units of the character at pos
wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len) wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len)
{ {
if (!text_utf8) if (!text_utf8)
@ -112,10 +116,10 @@ namespace nana
if (len) if (len)
*len = 1; *len = 1;
return *text_utf8; return *text_utf8; // uch ?
} }
if (uch < 0xC0) if (uch < 0xC0) // use police or ??
{ {
if (len) if (len)
*len = 0; *len = 0;
@ -151,6 +155,7 @@ namespace nana
return 0; return 0;
} }
/// return a code point (max 16 bits?) and the len in code units of the character at pos
wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len) wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len)
{ {
const char* ptr; const char* ptr;
@ -210,22 +215,23 @@ namespace nana
} }
namespace detail namespace detail
{ {
/// candidate to be more general??
class locale_initializer class locale_initializer
{ {
public: public:
static void init() static void init()
{ {
static bool initialized = false; static bool initialized = false;
if(false == initialized) if (initialized) return;
{
initialized = true; initialized = true;
//Only set the C library locale //Only set the C library locale
std::setlocale(LC_CTYPE, ""); std::setlocale(LC_CTYPE, "");
}
} }
}; };
/// convert wchar C string from ? ANSI code page CP_ACP (windows) or LC_CTYPE c locale (-nix) into utf8 std::string
bool wc2mb(std::string& mbstr, const wchar_t * s) bool wc2mb(std::string& mbstr, const wchar_t * s)
{ {
if(nullptr == s || *s == 0) if(nullptr == s || *s == 0)
@ -258,7 +264,8 @@ namespace nana
#endif #endif
return true; return true;
} }
/// convert a char C-string from The system default Windows ANSI code page CP_ACP or from LC_CTYPE c locale (-nix) into utf16 std::wstring
bool mb2wc(std::wstring& wcstr, const char* s) bool mb2wc(std::wstring& wcstr, const char* s)
{ {
if(nullptr == s || *s == 0) if(nullptr == s || *s == 0)
@ -291,6 +298,7 @@ namespace nana
return true; return true;
} }
/// convert a char C string from The system default Windows ANSI code page CP_ACP or LC_CTYPE c locale (-nix) into utf16 std::string
bool mb2wc(std::string& wcstr, const char* s) bool mb2wc(std::string& wcstr, const char* s)
{ {
if(nullptr == s || *s == 0) if(nullptr == s || *s == 0)
@ -304,6 +312,7 @@ namespace nana
{ {
wcstr.resize((chars - 1) * sizeof(wchar_t)); wcstr.resize((chars - 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, s, -1, reinterpret_cast<wchar_t*>(&wcstr[0]), chars - 1); ::MultiByteToWideChar(CP_ACP, 0, s, -1, reinterpret_cast<wchar_t*>(&wcstr[0]), chars - 1);
// ^ the trick !
} }
#else #else
locale_initializer::init(); locale_initializer::init();
@ -338,17 +347,98 @@ namespace nana
virtual std::wstring&& wstr_move() = 0; virtual std::wstring&& wstr_move() = 0;
}; };
/// playing with the idea - we need a mechanisme to set a user selected police - Testing an abtract interphase
struct encoding_error_police
{
virtual unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) = 0;
virtual ~encoding_error_police() = default;
};
/// the current nana default: it is safe - you may want to keep it ! use the other at your risk: mainly for debugging
struct utf8_error_police : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
current_code_unit = end;
return 0;
}
};
///
struct utf8_error_police_def_char : public encoding_error_police
{
static unsigned long def_error_mark ;
unsigned long error_mark{ def_error_mark };
utf8_error_police_def_char() = default;
utf8_error_police_def_char( unsigned long mark): error_mark{mark}{}
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
++current_code_unit; //check (p != end) ?
return error_mark;
}
};
unsigned long utf8_error_police_def_char::def_error_mark{ '*' };
///
struct utf8_error_police_throw : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
//utf8_Error::use_throw = true;
utf8_Error(std::string("The text is not encoded in UTF8: ") +
reinterpret_cast<const char*>( current_code_unit) ).emit();;
current_code_unit = end;
return 0;
}
};
struct utf8_error_police_latin : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
return *(current_code_unit++) ;
}
};
/// buggie?
struct utf8_error_police_system : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
std::wstring wc;
mb2wc(wc, reinterpret_cast<const char*>(current_code_unit));
current_code_unit++;
//wchar_t *p = &wc[0];
return wc[0]; // use utf16char but what endian?
}
};
// auto def_encoding_error_police = std::make_unique<utf8_error_police>(); // the nana default
// auto def_encoding_error_police = std::make_unique<utf8_error_police_latin>();
// auto def_encoding_error_police = std::make_unique<utf8_error_police_throw>();
// auto def_encoding_error_police = std::make_unique<utf8_error_police_def_char>('X');
auto def_encoding_error_police = std::make_unique<utf8_error_police_system>();
#ifndef STD_CODECVT_NOT_SUPPORTED #ifndef STD_CODECVT_NOT_SUPPORTED
class charset_string class charset_string
: public charset_encoding_interface : public charset_encoding_interface
{ {
public: public:
charset_string(const std::string& s) charset_string(const std::string& s)
: data_(s), is_unicode_(false) : data_(s)
{} {}
charset_string(std::string&& s) charset_string(std::string&& s)
: data_(std::move(s)), is_unicode_(false) : data_(std::move(s))
{} {}
charset_string(const std::string& s, unicode encoding) charset_string(const std::string& s, unicode encoding)
@ -501,9 +591,9 @@ namespace nana
} }
private: private:
std::string data_; std::string data_;
std::wstring wdata_for_move_; std::wstring wdata_for_move_{};
bool is_unicode_; bool is_unicode_{ false };
unicode utf_x_; unicode utf_x_{ unicode::utf8 };
}; };
class charset_wstring class charset_wstring
@ -578,37 +668,42 @@ namespace nana
std::string data_for_move_; std::string data_for_move_;
}; };
#else #else
/// return the first code point and move the pointer to next character, springing to the end by errors
unsigned long utf8char(const unsigned char*& p, const unsigned char* end) unsigned long utf8char(const unsigned char*& p, const unsigned char* end)
{ {
if(p != end) if(p != end)
{ {
if(*p < 0x80) if(*p < 0x80) // ASCII char 0-127 or 0-0x80
{ {
return *(p++); return *(p++);
} }
unsigned ch = *p; unsigned ch = *p;
unsigned long code; unsigned long code;
if(ch < 0xC0) if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page
{ {
p = end; //return *(p++); // temp: assume equal
return 0; //p = end;
//return 0;
return def_encoding_error_police->next_code_point(p, end);
} }
else if(ch < 0xE0 && (p + 1 <= end)) else if(ch < 0xE0 && (p + 1 <= end)) // two byte chararcter
{ {
code = ((ch & 0x1F) << 6) | (p[1] & 0x3F); code = ((ch & 0x1F) << 6) | (p[1] & 0x3F);
p += 2; p += 2;
} }
else if(ch < 0xF0 && (p + 2 <= end)) else if(ch < 0xF0 && (p + 2 <= end)) // 3 byte character
{ {
code = ((((ch & 0xF) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F); code = ((((ch & 0xF) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F);
p += 3; p += 3;
} }
else if(ch < 0x1F && (p + 3 <= end)) else if(ch < 0x1F && (p + 3 <= end)) // 4 byte character
{ {
code = ((((((ch & 0x7) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F)) << 6) | (p[3] & 0x3F); code = ((((((ch & 0x7) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F)) << 6) | (p[3] & 0x3F);
p += 4; p += 4;
} }
else else // error, go to end
{ {
p = end; p = end;
return 0; return 0;
@ -950,11 +1045,11 @@ namespace nana
{ {
public: public:
charset_string(const std::string& s) charset_string(const std::string& s)
: data_(s), is_unicode_(false) : data_(s)
{} {}
charset_string(std::string&& s) charset_string(std::string&& s)
: data_(std::move(s)), is_unicode_(false) : data_(std::move(s))
{} {}
charset_string(const std::string& s, unicode encoding) charset_string(const std::string& s, unicode encoding)
@ -1067,12 +1162,21 @@ namespace nana
{ {
switch(encoding) switch(encoding)
{ {
#if defined(NANA_WINDOWS)
case unicode::utf8:
return utf16_to_utf8(wcstr);
case unicode::utf32:
return utf16_to_utf32(wcstr);
case unicode::utf16:
return wcstr;
#else //POSIX
case unicode::utf8: case unicode::utf8:
return utf32_to_utf8(wcstr); return utf32_to_utf8(wcstr);
case unicode::utf16: case unicode::utf16:
return utf32_to_utf16(wcstr); return utf32_to_utf16(wcstr);
case unicode::utf32: case unicode::utf32:
return wcstr; return wcstr;
#endif
} }
} }
return {}; return {};
@ -1122,9 +1226,9 @@ namespace nana
} }
private: private:
std::string data_; std::string data_;
std::wstring wdata_for_move_; std::wstring wdata_for_move_{};
bool is_unicode_; bool is_unicode_{ false };
unicode utf_x_; unicode utf_x_{ unicode::utf8 };
}; };
@ -1195,7 +1299,7 @@ namespace nana
} }
private: private:
std::wstring data_; std::wstring data_;
std::string data_for_move_; std::string data_for_move_{};
}; };
#endif #endif
} }

View File

@ -17,62 +17,65 @@
#include <cassert> #include <cassert>
namespace { namespace {
void localtime(struct tm& tm) std::tm localtime()
{ {
#if defined(NANA_WINDOWS) && !defined(NANA_MINGW) #if defined(NANA_WINDOWS) && !defined(NANA_MINGW)
time_t t; time_t t;
::time(&t); ::time(&t);
std::tm tm;
if(localtime_s(&tm, &t) != 0) if(localtime_s(&tm, &t) != 0)
{
assert(false); assert(false);
}
return tm;
#else #else
time_t t = std::time(nullptr); time_t t = std::time(nullptr);
struct tm * tm_addr = std::localtime(&t); struct tm * tm_addr = std::localtime(&t);
assert(tm_addr); assert(tm_addr);
tm = *tm_addr;
return *tm_addr;
#endif #endif
} }
::nana::date::value to_dateval(const std::tm& t)
{
return {static_cast<unsigned>(t.tm_year + 1900), static_cast<unsigned>(t.tm_mon + 1), static_cast<unsigned>(t.tm_mday)};
}
::nana::time::value to_timeval(const std::tm& t)
{
return {static_cast<unsigned>(t.tm_hour), static_cast<unsigned>(t.tm_min), static_cast<unsigned>(t.tm_sec)};
}
} // namespace anonymous } // namespace anonymous
namespace nana namespace nana
{ {
//class date //class date
void date::set(const std::tm& t) void date::set(const std::tm& t)
{ {
value_.year = t.tm_year + 1900; value_ = to_dateval(t);
value_.month = t.tm_mon + 1;
value_.day = t.tm_mday;
} }
date::date() date::date()
: value_(to_dateval(localtime()))
{ {
struct tm t;
localtime(t);
set(t);
} }
date::date(const std::tm& t) date::date(const std::tm& t)
: value_(to_dateval(t))
{ {
set(t);
} }
date::date(int year, int month, int day) date::date(int year, int month, int day)
: value_({static_cast<unsigned>(year), static_cast<unsigned>(month), static_cast<unsigned>(day)})
{ {
if(1601 <= year && year < 30827 && 0 < month && month < 13 && day > 0) if(1601 <= year && year < 30827 && 0 < month && month < 13 && day > 0)
{ {
if(day <= static_cast<int>(date::month_days(year, month))) if(day <= static_cast<int>(date::month_days(year, month)))
{
value_.year = year;
value_.month = month;
value_.day = day;
return; return;
}
} }
struct tm t; set(localtime());
localtime(t);
set(t);
} }
date date::operator - (int off) const date date::operator - (int off) const
@ -258,39 +261,27 @@ namespace nana
//class time //class time
void time::set(const std::tm& t) void time::set(const std::tm& t)
{ {
value_.hour = t.tm_hour; value_ = to_timeval(t);
value_.minute = t.tm_min;
value_.second = t.tm_sec;
} }
time::time() time::time()
: value_(to_timeval(localtime()))
{ {
struct tm t;
localtime(t);
set(t);
} }
time::time(const std::tm& t) time::time(const std::tm& t)
: value_(to_timeval(t))
{ {
value_.hour = t.tm_hour;
value_.minute = t.tm_min;
value_.second = t.tm_sec;
} }
time::time(unsigned hour, unsigned minute, unsigned second) time::time(unsigned hour, unsigned minute, unsigned second)
: value_({hour, minute, second})
{ {
if(hour < 24 && minute < 60 && second < 62) if(hour < 24 && minute < 60 && second < 62)
{
value_.hour = hour;
value_.minute = minute;
value_.second = second;
return; return;
}
struct tm t;
localtime(t);
set(t);
}
set(localtime());
}
const time::value& time::read() const const time::value& time::read() const
{ {
return value_; return value_;

View File

@ -436,6 +436,51 @@ namespace std
} }
#endif #endif
//#ifdef STD_put_time_NOT_SUPPORTED
#include <ctime>
#include <cwchar>
namespace std
{
//Workaround for no implemenation of std::put_time in gcc < 5.
/* std unspecified return type */
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
//template< >
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt)
{
unsigned sz = 200;
std::string str(sz, '\0');
sz = std::strftime(&str[0], str.size() - 1, fmt, tmb);
str.resize(sz);
return str;
}
//Defined in header <ctime>
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
//template<>
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt)
//{
// unsigned sz = 200;
// std::wstring str(sz, L'\0');
// sz = std::wcsftime(&str[0], str.size() - 1, fmt, tmb);
// str.resize(sz);
// return str;
//}
// http://en.cppreference.com/w/cpp/chrono/c/wcsftime
// Defined in header <cwchar>
// std::size_t wcsftime(wchar_t* str, std::size_t count, const wchar_t* format, const std::tm* time);
// Converts the date and time information from a given calendar time time to a null - terminated
// wide character string str according to format string format.Up to count bytes are written.
// Parameters
// str - pointer to the first element of the wchar_t array for output
// count - maximum number of wide characters to write
// format - pointer to a null - terminated wide character string specifying the format of conversion.
}
//#endif // STD_put_time_NOT_SUPPORTED
#include <iostream>
namespace nana namespace nana
{ {
bool is_utf8(const char* str, std::size_t len) bool is_utf8(const char* str, std::size_t len)
@ -468,25 +513,83 @@ namespace nana
return true; return true;
} }
//class utf8_Error
#if defined(_MSC_VER)
# if (_MSC_VER < 1900)
//A workaround for lack support of C++11 inheriting constructors for VC2013
utf8_Error::utf8_Error(const std::string& msg)
: std::runtime_error(msg)
{}
# endif
#endif
void utf8_Error::emit()
{
if (use_throw)
throw utf8_Error(*this);
std::cerr << what();
}
//bool utf8_Error::use_throw{true};
bool utf8_Error::use_throw{ false };
//end class utf8_Error
void throw_not_utf8(const std::string& text) void throw_not_utf8(const std::string& text)
{ {
if (!is_utf8(text.c_str(), text.length())) if (!is_utf8(text.c_str(), text.length()))
throw std::invalid_argument("The text is not encoded in UTF8"); return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
} }
void throw_not_utf8(const char* text, std::size_t len) void throw_not_utf8(const char* text, std::size_t len)
{ {
if (!is_utf8(text, len)) if (!is_utf8(text, len))
throw std::invalid_argument("The text is not encoded in UTF8"); return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit();
//throw std::invalid_argument("The text is not encoded in UTF8");
} }
void throw_not_utf8(const char* text) void throw_not_utf8(const char* text)
{ {
if (!is_utf8(text, std::strlen(text))) if (!is_utf8(text, std::strlen(text)))
throw std::invalid_argument("The text is not encoded in UTF8"); return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
//throw std::invalid_argument("The text is not encoded in UTF8");
} }
std::string recode_to_utf8(std::string no_utf8)
{
return nana::charset(std::move(no_utf8)).to_bytes(nana::unicode::utf8);
}
/// this text needed change, it needed review ??
bool review_utf8(const std::string& text)
{
if (!is_utf8(text.c_str(), text.length()))
{
utf8_Error(std::string("\nThe const text is not encoded in UTF8: ") + text).emit();
return true; /// it needed change, it needed review !!
}
else
return false;
}
/// this text needed change, it needed review ??
bool review_utf8(std::string& text)
{
if (!is_utf8(text.c_str(), text.length()))
{
utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
text=recode_to_utf8(text);
return true; /// it needed change, it needed review !!
}
else
return false;
}
const std::string& to_utf8(const std::string& str) const std::string& to_utf8(const std::string& str)
{ {
return str; return str;

View File

@ -16,6 +16,9 @@
#include <nana/detail/platform_spec_selector.hpp> #include <nana/detail/platform_spec_selector.hpp>
#if defined(NANA_POSIX) && defined(NANA_X11) #if defined(NANA_POSIX) && defined(NANA_X11)
#include <nana/push_ignore_diagnostic>
#include <X11/Xlocale.h> #include <X11/Xlocale.h>
#include <locale> #include <locale>
#include <map> #include <map>
@ -432,13 +435,13 @@ namespace detail
platform_spec::instance().unlock_xlib(); platform_spec::instance().unlock_xlib();
} }
int X11_error_handler(Display* disp, XErrorEvent* err) int X11_error_handler(Display*, XErrorEvent* err)
{ {
platform_spec::instance().error_code = err->error_code; platform_spec::instance().error_code = err->error_code;
return 0; return 0;
} }
int X11_fatal_handler(Display* disp) int X11_fatal_handler(Display*)
{ {
return 0; return 0;
} }
@ -1414,4 +1417,6 @@ namespace detail
} }
}//end namespace detail }//end namespace detail
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif //NANA_POSIX && NANA_X11 #endif //NANA_POSIX && NANA_X11

View File

@ -1,7 +1,7 @@
/* /**
* Platform Specification Implementation * Platform Specification Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -9,7 +9,7 @@
* *
* @file: nana/detail/platform_spec.cpp * @file: nana/detail/platform_spec.cpp
* *
* This file provides basis class and data structrue that required by nana * @brief basis classes and data structrues required by nana
*/ */
#include <nana/detail/platform_spec_selector.hpp> #include <nana/detail/platform_spec_selector.hpp>
@ -19,9 +19,172 @@
#include <shellapi.h> #include <shellapi.h>
#include <stdexcept> #include <stdexcept>
#if defined(_MSC_VER)
#include <VersionHelpers.h>
#endif // _MSVC ///////////////////////////////////////////////////////////////////////////////////////////////////////
/******************************************************************
* *
* VersionHelpers.h -- This module defines helper functions to *
* promote version check with proper *
* comparisons. *
* *
* Copyright (c) Microsoft Corp. All rights reserved. *
* *
******************************************************************/
#include <specstrings.h> // for _In_, etc.
#if !defined(__midl) && !defined(SORTPP_PASS)
#if (NTDDI_VERSION >= NTDDI_WINXP)
#ifdef __cplusplus
#define VERSIONHELPERAPI inline bool
#else // __cplusplus
#define VERSIONHELPERAPI FORCEINLINE BOOL
#endif // __cplusplus
VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 };
DWORDLONG const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}
VERSIONHELPERAPI
IsWindowsXPOrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
}
VERSIONHELPERAPI
IsWindowsXPSP1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
}
VERSIONHELPERAPI
IsWindowsXPSP2OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
}
VERSIONHELPERAPI
IsWindowsXPSP3OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
}
VERSIONHELPERAPI
IsWindowsVistaOrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
}
VERSIONHELPERAPI
IsWindowsVistaSP1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
}
VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}
VERSIONHELPERAPI
IsWindows7OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
}
VERSIONHELPERAPI
IsWindows7SP1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
}
#ifndef _WIN32_WINNT_WIN8 // (0x0602)
#define _WIN32_WINNT_WIN8 (0x0602)
#endif // _WIN32_WINNT_WIN8(0x0602)
VERSIONHELPERAPI
IsWindows8OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
}
#ifndef _WIN32_WINNT_WINBLUE // (0x0602)
#define _WIN32_WINNT_WINBLUE (0x0602)
#endif // _WIN32_WINNT_WINBLUE (0x0602)
VERSIONHELPERAPI
IsWindows8Point1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
}
VERSIONHELPERAPI
IsWindowsServer()
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0, 0, VER_NT_WORKSTATION };
DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
}
#endif // NTDDI_VERSION
#endif // defined(__midl)
////////////////////////////////////////////////////////////////////////////////////////////////////
//#if defined(_MSC_VER)
////#include <VersionHelpers.h>
//bool IsWindowsVistaOrGreater() { return false; }
//bool //VERSIONHELPERAPI
//IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
//{
// OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 };
// DWORDLONG const dwlConditionMask = VerSetConditionMask(
// VerSetConditionMask(
// VerSetConditionMask(
// 0, VER_MAJORVERSION, VER_GREATER_EQUAL),
// VER_MINORVERSION, VER_GREATER_EQUAL),
// VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
//
// osvi.dwMajorVersion = wMajorVersion;
// osvi.dwMinorVersion = wMinorVersion;
// osvi.wServicePackMajor = wServicePackMajor;
//
// return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
//}
//
//
//
//#endif // _MSVC
namespace nana namespace nana
{ {

View File

@ -37,12 +37,12 @@
#endif #endif
namespace nana { namespace experimental { namespace nana { namespace experimental { namespace filesystem
#ifndef CXX_NO_INLINE_NAMESPACE
inline namespace v1 {
#endif
namespace filesystem
{ {
#ifndef CXX_NO_INLINE_NAMESPACE
inline namespace v1 {
#endif
//class filesystem_error //class filesystem_error
filesystem_error::filesystem_error(const std::string& msg, std::error_code err) filesystem_error::filesystem_error(const std::string& msg, std::error_code err)
: std::system_error(err, msg) : std::system_error(err, msg)
@ -59,12 +59,12 @@ namespace nana { namespace experimental {
path2_(path2) path2_(path2)
{} {}
const path& filesystem_error::path1() const const path& filesystem_error::path1() const noexcept
{ {
return path1_; return path1_;
} }
const path&filesystem_error::path2() const const path& filesystem_error::path2() const noexcept
{ {
return path2_; return path2_;
} }
@ -110,7 +110,8 @@ namespace nana { namespace experimental {
return pathstr_.compare(p.pathstr_); return pathstr_.compare(p.pathstr_);
} }
bool path::empty() const /// true if the path is empty, false otherwise. ??
bool path::empty() const noexcept
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES); return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES);
@ -122,17 +123,20 @@ namespace nana { namespace experimental {
path path::extension() const path path::extension() const
{ {
// todo: make more globlal
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
auto pos = pathstr_.find_last_of(L"\\/."); auto SLorP=L"\\/.";
auto P=L'.';
#else #else
auto pos = pathstr_.find_last_of("\\/."); auto SLorP="\\/.";
auto P='.';
#endif #endif
if ((pos == pathstr_.npos) || (pathstr_[pos] != '.')) auto pos = pathstr_.find_last_of(SLorP);
return path();
if ( ( pos == pathstr_.npos)
if (pos + 1 == pathstr_.size()) || ( pathstr_[pos] != P )
return path(); || ( pos + 1 == pathstr_.size() ))
return path();
return path(pathstr_.substr(pos)); return path(pathstr_.substr(pos));
} }
@ -384,7 +388,7 @@ namespace nana { namespace experimental {
} }
}; };
directory_iterator::directory_iterator() directory_iterator::directory_iterator() noexcept
: end_(true), : end_(true),
handle_(nullptr) handle_(nullptr)
{} {}
@ -414,14 +418,10 @@ namespace nana { namespace experimental {
bool directory_iterator::equal(const directory_iterator& x) const bool directory_iterator::equal(const directory_iterator& x) const
{ {
if (end_ && (end_ == x.end_)) return true; if (end_ && (end_ == x.end_)) return true;
return (value_.path().filename() == x.value_.path().filename()); return (value_.path().filename() == x.value_.path().filename());
} }
// enable directory_iterator range-based for statements
directory_iterator directory_iterator::begin() { return *this; }
directory_iterator directory_iterator::end() { return{}; }
void directory_iterator::_m_prepare(const path& file_path) void directory_iterator::_m_prepare(const path& file_path)
{ {
path_ = file_path.native(); path_ = file_path.native();
@ -785,6 +785,13 @@ namespace nana { namespace experimental {
return false; return false;
} }
file_time_type last_write_time(const path& p)
{
struct tm t;
modified_file_time(p, t);
std::chrono::system_clock::time_point dateTime =std::chrono::system_clock::from_time_t( mktime(&t) );
return dateTime;
}
bool create_directory(const path& p) bool create_directory(const path& p)
{ {
@ -806,6 +813,7 @@ namespace nana { namespace experimental {
bool remove(const path& p, std::error_code & ec) bool remove(const path& p, std::error_code & ec)
{ {
ec.clear();
auto stat = status(p); auto stat = status(p);
if (stat.type() == file_type::directory) if (stat.type() == file_type::directory)
return detail::rm_dir(p); return detail::rm_dir(p);

View File

@ -207,10 +207,10 @@ namespace nana
{ {
switch(categ) switch(categ)
{ {
case category::root_tag::value: case category::flags::root:
attribute.root = new attr_root_tag; attribute.root = new attr_root_tag;
break; break;
case category::frame_tag::value: case category::flags::frame:
attribute.frame = new attr_frame_tag; attribute.frame = new attr_frame_tag;
break; break;
default: default:
@ -222,10 +222,10 @@ namespace nana
{ {
switch(category) switch(category)
{ {
case category::root_tag::value: case category::flags::root:
delete attribute.root; delete attribute.root;
break; break;
case category::frame_tag::value: case category::flags::frame:
delete attribute.frame; delete attribute.frame;
break; break;
default: break; default: break;
@ -236,7 +236,7 @@ namespace nana
//basic_window //basic_window
//@brief: constructor for the root window //@brief: constructor for the root window
basic_window::basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&& wdg_notifier, category::root_tag**) basic_window::basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&& wdg_notifier, category::root_tag**)
: widget_notifier(std::move(wdg_notifier)), other(category::root_tag::value) : widget_notifier(std::move(wdg_notifier)), other(category::flags::root)
{ {
drawer.bind(this); drawer.bind(this);
_m_init_pos_and_size(nullptr, rectangle()); _m_init_pos_and_size(nullptr, rectangle());
@ -256,7 +256,7 @@ namespace nana
//@brief: bind a native window and baisc_window //@brief: bind a native window and baisc_window
void basic_window::bind_native_window(native_window_type wd, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, nana::paint::graphics& graphics) void basic_window::bind_native_window(native_window_type wd, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, nana::paint::graphics& graphics)
{ {
if(category::root_tag::value == this->other.category) if(category::flags::root == this->other.category)
{ {
this->root = wd; this->root = wd;
dimension.width = width; dimension.width = width;
@ -270,7 +270,7 @@ namespace nana
void basic_window::frame_window(native_window_type wd) void basic_window::frame_window(native_window_type wd)
{ {
if(category::frame_tag::value == this->other.category) if(category::flags::frame == this->other.category)
other.attribute.frame->container = wd; other.attribute.frame->container = wd;
} }
@ -357,12 +357,12 @@ namespace nana
void basic_window::_m_initialize(basic_window* agrparent) void basic_window::_m_initialize(basic_window* agrparent)
{ {
if(other.category == category::root_tag::value) if(category::flags::root == other.category)
{ {
if(agrparent && (nana::system::this_thread_id() != agrparent->thread_id)) if(agrparent && (nana::system::this_thread_id() != agrparent->thread_id))
agrparent = nullptr; agrparent = nullptr;
while(agrparent && (agrparent->other.category != category::root_tag::value)) while(agrparent && (category::flags::root != agrparent->other.category))
agrparent = agrparent->parent; agrparent = agrparent->parent;
owner = agrparent; owner = agrparent;

View File

@ -36,6 +36,18 @@ namespace nana
detail::bedrock::instance().wd_manager().internal_lock().unlock(); detail::bedrock::instance().wd_manager().internal_lock().unlock();
} }
//end class internal_scope_guard //end class internal_scope_guard
//class internal_revert_guard
internal_revert_guard::internal_revert_guard()
{
detail::bedrock::instance().wd_manager().internal_lock().revert();
}
internal_revert_guard::~internal_revert_guard()
{
detail::bedrock::instance().wd_manager().internal_lock().forward();
}
//end class internal_revert_guard
//class event_arg //class event_arg
void event_arg::stop_propagation() const void event_arg::stop_propagation() const

View File

@ -227,7 +227,7 @@ namespace detail
return impl_->estore; return impl_->estore;
} }
void bedrock::map_through_widgets(core_window_t* wd, native_drawable_type drawable) void bedrock::map_through_widgets(core_window_t*, native_drawable_type)
{ {
//No implementation for Linux //No implementation for Linux
} }
@ -250,9 +250,13 @@ namespace detail
_m_emit_core(evt_code, wd, false, arg); _m_emit_core(evt_code, wd, false, arg);
if(ask_update) //A child of wd may not be drawn if it was out of wd's range before wd resized,
wd_manager().do_lazy_refresh(wd, false); //so refresh all children of wd when a resized occurs.
else if(ask_update || (event_code::resized == evt_code))
{
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code));
}
else if(wd_manager().available(wd))
wd->other.upd_state = core_window_t::update_state::none; wd->other.upd_state = core_window_t::update_state::none;
if(thrd) thrd->event_window = prev_wd; if(thrd) thrd->event_window = prev_wd;
@ -358,7 +362,7 @@ namespace detail
} }
} }
void window_proc_for_packet(Display * display, nana::detail::msg_packet_tag& msg) void window_proc_for_packet(Display * /*display*/, nana::detail::msg_packet_tag& msg)
{ {
static auto& brock = detail::bedrock::instance(); static auto& brock = detail::bedrock::instance();
@ -477,7 +481,7 @@ namespace detail
return wchar_t(keysym); return wchar_t(keysym);
} }
void window_proc_for_xevent(Display* display, XEvent& xevent) void window_proc_for_xevent(Display* /*display*/, XEvent& xevent)
{ {
typedef detail::bedrock::core_window_t core_window_t; typedef detail::bedrock::core_window_t core_window_t;
@ -486,7 +490,8 @@ namespace detail
static core_window_t* last_mouse_down_window; static core_window_t* last_mouse_down_window;
auto native_window = reinterpret_cast<native_window_type>(event_window(xevent)); auto native_window = reinterpret_cast<native_window_type>(event_window(xevent));
auto root_runtime = brock.wd_manager().root_runtime(native_window); auto & wd_manager = brock.wd_manager();
auto root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime) if(root_runtime)
{ {
@ -506,7 +511,7 @@ namespace detail
if(pressed_wd_space) if(pressed_wd_space)
break; break;
msgwnd = brock.wd_manager().find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y); msgwnd = wd_manager.find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y);
if(msgwnd) if(msgwnd)
{ {
if (mouse_action::pressed != msgwnd->flags.action) if (mouse_action::pressed != msgwnd->flags.action)
@ -520,7 +525,7 @@ namespace detail
arg.evt_code = event_code::mouse_move; arg.evt_code = event_code::mouse_move;
brock.emit(event_code::mouse_move, msgwnd, arg, true, &context); brock.emit(event_code::mouse_move, msgwnd, arg, true, &context);
if (!brock.wd_manager().available(hovered_wd)) if (!wd_manager.available(hovered_wd))
hovered_wd = nullptr; hovered_wd = nullptr;
} }
break; break;
@ -544,7 +549,7 @@ namespace detail
if(msgwnd->dimension.width != static_cast<unsigned>(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast<unsigned>(xevent.xconfigure.height)) if(msgwnd->dimension.width != static_cast<unsigned>(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast<unsigned>(xevent.xconfigure.height))
{ {
auto & cf = xevent.xconfigure; auto & cf = xevent.xconfigure;
brock.wd_manager().size(msgwnd, nana::size{static_cast<unsigned>(cf.width), static_cast<unsigned>(cf.height)}, true, true); wd_manager.size(msgwnd, nana::size{static_cast<unsigned>(cf.width), static_cast<unsigned>(cf.height)}, true, true);
} }
if(msgwnd->pos_native.x != xevent.xconfigure.x || msgwnd->pos_native.y != xevent.xconfigure.y) if(msgwnd->pos_native.x != xevent.xconfigure.x || msgwnd->pos_native.y != xevent.xconfigure.y)
@ -562,7 +567,7 @@ namespace detail
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5) if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
break; break;
msgwnd = brock.wd_manager().find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
if(nullptr == msgwnd) break; if(nullptr == msgwnd) break;
if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true))
@ -584,7 +589,7 @@ namespace detail
context.event_window = new_focus; context.event_window = new_focus;
auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press); auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press);
if (kill_focus != new_focus) if (kill_focus != new_focus)
brock.wd_manager().do_lazy_refresh(kill_focus, false); wd_manager.do_lazy_refresh(kill_focus, false);
} }
} }
@ -598,7 +603,7 @@ namespace detail
arg.evt_code = dbl_click ? event_code::dbl_click : event_code::mouse_down; arg.evt_code = dbl_click ? event_code::dbl_click : event_code::mouse_down;
if(brock.emit(arg.evt_code, msgwnd, arg, true, &context)) if(brock.emit(arg.evt_code, msgwnd, arg, true, &context))
{ {
if (brock.wd_manager().available(msgwnd)) if (wd_manager.available(msgwnd))
{ {
pressed_wd = msgwnd; pressed_wd = msgwnd;
//If a root window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event. //If a root window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event.
@ -606,8 +611,9 @@ namespace detail
{ {
//call the drawer mouse up event for restoring the surface graphics //call the drawer mouse up event for restoring the surface graphics
msgwnd->flags.action = mouse_action::normal; msgwnd->flags.action = mouse_action::normal;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
} }
} }
@ -638,7 +644,7 @@ namespace detail
} }
else else
{ {
msgwnd = brock.wd_manager().find_window(native_window, xevent.xbutton.x, xevent.xbutton.y); msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
if(nullptr == msgwnd) if(nullptr == msgwnd)
break; break;
@ -669,7 +675,7 @@ namespace detail
} }
//Do mouse_up, this handle may be closed by click handler. //Do mouse_up, this handle may be closed by click handler.
if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled) if(wd_manager.available(msgwnd) && msgwnd->flags.enabled)
{ {
if(hit) if(hit)
msgwnd->flags.action = mouse_action::over; msgwnd->flags.action = mouse_action::over;
@ -683,7 +689,7 @@ namespace detail
if(click_arg.window_handle) if(click_arg.window_handle)
evt_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); evt_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
if (brock.wd_manager().available(msgwnd)) if (wd_manager.available(msgwnd))
{ {
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
evt_ptr->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd)); evt_ptr->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd));
@ -692,29 +698,27 @@ namespace detail
else if(click_arg.window_handle) else if(click_arg.window_handle)
msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
pressed_wd = nullptr; pressed_wd = nullptr;
} }
break; break;
case DestroyNotify: case DestroyNotify:
if(wd_manager.available(msgwnd))
{ {
auto & spec = nana::detail::platform_spec::instance(); //The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window().
if(brock.wd_manager().available(msgwnd)) if (msgwnd->root == brock.get_menu())
{ {
//The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window(). brock.erase_menu(false);
if (msgwnd->root == brock.get_menu()) brock.delay_restore(3); //Restores if delay_restore not decleared
{
brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared
}
spec.remove(native_window);
brock.wd_manager().destroy(msgwnd);
brock.manage_form_loader(msgwnd, false);
brock.wd_manager().destroy_handle(msgwnd);
} }
auto & spec = ::nana::detail::platform_spec::instance();
spec.remove(native_window);
wd_manager.destroy(msgwnd);
brock.manage_form_loader(msgwnd, false);
wd_manager.destroy_handle(msgwnd);
} }
break; break;
case MotionNotify: case MotionNotify:
@ -732,8 +736,8 @@ namespace detail
if(pressed_wd_space) if(pressed_wd_space)
break; break;
msgwnd = brock.wd_manager().find_window(native_window, xevent.xmotion.x, xevent.xmotion.y); msgwnd = wd_manager.find_window(native_window, xevent.xmotion.x, xevent.xmotion.y);
if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd)) if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
{ {
brock.event_msleave(hovered_wd); brock.event_msleave(hovered_wd);
hovered_wd->flags.action = mouse_action::normal; hovered_wd->flags.action = mouse_action::normal;
@ -741,14 +745,14 @@ namespace detail
//if msgwnd is neither a captured window nor a child of captured window, //if msgwnd is neither a captured window nor a child of captured window,
//redirect the msgwnd to the captured window. //redirect the msgwnd to the captured window.
auto cap_wd = brock.wd_manager().capture_redirect(msgwnd); auto cap_wd = wd_manager.capture_redirect(msgwnd);
if(cap_wd) if(cap_wd)
msgwnd = cap_wd; msgwnd = cap_wd;
} }
else if(msgwnd) else if(msgwnd)
{ {
bool prev_captured_inside; bool prev_captured_inside;
if(brock.wd_manager().capture_window_entered(xevent.xmotion.x, xevent.xmotion.y, prev_captured_inside)) if(wd_manager.capture_window_entered(xevent.xmotion.x, xevent.xmotion.y, prev_captured_inside))
{ {
event_code evt_code; event_code evt_code;
if(prev_captured_inside) if(prev_captured_inside)
@ -787,7 +791,7 @@ namespace detail
arg.evt_code = event_code::mouse_move; arg.evt_code = event_code::mouse_move;
brock.emit(event_code::mouse_move, msgwnd, arg, true, &context); brock.emit(event_code::mouse_move, msgwnd, arg, true, &context);
} }
if (!brock.wd_manager().available(hovered_wd)) if (!wd_manager.available(hovered_wd))
hovered_wd = nullptr; hovered_wd = nullptr;
break; break;
case MapNotify: case MapNotify:
@ -852,7 +856,6 @@ namespace detail
keybuf[len] = 0; keybuf[len] = 0;
wchar_t os_code = 0; wchar_t os_code = 0;
auto & wd_manager = brock.wd_manager();
switch(status) switch(status)
{ {
case XLookupKeySym: case XLookupKeySym:
@ -934,7 +937,7 @@ namespace detail
brock.emit(event_code::key_press, msgwnd, arg, true, &context); brock.emit(event_code::key_press, msgwnd, arg, true, &context);
if(brock.wd_manager().available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd)) if(wd_manager.available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd))
{ {
int cmd = (menu_wd && (keyboard::escape == static_cast<wchar_t>(arg.key)) ? 1 : 0 ); int cmd = (menu_wd && (keyboard::escape == static_cast<wchar_t>(arg.key)) ? 1 : 0 );
brock.delay_restore(cmd); brock.delay_restore(cmd);
@ -1041,7 +1044,7 @@ namespace detail
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = reinterpret_cast<window>(msgwnd);
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
pressed_wd_space = nullptr; pressed_wd_space = nullptr;
} }
@ -1072,7 +1075,7 @@ namespace detail
{ {
bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus);
if (set_focus) if (set_focus)
brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::general); wd_manager.set_focus(msgwnd, false, arg_focus::reason::general);
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_release; arg.evt_code = event_code::key_release;
@ -1111,7 +1114,7 @@ namespace detail
} }
} }
root_runtime = brock.wd_manager().root_runtime(native_window); root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime) if(root_runtime)
{ {
context.event_window = pre_event_window; context.event_window = pre_event_window;
@ -1126,14 +1129,14 @@ namespace detail
} }
auto thread_id = ::nana::system::this_thread_id(); auto thread_id = ::nana::system::this_thread_id();
brock.wd_manager().call_safe_place(thread_id); wd_manager.call_safe_place(thread_id);
if(msgwnd) if(msgwnd)
brock.wd_manager().remove_trash_handle(thread_id); wd_manager.remove_trash_handle(thread_id);
} }
} }
void bedrock::pump_event(window modal_window, bool is_modal) void bedrock::pump_event(window modal_window, bool /*is_modal*/)
{ {
thread_context * context = open_thread_context(); thread_context * context = open_thread_context();
if(0 == context->window_count) if(0 == context->window_count)

View File

@ -1,4 +1,4 @@
/* /**
* A Bedrock Implementation * A Bedrock 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-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,7 +7,8 @@
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/detail/win32/bedrock.cpp * @file nana/gui/detail/win32/bedrock.cpp
* @brief A Bedrock Implementation
* @contributors: Ariel Vina-Rodriguez * @contributors: Ariel Vina-Rodriguez
*/ */
@ -25,6 +26,8 @@
#include <nana/gui/detail/element_store.hpp> #include <nana/gui/detail/element_store.hpp>
#include <nana/gui/detail/color_schemes.hpp> #include <nana/gui/detail/color_schemes.hpp>
#include <iostream>
#ifndef WM_MOUSEWHEEL #ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A #define WM_MOUSEWHEEL 0x020A
#endif #endif
@ -232,6 +235,7 @@ namespace detail
if(wd_manager().number_of_core_window()) if(wd_manager().number_of_core_window())
{ {
std::string msg = "Nana.GUI detects a memory leaks in window_manager, " + std::to_string(wd_manager().number_of_core_window()) + " window(s) are not uninstalled."; std::string msg = "Nana.GUI detects a memory leaks in window_manager, " + std::to_string(wd_manager().number_of_core_window()) + " window(s) are not uninstalled.";
std::cerr << msg; /// \todo add list of cations of open windows and if aut testin GUI do auto Ok after 2 sec.
::MessageBoxA(0, msg.c_str(), ("Nana C++ Library"), MB_OK); ::MessageBoxA(0, msg.c_str(), ("Nana C++ Library"), MB_OK);
} }
@ -239,8 +243,8 @@ namespace detail
delete pi_data_; delete pi_data_;
} }
//inc_window
//@brief: increament the number of windows /// @brief increament the number of windows in the thread id
int bedrock::inc_window(unsigned tid) int bedrock::inc_window(unsigned tid)
{ {
//impl refers to the object of private_impl, the object is created when bedrock is creating. //impl refers to the object of private_impl, the object is created when bedrock is creating.
@ -453,6 +457,7 @@ namespace detail
{ {
(msgbox(modal_window, "An exception during message pumping!").icon(msgbox::icon_information) (msgbox(modal_window, "An exception during message pumping!").icon(msgbox::icon_information)
<<"An uncaptured non-std exception during message pumping!" <<"An uncaptured non-std exception during message pumping!"
<< "\n in form: " << API::window_caption(modal_window)
).show(); ).show();
internal_scope_guard lock; internal_scope_guard lock;
_m_except_handler(); _m_except_handler();
@ -650,6 +655,14 @@ namespace detail
case nana::detail::messages::tray: case nana::detail::messages::tray:
notifications_window_proc(wd, wParam, lParam); notifications_window_proc(wd, wParam, lParam);
return true; return true;
case nana::detail::messages::affinity_execute:
if (wParam)
{
auto arg = reinterpret_cast<detail::messages::arg_affinity_execute*>(wParam);
if (arg->function_ptr)
(*arg->function_ptr)();
}
break;
default: default:
break; break;
} }
@ -772,7 +785,9 @@ namespace detail
static restrict::TRACKMOUSEEVENT track = {sizeof track, 0x00000002}; static restrict::TRACKMOUSEEVENT track = {sizeof track, 0x00000002};
auto native_window = reinterpret_cast<native_window_type>(root_window); auto native_window = reinterpret_cast<native_window_type>(root_window);
auto* root_runtime = brock.wd_manager().root_runtime(native_window);
auto & wd_manager = brock.wd_manager();
auto* root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime) if(root_runtime)
{ {
@ -817,7 +832,7 @@ namespace detail
bool take_over = false; bool take_over = false;
auto mmi = reinterpret_cast<MINMAXINFO*>(lParam); auto mmi = reinterpret_cast<MINMAXINFO*>(lParam);
if(msgwnd->min_track_size.width && msgwnd->min_track_size.height) if(!msgwnd->min_track_size.empty())
{ {
mmi->ptMinTrackSize.x = static_cast<LONG>(msgwnd->min_track_size.width + msgwnd->extra_width); mmi->ptMinTrackSize.x = static_cast<LONG>(msgwnd->min_track_size.width + msgwnd->extra_width);
mmi->ptMinTrackSize.y = static_cast<LONG>(msgwnd->min_track_size.height + msgwnd->extra_height); mmi->ptMinTrackSize.y = static_cast<LONG>(msgwnd->min_track_size.height + msgwnd->extra_height);
@ -878,14 +893,14 @@ namespace detail
break; break;
pressed_wd = nullptr; pressed_wd = nullptr;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if(msgwnd && msgwnd->flags.enabled) if(msgwnd && msgwnd->flags.enabled)
{ {
if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus) if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus)
{ {
auto killed = brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::mouse_press); auto killed = brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::mouse_press);
if (killed != msgwnd) if (killed != msgwnd)
brock.wd_manager().do_lazy_refresh(killed, false); wd_manager.do_lazy_refresh(killed, false);
} }
arg_mouse arg; arg_mouse arg;
@ -903,7 +918,7 @@ namespace detail
if (pressed_wd_space) if (pressed_wd_space)
break; break;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if ((nullptr == msgwnd) || (pressed_wd && (msgwnd != pressed_wd))) if ((nullptr == msgwnd) || (pressed_wd && (msgwnd != pressed_wd)))
break; break;
@ -924,7 +939,7 @@ namespace detail
{ {
auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press); auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press);
if (kill_focus != new_focus) if (kill_focus != new_focus)
brock.wd_manager().do_lazy_refresh(kill_focus, false); wd_manager.do_lazy_refresh(kill_focus, false);
} }
} }
@ -941,14 +956,14 @@ namespace detail
auto pos = native_interface::cursor_position(); auto pos = native_interface::cursor_position();
auto rootwd = native_interface::find_window(pos.x, pos.y); auto rootwd = native_interface::find_window(pos.x, pos.y);
native_interface::calc_window_point(rootwd, pos); native_interface::calc_window_point(rootwd, pos);
if(msgwnd != brock.wd_manager().find_window(rootwd, pos.x, pos.y)) if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y))
{ {
//call the drawer mouse up event for restoring the surface graphics //call the drawer mouse up event for restoring the surface graphics
msgwnd->flags.action = mouse_action::normal; msgwnd->flags.action = mouse_action::normal;
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
} }
} }
@ -964,7 +979,7 @@ namespace detail
if (pressed_wd_space) if (pressed_wd_space)
break; break;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if(nullptr == msgwnd) if(nullptr == msgwnd)
break; break;
@ -993,7 +1008,7 @@ namespace detail
} }
//Do mouse_up, this handle may be closed by click handler. //Do mouse_up, this handle may be closed by click handler.
if(brock.wd_manager().available(msgwnd) && msgwnd->flags.enabled) if(wd_manager.available(msgwnd) && msgwnd->flags.enabled)
{ {
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
@ -1001,7 +1016,7 @@ namespace detail
if (click_arg.window_handle) if (click_arg.window_handle)
retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
if (brock.wd_manager().available(msgwnd)) if (wd_manager.available(msgwnd))
{ {
arg.evt_code = event_code::mouse_up; arg.evt_code = event_code::mouse_up;
retain->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd)); retain->mouse_up.emit(arg, reinterpret_cast<window>(msgwnd));
@ -1010,7 +1025,7 @@ namespace detail
else if (click_arg.window_handle) else if (click_arg.window_handle)
retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd)); retain->click.emit(click_arg, reinterpret_cast<window>(msgwnd));
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
pressed_wd = nullptr; pressed_wd = nullptr;
break; break;
@ -1019,8 +1034,8 @@ namespace detail
if (pressed_wd_space) if (pressed_wd_space)
break; break;
msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd)) if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
{ {
brock.event_msleave(hovered_wd); brock.event_msleave(hovered_wd);
hovered_wd->flags.action = mouse_action::normal; hovered_wd->flags.action = mouse_action::normal;
@ -1028,7 +1043,7 @@ namespace detail
//if msgwnd is neither captured window nor the child of captured window, //if msgwnd is neither captured window nor the child of captured window,
//redirect the msgwnd to the captured window. //redirect the msgwnd to the captured window.
auto wd = brock.wd_manager().capture_redirect(msgwnd); auto wd = wd_manager.capture_redirect(msgwnd);
if(wd) if(wd)
msgwnd = wd; msgwnd = wd;
} }
@ -1036,7 +1051,7 @@ namespace detail
else if(msgwnd) else if(msgwnd)
{ {
bool prev_captured_inside; bool prev_captured_inside;
if(brock.wd_manager().capture_window_entered(pmdec.mouse.x, pmdec.mouse.y, prev_captured_inside)) if(wd_manager.capture_window_entered(pmdec.mouse.x, pmdec.mouse.y, prev_captured_inside))
{ {
event_code evt_code; event_code evt_code;
if(prev_captured_inside) if(prev_captured_inside)
@ -1084,7 +1099,7 @@ namespace detail
track.hwndTrack = native_window; track.hwndTrack = native_window;
restrict::track_mouse_event(&track); restrict::track_mouse_event(&track);
} }
if (!brock.wd_manager().available(hovered_wd)) if (!wd_manager.available(hovered_wd))
hovered_wd = nullptr; hovered_wd = nullptr;
break; break;
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
@ -1100,7 +1115,7 @@ namespace detail
if (pointer_wd == root_window) if (pointer_wd == root_window)
{ {
::ScreenToClient(pointer_wd, &scr_pos); ::ScreenToClient(pointer_wd, &scr_pos);
auto scrolled_wd = brock.wd_manager().find_window(reinterpret_cast<native_window_type>(pointer_wd), scr_pos.x, scr_pos.y); auto scrolled_wd = wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), scr_pos.x, scr_pos.y);
def_window_proc = true; def_window_proc = true;
auto evt_wd = scrolled_wd; auto evt_wd = scrolled_wd;
@ -1110,7 +1125,7 @@ namespace detail
{ {
def_window_proc = false; def_window_proc = false;
nana::point mspos{ scr_pos.x, scr_pos.y }; nana::point mspos{ scr_pos.x, scr_pos.y };
brock.wd_manager().calc_window_point(evt_wd, mspos); wd_manager.calc_window_point(evt_wd, mspos);
arg_wheel arg; arg_wheel arg;
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
@ -1124,14 +1139,14 @@ namespace detail
if (scrolled_wd && (nullptr == evt_wd)) if (scrolled_wd && (nullptr == evt_wd))
{ {
nana::point mspos{ scr_pos.x, scr_pos.y }; nana::point mspos{ scr_pos.x, scr_pos.y };
brock.wd_manager().calc_window_point(scrolled_wd, mspos); wd_manager.calc_window_point(scrolled_wd, mspos);
arg_wheel arg; arg_wheel arg;
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
assign_arg(arg, scrolled_wd, pmdec); assign_arg(arg, scrolled_wd, pmdec);
draw_invoker(&drawer::mouse_wheel, scrolled_wd, arg, &context); draw_invoker(&drawer::mouse_wheel, scrolled_wd, arg, &context);
brock.wd_manager().do_lazy_refresh(scrolled_wd, false); wd_manager.do_lazy_refresh(scrolled_wd, false);
} }
} }
else else
@ -1149,7 +1164,7 @@ namespace detail
POINT pos; POINT pos;
::DragQueryPoint(drop, &pos); ::DragQueryPoint(drop, &pos);
msgwnd = brock.wd_manager().find_window(native_window, pos.x, pos.y); msgwnd = wd_manager.find_window(native_window, pos.x, pos.y);
if(msgwnd) if(msgwnd)
{ {
arg_dropfiles dropfiles; arg_dropfiles dropfiles;
@ -1180,11 +1195,11 @@ namespace detail
dropfiles.pos.x = pos.x; dropfiles.pos.x = pos.x;
dropfiles.pos.y = pos.y; dropfiles.pos.y = pos.y;
brock.wd_manager().calc_window_point(msgwnd, dropfiles.pos); wd_manager.calc_window_point(msgwnd, dropfiles.pos);
dropfiles.window_handle = reinterpret_cast<window>(msgwnd); dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast<window>(msgwnd)); msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast<window>(msgwnd));
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
} }
@ -1272,7 +1287,7 @@ namespace detail
break; break;
case WM_SIZE: case WM_SIZE:
if(wParam != SIZE_MINIMIZED) if(wParam != SIZE_MINIMIZED)
brock.wd_manager().size(msgwnd, size(pmdec.size.width, pmdec.size.height), true, true); wd_manager.size(msgwnd, size(pmdec.size.width, pmdec.size.height), true, true);
break; break;
case WM_MOVE: case WM_MOVE:
brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam)); brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
@ -1298,7 +1313,7 @@ namespace detail
case WM_SYSCHAR: case WM_SYSCHAR:
def_window_proc = true; def_window_proc = true;
brock.shortkey_occurred(true); brock.shortkey_occurred(true);
msgwnd = brock.wd_manager().find_shortkey(native_window, static_cast<unsigned long>(wParam)); msgwnd = wd_manager.find_shortkey(native_window, static_cast<unsigned long>(wParam));
if(msgwnd) if(msgwnd)
{ {
arg_keyboard arg; arg_keyboard arg;
@ -1345,7 +1360,7 @@ namespace detail
bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus); bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_focus);
if (set_focus) if (set_focus)
brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::general); wd_manager.set_focus(msgwnd, false, arg_focus::reason::general);
arg_keyboard arg; arg_keyboard arg;
arg.evt_code = event_code::key_release; arg.evt_code = event_code::key_release;
@ -1375,9 +1390,7 @@ namespace detail
if(msgwnd) if(msgwnd)
{ {
auto & wd_manager = brock.wd_manager(); if((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab
if ((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab
{ {
bool is_forward = (::GetKeyState(VK_SHIFT) >= 0); bool is_forward = (::GetKeyState(VK_SHIFT) >= 0);
@ -1498,7 +1511,7 @@ namespace detail
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = reinterpret_cast<window>(msgwnd);
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
brock.wd_manager().do_lazy_refresh(msgwnd, false); wd_manager.do_lazy_refresh(msgwnd, false);
} }
pressed_wd_space = nullptr; pressed_wd_space = nullptr;
} }
@ -1544,12 +1557,12 @@ namespace detail
brock.erase_menu(false); brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared brock.delay_restore(3); //Restores if delay_restore not decleared
} }
brock.wd_manager().destroy(msgwnd); wd_manager.destroy(msgwnd);
nana::detail::platform_spec::instance().release_window_icon(msgwnd->root); nana::detail::platform_spec::instance().release_window_icon(msgwnd->root);
break; break;
case WM_NCDESTROY: case WM_NCDESTROY:
brock.manage_form_loader(msgwnd, false); brock.manage_form_loader(msgwnd, false);
brock.wd_manager().destroy_handle(msgwnd); wd_manager.destroy_handle(msgwnd);
if(--context.window_count <= 0) if(--context.window_count <= 0)
{ {
@ -1561,7 +1574,7 @@ namespace detail
def_window_proc = true; def_window_proc = true;
} }
root_runtime = brock.wd_manager().root_runtime(native_window); root_runtime = wd_manager.root_runtime(native_window);
if(root_runtime) if(root_runtime)
{ {
root_runtime->condition.pressed = pressed_wd; root_runtime->condition.pressed = pressed_wd;

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-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 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
@ -13,6 +13,9 @@
#include <nana/detail/platform_spec_selector.hpp> #include <nana/detail/platform_spec_selector.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/screen.hpp> #include <nana/gui/screen.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/window_manager.hpp>
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#if defined(STD_THREAD_NOT_SUPPORTED) #if defined(STD_THREAD_NOT_SUPPORTED)
#include <nana/std_mutex.hpp> #include <nana/std_mutex.hpp>
@ -23,8 +26,6 @@
#include "../../paint/detail/image_ico.hpp" #include "../../paint/detail/image_ico.hpp"
#elif defined(NANA_X11) #elif defined(NANA_X11)
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/window_manager.hpp>
#endif #endif
namespace nana{ namespace nana{
@ -131,9 +132,13 @@ namespace nana{
} }
} }
if (async) if (async)
{
::ShowWindowAsync(wd, cmd); ::ShowWindowAsync(wd, cmd);
else return;
::ShowWindow(wd, cmd); }
internal_revert_guard revert;
::ShowWindow(wd, cmd);
} }
#elif defined(NANA_X11) #elif defined(NANA_X11)
namespace restrict namespace restrict
@ -143,6 +148,33 @@ namespace nana{
#endif #endif
//struct native_interface //struct native_interface
void native_interface::affinity_execute(native_window_type native_handle, const std::function<void()>& fn)
{
if (!fn)
return;
#if defined(NANA_WINDOWS)
auto mswin = reinterpret_cast<HWND>(native_handle);
if (::IsWindow(mswin))
{
if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(mswin, nullptr))
{
detail::messages::arg_affinity_execute arg;
arg.function_ptr = &fn;
internal_revert_guard revert;
::SendMessage(mswin, detail::messages::affinity_execute, reinterpret_cast<WPARAM>(&arg), 0);
return;
}
}
fn();
#else
fn();
#endif
}
nana::size native_interface::primary_monitor_size() nana::size native_interface::primary_monitor_size()
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
@ -173,6 +205,8 @@ namespace nana{
mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top); mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top);
} }
} }
#else
static_cast<void>(pos); //eliminate unused parameter compiler warning.
#endif #endif
return rectangle{ primary_monitor_size() }; return rectangle{ primary_monitor_size() };
} }
@ -547,6 +581,8 @@ namespace nana{
activate_window(reinterpret_cast<native_window_type>( activate_window(reinterpret_cast<native_window_type>(
::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER) ::GetWindow(reinterpret_cast<HWND>(wd), GW_OWNER)
)); ));
#else
static_cast<void>(wd); //eliminate unused parameter compiler warning.
#endif #endif
} }
@ -565,6 +601,8 @@ namespace nana{
else else
::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0); ::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0);
} }
#else
static_cast<void>(wd); //eliminate unused parameter compiler warning.
#endif #endif
} }
@ -640,6 +678,7 @@ namespace nana{
::XFlush(disp); ::XFlush(disp);
} }
static_cast<void>(active); //eliminate unused parameter compiler warning.
#endif #endif
} }
@ -715,6 +754,7 @@ namespace nana{
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
::InvalidateRect(reinterpret_cast<HWND>(wd), nullptr, true); ::InvalidateRect(reinterpret_cast<HWND>(wd), nullptr, true);
#elif defined(NANA_X11) #elif defined(NANA_X11)
static_cast<void>(wd); //eliminate unused parameter compiler warning.
#endif #endif
} }
@ -963,6 +1003,7 @@ namespace nana{
::SetWindowPos(native_wd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); ::SetWindowPos(native_wd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::AttachThreadInput(::GetCurrentThreadId(), fg_tid, FALSE); ::AttachThreadInput(::GetCurrentThreadId(), fg_tid, FALSE);
#else #else
static_cast<void>(activated); //eliminate unused parameter compiler warning.
set_window_z_order(wd, nullptr, z_order_action::top); set_window_z_order(wd, nullptr, z_order_action::top);
#endif #endif
} }
@ -1110,11 +1151,18 @@ namespace nana{
auto native_interface::window_caption(native_window_type wd) -> native_string_type auto native_interface::window_caption(native_window_type wd) -> native_string_type
{ {
native_string_type str;
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
auto & lock = bedrock::instance().wd_manager().internal_lock();
bool is_current_thread = (::GetCurrentThreadId() == ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr));
if (!is_current_thread)
lock.revert();
int length = ::GetWindowTextLength(reinterpret_cast<HWND>(wd)); int length = ::GetWindowTextLength(reinterpret_cast<HWND>(wd));
if(length > 0) if(length > 0)
{ {
native_string_type str;
//One for NULL terminator which GetWindowText will write. //One for NULL terminator which GetWindowText will write.
str.resize(length+1); str.resize(length+1);
@ -1122,9 +1170,11 @@ namespace nana{
//Remove the null terminator writtien by GetWindowText //Remove the null terminator writtien by GetWindowText
str.resize(length); str.resize(length);
return str;
} }
if (!is_current_thread)
lock.forward();
#elif defined(NANA_X11) #elif defined(NANA_X11)
nana::detail::platform_scope_guard psg; nana::detail::platform_scope_guard psg;
::XTextProperty txtpro; ::XTextProperty txtpro;
@ -1136,14 +1186,13 @@ namespace nana{
{ {
if(size > 1) if(size > 1)
{ {
std::string text = *strlist; str = *strlist;
::XFreeStringList(strlist); ::XFreeStringList(strlist);
return text;
} }
} }
} }
#endif #endif
return native_string_type(); return str;
} }
void native_interface::capture_window(native_window_type wd, bool cap) void native_interface::capture_window(native_window_type wd, bool cap)
@ -1305,7 +1354,10 @@ namespace nana{
if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr)) if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast<HWND>(wd), nullptr))
::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::async_set_focus, 0, 0); ::PostMessage(reinterpret_cast<HWND>(wd), nana::detail::messages::async_set_focus, 0, 0);
else else
{
internal_revert_guard revert;
::SetFocus(reinterpret_cast<HWND>(wd)); ::SetFocus(reinterpret_cast<HWND>(wd));
}
} }
#elif defined(NANA_X11) #elif defined(NANA_X11)
nana::detail::platform_scope_guard lock; nana::detail::platform_scope_guard lock;
@ -1414,6 +1466,11 @@ namespace nana{
if(static_cast<unsigned>(y) > sz.height + ext_height) if(static_cast<unsigned>(y) > sz.height + ext_height)
sz.height = static_cast<unsigned>(y); sz.height = static_cast<unsigned>(y);
} }
#else
//eliminate unused parameter compiler warning.
static_cast<void>(ext_width);
static_cast<void>(ext_height);
static_cast<void>(true_for_max);
#endif #endif
return sz; return sz;
} }

View File

@ -53,7 +53,7 @@ namespace nana
//get the root graphics //get the root graphics
auto& graph = *(wd->root_graph); auto& graph = *(wd->root_graph);
if (wd->other.category != category::lite_widget_tag::value) if (category::flags::lite_widget != wd->other.category)
graph.bitblt(vr, wd->drawer.graphics, nana::point(vr.x - wd->pos_root.x, vr.y - wd->pos_root.y)); graph.bitblt(vr, wd->drawer.graphics, nana::point(vr.x - wd->pos_root.x, vr.y - wd->pos_root.y));
_m_paste_children(wd, is_child_refreshed, have_refreshed, vr, graph, nana::point()); _m_paste_children(wd, is_child_refreshed, have_refreshed, vr, graph, nana::point());
@ -66,7 +66,7 @@ namespace nana
nana::point p_src; nana::point p_src;
for (auto & el : blocks) for (auto & el : blocks)
{ {
if (el.window->other.category == category::frame_tag::value) if (category::flags::frame == el.window->other.category)
{ {
native_window_type container = el.window->other.attribute.frame->container; native_window_type container = el.window->other.attribute.frame->container;
native_interface::refresh_window(container); native_interface::refresh_window(container);
@ -95,9 +95,9 @@ namespace nana
} }
//read_visual_rectangle //read_visual_rectangle
//@brief: Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget, ///@brief Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget,
// the visual rectangle is a rectangular block that a window should be displayed on screen. /// the visual rectangle is a rectangular block that a window should be displayed on screen.
// The result is a rectangle that is a visible area for its ancesters. /// The result is a rectangle that is a visible area for its ancesters.
bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual) bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual)
{ {
if (! wd->displayed()) return false; if (! wd->displayed()) return false;
@ -158,7 +158,7 @@ namespace nana
bool window_layout::enable_effects_bground(core_window_t * wd, bool enabled) bool window_layout::enable_effects_bground(core_window_t * wd, bool enabled)
{ {
if (wd->other.category != category::widget_tag::value) if (category::flags::widget != wd->other.category)
return false; return false;
if (false == enabled) if (false == enabled)
@ -199,11 +199,11 @@ namespace nana
nana::point rpos{ wd->pos_root }; nana::point rpos{ wd->pos_root };
auto & glass_buffer = wd->other.glass_buffer; auto & glass_buffer = wd->other.glass_buffer;
if (wd->parent->other.category == category::lite_widget_tag::value) if (category::flags::lite_widget == wd->parent->other.category)
{ {
std::vector<core_window_t*> layers; std::vector<core_window_t*> layers;
core_window_t * beg = wd->parent; core_window_t * beg = wd->parent;
while (beg && (beg->other.category == category::lite_widget_tag::value)) while (beg && (category::flags::lite_widget == beg->other.category))
{ {
layers.push_back(beg); layers.push_back(beg);
beg = beg->parent; beg = beg->parent;
@ -229,7 +229,7 @@ namespace nana
nana::rectangle ovlp; nana::rectangle ovlp;
if (child->visible && overlap(r, rectangle(child->pos_owner, child->dimension), ovlp)) if (child->visible && overlap(r, rectangle(child->pos_owner, child->dimension), ovlp))
{ {
if (child->other.category != category::lite_widget_tag::value) if (category::flags::lite_widget != child->other.category)
glass_buffer.bitblt(nana::rectangle(ovlp.x - pre->pos_owner.x, ovlp.y - pre->pos_owner.y, ovlp.width, ovlp.height), child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y)); glass_buffer.bitblt(nana::rectangle(ovlp.x - pre->pos_owner.x, ovlp.y - pre->pos_owner.y, ovlp.width, ovlp.height), child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y));
ovlp.x += pre->pos_root.x; ovlp.x += pre->pos_root.x;
ovlp.y += pre->pos_root.y; ovlp.y += pre->pos_root.y;
@ -250,7 +250,7 @@ namespace nana
nana::rectangle ovlp; nana::rectangle ovlp;
if (child->visible && overlap(r_of_wd, rectangle{ child->pos_owner, child->dimension }, ovlp)) if (child->visible && overlap(r_of_wd, rectangle{ child->pos_owner, child->dimension }, ovlp))
{ {
if (child->other.category != category::lite_widget_tag::value) if (category::flags::lite_widget != child->other.category)
glass_buffer.bitblt(nana::rectangle{ ovlp.x - wd->pos_owner.x, ovlp.y - wd->pos_owner.y, ovlp.width, ovlp.height }, child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y)); glass_buffer.bitblt(nana::rectangle{ ovlp.x - wd->pos_owner.x, ovlp.y - wd->pos_owner.y, ovlp.width, ovlp.height }, child->drawer.graphics, nana::point(ovlp.x - child->pos_owner.x, ovlp.y - child->pos_owner.y));
ovlp.x += wd->pos_root.x; ovlp.x += wd->pos_root.x;
@ -285,7 +285,7 @@ namespace nana
if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect)) if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect))
{ {
bool have_child_refreshed = false; bool have_child_refreshed = false;
if (child->other.category != category::lite_widget_tag::value) if (category::flags::lite_widget != child->other.category)
{ {
if (is_child_refreshed && (false == child->flags.refreshing)) if (is_child_refreshed && (false == child->flags.refreshing))
{ {
@ -357,7 +357,7 @@ namespace nana
//_m_notify_glasses //_m_notify_glasses
//@brief: Notify the glass windows that are overlapped with the specified vis_rect //@brief: Notify the glass windows that are overlapped with the specified vis_rect
void window_layout::_m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& r_visual) void window_layout::_m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& /*r_visual*/)
{ {
typedef category::flags cat_flags; typedef category::flags cat_flags;

View File

@ -311,7 +311,7 @@ namespace detail
wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph); wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph);
impl_->wd_register.insert(wd, wd->thread_id); impl_->wd_register.insert(wd, wd->thread_id);
if (owner && owner->other.category == category::frame_tag::value) if (owner && (category::flags::frame == owner->other.category))
insert_frame(owner, wd); insert_frame(owner, wd);
bedrock::inc_window(wd->thread_id); bedrock::inc_window(wd->thread_id);
@ -343,7 +343,7 @@ namespace detail
{ {
//Thread-Safe Required! //Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
if(frame->other.category == category::frame_tag::value) if(category::flags::frame == frame->other.category)
frame->other.attribute.frame->attach.push_back(wd); frame->other.attribute.frame->attach.push_back(wd);
return true; return true;
} }
@ -356,9 +356,9 @@ namespace detail
{ {
//Thread-Safe Required! //Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
if(frame->other.category == category::frame_tag::value) if(category::flags::frame == frame->other.category)
{ {
if (impl_->wd_register.available(wd) && wd->other.category == category::root_tag::value && wd->root != frame->root) if (impl_->wd_register.available(wd) && (category::flags::root == wd->other.category) && wd->root != frame->root)
{ {
frame->other.attribute.frame->attach.push_back(wd->root); frame->other.attribute.frame->attach.push_back(wd->root);
return true; return true;
@ -461,7 +461,7 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd) == false) return; if (impl_->wd_register.available(wd) == false) return;
if((wd->other.category == category::root_tag::value) || (wd->other.category != category::frame_tag::value)) if((category::flags::root == wd->other.category) || (category::flags::frame != wd->other.category))
{ {
impl_->misc_register.erase(wd->root); impl_->misc_register.erase(wd->root);
impl_->wd_register.remove(wd); impl_->wd_register.remove(wd);
@ -481,7 +481,7 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd)) if (impl_->wd_register.available(wd))
{ {
if(wd->other.category == category::root_tag::value) if(category::flags::root == wd->other.category)
native_interface::window_icon(wd->root, small_icon, big_icon); native_interface::window_icon(wd->root, small_icon, big_icon);
} }
} }
@ -501,9 +501,9 @@ namespace detail
native_window_type nv = nullptr; native_window_type nv = nullptr;
switch(wd->other.category) switch(wd->other.category)
{ {
case category::root_tag::value: case category::flags::root:
nv = wd->root; break; nv = wd->root; break;
case category::frame_tag::value: case category::flags::frame:
nv = wd->other.attribute.frame->container; break; nv = wd->other.attribute.frame->container; break;
default: //category::widget_tag, category::lite_widget_tag default: //category::widget_tag, category::lite_widget_tag
break; break;
@ -700,7 +700,7 @@ namespace detail
wd->dimension = sz; wd->dimension = sz;
if(category::lite_widget_tag::value != 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.make(sz);
@ -711,13 +711,13 @@ namespace detail
if(graph_state != wd->drawer.graphics.empty()) if(graph_state != wd->drawer.graphics.empty())
wd->drawer.typeface_changed(); wd->drawer.typeface_changed();
if(category::root_tag::value == wd->other.category) if(category::flags::root == wd->other.category)
{ {
wd->root_graph->make(sz); wd->root_graph->make(sz);
if(false == passive) if(false == passive)
native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height)); native_interface::window_size(wd->root, sz + nana::size(wd->extra_width, wd->extra_height));
} }
else if(category::frame_tag::value == wd->other.category) else if(category::flags::frame == wd->other.category)
{ {
native_interface::window_size(wd->other.attribute.frame->container, sz); native_interface::window_size(wd->other.attribute.frame->container, sz);
for(auto natwd : wd->other.attribute.frame->attach) for(auto natwd : wd->other.attribute.frame->attach)
@ -828,7 +828,7 @@ namespace detail
//do_lazy_refresh //do_lazy_refresh
//@brief: defined a behavior of flush the screen //@brief: defined a behavior of flush the screen
//@return: it returns true if the wnd is available //@return: it returns true if the wnd is available
bool window_manager::do_lazy_refresh(core_window_t* wd, bool force_copy_to_screen) bool window_manager::do_lazy_refresh(core_window_t* wd, bool force_copy_to_screen, bool refresh_tree)
{ {
//Thread-Safe Required! //Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_); std::lock_guard<decltype(mutex_)> lock(mutex_);
@ -843,8 +843,11 @@ namespace detail
{ {
if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen) if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen)
{ {
window_layer::paint(wd, false, false); window_layer::paint(wd, false, refresh_tree);
this->map(wd, force_copy_to_screen); this->map(wd, force_copy_to_screen);
wd->drawer.graphics.save_as_file("d:\\button.bmp");
wd->root_graph->save_as_file("d:\\button_root.bmp");
} }
else if (effects::edge_nimbus::none != wd->effect.edge_nimbus) else if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
{ {
@ -852,7 +855,7 @@ namespace detail
} }
} }
else else
window_layer::paint(wd, true, false); //only refreshing if it has an invisible parent window_layer::paint(wd, true, refresh_tree); //only refreshing if it has an invisible parent
} }
wd->other.upd_state = core_window_t::update_state::none; wd->other.upd_state = core_window_t::update_state::none;
return true; return true;
@ -1362,7 +1365,7 @@ namespace detail
root_attr->menubar = nullptr; root_attr->menubar = nullptr;
} }
if (wd->other.category == category::root_tag::value) if (wd->other.category == category::flags::root)
{ {
root_runtime(wd->root)->shortkeys.clear(); root_runtime(wd->root)->shortkeys.clear();
wd->other.attribute.root->focus = nullptr; wd->other.attribute.root->focus = nullptr;
@ -1442,7 +1445,7 @@ namespace detail
} }
} }
if (wd->other.category == category::frame_tag::value) if (category::flags::frame == wd->other.category)
{ {
//remove the frame handle from the WM frames manager. //remove the frame handle from the WM frames manager.
utl::erase(root_attr->frames, wd); utl::erase(root_attr->frames, wd);
@ -1599,7 +1602,7 @@ namespace detail
for(auto i = wd->children.rbegin(); i != wd->children.rend(); ++i) for(auto i = wd->children.rbegin(); i != wd->children.rend(); ++i)
{ {
core_window_t* child = *i; core_window_t* child = *i;
if((child->other.category != category::root_tag::value) && _m_effective(child, pos)) if((child->other.category != category::flags::root) && _m_effective(child, pos))
{ {
child = _m_find(child, pos); child = _m_find(child, pos);
if(child) if(child)

View File

@ -212,7 +212,7 @@ namespace nana
class menu_crook class menu_crook
: public crook_interface : public crook_interface
{ {
bool draw(graph_reference graph, const ::nana::color&, const ::nana::color& fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override bool draw(graph_reference graph, const ::nana::color&, const ::nana::color& fgcolor, const nana::rectangle& r, element_state, const data& crook_data) override
{ {
if(crook_data.check_state == state::unchecked) if(crook_data.check_state == state::unchecked)
return true; return true;
@ -266,7 +266,7 @@ namespace nana
class border_depressed class border_depressed
: public border_interface : public border_interface
{ {
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, unsigned weight) bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color&, const ::nana::rectangle& r, element_state estate, unsigned)
{ {
graph.rectangle(r, false, static_cast<color_rgb>((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E)); graph.rectangle(r, false, static_cast<color_rgb>((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E));
graph.rectangle(::nana::rectangle(r).pare_off(1), false, bgcolor); graph.rectangle(::nana::rectangle(r).pare_off(1), false, bgcolor);
@ -277,7 +277,7 @@ namespace nana
class arrow_solid_triangle class arrow_solid_triangle
: public arrow_interface : public arrow_interface
{ {
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, direction dir) override bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, direction dir) override
{ {
::nana::point pos{ r.x + 3, r.y + 3 }; ::nana::point pos{ r.x + 3, r.y + 3 };
switch (dir) switch (dir)
@ -318,7 +318,7 @@ namespace nana
class arrow_hollow_triangle class arrow_hollow_triangle
: public arrow_interface : public arrow_interface
{ {
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override
{ {
int x = r.x + 3; int x = r.x + 3;
int y = r.y + 3; int y = r.y + 3;
@ -364,7 +364,7 @@ namespace nana
class arrowhead class arrowhead
: public arrow_interface : public arrow_interface
{ {
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override
{ {
int x = r.x; int x = r.x;
int y = r.y + 5; int y = r.y + 5;
@ -425,7 +425,7 @@ namespace nana
class arrow_double class arrow_double
: public arrow_interface : public arrow_interface
{ {
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, ::nana::direction dir) override bool draw(graph_reference graph, const ::nana::color&, const ::nana::color&, const ::nana::rectangle& r, element_state, ::nana::direction dir) override
{ {
int x = r.x; int x = r.x;
int y = r.y; int y = r.y;
@ -486,7 +486,7 @@ namespace nana
class annex_button class annex_button
: public element_interface : public element_interface
{ {
bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color& fgcolor, const rectangle& r, element_state estate) override bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color&, const rectangle& r, element_state estate) override
{ {
auto bgcolor = arg_bgcolor; auto bgcolor = arg_bgcolor;

View File

@ -355,13 +355,15 @@ namespace nana
msgbox::msgbox(const std::string& title) msgbox::msgbox(const std::string& title)
: wd_(nullptr), title_(title), button_(ok), icon_(icon_none) : wd_(nullptr), title_(title), button_(ok), icon_(icon_none)
{ {
throw_not_utf8(title_); // throw_not_utf8(title_);
review_utf8(title_);
} }
msgbox::msgbox(window wd, const std::string& title, button_t b) msgbox::msgbox(window wd, const std::string& title, button_t b)
: wd_(wd), title_(title), button_(b), icon_(icon_none) : wd_(wd), title_(title), button_(b), icon_(icon_none)
{ {
throw_not_utf8(title_); // throw_not_utf8(title_);
review_utf8(title_);
} }
msgbox& msgbox::icon(icon_t ic) msgbox& msgbox::icon(icon_t ic)
@ -702,7 +704,7 @@ namespace nana
impl->spinbox.value(std::to_string(impl->value)); impl->spinbox.value(std::to_string(impl->value));
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized&)
{ {
impl->label.size({ label_px, 24 }); impl->label.size({ label_px, 24 });
impl->spinbox.size({ value_px, 24 }); impl->spinbox.size({ value_px, 24 });
@ -780,7 +782,7 @@ namespace nana
impl->spinbox.value(std::to_string(impl->value)); impl->spinbox.value(std::to_string(impl->value));
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized&)
{ {
impl->label.size(::nana::size{ label_px, 24 }); impl->label.size(::nana::size{ label_px, 24 });
impl->spinbox.size(::nana::size{ value_px, 24 }); impl->spinbox.size(::nana::size{ value_px, 24 });

View File

@ -314,6 +314,8 @@ namespace nana
::Shell_NotifyIcon(impl_->icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); ::Shell_NotifyIcon(impl_->icon_added ? NIM_MODIFY : NIM_ADD, &icon_data);
impl_->icon_added = true; impl_->icon_added = true;
#else
static_cast<void>(str); //to eliminate unused parameter compiler warning.
#endif #endif
} }
@ -330,6 +332,8 @@ namespace nana
impl_->set_icon(impl_->icon_handle); impl_->set_icon(impl_->icon_handle);
::DestroyIcon(pre_icon); ::DestroyIcon(pre_icon);
} }
#else
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning
#endif #endif
} }
@ -338,6 +342,8 @@ namespace nana
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
impl_->icons.push_back(icon); impl_->icons.push_back(icon);
#else
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning.
#endif #endif
} }
@ -352,6 +358,8 @@ namespace nana
} }
else else
impl_->ani_timer.stop(); impl_->ani_timer.stop();
#else
static_cast<void>(ms); //to eliminate unused parameter compiler warning.
#endif #endif
} }

View File

@ -15,6 +15,7 @@
#include <cmath> #include <cmath>
#include <map> #include <map>
#include <deque> #include <deque>
#include <nana/push_ignore_diagnostic>
#include <nana/deploy.hpp> #include <nana/deploy.hpp>
#include <nana/gui/place.hpp> #include <nana/gui/place.hpp>
#include <nana/gui/programming_interface.hpp> #include <nana/gui/programming_interface.hpp>
@ -522,12 +523,18 @@ namespace nana
//It will delete the element and recollocate when the window destroyed. //It will delete the element and recollocate when the window destroyed.
event_handle _m_make_destroy(window wd) event_handle _m_make_destroy(window wd)
{ {
return API::events(wd).destroy.connect([this, wd](const arg_destroy& arg) return API::events(wd).destroy.connect([this, wd](const arg_destroy&)
{ {
for (auto i = elements.begin(), end = elements.end(); i != end; ++i) for (auto i = elements.begin(), end = elements.end(); i != end; ++i)
{ {
if (!API::is_destroying(API::get_parent_window(wd))) if (i->handle == wd)
place_ptr_->collocate(); {
elements.erase(i);
if (!API::is_destroying(API::get_parent_window(wd)))
place_ptr_->collocate();
break;
}
} }
}); });
} }
@ -1125,7 +1132,7 @@ namespace nana
} }
} }
void collocate(window wd) override void collocate(window) override
{ {
if (!field || !(visible && display)) if (!field || !(visible && display))
return; return;
@ -1321,8 +1328,6 @@ namespace nana
public: public:
div_splitter(place_parts::number_t init_weight) div_splitter(place_parts::number_t init_weight)
: division(kind::splitter, std::string()), : division(kind::splitter, std::string()),
splitter_cursor_(cursor::arrow),
pause_move_collocate_(false),
init_weight_(init_weight) init_weight_(init_weight)
{ {
this->weight.assign(splitter_px); this->weight.assign(splitter_px);
@ -1374,9 +1379,18 @@ namespace nana
left_pixels_ = area_left.*px_ptr; left_pixels_ = area_left.*px_ptr;
right_pixels_ = area_right.*px_ptr; right_pixels_ = area_right.*px_ptr;
grabbed_ = true;
}
else if(event_code::mouse_up == arg.evt_code)
{
grabbed_ = false;
} }
else if (event_code::mouse_move == arg.evt_code) else if (event_code::mouse_move == arg.evt_code)
{ {
if(!grabbed_)
return;
const bool vert = (::nana::cursor::size_we != splitter_cursor_); const bool vert = (::nana::cursor::size_we != splitter_cursor_);
auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w(); auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w();
int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x); int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x);
@ -1413,8 +1427,10 @@ namespace nana
} }
}; };
splitter_.events().mouse_down.connect_unignorable(grab_fn); auto & events = splitter_.events();
splitter_.events().mouse_move.connect_unignorable(grab_fn); events.mouse_down.connect_unignorable(grab_fn);
events.mouse_up.connect_unignorable(grab_fn);
events.mouse_move.connect_unignorable(grab_fn);
} }
auto limited_range = _m_update_splitter_range(); auto limited_range = _m_update_splitter_range();
@ -1527,13 +1543,14 @@ namespace nana
return area; return area;
} }
private: private:
nana::cursor splitter_cursor_; nana::cursor splitter_cursor_{nana::cursor::arrow};
place_parts::splitter<true> splitter_; place_parts::splitter<true> splitter_;
nana::point begin_point_; nana::point begin_point_;
int left_pos_, right_pos_; int left_pos_, right_pos_;
unsigned left_pixels_, right_pixels_; unsigned left_pixels_, right_pixels_;
dragger dragger_; dragger dragger_;
bool pause_move_collocate_; //A flag represents whether do move when collocating. bool grabbed_{ false };
bool pause_move_collocate_{ false }; //A flag represents whether do move when collocating.
place_parts::number_t init_weight_; place_parts::number_t init_weight_;
}; };
@ -1558,7 +1575,7 @@ namespace nana
} }
} }
void collocate(window wd) override void collocate(window) override
{ {
if (!dockable_field) if (!dockable_field)
{ {
@ -2847,3 +2864,5 @@ namespace nana
} }
//end class place //end class place
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic>

View File

@ -280,64 +280,11 @@ namespace nana
void add_pane(factory & fn) void add_pane(factory & fn)
{ {
rectangle r{ point(), this->size()}; auto fn_ptr = &fn;
API::dev::affinity_execute(*this, [this, fn_ptr]
//get a rectangle excluding caption
r.y = 20;
if (r.height > 20)
r.height -= 20;
else
r.height = 0;
if (!tabbar_)
{ {
if (panels_.size() > 0) _m_add_pane(*fn_ptr);
{ });
tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear();
tabbar_->events().selected([this](const event_arg&)
{
auto handle = tabbar_->attach(tabbar_->selected());
//Set caption through a caption of window specified by handle
//Empty if handle is null
caption_.caption(API::window_caption(handle));
});
tabbar_->move({ 0, r.bottom() - 20, r.width, 20 });
r.height -= 20;
std::size_t pos = 0;
for (auto & pn : panels_)
{
tabbar_->push_back(pn.widget_ptr->caption());
tabbar_->attach(pos++, *pn.widget_ptr);
}
}
}
else
r.height -= 20;
auto wdg = fn(*this);
if (tabbar_)
{
tabbar_->push_back(wdg->caption());
tabbar_->attach(panels_.size(), wdg->handle());
}
if (panels_.empty())
caption_.caption(wdg->caption());
panels_.emplace_back();
panels_.back().widget_ptr.swap(wdg);
for (auto & pn : panels_)
{
if (pn.widget_ptr)
pn.widget_ptr->move(r);
}
} }
void float_away(const ::nana::point& move_pos) void float_away(const ::nana::point& move_pos)
@ -382,6 +329,71 @@ namespace nana
{ {
return (nullptr != container_); return (nullptr != container_);
} }
private:
void _m_add_pane(factory & fn)
{
rectangle r{ point(), this->size() };
//get a rectangle excluding caption
r.y = 20;
if (r.height > 20)
r.height -= 20;
else
r.height = 0;
if (!tabbar_)
{
if (panels_.size() > 0)
{
tabbar_.reset(new tabbar_lite(*this));
tabbar_->events().selected.clear();
tabbar_->events().selected([this]
{
auto handle = tabbar_->attach(tabbar_->selected());
//Set caption through a caption of window specified by handle
//Empty if handle is null
caption_.caption(API::window_caption(handle));
});
r.height -= 20;
tabbar_->move({ 0, r.bottom(), r.width, 20 });
std::size_t pos = 0;
for (auto & pn : panels_)
{
tabbar_->push_back(pn.widget_ptr->caption());
tabbar_->attach(pos++, *pn.widget_ptr);
}
}
}
else
r.height -= 20;
auto wdg = fn(*this);
if (wdg)
{
if (tabbar_)
{
tabbar_->push_back(::nana::charset(wdg->caption()));
tabbar_->attach(panels_.size(), wdg->handle());
}
if (panels_.empty())
{
caption_.caption(wdg->caption());
}
panels_.emplace_back();
panels_.back().widget_ptr.swap(wdg);
for (auto & pn : panels_)
{
if (pn.widget_ptr)
pn.widget_ptr->move(r);
}
}
}
private: private:
window host_window_{nullptr}; window host_window_{nullptr};
place_parts::dock_notifier_interface* notifier_{ nullptr }; place_parts::dock_notifier_interface* notifier_{ nullptr };

View File

@ -104,8 +104,7 @@ namespace API
{ {
if (iwd->effect.edge_nimbus == effects::edge_nimbus::none) if (iwd->effect.edge_nimbus == effects::edge_nimbus::none)
{ {
basic_window::edge_nimbus_action ena = { iwd }; cont.push_back(basic_window::edge_nimbus_action{ iwd, false});
cont.push_back(ena);
} }
iwd->effect.edge_nimbus = static_cast<effects::edge_nimbus>(static_cast<unsigned>(en) | static_cast<unsigned>(iwd->effect.edge_nimbus)); iwd->effect.edge_nimbus = static_cast<effects::edge_nimbus>(static_cast<unsigned>(en) | static_cast<unsigned>(iwd->effect.edge_nimbus));
} }
@ -180,6 +179,11 @@ namespace API
namespace dev namespace dev
{ {
void affinity_execute(window window_handle, const std::function<void()>& fn)
{
interface_type::affinity_execute(root(window_handle), fn);
}
bool set_events(window wd, const std::shared_ptr<general_events>& gep) bool set_events(window wd, const std::shared_ptr<general_events>& gep)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
@ -330,7 +334,7 @@ namespace API
return nullptr; return nullptr;
} }
//exit
//close all windows in current thread //close all windows in current thread
void exit() void exit()
{ {
@ -367,6 +371,42 @@ namespace API
interface_type::close_window(i); interface_type::close_window(i);
} }
} }
//close all windows
void exit_all()
{
std::vector<basic_window*> v;
internal_scope_guard lock;
restrict::wd_manager().all_handles(v);
if (v.size())
{
std::vector<native_window_type> roots;
native_window_type root = nullptr;
//unsigned tid = nana::system::this_thread_id();
for (auto wd : v)
{
if (/*(wd->thread_id == tid) &&*/ (wd->root != root))
{
root = wd->root;
bool exists = false;
for (auto i = roots.cbegin(); i != roots.cend(); ++i)
{
if (*i == root)
{
exists = true;
break;
}
}
if (!exists)
roots.push_back(root);
}
}
for (auto i : roots)
interface_type::close_window(i);
}
}
//transform_shortkey_text //transform_shortkey_text
//@brief: This function searchs whether the text contains a '&' and removes the character for transforming. //@brief: This function searchs whether the text contains a '&' and removes the character for transforming.

View File

@ -167,6 +167,8 @@ namespace nana
} }
} }
} }
#else
static_cast<void>(pos); //to eliminate unused parameter compiler warning.
#endif #endif
return get_primary(); return get_primary();
} }

View File

@ -227,7 +227,7 @@ namespace nana
window_->tooltip_move(API::cursor_position(), true); window_->tooltip_move(API::cursor_position(), true);
} }
void show_duration(window wd, point pos, const std::string& text, std::size_t duration) void show_duration(window /*wd*/, point pos, const std::string& text, std::size_t duration)
{ {
if (nullptr == window_ || window_->tooltip_empty()) if (nullptr == window_ || window_->tooltip_empty())
{ {

View File

@ -163,7 +163,7 @@ namespace nana{ namespace drawerbase
_m_press(graph, false); _m_press(graph, false);
} }
void trigger::key_press(graph_reference graph, const arg_keyboard& arg) void trigger::key_press(graph_reference, const arg_keyboard& arg)
{ {
bool ch_tabstop_next; bool ch_tabstop_next;
switch(arg.key) switch(arg.key)

View File

@ -216,7 +216,7 @@ namespace nana{ namespace drawerbase
uiobj.check(false); uiobj.check(false);
uiobj.react(false); uiobj.react(false);
element_tag el = {}; element_tag el;
el.uiobj = &uiobj; el.uiobj = &uiobj;

View File

@ -611,7 +611,7 @@ namespace nana
} }
} }
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg) void trigger::mouse_down(graph_reference, const arg_mouse& arg)
{ {
//drawer_->set_mouse_press(true); //drawer_->set_mouse_press(true);
drawer_->set_button_state(element_state::pressed, false); drawer_->set_button_state(element_state::pressed, false);
@ -629,7 +629,7 @@ namespace nana
} }
} }
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg) void trigger::mouse_up(graph_reference, const arg_mouse& arg)
{ {
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister()) if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
{ {
@ -656,7 +656,7 @@ namespace nana
} }
} }
void trigger::mouse_wheel(graph_reference graph, const arg_wheel& arg) void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
{ {
if(drawer_->widget_ptr()->enabled()) if(drawer_->widget_ptr()->enabled())
{ {
@ -714,7 +714,7 @@ namespace nana
API::dev::lazy_refresh(); API::dev::lazy_refresh();
} }
void trigger::key_char(graph_reference graph, const arg_keyboard& arg) void trigger::key_char(graph_reference, const arg_keyboard& arg)
{ {
if (drawer_->editor()->respond_char(arg)) if (drawer_->editor()->respond_char(arg))
API::dev::lazy_refresh(); API::dev::lazy_refresh();

View File

@ -18,7 +18,7 @@ namespace nana
namespace form namespace form
{ {
//class trigger //class trigger
void trigger::attached(widget_reference wdg, graph_reference graph) void trigger::attached(widget_reference wdg, graph_reference)
{ {
wd_ = &wdg; wd_ = &wdg;
API::ignore_mouse_focus(wdg, true); API::ignore_mouse_focus(wdg, true);

View File

@ -437,7 +437,7 @@ namespace nana
return total_w; return total_w;
} }
bool _m_each_line(graph_reference graph, dstream::linecontainer& line, render_status& rs) bool _m_each_line(graph_reference graph, dstream::linecontainer&, render_status& rs)
{ {
std::wstring text; std::wstring text;
iterator block_start; iterator block_start;

View File

@ -329,7 +329,7 @@ namespace nana
struct column_t struct column_t
{ {
native_string_type text; ///< "text" header of the column number "index" with weigth "pixels" native_string_type text; ///< "text" header of the column number "index" with weigth "pixels"
unsigned pixels; unsigned pixels; ///< width
bool visible{true}; bool visible{true};
size_type index; size_type index;
std::function<bool(const std::string&, nana::any*, const std::string&, nana::any*, bool reverse)> weak_ordering; std::function<bool(const std::string&, nana::any*, const std::string&, nana::any*, bool reverse)> weak_ordering;
@ -338,6 +338,7 @@ namespace nana
column_t(native_string_type&& txt, unsigned px, size_type pos) column_t(native_string_type&& txt, unsigned px, size_type pos)
: text(std::move(txt)), pixels(px), index(pos) : text(std::move(txt)), pixels(px), index(pos)
{} {}
/// \todo introduce default cell format
}; };
using container = std::vector<column_t> ; using container = std::vector<column_t> ;
@ -410,7 +411,7 @@ namespace nana
return cont_.back().index; return cont_.back().index;
} }
void item_width(size_type pos, unsigned width) void item_width(size_type pos, unsigned width) ///< set the column width
{ {
column(pos).pixels = width; column(pos).pixels = width;
} }
@ -427,7 +428,7 @@ namespace nana
return 0; return 0;
} }
unsigned pixels() const unsigned pixels() const ///< the visible width of the whole header
{ {
unsigned pixels = 0; unsigned pixels = 0;
for(auto & m : cont_) for(auto & m : cont_)
@ -470,12 +471,13 @@ namespace nana
{ {
if(x < static_cast<int>(col.pixels)) if(x < static_cast<int>(col.pixels))
return col.index; return col.index;
x -= col.pixels; if (col.visible)
x -= col.pixels;
} }
return npos; return npos;
} }
/// return the left position of the column originaly at index "pos" . /// return the left position and width (in variable *pixels) of the column originaly at index "pos" .
int item_pos(size_type pos, unsigned * pixels) const int item_pos(size_type pos, unsigned * pixels) const
{ {
int left = 0; int left = 0;
@ -493,7 +495,8 @@ namespace nana
} }
return left; return left;
} }
/// return the original index of the visible col currently before(in front of) or after the col originaly at index "index"
/// return the original index of the visible col currently before(in front of) or after the col originaly at index "index"
size_type neighbor(size_type index, bool front) const size_type neighbor(size_type index, bool front) const
{ {
size_type n = npos; size_type n = npos;
@ -509,11 +512,12 @@ namespace nana
break; break;
} }
else if(i->visible) else if(i->visible)
n = i->index; n = i->index;
} }
return npos; return npos;
} }
/// return the original index of the currently first visible col
/// return the original index of the currently first visible col
size_type begin() const size_type begin() const
{ {
for(const auto & m : cont_) for(const auto & m : cont_)
@ -532,7 +536,8 @@ namespace nana
} }
return npos; return npos;
} }
/// move the col originaly at index to the position currently in front (or after) the col originaly at index "to" invalidating some current index
/// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index
void move(size_type index, size_type to, bool front) throw() void move(size_type index, size_type to, bool front) throw()
{ {
if ((index == to) || (index >= cont_.size()) || (to >= cont_.size())) if ((index == to) || (index >= cont_.size()) || (to >= cont_.size()))
@ -879,7 +884,8 @@ namespace nana
list_.back().key_ptr = ptr; list_.back().key_ptr = ptr;
return &list_.back(); return &list_.back();
} }
/// add a new cat created at "pos" and return a ref to it
/// add a new cat created at "pos" and return a ref to it
category_t* create_cat(std::size_t pos, native_string_type&& text) category_t* create_cat(std::size_t pos, native_string_type&& text)
{ {
return &(*list_.emplace(this->get(pos), std::move(text))); return &(*list_.emplace(this->get(pos), std::move(text)));
@ -1828,9 +1834,7 @@ namespace nana
};//end class es_lister };//end class es_lister
//struct essence_t /// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public.
//@brief: this struct gives many data for listbox,
// the state of the struct does not effect on member funcions, therefore all data members are public.
struct essence_t struct essence_t
{ {
enum class item_state{normal, highlighted, pressed, grabbed, floated}; enum class item_state{normal, highlighted, pressed, grabbed, floated};
@ -1859,7 +1863,7 @@ namespace nana
struct scroll_part struct scroll_part
{ {
static const unsigned scale = 16; static const unsigned scale = 16; // ?
int offset_x; int offset_x;
index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category. index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category.
// need to be abs??? to see the same item after sort() ?? // need to be abs??? to see the same item after sort() ??
@ -1942,8 +1946,8 @@ namespace nana
//number_of_lister_item //number_of_lister_item
//@brief: Returns the number of items that are contained in pixels /// @brief Returns the number of items that are contained in pixels
//@param,with_rest: Means whether including extra one item that is not completely contained in reset pixels. /// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels.
size_type number_of_lister_items(bool with_rest) const size_type number_of_lister_items(bool with_rest) const
{ {
unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale); unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale);
@ -1983,8 +1987,9 @@ namespace nana
void trace_item_abs( index_pair abs_pos ) void trace_item_abs( index_pair abs_pos )
{ {
if(abs_pos.item == npos && abs_pos.cat == scroll.offset_y_abs.cat if( abs_pos.item == npos
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat && abs_pos.cat == scroll.offset_y_abs.cat
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat
return; return;
trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ; trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ;
@ -2072,10 +2077,10 @@ namespace nana
bool v = (lister.the_number_of_expanded() > screen_number); bool v = (lister.the_number_of_expanded() > screen_number);
if(v == true && h == false) if(v == true && h == false)
h = (header_s > (sz.width - 2 - scroll.scale)); h = ( (header_s + 2 + scroll.scale ) > sz.width); // 2?
unsigned width = sz.width - 2 - (v ? scroll.scale : 0); unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2?
unsigned height = sz.height - 2 - (h ? scroll.scale : 0); unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2?
//event hander for scrollbars //event hander for scrollbars
auto evt_fn = [this](const arg_scroll& arg) auto evt_fn = [this](const arg_scroll& arg)
@ -2168,7 +2173,8 @@ namespace nana
return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0); return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0);
} }
std::pair<parts, size_t> where(int x, int y){ std::pair<parts, size_t> where(int x, int y)
{
std::pair<parts, size_t> new_where; std::pair<parts, size_t> new_where;
if(2 < x && x < static_cast<int>(graph->width()) - 2 && 1 < y && y < static_cast<int>(graph->height()) - 1) if(2 < x && x < static_cast<int>(graph->width()) - 2 && 1 < y && y < static_cast<int>(graph->height()) - 1)
@ -2614,15 +2620,15 @@ namespace nana
return list_str ; return list_str ;
} }
void es_lister::categ_selected(size_type cat, bool sel) void es_lister::categ_selected(size_type cat, bool sel)
{ {
cat_proxy cpx{ess_,cat}; cat_proxy cpx{ess_,cat};
for (item_proxy &it : cpx ) for (item_proxy &it : cpx )
{ {
if (it.selected() != sel) if (it.selected() != sel)
it.select(sel); it.select(sel);
} }
last_selected_abs = last_selected_dpl = index_pair{cat, npos}; last_selected_abs = last_selected_dpl = index_pair{cat, npos};
} }
class drawer_header_impl class drawer_header_impl
@ -2644,6 +2650,7 @@ namespace nana
item_spliter_ = npos; item_spliter_ = npos;
} }
/// return true an set member item_spliter_ if x is in the spliter area after that header item (column)
bool mouse_spliter(const nana::rectangle& r, int x) bool mouse_spliter(const nana::rectangle& r, int x)
{ {
if(essence_->ptr_state == item_state::highlighted) if(essence_->ptr_state == item_state::highlighted)
@ -2658,7 +2665,7 @@ namespace nana
item_spliter_ = hd.index; // original index item_spliter_ = hd.index; // original index
return true; return true;
} }
x -= hd.pixels; x -= hd.pixels;
} }
} }
} }
@ -2672,7 +2679,7 @@ namespace nana
if(is_grab) if(is_grab)
{ {
ref_xpos_ = pos.x; ref_xpos_ = pos.x;
if(item_spliter_ != npos) if(item_spliter_ != npos) // resize header item, not move it
orig_item_width_ = essence_->header.column(item_spliter_).pixels; orig_item_width_ = essence_->header.column(item_spliter_).pixels;
} }
else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second) else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second)
@ -2680,21 +2687,21 @@ namespace nana
} }
//grab_move //grab_move
//@brief: draw when an item is grabbing. /// @brief draw when an item is grabbing.
//@return: 0 = no graphics changed, 1 = just update, 2 = refresh /// @return 0 = no graphics changed, 1 = just update, 2 = refresh
int grab_move(const nana::rectangle& rect, const nana::point& pos) int grab_move(const nana::rectangle& rect, const nana::point& pos)
{ {
if(item_spliter_ == npos) if(item_spliter_ == npos)
{ { // move header item, not resize it
draw(rect); draw(rect); // first draw the entery header as it was
_m_make_float(rect, pos); _m_make_float(rect, pos); // now draw one floating header item
//Draw the target strip //Draw the target strip
grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front); grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front);
return 1; return 1;
} }
else else
{ { // resize header item, not move it
const auto& item = essence_->header.column(item_spliter_); const auto& item = essence_->header.column(item_spliter_);
//Resize the item specified by item_spliter_. //Resize the item specified by item_spliter_.
auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); auto new_w = orig_item_width_ - (ref_xpos_ - pos.x);
@ -3003,9 +3010,19 @@ namespace nana
} }
} }
//Draws an item /// Draws an item
//@param content_r the rectangle of list content void _m_draw_item(const category_t& cat,
void _m_draw_item(const category_t& cat, const index_pair& item_pos, const int x, const int y, const int txtoff, unsigned width, const nana::rectangle& content_r, const std::vector<size_type>& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const const index_pair& item_pos,
const int x,
const int y,
const int txtoff,
unsigned width,
const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn
const std::vector<size_type>& seqs,
nana::color bgcolor,
nana::color fgcolor,
item_state state
) const
{ {
auto & item = cat.items[item_pos.item]; auto & item = cat.items[item_pos.item];
@ -3022,7 +3039,7 @@ namespace nana
if (item.flags.selected) if (item.flags.selected)
bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected" bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected"
else else
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend
} }
unsigned show_w = width - essence_->scroll.offset_x; unsigned show_w = width - essence_->scroll.offset_x;
@ -3148,6 +3165,7 @@ namespace nana
{ {
auto cell_txtcolor = fgcolor; auto cell_txtcolor = fgcolor;
auto & m_cell = item.cells[column_pos]; auto & m_cell = item.cells[column_pos];
review_utf8(m_cell.text);
nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry
if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need
@ -3338,19 +3356,19 @@ namespace nana
if(essence_->ptr_state == item_state::pressed) if(essence_->ptr_state == item_state::pressed)
{ {
if(essence_->pointer_where.first == parts::header) if(essence_->pointer_where.first == parts::header)
{ { // moving a pressed header : grab it (or split-resize?)
essence_->ptr_state = item_state::grabbed; essence_->ptr_state = item_state::grabbed;
nana::point pos = arg.pos; nana::point pos = arg.pos;
essence_->widget_to_header(pos); essence_->widget_to_header(pos);
drawer_header_->grab(pos, true); drawer_header_->grab(pos, true);
essence_->lister.wd_ptr()->set_capture(true); essence_->lister.wd_ptr()->set_capture(true);
update = 2; //0 = nothing, 1 = update, 2 = refresh
update = 2;
} }
} }
if(essence_->ptr_state == item_state::grabbed) if(essence_->ptr_state == item_state::grabbed)
{ { // moving a grabbed header
nana::point pos = arg.pos; nana::point pos = arg.pos;
essence_->widget_to_header(pos); essence_->widget_to_header(pos);
@ -3436,6 +3454,9 @@ namespace nana
if (lister.forward(essence_->scroll.offset_y_dpl, ptr_where.second, item_pos)) if (lister.forward(essence_->scroll.offset_y_dpl, ptr_where.second, item_pos))
{ {
auto * item_ptr = (item_pos.is_item() ? &lister.at(item_pos) : nullptr); auto * item_ptr = (item_pos.is_item() ? &lister.at(item_pos) : nullptr);
const index_pair abs_item_pos{ item_pos.cat, lister.absolute(item_pos) };
if(ptr_where.first == parts::lister) if(ptr_where.first == parts::lister)
{ {
bool sel = true; bool sel = true;
@ -3444,28 +3465,32 @@ namespace nana
if (arg.shift) if (arg.shift)
lister.select_display_range(lister.last_selected_abs , item_pos, sel); lister.select_display_range(lister.last_selected_abs , item_pos, sel);
else if (arg.ctrl) else if (arg.ctrl)
sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected(); sel = !item_proxy(essence_, abs_item_pos).selected();
else else
lister.select_for_all(false); //cancel all selections lister.select_for_all(false); //cancel all selections
} }
else else
sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected(); {
//Clicking on a category is ignored when single selection is enabled.
//Fixed by Greentwip(issue #121)
if (item_ptr)
sel = !item_proxy(essence_, abs_item_pos).selected();
}
if(item_ptr) if(item_ptr)
{ {
item_ptr->flags.selected = sel; item_ptr->flags.selected = sel;
index_pair last_selected(item_pos.cat, lister.absolute(item_pos));
arg_listbox arg{item_proxy{essence_, last_selected}, sel}; arg_listbox arg{ item_proxy{ essence_, abs_item_pos }, sel };
lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle()); lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle());
if (item_ptr->flags.selected) if (item_ptr->flags.selected)
{ {
lister.cancel_others_if_single_enabled(true, last_selected); lister.cancel_others_if_single_enabled(true, abs_item_pos);
essence_->lister.last_selected_abs = last_selected; essence_->lister.last_selected_abs = abs_item_pos;
} }
else if (essence_->lister.last_selected_abs == last_selected) else if (essence_->lister.last_selected_abs == abs_item_pos)
essence_->lister.last_selected_abs.set_both(npos); essence_->lister.last_selected_abs.set_both(npos);
} }
else if(!lister.single_selection()) else if(!lister.single_selection())
@ -3482,7 +3507,7 @@ namespace nana
lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle()); lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle());
if (item_ptr->flags.checked) if (item_ptr->flags.checked)
lister.cancel_others_if_single_enabled(false, abs_pos); lister.cancel_others_if_single_enabled(false, abs_item_pos);
} }
else if (! lister.single_check()) else if (! lister.single_check())
lister.categ_checked_reverse(item_pos.cat); lister.categ_checked_reverse(item_pos.cat);
@ -3550,15 +3575,16 @@ namespace nana
} }
} }
void trigger::dbl_click(graph_reference graph, const arg_mouse& arg) void trigger::dbl_click(graph_reference graph, const arg_mouse&)
{ {
if (essence_->pointer_where.first == essence_t::parts::header) if (essence_->pointer_where.first == essence_t::parts::header)
if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) if (cursor::size_we == essence_->lister.wd_ptr()->cursor())
{ {
if (essence(). auto_width(drawer_header_->item_spliter() )) // ? in order //adjust the width of column to its content.
essence().update(); if (essence_->auto_width(drawer_header_->item_spliter() ))
return; essence_->update();
} return;
}
if (essence_->pointer_where.first != essence_t::parts::lister) if (essence_->pointer_where.first != essence_t::parts::lister)
return; return;
@ -3575,7 +3601,8 @@ namespace nana
arg_listbox_category arg_cat(cat_proxy(essence_, item_pos.cat)); arg_listbox_category arg_cat(cat_proxy(essence_, item_pos.cat));
lister.wd_ptr()->events().category_dbl_click.emit(arg_cat, lister.wd_ptr()->handle()); lister.wd_ptr()->events().category_dbl_click.emit(arg_cat, lister.wd_ptr()->handle());
if (!arg_cat.category_change_blocked()){ if (!arg_cat.category_change_blocked())
{
bool do_expand = (lister.expand(item_pos.cat) == false); bool do_expand = (lister.expand(item_pos.cat) == false);
lister.expand(item_pos.cat, do_expand); lister.expand(item_pos.cat, do_expand);
@ -3604,8 +3631,8 @@ namespace nana
{ {
bool up = false; bool up = false;
if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0)
return ; return ;
switch(arg.key) switch(arg.key)
{ {
@ -3623,49 +3650,46 @@ namespace nana
} }
break; break;
case keyboard::os_pageup : case keyboard::os_pageup :
up = true; up = true;
case keyboard::os_pagedown: case keyboard::os_pagedown:
{ {
auto& scrl = essence_->scroll.v; auto& scrl = essence_->scroll.v;
if (! scrl.make_page_scroll(!up)) if (! scrl.make_page_scroll(!up))
return; return;
essence_->lister.select_for_all(false); essence_->lister.select_for_all(false);
index_pair idx{essence_->scroll_y_dpl()}; index_pair idx{essence_->scroll_y_dpl()};
if (!up) if (!up)
essence_->lister.forward(idx, scrl.range()-1, idx); essence_->lister.forward(idx, scrl.range()-1, idx);
if (idx.is_item()) if (idx.is_item())
item_proxy::from_display(essence_, idx).select(true); item_proxy::from_display(essence_, idx).select(true);
else else if(!essence_->lister.single_selection())
if(!essence_->lister.single_selection())
essence_->lister.categ_selected(idx.cat, true); essence_->lister.categ_selected(idx.cat, true);
essence_->trace_last_selected_item (); essence_->trace_last_selected_item ();
break; break;
} }
case keyboard::os_home: case keyboard::os_home:
{ {
essence_->lister.select_for_all(false); essence_->lister.select_for_all(false);
index_pair frst{essence_->lister.first()}; index_pair frst{essence_->lister.first()};
if (frst.is_item()) if (frst.is_item())
item_proxy::from_display(essence_, frst).select(true); item_proxy::from_display(essence_, frst).select(true);
else else if(!essence_->lister.single_selection())
if(!essence_->lister.single_selection())
essence_->lister.categ_selected(frst.cat, true); essence_->lister.categ_selected(frst.cat, true);
essence_->trace_last_selected_item (); essence_->trace_last_selected_item ();
break; break;
} }
case keyboard::os_end: case keyboard::os_end:
essence_->lister.select_for_all(false); essence_->lister.select_for_all(false);
item_proxy::from_display(essence_, essence_->lister.last()).select(true); item_proxy::from_display(essence_, essence_->lister.last()).select(true);
essence_->trace_last_selected_item (); essence_->trace_last_selected_item ();
break; break;
default: default:
return; return;
} }
@ -3677,20 +3701,19 @@ namespace nana
{ {
switch(arg.key) switch(arg.key)
{ {
case keyboard::copy: case keyboard::copy:
{ {
export_options exp_opt {essence_->def_exp_options}; export_options exp_opt {essence_->def_exp_options};
exp_opt.columns_order = essence_->header.all_headers(true); exp_opt.columns_order = essence_->header.all_headers(true);
exp_opt.only_selected_items = true; exp_opt.only_selected_items = true;
::nana::system::dataexch().set(essence_->to_string(exp_opt)); ::nana::system::dataexch().set(essence_->to_string(exp_opt));
return; return;
} }
case keyboard::select_all : case keyboard::select_all :
essence_->lister.select_for_all(true); essence_->lister.select_for_all(true);
refresh(graph); refresh(graph);
API::dev::lazy_refresh(); API::dev::lazy_refresh();
break; break;
default: default:
return; return;
} }
@ -3699,6 +3722,7 @@ namespace nana
//end class trigger //end class trigger
//class item_proxy //class item_proxy
item_proxy::item_proxy(essence_t * ess) item_proxy::item_proxy(essence_t * ess)
: ess_(ess) : ess_(ess)
{} {}
@ -3714,23 +3738,24 @@ namespace nana
} }
} }
/// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort()
item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative) item_proxy item_proxy::from_display(essence_t *ess, const index_pair &relative)
{ {
return item_proxy{ess, ess->lister.absolute_pair(relative)}; return item_proxy{ess, ess->lister.absolute_pair(relative)};
} }
item_proxy item_proxy::from_display(const index_pair &relative) const
{
return item_proxy{ess_, ess_->lister.absolute_pair(relative)};
}
/// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort() item_proxy item_proxy::from_display(const index_pair &relative) const
index_pair item_proxy::to_display() const {
{ return item_proxy{ess_, ess_->lister.absolute_pair(relative)};
return ess_->lister.relative_pair(pos_); }
}
bool item_proxy::empty() const /// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort()
index_pair item_proxy::to_display() const
{
return ess_->lister.relative_pair(pos_);
}
bool item_proxy::empty() const
{ {
return !ess_; return !ess_;
} }
@ -3753,8 +3778,8 @@ namespace nana
return cat_->items.at(pos_.item).flags.checked; return cat_->items.at(pos_.item).flags.checked;
} }
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected /// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
item_proxy & item_proxy::select(bool s) item_proxy & item_proxy::select(bool s)
{ {
auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat? auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat?
if(m.flags.selected == s) return *this; // ignore if no change if(m.flags.selected == s) return *this; // ignore if no change
@ -3968,6 +3993,7 @@ namespace nana
//end class item_proxy //end class item_proxy
//class cat_proxy //class cat_proxy
//the member cat_ is used for fast accessing to the category //the member cat_ is used for fast accessing to the category
cat_proxy::cat_proxy(essence_t * ess, size_type pos) cat_proxy::cat_proxy(essence_t * ess, size_type pos)
: ess_(ess), : ess_(ess),
@ -4296,7 +4322,7 @@ namespace nana
} }
//Implementation of arg_category //Implementation of arg_listbox_category
//Contributed by leobackes(pr#97) //Contributed by leobackes(pr#97)
arg_listbox_category::arg_listbox_category(const nana::drawerbase::listbox::cat_proxy& cat) noexcept arg_listbox_category::arg_listbox_category(const nana::drawerbase::listbox::cat_proxy& cat) noexcept
: category(cat), block_change_(false) : category(cat), block_change_(false)
@ -4315,6 +4341,7 @@ namespace nana
//class listbox //class listbox
listbox::listbox(window wd, bool visible) listbox::listbox(window wd, bool visible)
{ {
create(wd, rectangle(), visible); create(wd, rectangle(), visible);
@ -4393,7 +4420,7 @@ namespace nana
} }
unsigned listbox::auto_width(size_type pos, unsigned max) unsigned listbox::auto_width(size_type pos, unsigned max)
{ {
auto & ess = _m_ess(); auto & ess = _m_ess();
unsigned max_w = ess.auto_width(pos, max); unsigned max_w = ess.auto_width(pos, max);
ess.update(); ess.update();
return max_w; return max_w;
@ -4479,34 +4506,33 @@ namespace nana
return *this; return *this;
} }
listbox::item_proxy listbox::at(const index_pair& pos_abs) const listbox::item_proxy listbox::at(const index_pair& pos_abs) const
{ {
return at(pos_abs.cat).at(pos_abs.item); return at(pos_abs.cat).at(pos_abs.item);
} }
// Contributed by leobackes(pr#97) // Contributed by leobackes(pr#97)
listbox::index_pair listbox::at ( const point& pos ) const listbox::index_pair listbox::at ( const point& pos ) const
{ {
auto & ess=_m_ess(); auto & ess=_m_ess();
auto _where=ess.where(pos.x, pos.y); auto _where=ess.where(pos.x, pos.y);
index_pair item_pos{npos,npos}; index_pair item_pos{npos,npos};
if(_where.first==drawerbase::listbox::essence_t::parts::lister){ if(_where.first==drawerbase::listbox::essence_t::parts::lister)
auto & offset_y = ess.scroll.offset_y_dpl; {
ess.lister.forward(offset_y, _where.second, item_pos); auto & offset_y = ess.scroll.offset_y_dpl;
} ess.lister.forward(offset_y, _where.second, item_pos);
return item_pos; }
} return item_pos;
}
//Contributed by leobackes(pr#97) //Contributed by leobackes(pr#97)
listbox::columns_indexs listbox::column_from_pos ( const point& pos ) listbox::columns_indexs listbox::column_from_pos ( const point& pos )
{ {
auto & ess=_m_ess(); auto & ess=_m_ess();
columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x);
return col; return col;
} }
void listbox::insert(const index_pair& pos, std::string text) void listbox::insert(const index_pair& pos, std::string text)
{ {

Some files were not shown because too many files have changed in this diff Show More