diff --git a/.gitignore b/.gitignore index ef6de4d4..e46bb0b6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/makefile-bkl/* *.ilk *.log [Bb]in +[Bb]in/ [Dd]ebug*/ *.lib *.a diff --git a/.travis.yml b/.travis.yml index 4dd0deb2..3e64fdb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ matrix: - alsa-oss - libx11-dev - libxft-dev + - libboost-filesystem-dev sources: - ubuntu-toolchain-r-test - env: CXX=g++-4.9 CC=gcc-4.9 @@ -55,7 +56,7 @@ matrix: - llvm-toolchain-precise 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" - 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 @@ -65,10 +66,71 @@ install: - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir before_script : - - mkdir bld - - cd bld + # travis dont have a fisical monitor. We need to instal an emulator: https://docs.travis-ci.com/user/gui-and-headless-browsers/ + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + - sleep 3 # give xvfb some time to start + # we have: qPCR4vir/nana/nana-demo and now we are in: qPCR4vir/nana/ our executable tests will assces: ../Examples/*.bmp etc.(need to be in parallel with nana-demo/Examples) + #- cd nana-demo + - mkdir bin + - cd bin 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 + - 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 + + diff --git a/CMakeLists.txt b/CMakeLists.txt index f4b6ec4f..46315d96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ -# CMake configuration for Nana +# CMake configuration for Nana # Author: Andrew Kornilov(https://github.com/ierofant) -# Contributor: -# Robert Hauck - Enable support for PNG/Freetype +# Contributors: +# Jinhao +# Robert Hauck - Enable support for PNG/Freetype # Qiangqiang Wu - Add biicode support # Ariel Vina-Rodriguez (qPCR4vir) @@ -9,16 +10,30 @@ #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 # 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) -option(LIBPNG_FROM_OS "Use libpng from operating system." ON) -option(ENABLE_JPEG "Enable the use of JPEG" OFF) -option(LIBJPEG_FROM_OS "Use libjpeg from operating system." ON) -option(ENABLE_AUDIO "Enable class audio::play for PCM playback." OFF) -option(CMAKE_VERBOSE_PREPROCESSOR "Show annoying debug messages during compilation." OFF) -option(CMAKE_STOP_VERBOSE_PREPROCESSOR "Stop compilation after showing the annoying debug messages." ON) -option(BUILD_NANA_DEMOS "Build all the demos form the nana_demo repository." OFF) -# The ISO C++ File System Technical Specification is optional. + +# It seems that project() defines essential system variables like CMAKE_FIND_LIBRARY_PREFIXES. +# https://bbs.archlinux.org/viewtopic.php?id=84967 +project(nana) +cmake_minimum_required(VERSION 2.8) + +set(NANA_LINKS) + +option(NANA_CMAKE_INSTALL_INCLUDES "Install nana includes when compile the library" ON) +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 # This is not a workaround, but an user option. # 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. # If you include the file # 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. -# Boost will be use only if you change one of the following: -option(CMAKE_BOOST_FILESYSTEM_AVAILABLE "Is Boost filesystem available?" OFF) -option(NANA_BOOST_FILESYSTEM_PREFERRED "Is Boost filesystem preferred over nana?" OFF) -option(CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if available (over ISO)?" OFF) -option(CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT "Where to find ?" "../") -option(CMAKE_BOOST_FILESYSTEM_LIB "Flag for the compiler to link: " "-lboost/fs") +# 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 none of them are available. +# You can change that default if you change one of the following +# (please don't define more than one of the _XX_FORCE options): +option(NANA_CMAKE_FIND_BOOST_FILESYSTEM "Search: Is Boost filesystem available?" ON) +option(NANA_CMAKE_NANA_FILESYSTEM_FORCE "Force nana filesystem over ISO and boost?" OFF) +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 ?" "../") +#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 (CMAKE_BOOST_FILESYSTEM_PREFERED OR CMAKE_BOOST_FILESYSTEM_FORCE) +if (NANA_CMAKE_NANA_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) - if (CMAKE_BOOST_FILESYSTEM_FORCE) - add_definitions(-DNANA_BOOST_FILESYSTEM_FORCE) - else() - add_definitions(-DNANA_BOOST_FILESYSTEM_PREFERED) - endif() - include_directories("${CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}") - list(APPEND NANA_LINKS "${CMAKE_BOOST_FILESYSTEM_LIB}") - endif (CMAKE_BOOST_FILESYSTEM_PREFERED OR CMAKE_BOOST_FILESYSTEM_FORCE) -endif (CMAKE_BOOST_FILESYSTEM_AVAILABLE) + include_directories(SYSTEM "${Boost_INCLUDE_DIR}") + list(APPEND NANA_LINKS "${Boost_LIBRARIES}") + endif (Boost_FOUND) + + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_STATIC_RUNTIME ON) # ?? + #set(Boost_USE_MULTITHREADED ON) + +endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) + -project(nana) -cmake_minimum_required(VERSION 2.8) # Compatibility with CMake 3.1 if(POLICY CMP0054) @@ -73,12 +108,11 @@ if(WIN32) endif(MSVC) 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) - endif(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + endif(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif(MINGW) -elseif(WIN32) - set(BUILD_FreeMe OFF) endif(WIN32) if(APPLE) @@ -103,34 +137,34 @@ if(UNIX) endif(UNIX) #Find PNG -if(ENABLE_PNG) +if(NANA_CMAKE_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) #set(NANA_PNG_LIB "png") list(APPEND NANA_LINKS -lpng ) - if(LIBPNG_FROM_OS) + if(NANA_CMAKE_LIBPNG_FROM_OS) find_package(PNG) if (PNG_FOUND) include_directories( ${PNG_INCLUDE_DIRS}) add_definitions(-DUSE_LIBPNG_FROM_OS) endif(PNG_FOUND) - endif(LIBPNG_FROM_OS) -endif(ENABLE_PNG) + endif(NANA_CMAKE_LIBPNG_FROM_OS) +endif(NANA_CMAKE_ENABLE_PNG) #Find JPEG -if(ENABLE_JPEG) +if(NANA_CMAKE_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) #set(NANA_JPEG_LIB "jpeg") list(APPEND NANA_LINKS -ljpeg ) - if(LIBJPEG_FROM_OS) + if(NANA_CMAKE_LIBJPEG_FROM_OS) find_package(JPEG) if (JPEG_FOUND) include_directories( ${JPEG_INCLUDE_DIRS}) add_definitions(-DUSE_LIBJPEG_FROM_OS) endif(JPEG_FOUND) - endif(LIBJPEG_FROM_OS) -endif(ENABLE_JPEG) + endif(NANA_CMAKE_LIBJPEG_FROM_OS) +endif(NANA_CMAKE_ENABLE_JPEG) -if(ENABLE_AUDIO) +if(NANA_CMAKE_ENABLE_AUDIO) add_definitions(-DNANA_ENABLE_AUDIO) if(UNIX) find_package(ASOUND) @@ -141,12 +175,11 @@ if(ENABLE_AUDIO) message(FATAL_ERROR "libasound is not found") endif(ASOUND_FOUND) endif(UNIX) -endif(ENABLE_AUDIO) +endif(NANA_CMAKE_ENABLE_AUDIO) -#Unicode -if(CMAKE_VERBOSE_PREPROCESSOR) +if(NANA_CMAKE_VERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR) -endif(CMAKE_VERBOSE_PREPROCESSOR) +endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) 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}/system NANA_SYSTEM_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/detail NANA_AUDIO_DETAIL_SOURCE) endif() @@ -186,185 +219,86 @@ add_library(${PROJECT_NAME} ${NANA_SOURCE} ${NANA_SYSTEM_SOURCE} ${NANA_THREADS_SOURCE}) - #Headers: use INCLUDE_DIRECTORIES - # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES + # Headers: use INCLUDE_DIRECTORIES + # Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES) target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) install(TARGETS ${PROJECT_NAME} ARCHIVE 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 ) - # TODO: move this nana-demo section to the nana demo repository, and here only include that cmake file -if (BUILD_NANA_DEMOS) - set (CMAKE_INSTALL_PREFIX ${DEMO_BIN}) - set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin) - set(CMAKE_INSTALL_PREFIX ) - - add_executable(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 (NANA_CMAKE_BUILD_DEMOS) - if (BUILD_FreeMe) - add_executable(FreeMe ../nana-demo/FreeMe.cpp) - set_property( TARGET FreeMe PROPERTY CXX_STANDARD 14 ) - target_link_libraries(FreeMe ${PROJECT_NAME} ) - install(TARGETS FreeMe RUNTIME DESTINATION &{DEMO_BIN}) - endif (BUILD_FreeMe) + if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) + add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) + enable_testing () + endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) - add_executable(notepad ../nana-demo/notepad.cpp) - set_property( TARGET notepad PROPERTY CXX_STANDARD 14 ) - target_link_libraries(notepad ${PROJECT_NAME} ) - install(TARGETS notepad RUNTIME DESTINATION &{DEMO_BIN}) + set (demos calculator file_explorer helloworld_demo notepad ) - add_executable(widget_show ../nana-demo/widget_show.cpp) - set_property( TARGET widget_show PROPERTY CXX_STANDARD 14 ) - target_link_libraries(widget_show ${PROJECT_NAME}) - install(TARGETS widget_show RUNTIME DESTINATION &{DEMO_BIN}) + foreach ( demo ${demos}) + add_executable(${demo} "../nana-demo/${demo}.cpp") + set_property( TARGET ${demo} PROPERTY CXX_STANDARD 14 ) + 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_property( TARGET widget_show2 PROPERTY CXX_STANDARD 14 ) - target_link_libraries(widget_show2 ${PROJECT_NAME}) - install(TARGETS widget_show2 RUNTIME DESTINATION &{DEMO_BIN}) + set (demos widget_show widget_show2 ) - 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) - set_property( TARGET file_explorer PROPERTY CXX_STANDARD 14 ) - target_link_libraries(file_explorer ${PROJECT_NAME} ) - install(TARGETS file_explorer RUNTIME DESTINATION &{DEMO_BIN}) + if (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + list(APPEND demos FreeMe) # ?? + endif (NANA_CMAKE_INCLUDE_EXPERIMENTAL_DEMOS) + # 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_property( TARGET animate-bmp PROPERTY CXX_STANDARD 14 ) - target_link_libraries(animate-bmp ${PROJECT_NAME}) + set (demos a_group_impl animate-bmp audio_player audio_player_simple background-effects categ clicked + decore dock drag-button draw example.button example_combox example_listbox example_menu + 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) - 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) +endif (NANA_CMAKE_BUILD_DEMOS) # set compile flags @@ -393,5 +327,15 @@ message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message ( "CMAKE_COMPILER_IS_GNUCXX= " ${CMAKE_COMPILER_IS_GNUCXX}) 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 ( "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}) + + diff --git a/README.md b/README.md index 5b985907..cd9a692d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # 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) diff --git a/build/makefile/readme.md b/build/makefile/readme.md index 1b8d9b1b..38ce2141 100644 --- a/build/makefile/readme.md +++ b/build/makefile/readme.md @@ -1,8 +1,8 @@ -Building Nana C++ Library -requires: +# Building Nana C++ Library directly with make +If you are using make directly, it require: 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++ diff --git a/build/vc2015/nana.vcxproj b/build/vc2015/nana.vcxproj index e9c0aa02..ce428ef7 100644 --- a/build/vc2015/nana.vcxproj +++ b/build/vc2015/nana.vcxproj @@ -249,6 +249,9 @@ + + + diff --git a/build/vc2015/nana.vcxproj.filters b/build/vc2015/nana.vcxproj.filters index 0f547b4e..aaac3c60 100644 --- a/build/vc2015/nana.vcxproj.filters +++ b/build/vc2015/nana.vcxproj.filters @@ -49,6 +49,9 @@ {53feb93f-2b86-4bf5-b2f3-f60ef1bbbf76} + + {6caffbf6-c023-4dbf-ba69-cdb49feddb5d} + @@ -280,4 +283,9 @@ Source Files\gui\detail + + + Header Files\filesystem + + \ No newline at end of file diff --git a/include/nana/audio/player.hpp b/include/nana/audio/player.hpp index c4fc3d87..0dad445f 100644 --- a/include/nana/audio/player.hpp +++ b/include/nana/audio/player.hpp @@ -1,6 +1,6 @@ #ifndef NANA_AUDIO_PLAYER_HPP #define NANA_AUDIO_PLAYER_HPP - +#include #include #ifdef NANA_ENABLE_AUDIO @@ -31,4 +31,7 @@ namespace nana{ namespace audio }//end namespace nana #endif //NANA_ENABLE_AUDIO -#endif \ No newline at end of file + +#include + +#endif diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index e990a681..4d13b6ec 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -15,6 +15,7 @@ #include #include +#include namespace nana { @@ -337,9 +338,9 @@ namespace nana bool operator==(const color& other) const; bool operator!=(const color& other) const; private: - double r_; - double g_; - double b_; + double r_{ 0.0 }; + double g_{ 0.0 }; + double b_{ 0.0 }; double a_{ 0.0 }; //invisible }; @@ -484,7 +485,7 @@ namespace nana southeast }; }//end namespace nana - +#include #endif diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index d23e0a48..2dc4c5f2 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -31,6 +31,7 @@ * - _SCL_SECURE_NO_WARNNGS, _CRT_SECURE_NO_DEPRECATE (VC) * - STD_CODECVT_NOT_SUPPORTED (VC RC, is a known issue on libstdc++, it works on libc++) * - 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_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8) @@ -133,9 +134,14 @@ #endif #endif - #if ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3 ) ) ) - #undef STD_FILESYSTEM_NOT_SUPPORTED - #endif + + #if ((__GNUC__ < 5) ) + # 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_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) @@ -147,8 +153,10 @@ #endif #if defined(NANA_MINGW) - //It's a knonwn issue under MinGW - #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED + #ifndef __MINGW64_VERSION_MAJOR + //It's a knonwn issue under MinGW(except MinGW-W64) + #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED + #endif #endif #if (__GNUC_MINOR__ < 8) diff --git a/include/nana/charset.hpp b/include/nana/charset.hpp index 41fa4d72..09f79bdf 100644 --- a/include/nana/charset.hpp +++ b/include/nana/charset.hpp @@ -46,7 +46,31 @@ namespace nana 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 { public: @@ -74,27 +98,3 @@ namespace nana }//end namespace nana #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); - -*/ \ No newline at end of file diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 6335f2e2..ae11279d 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -39,20 +39,30 @@ // https://github.com/meganz/mingw-std-threads //#define NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ -//////////////////////////// -// The ISO C++ File System Technical Specification 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 -// 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. -// Boost will be use only if you change one of the following (set the includes and link correspondly): -//#define NANA_BOOST_FILESYSTEM_AVAILABLE // "Is Boost filesystem available?" -//#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)? +//# 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 +//# 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 none of them are available. +//# You can change that default if you change one of the following +//# (please don't define more than one of the _XX_FORCE options): +// +//#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 ?" "../") +// 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 @@ -83,6 +93,17 @@ #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) //#define VERBOSE_PREPROCESSOR #endif diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 19163c82..9a9a2a6b 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -14,6 +14,7 @@ #ifndef NANA_DEPLOY_HPP #define NANA_DEPLOY_HPP +#include #include #if defined(VERBOSE_PREPROCESSOR) @@ -92,14 +93,57 @@ namespace std } #endif +#ifdef STD_put_time_NOT_SUPPORTED +#include +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/**/(const std::tm* tmb, const char* fmt); + + //Defined in header + // std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time); + //template<> + //std::wstring put_time(const std::tm* tmb, const wchar_t* fmt); +} +#endif // STD_put_time_NOT_SUPPORTED + 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 bool is_utf8(const char* str, std::size_t len); void throw_not_utf8(const std::string& text); void throw_not_utf8(const char*, std::size_t len); 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&); std::string to_utf8(const std::wstring&); @@ -190,5 +234,5 @@ namespace std { make_unique(Args&&...) = delete; } #endif //STD_make_unique_NOT_SUPPORTED - -#endif //NANA_MACROS_HPP +#include +#endif //NANA_DEPLOY_HPP diff --git a/include/nana/detail/linux_X11/platform_spec.hpp b/include/nana/detail/linux_X11/platform_spec.hpp index c8866d9d..e701c203 100644 --- a/include/nana/detail/linux_X11/platform_spec.hpp +++ b/include/nana/detail/linux_X11/platform_spec.hpp @@ -18,6 +18,8 @@ #ifndef NANA_DETAIL_PLATFORM_SPEC_HPP #define NANA_DETAIL_PLATFORM_SPEC_HPP +#include + #include #include #include @@ -60,6 +62,8 @@ namespace detail class charset_conv { + charset_conv(const charset_conv&) = delete; + charset_conv& operator=(const charset_conv*) = delete; public: charset_conv(const char* tocode, const char* fromcode); ~charset_conv(); @@ -118,6 +122,9 @@ namespace detail void update_color(); void update_text_color(); private: + drawable_impl_type(const drawable_impl_type&) = delete; + drawable_impl_type& operator=(const drawable_impl_type&) = delete; + unsigned current_color_{ 0xFFFFFF }; unsigned color_{ 0xFFFFFFFF }; unsigned text_color_{ 0xFFFFFFFF }; @@ -188,8 +195,8 @@ namespace detail native_window_type owner; std::vector * owned; }; - public: - int error_code; + public: + int error_code; public: typedef drawable_impl_type::font_ptr_t font_ptr_t; typedef void (*timer_proc_type)(unsigned tid); @@ -197,6 +204,8 @@ namespace detail typedef ::nana::event_code event_code; 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(); @@ -327,6 +336,7 @@ namespace detail }//end namespace nana +#include // .h ward #endif diff --git a/include/nana/detail/platform_spec_selector.hpp b/include/nana/detail/platform_spec_selector.hpp index d230088f..fc4504f8 100644 --- a/include/nana/detail/platform_spec_selector.hpp +++ b/include/nana/detail/platform_spec_selector.hpp @@ -1,15 +1,15 @@ -/* +/** * Selector of Platform Specification * 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. * (See accompanying file LICENSE_1_0.txt or copy at * 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 diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index 9e868e0b..23abd002 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -1,7 +1,7 @@ /* * Platform Specification Implementation * 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. * (See accompanying file LICENSE_1_0.txt or copy at @@ -25,6 +25,7 @@ #include #include #include +#include namespace nana { @@ -63,9 +64,15 @@ namespace detail bool forced; }; + struct arg_affinity_execute + { + const std::function * function_ptr; + }; + enum { tray = 0x501, + async_activate, async_set_focus, remote_flush_surface, @@ -74,6 +81,10 @@ namespace detail operate_caret, //wParam: 1=Destroy, 2=SetPos remote_thread_set_window_pos, remote_thread_set_window_text, + + //Execute a function in a thread with is associated with a specified native window + affinity_execute, + user, }; }; @@ -142,6 +153,9 @@ namespace detail unsigned whitespace_pixels; }string; + drawable_impl_type(const drawable_impl_type&) = delete; + drawable_impl_type& operator=(const drawable_impl_type&) = delete; + drawable_impl_type(); ~drawable_impl_type(); diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index a3a3e373..a62a5707 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -1,4 +1,4 @@ -/* +/** * A ISO C++ filesystem Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,17 +7,17 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/filesystem/filesystem.hpp - * Modiffied by Ariel Vina-Rodriguez: - * Now mimic std::experimental::filesystem::v1 (boost v3) - * and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013 + * @file nana/filesystem/filesystem.hpp + * @author Jinhao, conributed: Ariel Vina-Rodriguez + * @brief Mimic std::experimental::filesystem::v1 (boost v3) + * 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 2014-07-04 // http://en.cppreference.com/w/cpp/experimental/fs // 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 header VS2015 // https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- 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://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. @@ -29,6 +29,9 @@ #ifndef NANA_FILESYSTEM_HPP #define NANA_FILESYSTEM_HPP + +#include + #include #include #include @@ -40,18 +43,14 @@ #include - // namespace std { namespace experimental { namespace filesystem { inline namespace v1 { - -namespace nana { namespace experimental { - -#ifndef CXX_NO_INLINE_NAMESPACE -inline namespace v1 +namespace nana { namespace experimental { namespace filesystem { +#ifndef CXX_NO_INLINE_NAMESPACE + inline namespace v1 + { #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 not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error @@ -82,7 +81,7 @@ namespace filesystem uintmax_t available; }; - using file_time_type = std::chrono::time_point;// trivial-clock> ; + using file_time_type = std::chrono::time_point; ///< trivial-clock> ; class file_status { @@ -116,7 +115,7 @@ namespace filesystem public: #if defined(NANA_WINDOWS) using value_type = wchar_t; - const static value_type preferred_separator = '\\'; + const static value_type preferred_separator = L'\\'; #else using value_type = char; const static value_type preferred_separator = '/'; @@ -131,23 +130,41 @@ namespace filesystem _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; - bool empty() const; - path extension() const; - - path parent_path() const; file_type what() const; - //decomposition - path filename() const; - - //modifiers - path& remove_filename(); - - - const value_type*c_str() const; const string_type& native() 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, const path& path2, std::error_code err); - const path& path1() const; //noexcept - const path& path2() const; //noexcept + const path& path1() const noexcept; + const path& path2() const noexcept; + // const char* what() const noexcept; private: path path1_; path path2_; @@ -229,33 +247,23 @@ namespace filesystem filesystem::path path_; }; - /// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator - //template + /// InputIterator that iterate over the sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator class directory_iterator :public std::iterator { using find_handle = void*; 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(const path& file_path); + directory_iterator() noexcept; + explicit directory_iterator(const path& dir); const value_type& operator*() const; const value_type* operator->() const; 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: template static bool _m_ignore(const Char * p) @@ -275,6 +283,16 @@ namespace filesystem find_handle handle_{nullptr}; 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; @@ -301,15 +319,23 @@ namespace filesystem std::uintmax_t file_size(const path& p); //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); - 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_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) { @@ -320,7 +346,7 @@ namespace filesystem 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); @@ -330,16 +356,21 @@ namespace filesystem bool create_directory(const path& p, const path& attributes); //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(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; - bool remove(const path& p); bool remove(const path& p, std::error_code& ec); // noexcept; @@ -381,4 +412,5 @@ namespace filesystem //namespace filesystem = experimental::filesystem; } //end namespace nana +#include #endif diff --git a/include/nana/filesystem/filesystem_ext.hpp b/include/nana/filesystem/filesystem_ext.hpp new file mode 100644 index 00000000..ef561665 --- /dev/null +++ b/include/nana/filesystem/filesystem_ext.hpp @@ -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 +#include + +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 // 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 + directory_only_iterator(Arg&&... arg ): DI(std::forward(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 // 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 + regular_file_only_iterator(Arg&&... arg ): DI(std::forward(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 diff --git a/include/nana/filesystem/filesystem_selector.hpp b/include/nana/filesystem/filesystem_selector.hpp new file mode 100644 index 00000000..b0d3ae3a --- /dev/null +++ b/include/nana/filesystem/filesystem_selector.hpp @@ -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 +* 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 + +#if (defined(NANA_FILESYSTEM_FORCE) || ( (defined(STD_FILESYSTEM_NOT_SUPPORTED) && !defined(BOOST_FILESYSTEM_AVAILABLE)) && !(defined(BOOST_FILESYSTEM_FORCE) || defined(STD_FILESYSTEM_FORCE)) ) ) + +# include + +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 + + // add boost::filesystem into std::experimental::filesystem +namespace std { + namespace experimental { + namespace filesystem { + using namespace boost::filesystem; + } // filesystem + } // experimental +} // std + +#else +# include +#endif + +#ifndef __cpp_lib_experimental_filesystem +# define __cpp_lib_experimental_filesystem 1 +#endif + + +#endif // NANA_FILESYSTEM_SELECTOR + + + + + diff --git a/include/nana/gui/animation.hpp b/include/nana/gui/animation.hpp index d9a62e26..9f0df563 100644 --- a/include/nana/gui/animation.hpp +++ b/include/nana/gui/animation.hpp @@ -12,7 +12,7 @@ #ifndef NANA_GUI_ANIMATION_HPP #define NANA_GUI_ANIMATION_HPP - +#include #include #include @@ -82,4 +82,5 @@ namespace nana impl * impl_; }; } //end namespace nana +#include #endif //NANA_GUI_ANIMATION_HPP diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index 723d3140..744fa9ba 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -1,20 +1,22 @@ -/* +/** + * \file basis.hpp + * \brief This file provides basis class and data structures required by the GUI + * * Basis Implementation * 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. * (See accompanying file LICENSE_1_0.txt or copy at * 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 #define NANA_GUI_BASIS_HPP +#include + #include "../basic_types.hpp" #include "../traits.hpp" //metacomp::fixed_type_set @@ -59,9 +61,9 @@ namespace nana }; //wait for constexpr struct widget_tag{ static const flags value = flags::widget; }; - struct lite_widget_tag : widget_tag{ static const flags value = flags::lite_widget;}; - struct root_tag : widget_tag{ static const flags value = flags::root; }; - struct frame_tag: widget_tag{ static const flags value = flags::frame; }; + struct lite_widget_tag : public widget_tag{ static const flags value = flags::lite_widget; }; + struct root_tag : public widget_tag{ static const flags value = flags::root; }; + struct frame_tag : public widget_tag{ static const flags value = flags::frame; }; }// end namespace category using native_window_type = detail::native_window_handle_impl*; @@ -152,7 +154,25 @@ namespace nana appearance(); 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 minimize{}; @@ -161,7 +181,20 @@ namespace nana struct taskbar{}; struct floating{}; 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()); + * \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() + * \endcode + */ template< typename Minimize = null_type, typename Maximize = 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, typename Floating = null_type, typename NoActive = null_type, @@ -227,4 +261,6 @@ namespace nana }; };//end namespace apper }//end namespace nana + +#include #endif diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index ed2e1db4..22f51122 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -1,4 +1,4 @@ -/* +/** * A Basic Window Widget Definition * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,11 +7,13 @@ * (See accompanying file LICENSE_1_0.txt or copy at * 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 #define NANA_GUI_DETAIL_BASIC_WINDOW_HPP +#include #include "drawer.hpp" #include "events_holder.hpp" #include "widget_colors.hpp" @@ -57,20 +59,18 @@ namespace detail ::nana::rectangle effective_range_; };//end class caret_descriptor - //tab_type - //@brief: Define some constant about tab category, these flags can be combine with operator | + /// Define some constant about tab category, these flags can be combine with operator | struct tab_type { enum t { - none, //process by nana - tabstop, //move to the next tabstop window - eating, //process by current window + none, ///< process by nana + tabstop, ///< move to the next tabstop window + eating, ///< process by current window }; }; - //struct basic_window - //@brief: a window data structure descriptor + /// a window data structure descriptor struct basic_window : public events_holder { @@ -87,8 +87,7 @@ namespace detail bool rendered; }; - //basic_window - //@brief: constructor for the root window + /// constructor for the root window basic_window(basic_window* owner, std::unique_ptr&&, category::root_tag**); template @@ -105,8 +104,7 @@ namespace detail ~basic_window(); - //bind_native_window - //@brief: bind a native window and baisc_window + /// 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 frame_window(native_window_type); @@ -115,13 +113,13 @@ namespace detail bool visible_parents() const; bool displayed() 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. basic_window * seek_non_lite_widget_ancestor() const; public: - //Override event_holder + /// Override event_holder bool set_events(const std::shared_ptr&) override; general_events * get_events() const override; private: @@ -131,7 +129,7 @@ namespace detail #if defined(NANA_LINUX) || defined(NANA_MACOS) point pos_native; #endif - point pos_root; //coordinate for root window + point pos_root; ///< coordinates of the root window point pos_owner; size dimension; ::nana::size min_track_size; @@ -146,9 +144,9 @@ namespace detail basic_window *owner; native_string_type title; - ::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. - paint::graphics* root_graph; //Refer to the root buffer 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. + paint::graphics* root_graph; ///< Refer to the root buffer graphics cursor predef_cursor; std::unique_ptr widget_notifier; @@ -156,20 +154,20 @@ namespace detail { bool enabled :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 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 destroying :1; - 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 dropable :1; ///< Whether the window has make mouse_drop event. + bool fullscreen :1; ///< When the window is maximizing whether it fit for fullscreen. bool borderless :1; - 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_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 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_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. 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; }flags; @@ -198,7 +196,7 @@ namespace detail 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; std::vector effects_edge_nimbus; basic_window* focus{nullptr}; @@ -210,13 +208,13 @@ namespace detail cursor state_cursor{nana::cursor::arrow}; basic_window* state_cursor_window{ nullptr }; - std::function draw_through; // A draw through renderer for root widgets. + std::function draw_through; ///< A draw through renderer for root widgets. }; const category::flags category; - 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. - paint::graphics glass_buffer; //if effect.bground is avaiable. Refer to window_layout::make_bground. + 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. + paint::graphics glass_buffer; ///< if effect.bground is avaiable. Refer to window_layout::make_bground. update_state upd_state; union @@ -229,13 +227,14 @@ namespace detail ~other_tag(); }other; - native_window_type root; //root Window handle - unsigned thread_id; //the identifier of the thread that created the window. + native_window_type root; ///< root Window handle + unsigned thread_id; ///< the identifier of the thread that created the window. unsigned index; container children; }; }//end namespace detail }//end namespace nana +#include #endif diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 88973217..e6d2e0e7 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -1,4 +1,4 @@ -/* +/** * A Bedrock Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,7 +7,9 @@ * (See accompanying file LICENSE_1_0.txt or copy at * 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 @@ -25,12 +27,14 @@ namespace detail struct basic_window; class window_manager; - //class bedrock - //@brief: bedrock is a fundamental core component, it provides a abstract to the OS platform - // and some basic functions. + + /// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions. class bedrock { bedrock(); + + bedrock(const bedrock&) = delete; + bedrock& operator=(const bedrock&) = delete; public: using core_window_t = basic_window; diff --git a/include/nana/gui/detail/bedrock_pi_data.hpp b/include/nana/gui/detail/bedrock_pi_data.hpp index 309a7930..7404777b 100644 --- a/include/nana/gui/detail/bedrock_pi_data.hpp +++ b/include/nana/gui/detail/bedrock_pi_data.hpp @@ -1,6 +1,8 @@ #ifndef NANA_DETAIL_BEDROCK_PI_DATA_HPP #define NANA_DETAIL_BEDROCK_PI_DATA_HPP +#include + #include #include "color_schemes.hpp" #include "events_operation.hpp" @@ -30,4 +32,7 @@ namespace nana }; } } + +#include + #endif diff --git a/include/nana/gui/detail/drawer.hpp b/include/nana/gui/detail/drawer.hpp index b680ec6a..26061033 100644 --- a/include/nana/gui/detail/drawer.hpp +++ b/include/nana/gui/detail/drawer.hpp @@ -13,6 +13,7 @@ #ifndef NANA_GUI_DETAIL_DRAWER_HPP #define NANA_GUI_DETAIL_DRAWER_HPP +#include #include #include "general_events.hpp" #include @@ -170,4 +171,6 @@ namespace nana }//end namespace detail }//end namespace nana +#include + #endif diff --git a/include/nana/gui/detail/element_store.hpp b/include/nana/gui/detail/element_store.hpp index 0035d4be..3ac5b242 100644 --- a/include/nana/gui/detail/element_store.hpp +++ b/include/nana/gui/detail/element_store.hpp @@ -15,9 +15,13 @@ #include #include + #include #include +#include + + namespace nana { namespace detail @@ -48,5 +52,6 @@ namespace detail }; }//end namespace detail } +#include #endif diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index 8986ee73..5992f1a0 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -12,6 +12,8 @@ #ifndef NANA_DETAIL_GENERAL_EVENTS_HPP #define NANA_DETAIL_GENERAL_EVENTS_HPP +#include + #include #include "event_code.hpp" #include "internal_scope_guard.hpp" @@ -84,7 +86,7 @@ namespace nana }; }//end namespace detail - /// base clase for all event argument types + /// base class for all event argument types class event_arg { public: @@ -99,7 +101,14 @@ namespace nana 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 class basic_event : public detail::event_base { @@ -108,7 +117,8 @@ namespace nana private: struct docker : public detail::docker_base - { + { + /// the callback/response function taking the typed argument std::function invoke; docker(basic_event * evt, std::function && ivk, bool unignorable_flag) @@ -125,10 +135,10 @@ namespace nana event_handle connect_front(Function && fn) { using prototype = typename std::remove_reference::type; - return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), false), true); } + /// It will not get called if stop_propagation() was called. event_handle connect(void (*fn)(arg_reference)) { 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 event_handle connect(Function && fn) { using prototype = typename std::remove_reference::type; - return _m_emplace(new docker(this, factory::value>::build(std::forward(fn)), false), false); } @@ -193,7 +202,6 @@ namespace nana continue; static_cast(*i)->invoke(arg); - if (window_handle && (!detail::check_window(window_handle))) break; } @@ -378,11 +386,11 @@ namespace nana } }; }; - + struct arg_mouse : 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::point pos; ///< cursor position in the event window ::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 /// with prototype void(const arg_mouse&) can be set for mouse_wheel. struct arg_wheel : public arg_mouse @@ -487,11 +496,11 @@ namespace nana { ::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 { ::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. @@ -531,4 +540,6 @@ namespace nana }//end namespace detail }//end namespace nana +#include + #endif diff --git a/include/nana/gui/detail/handle_manager.hpp b/include/nana/gui/detail/handle_manager.hpp index 7e8f670d..716433be 100644 --- a/include/nana/gui/detail/handle_manager.hpp +++ b/include/nana/gui/detail/handle_manager.hpp @@ -25,6 +25,8 @@ #include #include +#include + namespace nana { @@ -288,4 +290,6 @@ namespace nana };//end class handle_manager }//end namespace detail }// end namespace nana +#include + #endif diff --git a/include/nana/gui/detail/inner_fwd_implement.hpp b/include/nana/gui/detail/inner_fwd_implement.hpp index e24853b0..659bc9a9 100644 --- a/include/nana/gui/detail/inner_fwd_implement.hpp +++ b/include/nana/gui/detail/inner_fwd_implement.hpp @@ -14,6 +14,7 @@ #ifndef NANA_GUI_INNER_FWD_IMPLEMENT_HPP #define NANA_GUI_INNER_FWD_IMPLEMENT_HPP +#include #include "inner_fwd.hpp" #include "basic_window.hpp" #include "../../paint/graphics.hpp" @@ -173,4 +174,7 @@ namespace nana{ }; } }//end namespace nana + +#include + #endif //NANA_GUI_INNER_FWD_IMPLEMENT_HPP diff --git a/include/nana/gui/detail/internal_scope_guard.hpp b/include/nana/gui/detail/internal_scope_guard.hpp index c4bdaaf6..6ad8ae80 100644 --- a/include/nana/gui/detail/internal_scope_guard.hpp +++ b/include/nana/gui/detail/internal_scope_guard.hpp @@ -1,7 +1,7 @@ /* * Forward Declaration of Internal Scope Guard * 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. * (See accompanying file LICENSE_1_0.txt or copy at @@ -26,6 +26,18 @@ namespace nana 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 \ No newline at end of file diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index aade67a5..737423bf 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -1,7 +1,7 @@ /* * Platform Implementation * 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. * (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; + //Execute a function in a thread which is associated with the specified native window. + static void affinity_execute(native_window_type, const std::function&); + static nana::size primary_monitor_size(); static rectangle screen_area_from_point(const point&); static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&); diff --git a/include/nana/gui/detail/window_layout.hpp b/include/nana/gui/detail/window_layout.hpp index f4bdfe0b..34987291 100644 --- a/include/nana/gui/detail/window_layout.hpp +++ b/include/nana/gui/detail/window_layout.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP #define NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP +#include #include #include @@ -84,5 +85,7 @@ namespace detail }//end namespace detail }//end namespace nana +#include + #endif //NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index d3468483..cab6ecb1 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -1,7 +1,7 @@ /* * Window Manager Implementation * 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. * (See accompanying file LICENSE_1_0.txt or copy at @@ -18,6 +18,8 @@ #ifndef NANA_GUI_DETAIL_WINDOW_MANAGER_HPP #define NANA_GUI_DETAIL_WINDOW_MANAGER_HPP +#include + #include #include "window_layout.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); 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_visual_rectangle(core_window_t*, nana::rectangle&); @@ -195,4 +197,7 @@ namespace detail };//end class window_manager }//end namespace detail }//end namespace nana + +#include + #endif diff --git a/include/nana/gui/dragger.hpp b/include/nana/gui/dragger.hpp index e34094ef..9e6bbbf2 100644 --- a/include/nana/gui/dragger.hpp +++ b/include/nana/gui/dragger.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_DRAGGER_HPP #define NANA_GUI_DRAGGER_HPP +#include #include "basis.hpp" #include "../basic_types.hpp" #include "../traits.hpp" @@ -44,4 +45,5 @@ namespace nana dragger_impl_t * impl_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/drawing.hpp b/include/nana/gui/drawing.hpp index fb1b966b..06ecece6 100644 --- a/include/nana/gui/drawing.hpp +++ b/include/nana/gui/drawing.hpp @@ -11,6 +11,8 @@ */ #ifndef NANA_GUI_DRAWING_HPP #define NANA_GUI_DRAWING_HPP + +#include #include "widgets/widget.hpp" #include "../traits.hpp" namespace nana @@ -46,4 +48,6 @@ namespace nana window handle_; };//end class drawing }//end namespace nana + +#include #endif diff --git a/include/nana/gui/element.hpp b/include/nana/gui/element.hpp index 7f0a891c..0ecfdad1 100644 --- a/include/nana/gui/element.hpp +++ b/include/nana/gui/element.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_ELEMENT_HPP #define NANA_GUI_ELEMENT_HPP +#include #include #include #include @@ -348,4 +349,5 @@ namespace nana }//end namespace element }//end namespace nana +#include #endif //NANA_GUI_ELEMENT_HPP diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index af5a1437..e21392e0 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_MSGBOX_HPP #define NANA_GUI_MSGBOX_HPP +#include #include @@ -253,5 +254,6 @@ namespace nana ::nana::rectangle valid_areas_[4]; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/notifier.hpp b/include/nana/gui/notifier.hpp index a557fd45..48442a96 100644 --- a/include/nana/gui/notifier.hpp +++ b/include/nana/gui/notifier.hpp @@ -14,6 +14,7 @@ #define NANA_GUI_NOTIFIER_HPP #include #include +#include namespace nana { @@ -65,4 +66,5 @@ namespace nana implement * impl_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/place.hpp b/include/nana/gui/place.hpp index 8f32545b..b10a8a18 100644 --- a/include/nana/gui/place.hpp +++ b/include/nana/gui/place.hpp @@ -15,6 +15,7 @@ #ifndef NANA_GUI_PLACE_HPP #define NANA_GUI_PLACE_HPP +#include #include #include #include @@ -145,5 +146,6 @@ namespace nana implement * impl_; }; }//end namespace nana +#include #endif //#ifndef NANA_GUI_PLACE_HPP diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 195b430b..c89508b4 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -60,6 +60,8 @@ namespace API //@brief: The interfaces defined in namespace dev are used for developing the nana.gui namespace dev { + void affinity_execute(window window_handle, const std::function&); + bool set_events(window, const std::shared_ptr&); template @@ -153,9 +155,17 @@ namespace API }; }//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); void unregister_shortkey(window); diff --git a/include/nana/gui/timer.hpp b/include/nana/gui/timer.hpp index 893a4e5d..9ae26f32 100644 --- a/include/nana/gui/timer.hpp +++ b/include/nana/gui/timer.hpp @@ -16,6 +16,7 @@ #ifndef NANA_GUI_TIMER_HPP #define NANA_GUI_TIMER_HPP #include +#include namespace nana { @@ -58,4 +59,5 @@ namespace nana implement * const impl_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/button.hpp b/include/nana/gui/widgets/button.hpp index bddeca77..e1813917 100644 --- a/include/nana/gui/widgets/button.hpp +++ b/include/nana/gui/widgets/button.hpp @@ -14,6 +14,8 @@ #define NANA_GUI_WIDGET_BUTTON_HPP #include "widget.hpp" #include +#include + namespace nana{ namespace drawerbase @@ -105,5 +107,7 @@ namespace nana{ void _m_caption(native_string_type&&) override; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/categorize.hpp b/include/nana/gui/widgets/categorize.hpp index d2a19141..1e64fa14 100644 --- a/include/nana/gui/widgets/categorize.hpp +++ b/include/nana/gui/widgets/categorize.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace nana { @@ -141,7 +142,7 @@ namespace nana void mouse_leave(graph_reference, const arg_mouse&) override; private: std::unique_ptr event_agent_; - scheme * scheme_; + scheme * scheme_{nullptr}; }; }//end namespace categorize }//end namespace drawerbase @@ -258,5 +259,5 @@ namespace nana } }; }//end namespace nana - +#include #endif diff --git a/include/nana/gui/widgets/checkbox.hpp b/include/nana/gui/widgets/checkbox.hpp index 8d458be3..8d06b590 100644 --- a/include/nana/gui/widgets/checkbox.hpp +++ b/include/nana/gui/widgets/checkbox.hpp @@ -12,6 +12,8 @@ #ifndef NANA_GUI_WIDGET_CHECKBOX_HPP #define NANA_GUI_WIDGET_CHECKBOX_HPP +#include + #include "widget.hpp" #include #include @@ -106,5 +108,6 @@ namespace drawerbase std::vector ui_container_; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/combox.hpp b/include/nana/gui/widgets/combox.hpp index 4d22a30e..7e478557 100644 --- a/include/nana/gui/widgets/combox.hpp +++ b/include/nana/gui/widgets/combox.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGETS_COMBOX_HPP #define NANA_GUI_WIDGETS_COMBOX_HPP +#include #include "widget.hpp" #include "float_listbox.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; }; } +#include #endif diff --git a/include/nana/gui/widgets/date_chooser.hpp b/include/nana/gui/widgets/date_chooser.hpp index 262a7a3b..b36d800f 100644 --- a/include/nana/gui/widgets/date_chooser.hpp +++ b/include/nana/gui/widgets/date_chooser.hpp @@ -12,7 +12,7 @@ #ifndef NANA_GUI_WIDGETS_DATE_CHOOSER_HPP #define NANA_GUI_WIDGETS_DATE_CHOOSER_HPP - +#include #include "widget.hpp" #include @@ -79,5 +79,6 @@ namespace nana void weekstr(unsigned index, ::std::string);/// #endif diff --git a/include/nana/gui/widgets/detail/tree_cont.hpp b/include/nana/gui/widgets/detail/tree_cont.hpp index 3618b814..c9684ba6 100644 --- a/include/nana/gui/widgets/detail/tree_cont.hpp +++ b/include/nana/gui/widgets/detail/tree_cont.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP #define NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP #include +#include namespace nana { @@ -515,4 +516,6 @@ namespace detail }//end namespace detail }//end namespace widgets }//end namesace nana + +#include #endif diff --git a/include/nana/gui/widgets/float_listbox.hpp b/include/nana/gui/widgets/float_listbox.hpp index 79a66e2f..590479fd 100644 --- a/include/nana/gui/widgets/float_listbox.hpp +++ b/include/nana/gui/widgets/float_listbox.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP #define NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP +#include #include "widget.hpp" #include @@ -101,5 +102,6 @@ namespace nana std::size_t index() const; }; } +#include #endif diff --git a/include/nana/gui/widgets/label.hpp b/include/nana/gui/widgets/label.hpp index 6b71bd88..f8c97eb9 100644 --- a/include/nana/gui/widgets/label.hpp +++ b/include/nana/gui/widgets/label.hpp @@ -12,8 +12,9 @@ #ifndef NANA_GUI_WIDGET_LABEL_HPP #define NANA_GUI_WIDGET_LABEL_HPP -#include "widget.hpp" +#include "widget.hpp" +#include namespace nana { @@ -80,4 +81,6 @@ namespace nana void _m_caption(native_string_type&&) override; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 58f02ef0..66dd726e 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -17,6 +17,8 @@ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #define NANA_GUI_WIDGETS_LISTBOX_HPP +#include + #include "widget.hpp" #include "detail/inline_widget.hpp" #include @@ -295,7 +297,18 @@ namespace nana throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); return *p; } + template + T & value() + { + auto * pany = _m_value(); + if (nullptr == pany) + throw std::runtime_error("listbox::item_proxy.value() is empty"); + T * p = any_cast(_m_value(false)); + if (nullptr == p) + throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); + return *p; + } template item_proxy & value(T&& t) { @@ -503,9 +516,7 @@ namespace nana { basic_event checked; basic_event selected; - - /// An event occurs when a listbox category is double clicking. - basic_event category_dbl_click; + basic_event category_dbl_click; ///< An event occurs when a listbox category is double clicking. }; struct scheme @@ -516,26 +527,40 @@ namespace nana color_proxy header_floated{ static_cast(0xBABBBC)}; color_proxy item_selected{ static_cast(0xD5EFFC) }; - unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ?? - ext_w = 5; + /// \todo how to implement some geometrical parameters ?? + 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 /*! \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. -A category is a text with can be \a selected, \a checked and \a expanded to show the items. -An item is formed by \a column-fields, each corresponding to one of the \a headers. -An item can be \a selected and \a checked. +\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. +A \a category is a text with can be \a selected, \a checked and \a expanded to show the \a items. +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. 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. -3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. +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. + 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: Irreflexivity (comp(x, x) returns false) and - antisymmetry(comp(a, b) != comp(b, a) returns true) + Antisymmetry(comp(a, b) != comp(b, a) returns true) A simple example. bool sort_compare( const std::string& s1, nana::any*, 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. { - int * i1 = o1->get(); - int * i2 = o2->get(); + int * i1 = any_cast(*o1); + int * i2 = any_cast(*o2); return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2)); - ;//some types may not be int. + // ^ some types may not be int. } 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; /// #endif diff --git a/include/nana/gui/widgets/menu.hpp b/include/nana/gui/widgets/menu.hpp index 335796d4..02372079 100644 --- a/include/nana/gui/widgets/menu.hpp +++ b/include/nana/gui/widgets/menu.hpp @@ -17,6 +17,8 @@ #include #include +#include + namespace nana { namespace drawerbase @@ -198,4 +200,6 @@ namespace nana detail::popuper menu_popuper(menu&, mouse = mouse::right_button); detail::popuper menu_popuper(menu&, window owner, const point&, mouse = mouse::right_button); }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/menubar.hpp b/include/nana/gui/widgets/menubar.hpp index 365d9b1c..3c799936 100644 --- a/include/nana/gui/widgets/menubar.hpp +++ b/include/nana/gui/widgets/menubar.hpp @@ -14,6 +14,7 @@ #define NANA_GUI_WIDGETS_MENUBAR_HPP #include "widget.hpp" #include "menu.hpp" +#include namespace nana { @@ -117,4 +118,6 @@ namespace nana ::nana::event_handle evt_resized_{nullptr}; };//end class menubar }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/picture.hpp b/include/nana/gui/widgets/picture.hpp index bd40f0e0..fc8e9c63 100644 --- a/include/nana/gui/widgets/picture.hpp +++ b/include/nana/gui/widgets/picture.hpp @@ -13,6 +13,8 @@ */ #ifndef NANA_GUI_WIDGET_PICTURE_HPP #define NANA_GUI_WIDGET_PICTURE_HPP +#include + #include "widget.hpp" namespace nana @@ -67,4 +69,6 @@ namespace nana bool transparent() const; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 3a260c85..dbbb6452 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -15,6 +15,7 @@ #include "widget.hpp" #include +#include namespace nana { @@ -502,4 +503,5 @@ namespace nana } };//end class scroll }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index 986bc438..3b438e4e 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -13,6 +13,8 @@ #ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP #define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP +#include + #include "textbase.hpp" #include "text_editor_part.hpp" #include @@ -218,7 +220,7 @@ namespace nana{ namespace widgets void set_end_caret(); 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 mask(wchar_t); @@ -358,12 +360,11 @@ namespace nana{ namespace widgets 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; bool move_to_end; mode mode_selection; - bool dragged; bool ignore_press; nana::upoint a, b; }select_; @@ -380,5 +381,7 @@ namespace nana{ namespace widgets }//end namespace widgets }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index f529299b..a34183ce 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -21,6 +21,8 @@ #include #include +#include + namespace nana{ namespace widgets{ namespace skeletons { //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; } + //Escape - if(ch == '\\') + if(this->format_enabled_ && (ch == '\\')) { if(iptr_ + 1 < endptr_) { ch = *(iptr_ + 1); - iptr_ += 2; + + if ('<' == ch || '>' == ch) //two characters need to be escaped. + { + iptr_ += 2; + } + else + { + //ignore escape + ch = '\\'; + iptr_++; + } } else { @@ -191,8 +204,8 @@ namespace nana{ namespace widgets{ namespace skeletons return token::eof; } } - - ++iptr_; + else + ++iptr_; idstr_.clear(); idstr_.append(1, ch); @@ -260,6 +273,8 @@ namespace nana{ namespace widgets{ namespace skeletons return token::eof; } + + if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || '_' == ch) { --iptr_; @@ -926,4 +941,5 @@ namespace nana{ namespace widgets{ namespace skeletons }//end namespace skeletons }//end namespace widgets }//end namepsace nana +#include #endif //NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM diff --git a/include/nana/gui/widgets/skeletons/textbase.hpp b/include/nana/gui/widgets/skeletons/textbase.hpp index 99cc5799..1c4085b2 100644 --- a/include/nana/gui/widgets/skeletons/textbase.hpp +++ b/include/nana/gui/widgets/skeletons/textbase.hpp @@ -13,6 +13,7 @@ #ifndef NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP #define NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP +#include #include #include @@ -536,4 +537,6 @@ namespace skeletons }//end namespace detail }//end namespace widgets }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/slider.hpp b/include/nana/gui/widgets/slider.hpp index c5372034..29adcf76 100644 --- a/include/nana/gui/widgets/slider.hpp +++ b/include/nana/gui/widgets/slider.hpp @@ -11,6 +11,9 @@ */ #ifndef NANA_GUI_WIDGETS_SLIDER_HPP #define NANA_GUI_WIDGETS_SLIDER_HPP + +#include + #include "widget.hpp" #include @@ -111,7 +114,7 @@ namespace nana }; }//end namespace slider }//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 : public widget_object { @@ -141,5 +144,6 @@ namespace nana bool transparent() const; }; }//end namespace nana +#include #endif diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index e3d28505..e090426a 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -12,6 +12,8 @@ #ifndef NANA_GUI_WIDGET_SPINBOX_HPP #define NANA_GUI_WIDGET_SPINBOX_HPP + +#include #include "widget.hpp" #include "skeletons/text_editor_part.hpp" @@ -68,7 +70,7 @@ namespace nana private: implementation * const impl_; }; - }; + } }//end namespace drawerbase /// Spinbox Widget @@ -110,5 +112,5 @@ namespace nana void _m_caption(native_string_type&&); }; //end class spinbox }//end namespace nana - +#include #endif //NANA_GUI_WIDGET_SPINBOX_HPP diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index ac009ee7..d8979911 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -13,6 +13,8 @@ */ #ifndef NANA_GUI_WIDGET_TABBAR_HPP #define NANA_GUI_WIDGET_TABBAR_HPP +#include + #include "widget.hpp" #include #include @@ -410,5 +412,6 @@ namespace nana void erase(std::size_t pos, bool close_attached = true); }; } +#include #endif diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index bc3b9ab1..e385b633 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -11,6 +11,8 @@ */ #ifndef NANA_GUI_WIDGET_TEXTBOX_HPP #define NANA_GUI_WIDGET_TEXTBOX_HPP +#include + #include #include "skeletons/textbase_export_interface.hpp" #include "skeletons/text_editor_part.hpp" @@ -224,4 +226,6 @@ namespace nana void _m_typeface(const paint::font&) override; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/toolbar.hpp b/include/nana/gui/widgets/toolbar.hpp index 8a4d3a40..24f27b32 100644 --- a/include/nana/gui/widgets/toolbar.hpp +++ b/include/nana/gui/widgets/toolbar.hpp @@ -12,6 +12,7 @@ #ifndef NANA_GUI_WIDGET_TOOLBAR_HPP #define NANA_GUI_WIDGET_TOOLBAR_HPP +#include #include "widget.hpp" @@ -101,4 +102,6 @@ namespace nana bool detached_; }; }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp index f0cc4cd1..69477824 100644 --- a/include/nana/gui/widgets/treebox.hpp +++ b/include/nana/gui/widgets/treebox.hpp @@ -17,6 +17,8 @@ #ifndef NANA_GUI_WIDGETS_TREEBOX_HPP #define NANA_GUI_WIDGETS_TREEBOX_HPP + +#include #include "widget.hpp" #include "detail/compset.hpp" #include "detail/tree_cont.hpp" @@ -307,14 +309,14 @@ namespace nana { _m_value() = t; return *this; - }; + } template item_proxy & value(T&& t) { _m_value() = std::move(t); return *this; - }; + } // Undocumentated methods for internal use trigger::node_type * _m_node() const; @@ -452,4 +454,6 @@ namespace nana item_proxy selected() const; ///< returns the selected node };//end class treebox }//end namespace nana +#include + #endif diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 14b6f2bd..f2515e00 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -12,6 +12,8 @@ #ifndef NANA_GUI_WIDGET_HPP #define NANA_GUI_WIDGET_HPP + +#include #include "../basis.hpp" #include "../programming_interface.hpp" #include @@ -481,4 +483,6 @@ namespace nana std::unique_ptr scheme_; };//end class widget_object }//end namespace nana + +#include #endif diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp index 1f104bbd..0500a6a0 100644 --- a/include/nana/gui/wvl.hpp +++ b/include/nana/gui/wvl.hpp @@ -1,14 +1,14 @@ -/* +/** * Nana GUI Library Definition * 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. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/gui/wvl.hpp - * @description: + * @file nana/gui/wvl.hpp + * @description * the header file contains the files required for running of Nana.GUI */ @@ -22,6 +22,7 @@ #include "msgbox.hpp" #include "place.hpp" + namespace nana { namespace detail @@ -58,6 +59,25 @@ namespace nana template using form_loader = detail::form_loader; - 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 = {} ///< 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 #endif diff --git a/include/nana/pat/cloneable.hpp b/include/nana/pat/cloneable.hpp index cf3d9d81..c6f5d1c9 100644 --- a/include/nana/pat/cloneable.hpp +++ b/include/nana/pat/cloneable.hpp @@ -13,6 +13,7 @@ #ifndef NANA_PAT_CLONEABLE_HPP #define NANA_PAT_CLONEABLE_HPP +#include #include #include #include @@ -97,9 +98,7 @@ namespace nana{ namespace pat{ typedef int inner_bool::* operator_bool_t; template - struct member_enabled - : public std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int> - {}; + using member_enabled = std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int>; public: cloneable() noexcept = default; @@ -207,5 +206,5 @@ namespace nana{ namespace pat{ using mutable_cloneable = cloneable; }//end namespace pat }//end namespace nana - +#include #endif diff --git a/include/nana/pop_ignore_diagnostic b/include/nana/pop_ignore_diagnostic new file mode 100644 index 00000000..23c39a69 --- /dev/null +++ b/include/nana/pop_ignore_diagnostic @@ -0,0 +1,5 @@ + +#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6) +# pragma GCC diagnostic pop +#endif + diff --git a/include/nana/push_ignore_diagnostic b/include/nana/push_ignore_diagnostic new file mode 100644 index 00000000..9ba463ad --- /dev/null +++ b/include/nana/push_ignore_diagnostic @@ -0,0 +1,4 @@ +#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Weffc++" +#endif diff --git a/include/nana/std_mutex.hpp b/include/nana/std_mutex.hpp index b508548e..38c07aaf 100644 --- a/include/nana/std_mutex.hpp +++ b/include/nana/std_mutex.hpp @@ -8,12 +8,12 @@ #include #include #include -#include -#include +//#include +//#include #include #include // http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno.h#L53 -#define EPROTO 71 /* Protocol error */ +//#define EPROTO 71 /* Protocol error */ #include #include #else diff --git a/include/nana/std_thread.hpp b/include/nana/std_thread.hpp index f3cf4bc0..e1df7ef7 100644 --- a/include/nana/std_thread.hpp +++ b/include/nana/std_thread.hpp @@ -5,6 +5,7 @@ #if defined(STD_THREAD_NOT_SUPPORTED) #if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + #include #else #include @@ -13,5 +14,11 @@ namespace std typedef boost::thread thread; } #endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + +#else + +#include + #endif // (STD_THREAD_NOT_SUPPORTED) + #endif // NANA_STD_THREAD_HPP diff --git a/include/nana/system/shared_wrapper.hpp b/include/nana/system/shared_wrapper.hpp index b1737cc2..ab14997e 100644 --- a/include/nana/system/shared_wrapper.hpp +++ b/include/nana/system/shared_wrapper.hpp @@ -30,7 +30,7 @@ namespace system typedef void* module_t; void* symbols(module_t handle, const char* symbol); - }; //end struct shared_helper + } //end namespace shared_helper }//end namespace detail class shared_wrapper diff --git a/include/nana/unicode_bidi.hpp b/include/nana/unicode_bidi.hpp index acd2b057..71a5f882 100644 --- a/include/nana/unicode_bidi.hpp +++ b/include/nana/unicode_bidi.hpp @@ -1,6 +1,8 @@ #ifndef NANA_UNICODE_BIDI_HPP #define NANA_UNICODE_BIDI_HPP #include +#include + namespace nana { @@ -60,7 +62,7 @@ namespace nana void _m_resolve_weak_types(); void _m_resolve_neutral_types(); void _m_resolve_implicit_levels(); - void _m_reordering_resolved_levels(const char_type*, std::vector & reordered); + void _m_reordering_resolved_levels(std::vector & reordered); static bidi_category _m_bidi_category(bidi_char); static bidi_char _m_char_dir(char_type); private: @@ -71,5 +73,6 @@ namespace nana }; } +#include #endif diff --git a/source/audio/player.cpp b/source/audio/player.cpp index e86f1798..5ede06a4 100644 --- a/source/audio/player.cpp +++ b/source/audio/player.cpp @@ -1,5 +1,8 @@ + +#include #include + #ifdef NANA_ENABLE_AUDIO #include @@ -67,4 +70,4 @@ namespace nana{ namespace audio }//end namespace audio }//end namespace nana -#endif //NANA_ENABLE_AUDIO \ No newline at end of file +#endif //NANA_ENABLE_AUDIO diff --git a/source/charset.cpp b/source/charset.cpp index ddf7207f..225cba40 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1,4 +1,4 @@ -/* +/** * A Character Encoding Set Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,9 +7,9 @@ * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * @file: nana/charset.cpp - * @brief: A conversion between unicode characters and multi bytes characters - * @contributions: + * @file nana/charset.cpp + * @brief A conversion between unicode characters and multi bytes characters + * @contributions * UTF16 4-byte decoding issue by Renke Yan. * Pr0curo(pr#98) */ @@ -20,6 +20,7 @@ #include #include #include //Added by Pr0curo(pr#98) +#include //GCC 4.7.0 does not implement the and codecvt_utfx classes #ifndef STD_CODECVT_NOT_SUPPORTED @@ -34,6 +35,7 @@ namespace nana { namespace utf { + /// return a pointer to the code unit of the character at pos const char* char_ptr(const char* text, unsigned pos) { auto ustr = reinterpret_cast(text); @@ -48,10 +50,10 @@ namespace nana continue; } - if (uch < 0xC0) + if (uch < 0xC0) // use police ? return nullptr; - if ((uch < 0xE0) && (ustr + 1 < end)) + if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0 ustr += 2; else if (uch < 0xF0 && (ustr + 2 <= end)) ustr += 3; @@ -64,6 +66,7 @@ namespace nana return reinterpret_cast(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) { auto ustr = reinterpret_cast(text_utf8.c_str()); @@ -94,6 +97,7 @@ namespace nana return reinterpret_cast(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) { if (!text_utf8) @@ -112,10 +116,10 @@ namespace nana if (len) *len = 1; - return *text_utf8; + return *text_utf8; // uch ? } - if (uch < 0xC0) + if (uch < 0xC0) // use police or ?? { if (len) *len = 0; @@ -151,6 +155,7 @@ namespace nana 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) { const char* ptr; @@ -210,22 +215,23 @@ namespace nana } namespace detail - { + { + /// candidate to be more general?? class locale_initializer { public: static void init() { static bool initialized = false; - if(false == initialized) - { - initialized = true; - //Only set the C library locale - std::setlocale(LC_CTYPE, ""); - } + if (initialized) return; + + initialized = true; + //Only set the C library locale + 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) { if(nullptr == s || *s == 0) @@ -258,7 +264,8 @@ namespace nana #endif 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) { if(nullptr == s || *s == 0) @@ -291,6 +298,7 @@ namespace nana 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) { if(nullptr == s || *s == 0) @@ -304,6 +312,7 @@ namespace nana { wcstr.resize((chars - 1) * sizeof(wchar_t)); ::MultiByteToWideChar(CP_ACP, 0, s, -1, reinterpret_cast(&wcstr[0]), chars - 1); + // ^ the trick ! } #else locale_initializer::init(); @@ -338,17 +347,98 @@ namespace nana 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( 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(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(); // the nana default +// auto def_encoding_error_police = std::make_unique(); +// auto def_encoding_error_police = std::make_unique(); +// auto def_encoding_error_police = std::make_unique('X'); + auto def_encoding_error_police = std::make_unique(); + + + #ifndef STD_CODECVT_NOT_SUPPORTED class charset_string : public charset_encoding_interface { public: charset_string(const std::string& s) - : data_(s), is_unicode_(false) + : data_(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) @@ -501,9 +591,9 @@ namespace nana } private: std::string data_; - std::wstring wdata_for_move_; - bool is_unicode_; - unicode utf_x_; + std::wstring wdata_for_move_{}; + bool is_unicode_{ false }; + unicode utf_x_{ unicode::utf8 }; }; class charset_wstring @@ -578,37 +668,42 @@ namespace nana std::string data_for_move_; }; #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) { if(p != end) { - if(*p < 0x80) + if(*p < 0x80) // ASCII char 0-127 or 0-0x80 { return *(p++); } unsigned ch = *p; unsigned long code; - if(ch < 0xC0) + if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page { - p = end; - return 0; + //return *(p++); // temp: assume equal + //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); 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); 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); p += 4; } - else + else // error, go to end { p = end; return 0; @@ -950,11 +1045,11 @@ namespace nana { public: charset_string(const std::string& s) - : data_(s), is_unicode_(false) + : data_(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) @@ -1067,12 +1162,21 @@ namespace nana { 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: return utf32_to_utf8(wcstr); case unicode::utf16: return utf32_to_utf16(wcstr); case unicode::utf32: return wcstr; +#endif } } return {}; @@ -1122,9 +1226,9 @@ namespace nana } private: std::string data_; - std::wstring wdata_for_move_; - bool is_unicode_; - unicode utf_x_; + std::wstring wdata_for_move_{}; + bool is_unicode_{ false }; + unicode utf_x_{ unicode::utf8 }; }; @@ -1195,7 +1299,7 @@ namespace nana } private: std::wstring data_; - std::string data_for_move_; + std::string data_for_move_{}; }; #endif } diff --git a/source/datetime.cpp b/source/datetime.cpp index 4682c32c..d633090d 100644 --- a/source/datetime.cpp +++ b/source/datetime.cpp @@ -17,62 +17,65 @@ #include namespace { - void localtime(struct tm& tm) + std::tm localtime() { #if defined(NANA_WINDOWS) && !defined(NANA_MINGW) time_t t; ::time(&t); + std::tm tm; if(localtime_s(&tm, &t) != 0) - { assert(false); - } + + return tm; #else time_t t = std::time(nullptr); struct tm * tm_addr = std::localtime(&t); assert(tm_addr); - tm = *tm_addr; + + return *tm_addr; #endif } + + ::nana::date::value to_dateval(const std::tm& t) + { + return {static_cast(t.tm_year + 1900), static_cast(t.tm_mon + 1), static_cast(t.tm_mday)}; + } + + ::nana::time::value to_timeval(const std::tm& t) + { + return {static_cast(t.tm_hour), static_cast(t.tm_min), static_cast(t.tm_sec)}; + } + } // namespace anonymous namespace nana { - //class date + //class date void date::set(const std::tm& t) { - value_.year = t.tm_year + 1900; - value_.month = t.tm_mon + 1; - value_.day = t.tm_mday; + value_ = to_dateval(t); } date::date() + : value_(to_dateval(localtime())) { - struct tm t; - localtime(t); - set(t); } date::date(const std::tm& t) + : value_(to_dateval(t)) { - set(t); } date::date(int year, int month, int day) + : value_({static_cast(year), static_cast(month), static_cast(day)}) { if(1601 <= year && year < 30827 && 0 < month && month < 13 && day > 0) { if(day <= static_cast(date::month_days(year, month))) - { - value_.year = year; - value_.month = month; - value_.day = day; return; - } } - struct tm t; - localtime(t); - set(t); + set(localtime()); } date date::operator - (int off) const @@ -258,39 +261,27 @@ namespace nana //class time void time::set(const std::tm& t) { - value_.hour = t.tm_hour; - value_.minute = t.tm_min; - value_.second = t.tm_sec; + value_ = to_timeval(t); } time::time() + : value_(to_timeval(localtime())) { - struct tm t; - localtime(t); - set(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) + : value_({hour, minute, second}) { if(hour < 24 && minute < 60 && second < 62) - { - value_.hour = hour; - value_.minute = minute; - value_.second = second; return; - } - struct tm t; - localtime(t); - set(t); - } + set(localtime()); + } const time::value& time::read() const { return value_; diff --git a/source/deploy.cpp b/source/deploy.cpp index 6971d563..f4337e54 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -436,6 +436,51 @@ namespace std } #endif +//#ifdef STD_put_time_NOT_SUPPORTED +#include +#include +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/**/(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 + // std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time); + //template<> + //std::wstring put_time(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 + // 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 + namespace nana { bool is_utf8(const char* str, std::size_t len) @@ -468,25 +513,83 @@ namespace nana 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) { 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) { 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) { 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) { return str; diff --git a/source/detail/platform_spec_posix.cpp b/source/detail/platform_spec_posix.cpp index 9713a0c9..a2121991 100644 --- a/source/detail/platform_spec_posix.cpp +++ b/source/detail/platform_spec_posix.cpp @@ -16,6 +16,9 @@ #include #if defined(NANA_POSIX) && defined(NANA_X11) + +#include + #include #include #include @@ -432,13 +435,13 @@ namespace detail 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; return 0; } - int X11_fatal_handler(Display* disp) + int X11_fatal_handler(Display*) { return 0; } @@ -1414,4 +1417,6 @@ namespace detail } }//end namespace detail }//end namespace nana + +#include #endif //NANA_POSIX && NANA_X11 diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 88317ede..a2968f5b 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -1,7 +1,7 @@ -/* +/** * Platform Specification Implementation * 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. * (See accompanying file LICENSE_1_0.txt or copy at @@ -9,7 +9,7 @@ * * @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 @@ -19,9 +19,172 @@ #include #include -#if defined(_MSC_VER) -#include -#endif // _MSVC + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +/****************************************************************** +* * +* VersionHelpers.h -- This module defines helper functions to * +* promote version check with proper * +* comparisons. * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +******************************************************************/ + +#include // 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 +//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 { diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index aca26162..69f467cf 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -37,12 +37,12 @@ #endif -namespace nana { namespace experimental { -#ifndef CXX_NO_INLINE_NAMESPACE - inline namespace v1 { -#endif - namespace filesystem +namespace nana { namespace experimental { namespace filesystem { +#ifndef CXX_NO_INLINE_NAMESPACE + inline namespace v1 { +#endif + //class filesystem_error filesystem_error::filesystem_error(const std::string& msg, std::error_code err) : std::system_error(err, msg) @@ -59,12 +59,12 @@ namespace nana { namespace experimental { path2_(path2) {} - const path& filesystem_error::path1() const + const path& filesystem_error::path1() const noexcept { return path1_; } - const path&filesystem_error::path2() const + const path& filesystem_error::path2() const noexcept { return path2_; } @@ -110,7 +110,8 @@ namespace nana { namespace experimental { 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) return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES); @@ -122,17 +123,20 @@ namespace nana { namespace experimental { path path::extension() const { + // todo: make more globlal #if defined(NANA_WINDOWS) - auto pos = pathstr_.find_last_of(L"\\/."); + auto SLorP=L"\\/."; + auto P=L'.'; #else - auto pos = pathstr_.find_last_of("\\/."); + auto SLorP="\\/."; + auto P='.'; #endif - if ((pos == pathstr_.npos) || (pathstr_[pos] != '.')) - return path(); + auto pos = pathstr_.find_last_of(SLorP); - - if (pos + 1 == pathstr_.size()) - return path(); + if ( ( pos == pathstr_.npos) + || ( pathstr_[pos] != P ) + || ( pos + 1 == pathstr_.size() )) + return path(); return path(pathstr_.substr(pos)); } @@ -384,7 +388,7 @@ namespace nana { namespace experimental { } }; - directory_iterator::directory_iterator() + directory_iterator::directory_iterator() noexcept : end_(true), handle_(nullptr) {} @@ -414,14 +418,10 @@ namespace nana { namespace experimental { bool directory_iterator::equal(const directory_iterator& x) const { 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) { path_ = file_path.native(); @@ -785,6 +785,13 @@ namespace nana { namespace experimental { 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) { @@ -806,6 +813,7 @@ namespace nana { namespace experimental { bool remove(const path& p, std::error_code & ec) { + ec.clear(); auto stat = status(p); if (stat.type() == file_type::directory) return detail::rm_dir(p); diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 9c1a5ae0..693a9bf7 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -207,10 +207,10 @@ namespace nana { switch(categ) { - case category::root_tag::value: + case category::flags::root: attribute.root = new attr_root_tag; break; - case category::frame_tag::value: + case category::flags::frame: attribute.frame = new attr_frame_tag; break; default: @@ -222,10 +222,10 @@ namespace nana { switch(category) { - case category::root_tag::value: + case category::flags::root: delete attribute.root; break; - case category::frame_tag::value: + case category::flags::frame: delete attribute.frame; break; default: break; @@ -236,7 +236,7 @@ namespace nana //basic_window //@brief: constructor for the root window basic_window::basic_window(basic_window* owner, std::unique_ptr&& 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); _m_init_pos_and_size(nullptr, rectangle()); @@ -256,7 +256,7 @@ namespace nana //@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) { - if(category::root_tag::value == this->other.category) + if(category::flags::root == this->other.category) { this->root = wd; dimension.width = width; @@ -270,7 +270,7 @@ namespace nana 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; } @@ -357,12 +357,12 @@ namespace nana 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)) agrparent = nullptr; - while(agrparent && (agrparent->other.category != category::root_tag::value)) + while(agrparent && (category::flags::root != agrparent->other.category)) agrparent = agrparent->parent; owner = agrparent; diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index d705261c..22bd4498 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -36,6 +36,18 @@ namespace nana detail::bedrock::instance().wd_manager().internal_lock().unlock(); } //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 void event_arg::stop_propagation() const diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 624fa042..72e8b53f 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -227,7 +227,7 @@ namespace detail 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 } @@ -250,9 +250,13 @@ namespace detail _m_emit_core(evt_code, wd, false, arg); - if(ask_update) - wd_manager().do_lazy_refresh(wd, false); - else + //A child of wd may not be drawn if it was out of wd's range before wd resized, + //so refresh all children of wd when a resized occurs. + if(ask_update || (event_code::resized == evt_code)) + { + 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; 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(); @@ -477,7 +481,7 @@ namespace detail 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; @@ -486,7 +490,8 @@ namespace detail static core_window_t* last_mouse_down_window; auto native_window = reinterpret_cast(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) { @@ -506,7 +511,7 @@ namespace detail if(pressed_wd_space) 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 (mouse_action::pressed != msgwnd->flags.action) @@ -520,7 +525,7 @@ namespace detail arg.evt_code = event_code::mouse_move; 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; } break; @@ -544,7 +549,7 @@ namespace detail if(msgwnd->dimension.width != static_cast(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast(xevent.xconfigure.height)) { auto & cf = xevent.xconfigure; - brock.wd_manager().size(msgwnd, nana::size{static_cast(cf.width), static_cast(cf.height)}, true, true); + wd_manager.size(msgwnd, nana::size{static_cast(cf.width), static_cast(cf.height)}, true, true); } 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) 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 ((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; auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press); 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; if(brock.emit(arg.evt_code, msgwnd, arg, true, &context)) { - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) { pressed_wd = msgwnd; //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 msgwnd->flags.action = mouse_action::normal; + 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 { - 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; @@ -669,7 +675,7 @@ namespace detail } //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) msgwnd->flags.action = mouse_action::over; @@ -683,7 +689,7 @@ namespace detail if(click_arg.window_handle) evt_ptr->click.emit(click_arg, reinterpret_cast(msgwnd)); - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) { arg.evt_code = event_code::mouse_up; evt_ptr->mouse_up.emit(arg, reinterpret_cast(msgwnd)); @@ -692,29 +698,27 @@ namespace detail else if(click_arg.window_handle) msgwnd->together.events_ptr->click.emit(click_arg, reinterpret_cast(msgwnd)); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } pressed_wd = nullptr; } break; case DestroyNotify: + if(wd_manager.available(msgwnd)) { - auto & spec = nana::detail::platform_spec::instance(); - if(brock.wd_manager().available(msgwnd)) + //The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window(). + if (msgwnd->root == brock.get_menu()) { - //The msgwnd may be destroyed if the window is destroyed by calling native interface of close_window(). - if (msgwnd->root == brock.get_menu()) - { - 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); + brock.erase_menu(false); + brock.delay_restore(3); //Restores if delay_restore not decleared } + + 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; case MotionNotify: @@ -732,8 +736,8 @@ namespace detail if(pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, xevent.xmotion.x, xevent.xmotion.y); - if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd)) + msgwnd = wd_manager.find_window(native_window, xevent.xmotion.x, xevent.xmotion.y); + if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd)) { brock.event_msleave(hovered_wd); 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, //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) msgwnd = cap_wd; } else if(msgwnd) { 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; if(prev_captured_inside) @@ -787,7 +791,7 @@ namespace detail arg.evt_code = event_code::mouse_move; 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; break; case MapNotify: @@ -852,7 +856,6 @@ namespace detail keybuf[len] = 0; wchar_t os_code = 0; - auto & wd_manager = brock.wd_manager(); switch(status) { case XLookupKeySym: @@ -934,7 +937,7 @@ namespace detail 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(arg.key)) ? 1 : 0 ); brock.delay_restore(cmd); @@ -1041,7 +1044,7 @@ namespace detail arg.window_handle = reinterpret_cast(msgwnd); 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; } @@ -1072,7 +1075,7 @@ namespace detail { bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_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.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) { context.event_window = pre_event_window; @@ -1126,14 +1129,14 @@ namespace detail } 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) - 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(); if(0 == context->window_count) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index d0bb0d82..8e5f24da 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -1,4 +1,4 @@ -/* +/** * A Bedrock Implementation * Nana C++ Library(http://www.nanapro.org) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) @@ -7,7 +7,8 @@ * (See accompanying file LICENSE_1_0.txt or copy at * 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 */ @@ -25,6 +26,8 @@ #include #include +#include + #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x020A #endif @@ -232,6 +235,7 @@ namespace detail 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::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); } @@ -239,8 +243,8 @@ namespace detail 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) { //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) <<"An uncaptured non-std exception during message pumping!" + << "\n in form: " << API::window_caption(modal_window) ).show(); internal_scope_guard lock; _m_except_handler(); @@ -650,6 +655,14 @@ namespace detail case nana::detail::messages::tray: notifications_window_proc(wd, wParam, lParam); return true; + case nana::detail::messages::affinity_execute: + if (wParam) + { + auto arg = reinterpret_cast(wParam); + if (arg->function_ptr) + (*arg->function_ptr)(); + } + break; default: break; } @@ -772,7 +785,9 @@ namespace detail static restrict::TRACKMOUSEEVENT track = {sizeof track, 0x00000002}; auto native_window = reinterpret_cast(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) { @@ -817,7 +832,7 @@ namespace detail bool take_over = false; auto mmi = reinterpret_cast(lParam); - if(msgwnd->min_track_size.width && msgwnd->min_track_size.height) + if(!msgwnd->min_track_size.empty()) { mmi->ptMinTrackSize.x = static_cast(msgwnd->min_track_size.width + msgwnd->extra_width); mmi->ptMinTrackSize.y = static_cast(msgwnd->min_track_size.height + msgwnd->extra_height); @@ -878,14 +893,14 @@ namespace detail break; 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->flags.take_active && !msgwnd->flags.ignore_mouse_focus) { auto killed = brock.wd_manager().set_focus(msgwnd, false, arg_focus::reason::mouse_press); if (killed != msgwnd) - brock.wd_manager().do_lazy_refresh(killed, false); + wd_manager.do_lazy_refresh(killed, false); } arg_mouse arg; @@ -903,7 +918,7 @@ namespace detail if (pressed_wd_space) 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))) break; @@ -924,7 +939,7 @@ namespace detail { auto kill_focus = brock.wd_manager().set_focus(new_focus, false, arg_focus::reason::mouse_press); 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 rootwd = native_interface::find_window(pos.x, pos.y); 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 msgwnd->flags.action = mouse_action::normal; arg.evt_code = event_code::mouse_up; 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) 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) break; @@ -993,7 +1008,7 @@ namespace detail } //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; draw_invoker(&drawer::mouse_up, msgwnd, arg, &context); @@ -1001,7 +1016,7 @@ namespace detail if (click_arg.window_handle) retain->click.emit(click_arg, reinterpret_cast(msgwnd)); - if (brock.wd_manager().available(msgwnd)) + if (wd_manager.available(msgwnd)) { arg.evt_code = event_code::mouse_up; retain->mouse_up.emit(arg, reinterpret_cast(msgwnd)); @@ -1010,7 +1025,7 @@ namespace detail else if (click_arg.window_handle) retain->click.emit(click_arg, reinterpret_cast(msgwnd)); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } pressed_wd = nullptr; break; @@ -1019,8 +1034,8 @@ namespace detail if (pressed_wd_space) break; - msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); - if (brock.wd_manager().available(hovered_wd) && (msgwnd != hovered_wd)) + msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); + if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd)) { brock.event_msleave(hovered_wd); 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, //redirect the msgwnd to the captured window. - auto wd = brock.wd_manager().capture_redirect(msgwnd); + auto wd = wd_manager.capture_redirect(msgwnd); if(wd) msgwnd = wd; } @@ -1036,7 +1051,7 @@ namespace detail else if(msgwnd) { 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; if(prev_captured_inside) @@ -1084,7 +1099,7 @@ namespace detail track.hwndTrack = native_window; restrict::track_mouse_event(&track); } - if (!brock.wd_manager().available(hovered_wd)) + if (!wd_manager.available(hovered_wd)) hovered_wd = nullptr; break; case WM_MOUSELEAVE: @@ -1100,7 +1115,7 @@ namespace detail if (pointer_wd == root_window) { ::ScreenToClient(pointer_wd, &scr_pos); - auto scrolled_wd = brock.wd_manager().find_window(reinterpret_cast(pointer_wd), scr_pos.x, scr_pos.y); + auto scrolled_wd = wd_manager.find_window(reinterpret_cast(pointer_wd), scr_pos.x, scr_pos.y); def_window_proc = true; auto evt_wd = scrolled_wd; @@ -1110,7 +1125,7 @@ namespace detail { def_window_proc = false; 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.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); @@ -1124,14 +1139,14 @@ namespace detail if (scrolled_wd && (nullptr == evt_wd)) { 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.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical); assign_arg(arg, scrolled_wd, pmdec); 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 @@ -1149,7 +1164,7 @@ namespace detail POINT 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) { arg_dropfiles dropfiles; @@ -1180,11 +1195,11 @@ namespace detail dropfiles.pos.x = pos.x; 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(msgwnd); msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles, reinterpret_cast(msgwnd)); - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); } } @@ -1272,7 +1287,7 @@ namespace detail break; case WM_SIZE: 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; case WM_MOVE: brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam)); @@ -1298,7 +1313,7 @@ namespace detail case WM_SYSCHAR: def_window_proc = true; brock.shortkey_occurred(true); - msgwnd = brock.wd_manager().find_shortkey(native_window, static_cast(wParam)); + msgwnd = wd_manager.find_shortkey(native_window, static_cast(wParam)); if(msgwnd) { arg_keyboard arg; @@ -1345,7 +1360,7 @@ namespace detail bool set_focus = (brock.focus() != msgwnd) && (!msgwnd->root_widget->flags.ignore_menubar_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.evt_code = event_code::key_release; @@ -1375,9 +1390,7 @@ namespace detail 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); @@ -1498,7 +1511,7 @@ namespace detail arg.window_handle = reinterpret_cast(msgwnd); 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; } @@ -1544,12 +1557,12 @@ namespace detail brock.erase_menu(false); 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); break; case WM_NCDESTROY: brock.manage_form_loader(msgwnd, false); - brock.wd_manager().destroy_handle(msgwnd); + wd_manager.destroy_handle(msgwnd); if(--context.window_count <= 0) { @@ -1561,7 +1574,7 @@ namespace detail def_window_proc = true; } - root_runtime = brock.wd_manager().root_runtime(native_window); + root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) { root_runtime->condition.pressed = pressed_wd; diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index ea84c1d3..b21eb270 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -1,7 +1,7 @@ /* * Platform Implementation * 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. * (See accompanying file LICENSE_1_0.txt or copy at @@ -13,6 +13,9 @@ #include #include #include +#include +#include + #if defined(NANA_WINDOWS) #if defined(STD_THREAD_NOT_SUPPORTED) #include @@ -23,8 +26,6 @@ #include "../../paint/detail/image_ico.hpp" #elif defined(NANA_X11) #include - #include - #include #endif namespace nana{ @@ -131,9 +132,13 @@ namespace nana{ } } if (async) + { ::ShowWindowAsync(wd, cmd); - else - ::ShowWindow(wd, cmd); + return; + } + + internal_revert_guard revert; + ::ShowWindow(wd, cmd); } #elif defined(NANA_X11) namespace restrict @@ -143,6 +148,33 @@ namespace nana{ #endif //struct native_interface + void native_interface::affinity_execute(native_window_type native_handle, const std::function& fn) + { + if (!fn) + return; + +#if defined(NANA_WINDOWS) + auto mswin = reinterpret_cast(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(&arg), 0); + + return; + } + } + + fn(); +#else + fn(); +#endif + } + nana::size native_interface::primary_monitor_size() { #if defined(NANA_WINDOWS) @@ -173,6 +205,8 @@ namespace nana{ mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top); } } +#else + static_cast(pos); //eliminate unused parameter compiler warning. #endif return rectangle{ primary_monitor_size() }; } @@ -547,6 +581,8 @@ namespace nana{ activate_window(reinterpret_cast( ::GetWindow(reinterpret_cast(wd), GW_OWNER) )); +#else + static_cast(wd); //eliminate unused parameter compiler warning. #endif } @@ -565,6 +601,8 @@ namespace nana{ else ::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0); } +#else + static_cast(wd); //eliminate unused parameter compiler warning. #endif } @@ -640,6 +678,7 @@ namespace nana{ ::XFlush(disp); } + static_cast(active); //eliminate unused parameter compiler warning. #endif } @@ -715,6 +754,7 @@ namespace nana{ #if defined(NANA_WINDOWS) ::InvalidateRect(reinterpret_cast(wd), nullptr, true); #elif defined(NANA_X11) + static_cast(wd); //eliminate unused parameter compiler warning. #endif } @@ -963,6 +1003,7 @@ namespace nana{ ::SetWindowPos(native_wd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); ::AttachThreadInput(::GetCurrentThreadId(), fg_tid, FALSE); #else + static_cast(activated); //eliminate unused parameter compiler warning. set_window_z_order(wd, nullptr, z_order_action::top); #endif } @@ -1110,11 +1151,18 @@ namespace nana{ auto native_interface::window_caption(native_window_type wd) -> native_string_type { + native_string_type str; + #if defined(NANA_WINDOWS) + auto & lock = bedrock::instance().wd_manager().internal_lock(); + bool is_current_thread = (::GetCurrentThreadId() == ::GetWindowThreadProcessId(reinterpret_cast(wd), nullptr)); + + if (!is_current_thread) + lock.revert(); + int length = ::GetWindowTextLength(reinterpret_cast(wd)); if(length > 0) { - native_string_type str; //One for NULL terminator which GetWindowText will write. str.resize(length+1); @@ -1122,9 +1170,11 @@ namespace nana{ //Remove the null terminator writtien by GetWindowText str.resize(length); - - return str; } + + if (!is_current_thread) + lock.forward(); + #elif defined(NANA_X11) nana::detail::platform_scope_guard psg; ::XTextProperty txtpro; @@ -1136,14 +1186,13 @@ namespace nana{ { if(size > 1) { - std::string text = *strlist; + str = *strlist; ::XFreeStringList(strlist); - return text; } } } #endif - return native_string_type(); + return str; } void native_interface::capture_window(native_window_type wd, bool cap) @@ -1305,7 +1354,10 @@ namespace nana{ if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast(wd), nullptr)) ::PostMessage(reinterpret_cast(wd), nana::detail::messages::async_set_focus, 0, 0); else + { + internal_revert_guard revert; ::SetFocus(reinterpret_cast(wd)); + } } #elif defined(NANA_X11) nana::detail::platform_scope_guard lock; @@ -1414,6 +1466,11 @@ namespace nana{ if(static_cast(y) > sz.height + ext_height) sz.height = static_cast(y); } +#else + //eliminate unused parameter compiler warning. + static_cast(ext_width); + static_cast(ext_height); + static_cast(true_for_max); #endif return sz; } diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index cc61cdc8..47fd3e06 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -53,7 +53,7 @@ namespace nana //get the root graphics 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)); _m_paste_children(wd, is_child_refreshed, have_refreshed, vr, graph, nana::point()); @@ -66,7 +66,7 @@ namespace nana nana::point p_src; 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_interface::refresh_window(container); @@ -95,9 +95,9 @@ namespace nana } //read_visual_rectangle - //@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 result is a rectangle that is a visible area for its ancesters. + ///@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 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) { if (! wd->displayed()) return false; @@ -158,7 +158,7 @@ namespace nana 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; if (false == enabled) @@ -199,11 +199,11 @@ namespace nana nana::point rpos{ wd->pos_root }; 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 layers; 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); beg = beg->parent; @@ -229,7 +229,7 @@ namespace nana nana::rectangle 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)); ovlp.x += pre->pos_root.x; ovlp.y += pre->pos_root.y; @@ -250,7 +250,7 @@ namespace nana nana::rectangle 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)); ovlp.x += wd->pos_root.x; @@ -285,7 +285,7 @@ namespace nana if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect)) { 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)) { @@ -357,7 +357,7 @@ namespace nana //_m_notify_glasses //@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; diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 29e7b97a..5714789f 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -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); 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); bedrock::inc_window(wd->thread_id); @@ -343,7 +343,7 @@ namespace detail { //Thread-Safe Required! std::lock_guard 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); return true; } @@ -356,9 +356,9 @@ namespace detail { //Thread-Safe Required! std::lock_guard 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); return true; @@ -461,7 +461,7 @@ namespace detail std::lock_guard lock(mutex_); 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_->wd_register.remove(wd); @@ -481,7 +481,7 @@ namespace detail std::lock_guard lock(mutex_); 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); } } @@ -501,9 +501,9 @@ namespace detail native_window_type nv = nullptr; switch(wd->other.category) { - case category::root_tag::value: + case category::flags::root: nv = wd->root; break; - case category::frame_tag::value: + case category::flags::frame: nv = wd->other.attribute.frame->container; break; default: //category::widget_tag, category::lite_widget_tag break; @@ -700,7 +700,7 @@ namespace detail 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(); wd->drawer.graphics.make(sz); @@ -711,13 +711,13 @@ namespace detail if(graph_state != wd->drawer.graphics.empty()) wd->drawer.typeface_changed(); - if(category::root_tag::value == wd->other.category) + if(category::flags::root == wd->other.category) { wd->root_graph->make(sz); if(false == passive) 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); for(auto natwd : wd->other.attribute.frame->attach) @@ -828,7 +828,7 @@ namespace detail //do_lazy_refresh //@brief: defined a behavior of flush the screen //@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! std::lock_guard lock(mutex_); @@ -843,8 +843,11 @@ namespace detail { 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); + + 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) { @@ -852,7 +855,7 @@ namespace detail } } 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; return true; @@ -1362,7 +1365,7 @@ namespace detail 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(); 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. utl::erase(root_attr->frames, wd); @@ -1599,7 +1602,7 @@ namespace detail for(auto i = wd->children.rbegin(); i != wd->children.rend(); ++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); if(child) diff --git a/source/gui/element.cpp b/source/gui/element.cpp index b2fdbb7f..e1f4b649 100644 --- a/source/gui/element.cpp +++ b/source/gui/element.cpp @@ -212,7 +212,7 @@ namespace nana class menu_crook : 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) return true; @@ -266,7 +266,7 @@ namespace nana class border_depressed : 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((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E)); graph.rectangle(::nana::rectangle(r).pare_off(1), false, bgcolor); @@ -277,7 +277,7 @@ namespace nana class arrow_solid_triangle : 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 }; switch (dir) @@ -318,7 +318,7 @@ namespace nana class arrow_hollow_triangle : 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 y = r.y + 3; @@ -364,7 +364,7 @@ namespace nana class arrowhead : 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 y = r.y + 5; @@ -425,7 +425,7 @@ namespace nana class arrow_double : 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 y = r.y; @@ -486,7 +486,7 @@ namespace nana class annex_button : 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; diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index 4b5cb5f3..7008e401 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -355,13 +355,15 @@ namespace nana msgbox::msgbox(const std::string& title) : 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) : 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) @@ -702,7 +704,7 @@ namespace nana 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->spinbox.size({ value_px, 24 }); @@ -780,7 +782,7 @@ namespace nana 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->spinbox.size(::nana::size{ value_px, 24 }); diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 3aa9cca9..427be904 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -314,6 +314,8 @@ namespace nana ::Shell_NotifyIcon(impl_->icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); impl_->icon_added = true; +#else + static_cast(str); //to eliminate unused parameter compiler warning. #endif } @@ -330,6 +332,8 @@ namespace nana impl_->set_icon(impl_->icon_handle); ::DestroyIcon(pre_icon); } +#else + static_cast(icon_file); //to eliminate unused parameter compiler warning #endif } @@ -338,6 +342,8 @@ namespace nana #if defined(NANA_WINDOWS) auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); impl_->icons.push_back(icon); +#else + static_cast(icon_file); //to eliminate unused parameter compiler warning. #endif } @@ -352,6 +358,8 @@ namespace nana } else impl_->ani_timer.stop(); +#else + static_cast(ms); //to eliminate unused parameter compiler warning. #endif } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 48ba39bc..8f981475 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -522,12 +523,18 @@ namespace nana //It will delete the element and recollocate when the window destroyed. 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) { - if (!API::is_destroying(API::get_parent_window(wd))) - place_ptr_->collocate(); + if (i->handle == wd) + { + 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)) return; @@ -1321,8 +1328,6 @@ namespace nana public: div_splitter(place_parts::number_t init_weight) : division(kind::splitter, std::string()), - splitter_cursor_(cursor::arrow), - pause_move_collocate_(false), init_weight_(init_weight) { this->weight.assign(splitter_px); @@ -1374,9 +1379,18 @@ namespace nana left_pixels_ = area_left.*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) { + if(!grabbed_) + return; + const bool vert = (::nana::cursor::size_we != splitter_cursor_); 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); @@ -1413,8 +1427,10 @@ namespace nana } }; - splitter_.events().mouse_down.connect_unignorable(grab_fn); - splitter_.events().mouse_move.connect_unignorable(grab_fn); + auto & events = splitter_.events(); + 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(); @@ -1527,13 +1543,14 @@ namespace nana return area; } private: - nana::cursor splitter_cursor_; + nana::cursor splitter_cursor_{nana::cursor::arrow}; place_parts::splitter splitter_; nana::point begin_point_; int left_pos_, right_pos_; unsigned left_pixels_, right_pixels_; 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_; }; @@ -1558,7 +1575,7 @@ namespace nana } } - void collocate(window wd) override + void collocate(window) override { if (!dockable_field) { @@ -2847,3 +2864,5 @@ namespace nana } //end class place }//end namespace nana + +#include diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 6d8843fc..3b0edceb 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -280,64 +280,11 @@ namespace nana void 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_) + auto fn_ptr = &fn; + API::dev::affinity_execute(*this, [this, fn_ptr] { - if (panels_.size() > 0) - { - 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); - } + _m_add_pane(*fn_ptr); + }); } void float_away(const ::nana::point& move_pos) @@ -382,6 +329,71 @@ namespace nana { 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: window host_window_{nullptr}; place_parts::dock_notifier_interface* notifier_{ nullptr }; diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 8e9e8edb..6dcfc63a 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -104,8 +104,7 @@ namespace API { if (iwd->effect.edge_nimbus == effects::edge_nimbus::none) { - basic_window::edge_nimbus_action ena = { iwd }; - cont.push_back(ena); + cont.push_back(basic_window::edge_nimbus_action{ iwd, false}); } iwd->effect.edge_nimbus = static_cast(static_cast(en) | static_cast(iwd->effect.edge_nimbus)); } @@ -180,6 +179,11 @@ namespace API namespace dev { + void affinity_execute(window window_handle, const std::function& fn) + { + interface_type::affinity_execute(root(window_handle), fn); + } + bool set_events(window wd, const std::shared_ptr& gep) { auto iwd = reinterpret_cast(wd); @@ -330,7 +334,7 @@ namespace API return nullptr; } - //exit + //close all windows in current thread void exit() { @@ -367,6 +371,42 @@ namespace API interface_type::close_window(i); } } + //close all windows + void exit_all() + { + std::vector v; + + internal_scope_guard lock; + restrict::wd_manager().all_handles(v); + if (v.size()) + { + std::vector 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 //@brief: This function searchs whether the text contains a '&' and removes the character for transforming. diff --git a/source/gui/screen.cpp b/source/gui/screen.cpp index 1a0be98b..da390bda 100644 --- a/source/gui/screen.cpp +++ b/source/gui/screen.cpp @@ -167,6 +167,8 @@ namespace nana } } } +#else + static_cast(pos); //to eliminate unused parameter compiler warning. #endif return get_primary(); } diff --git a/source/gui/tooltip.cpp b/source/gui/tooltip.cpp index ac76b7d6..433c247b 100644 --- a/source/gui/tooltip.cpp +++ b/source/gui/tooltip.cpp @@ -227,7 +227,7 @@ namespace nana 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()) { diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index ac50d47d..f4a1ab3f 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -163,7 +163,7 @@ namespace nana{ namespace drawerbase _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; switch(arg.key) diff --git a/source/gui/widgets/checkbox.cpp b/source/gui/widgets/checkbox.cpp index 7e567044..f5980da9 100644 --- a/source/gui/widgets/checkbox.cpp +++ b/source/gui/widgets/checkbox.cpp @@ -216,7 +216,7 @@ namespace nana{ namespace drawerbase uiobj.check(false); uiobj.react(false); - element_tag el = {}; + element_tag el; el.uiobj = &uiobj; diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index dfa911d0..2e1d4546 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -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_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()) { @@ -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()) { @@ -714,7 +714,7 @@ namespace nana 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)) API::dev::lazy_refresh(); diff --git a/source/gui/widgets/form.cpp b/source/gui/widgets/form.cpp index eab587ad..af43ea37 100644 --- a/source/gui/widgets/form.cpp +++ b/source/gui/widgets/form.cpp @@ -18,7 +18,7 @@ namespace nana namespace form { //class trigger - void trigger::attached(widget_reference wdg, graph_reference graph) + void trigger::attached(widget_reference wdg, graph_reference) { wd_ = &wdg; API::ignore_mouse_focus(wdg, true); diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index ed6c2828..d500eed9 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -437,7 +437,7 @@ namespace nana 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; iterator block_start; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 88bfe21f..41254770 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -329,7 +329,7 @@ namespace nana struct column_t { native_string_type text; ///< "text" header of the column number "index" with weigth "pixels" - unsigned pixels; + unsigned pixels; ///< width bool visible{true}; size_type index; std::function weak_ordering; @@ -338,6 +338,7 @@ namespace nana column_t(native_string_type&& txt, unsigned px, size_type pos) : text(std::move(txt)), pixels(px), index(pos) {} + /// \todo introduce default cell format }; using container = std::vector ; @@ -410,7 +411,7 @@ namespace nana 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; } @@ -427,7 +428,7 @@ namespace nana return 0; } - unsigned pixels() const + unsigned pixels() const ///< the visible width of the whole header { unsigned pixels = 0; for(auto & m : cont_) @@ -470,12 +471,13 @@ namespace nana { if(x < static_cast(col.pixels)) return col.index; - x -= col.pixels; + if (col.visible) + x -= col.pixels; } 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 left = 0; @@ -493,7 +495,8 @@ namespace nana } 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 n = npos; @@ -509,11 +512,12 @@ namespace nana break; } else if(i->visible) - n = i->index; + n = i->index; } 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 { for(const auto & m : cont_) @@ -532,7 +536,8 @@ namespace nana } 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() { if ((index == to) || (index >= cont_.size()) || (to >= cont_.size())) @@ -879,7 +884,8 @@ namespace nana list_.back().key_ptr = ptr; 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) { return &(*list_.emplace(this->get(pos), std::move(text))); @@ -1828,9 +1834,7 @@ namespace nana };//end class es_lister - //struct essence_t - //@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. + /// 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. struct essence_t { enum class item_state{normal, highlighted, pressed, grabbed, floated}; @@ -1859,7 +1863,7 @@ namespace nana struct scroll_part { - static const unsigned scale = 16; + static const unsigned scale = 16; // ? 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. // need to be abs??? to see the same item after sort() ?? @@ -1942,8 +1946,8 @@ namespace nana //number_of_lister_item - //@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. + /// @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. 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); @@ -1983,8 +1987,9 @@ namespace nana void trace_item_abs( index_pair abs_pos ) { - if(abs_pos.item == npos && abs_pos.cat == scroll.offset_y_abs.cat - && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat + if( abs_pos.item == npos + && abs_pos.cat == scroll.offset_y_abs.cat + && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat return; 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); 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 height = sz.height - 2 - (h ? scroll.scale : 0); + unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2? + unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2? //event hander for scrollbars 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); } - std::pair where(int x, int y){ + std::pair where(int x, int y) + { std::pair new_where; if(2 < x && x < static_cast(graph->width()) - 2 && 1 < y && y < static_cast(graph->height()) - 1) @@ -2614,15 +2620,15 @@ namespace nana 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}; - for (item_proxy &it : cpx ) - { - if (it.selected() != sel) + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) + { + if (it.selected() != 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 @@ -2644,6 +2650,7 @@ namespace nana 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) { if(essence_->ptr_state == item_state::highlighted) @@ -2658,7 +2665,7 @@ namespace nana item_spliter_ = hd.index; // original index return true; } - x -= hd.pixels; + x -= hd.pixels; } } } @@ -2672,7 +2679,7 @@ namespace nana if(is_grab) { 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; } else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second) @@ -2680,21 +2687,21 @@ namespace nana } //grab_move - //@brief: draw when an item is grabbing. - //@return: 0 = no graphics changed, 1 = just update, 2 = refresh + /// @brief draw when an item is grabbing. + /// @return 0 = no graphics changed, 1 = just update, 2 = refresh int grab_move(const nana::rectangle& rect, const nana::point& pos) { if(item_spliter_ == npos) - { - draw(rect); - _m_make_float(rect, pos); + { // move header item, not resize it + draw(rect); // first draw the entery header as it was + _m_make_float(rect, pos); // now draw one floating header item //Draw the target strip grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front); return 1; } else - { + { // resize header item, not move it const auto& item = essence_->header.column(item_spliter_); //Resize the item specified by item_spliter_. auto new_w = orig_item_width_ - (ref_xpos_ - pos.x); @@ -3003,9 +3010,19 @@ namespace nana } } - //Draws an item - //@param content_r the rectangle of list content - 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& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const + /// Draws an item + 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, ///< the rectangle where the full list content have to be drawn + const std::vector& seqs, + nana::color bgcolor, + nana::color fgcolor, + item_state state + ) const { auto & item = cat.items[item_pos.item]; @@ -3022,7 +3039,7 @@ namespace nana if (item.flags.selected) bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected" 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; @@ -3148,6 +3165,7 @@ namespace nana { auto cell_txtcolor = fgcolor; 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 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_->pointer_where.first == parts::header) - { + { // moving a pressed header : grab it (or split-resize?) essence_->ptr_state = item_state::grabbed; nana::point pos = arg.pos; essence_->widget_to_header(pos); drawer_header_->grab(pos, true); + essence_->lister.wd_ptr()->set_capture(true); - - update = 2; + update = 2; //0 = nothing, 1 = update, 2 = refresh } } if(essence_->ptr_state == item_state::grabbed) - { + { // moving a grabbed header nana::point pos = arg.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)) { 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) { bool sel = true; @@ -3444,28 +3465,32 @@ namespace nana if (arg.shift) lister.select_display_range(lister.last_selected_abs , item_pos, sel); 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 lister.select_for_all(false); //cancel all selections } 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) { 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()); if (item_ptr->flags.selected) { - lister.cancel_others_if_single_enabled(true, last_selected); - essence_->lister.last_selected_abs = last_selected; + lister.cancel_others_if_single_enabled(true, abs_item_pos); + 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); } else if(!lister.single_selection()) @@ -3482,7 +3507,7 @@ namespace nana lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle()); 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()) 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 (cursor::size_we == essence_->lister.wd_ptr()->cursor()) - { - if (essence(). auto_width(drawer_header_->item_spliter() )) // ? in order - essence().update(); - return; - } + { + //adjust the width of column to its content. + if (essence_->auto_width(drawer_header_->item_spliter() )) + essence_->update(); + return; + } if (essence_->pointer_where.first != essence_t::parts::lister) return; @@ -3575,7 +3601,8 @@ namespace nana 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()); - if (!arg_cat.category_change_blocked()){ + if (!arg_cat.category_change_blocked()) + { bool do_expand = (lister.expand(item_pos.cat) == false); lister.expand(item_pos.cat, do_expand); @@ -3604,8 +3631,8 @@ namespace nana { bool up = false; - if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) - return ; + if (essence_->lister.size_categ()==1 && essence_->lister.size_item(0)==0) + return ; switch(arg.key) { @@ -3623,49 +3650,46 @@ namespace nana } break; - case keyboard::os_pageup : + case keyboard::os_pageup : up = true; - case keyboard::os_pagedown: - { - auto& scrl = essence_->scroll.v; - if (! scrl.make_page_scroll(!up)) - return; - essence_->lister.select_for_all(false); + case keyboard::os_pagedown: + { + auto& scrl = essence_->scroll.v; + if (! scrl.make_page_scroll(!up)) + return; + essence_->lister.select_for_all(false); - index_pair idx{essence_->scroll_y_dpl()}; - if (!up) - essence_->lister.forward(idx, scrl.range()-1, idx); + index_pair idx{essence_->scroll_y_dpl()}; + if (!up) + essence_->lister.forward(idx, scrl.range()-1, idx); - if (idx.is_item()) - item_proxy::from_display(essence_, idx).select(true); - else - if(!essence_->lister.single_selection()) + if (idx.is_item()) + item_proxy::from_display(essence_, idx).select(true); + else if(!essence_->lister.single_selection()) essence_->lister.categ_selected(idx.cat, true); - essence_->trace_last_selected_item (); + essence_->trace_last_selected_item (); - break; - } - case keyboard::os_home: - { - essence_->lister.select_for_all(false); + break; + } + case keyboard::os_home: + { + essence_->lister.select_for_all(false); - index_pair frst{essence_->lister.first()}; - if (frst.is_item()) - item_proxy::from_display(essence_, frst).select(true); - else - if(!essence_->lister.single_selection()) + index_pair frst{essence_->lister.first()}; + if (frst.is_item()) + item_proxy::from_display(essence_, frst).select(true); + else if(!essence_->lister.single_selection()) essence_->lister.categ_selected(frst.cat, true); - essence_->trace_last_selected_item (); - break; - } - case keyboard::os_end: - essence_->lister.select_for_all(false); - item_proxy::from_display(essence_, essence_->lister.last()).select(true); - essence_->trace_last_selected_item (); - break; - + essence_->trace_last_selected_item (); + break; + } + case keyboard::os_end: + essence_->lister.select_for_all(false); + item_proxy::from_display(essence_, essence_->lister.last()).select(true); + essence_->trace_last_selected_item (); + break; default: return; } @@ -3677,20 +3701,19 @@ namespace nana { switch(arg.key) { - case keyboard::copy: - { - export_options exp_opt {essence_->def_exp_options}; - exp_opt.columns_order = essence_->header.all_headers(true); - exp_opt.only_selected_items = true; - ::nana::system::dataexch().set(essence_->to_string(exp_opt)); - return; - } - case keyboard::select_all : - essence_->lister.select_for_all(true); + case keyboard::copy: + { + export_options exp_opt {essence_->def_exp_options}; + exp_opt.columns_order = essence_->header.all_headers(true); + exp_opt.only_selected_items = true; + ::nana::system::dataexch().set(essence_->to_string(exp_opt)); + return; + } + case keyboard::select_all : + essence_->lister.select_for_all(true); refresh(graph); API::dev::lazy_refresh(); break; - default: return; } @@ -3699,6 +3722,7 @@ namespace nana //end class trigger //class item_proxy + item_proxy::item_proxy(essence_t * 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() - item_proxy item_proxy::from_display(essence_t *ess, const index_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)}; - } + /// 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) + { + 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() - index_pair item_proxy::to_display() const - { - return ess_->lister.relative_pair(pos_); - } + item_proxy item_proxy::from_display(const index_pair &relative) const + { + return item_proxy{ess_, ess_->lister.absolute_pair(relative)}; + } - 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_; } @@ -3753,8 +3778,8 @@ namespace nana 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 - item_proxy & item_proxy::select(bool s) + /// 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) { 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 @@ -3968,6 +3993,7 @@ namespace nana //end class item_proxy //class cat_proxy + //the member cat_ is used for fast accessing to the category cat_proxy::cat_proxy(essence_t * ess, size_type pos) : ess_(ess), @@ -4296,7 +4322,7 @@ namespace nana } - //Implementation of arg_category + //Implementation of arg_listbox_category //Contributed by leobackes(pr#97) arg_listbox_category::arg_listbox_category(const nana::drawerbase::listbox::cat_proxy& cat) noexcept : category(cat), block_change_(false) @@ -4315,6 +4341,7 @@ namespace nana //class listbox + listbox::listbox(window wd, bool visible) { create(wd, rectangle(), visible); @@ -4393,7 +4420,7 @@ namespace nana } 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); ess.update(); return max_w; @@ -4479,34 +4506,33 @@ namespace nana 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); } // Contributed by leobackes(pr#97) - listbox::index_pair listbox::at ( const point& pos ) const - { - auto & ess=_m_ess(); - auto _where=ess.where(pos.x, pos.y); - index_pair item_pos{npos,npos}; - 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); - } - return item_pos; - } + listbox::index_pair listbox::at ( const point& pos ) const + { + auto & ess=_m_ess(); + auto _where=ess.where(pos.x, pos.y); + index_pair item_pos{npos,npos}; + 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); + } + return item_pos; + } //Contributed by leobackes(pr#97) - listbox::columns_indexs listbox::column_from_pos ( const point& pos ) - { - auto & ess=_m_ess(); - columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); - return col; - } - - + listbox::columns_indexs listbox::column_from_pos ( const point& pos ) + { + auto & ess=_m_ess(); + columns_indexs col=ess.header.item_by_x(pos.x - 2 - ess.scroll.offset_x); + return col; + } void listbox::insert(const index_pair& pos, std::string text) { diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 02a5b551..f4f66e31 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -398,24 +398,28 @@ namespace nana //Draw text, the text is transformed from orignal for hotkey character wchar_t hotkey; std::string::size_type hotkey_pos; - auto text = to_wstring(API::transform_shortkey_text(m.text, hotkey, &hotkey_pos)); + auto text = API::transform_shortkey_text(m.text, hotkey, &hotkey_pos); if (m.image.empty() == false) renderer->item_image(graph, nana::point(item_r.x + 5, item_r.y + static_cast(item_h_px - image_px) / 2 - 1), image_px, m.image); - renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), to_utf8(text), strpixels, attr); + renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr); if (hotkey) { m.hotkey = hotkey; if (m.flags.enabled) { - unsigned off_w = (hotkey_pos ? graph.text_extent_size(text, static_cast(hotkey_pos)).width : 0); - nana::size hotkey_size = graph.text_extent_size(text.c_str() + hotkey_pos, 1); - int x = item_r.x + 40 + off_w; - int y = item_r.y + text_top_off + hotkey_size.height; + auto off_px = (hotkey_pos ? graph.text_extent_size(text.c_str(), hotkey_pos).width : 0); + auto hotkey_px = graph.text_extent_size(text.c_str() + hotkey_pos, 1).width; - graph_->line({ x, y }, { x + static_cast(hotkey_size.width) - 1, y }, colors::black); + unsigned ascent, descent, inleading; + graph.text_metrics(ascent, descent, inleading); + + int x = item_r.x + 40 + off_px; + int y = item_r.y + text_top_off + ascent + 1; + + graph_->line({ x, y }, { x + static_cast(hotkey_px)-1, y }, colors::black); } } @@ -582,9 +586,12 @@ namespace nana } else if(m.flags.enabled) { - std::move(fn_close_tree_)(); - item_proxy ip(index, m); - m.functor.operator()(ip); + fn_close_tree_(); + if (m.functor) + { + item_proxy ip(index, m); + m.functor.operator()(ip); + } return 1; } } diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 747e29a9..66367622 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -53,7 +53,7 @@ namespace nana{ namespace widgets return cmd_; } - virtual bool merge(const undoable_command_interface& rhs) override + virtual bool merge(const undoable_command_interface&) override { return false; } @@ -273,8 +273,8 @@ namespace nana{ namespace widgets : editor_(editor) {} - void merge_lines(std::size_t first, std::size_t second) override{} - void add_lines(std::size_t pos, std::size_t lines) override{} + void merge_lines(std::size_t, std::size_t) override{} + void add_lines(std::size_t, std::size_t) override{} void pre_calc_line(std::size_t, unsigned) override{} void pre_calc_lines(unsigned) override{} @@ -283,12 +283,12 @@ namespace nana{ namespace widgets return editor_.textbase_.lines(); } - std::size_t take_lines(std::size_t pos) const override + std::size_t take_lines(std::size_t) const override { return 1; } - void update_line(std::size_t textline, std::size_t secondary_before) override + void update_line(std::size_t textline, std::size_t) override { int top = editor_._m_text_top_base() + static_cast(editor_.line_height() * (textline - editor_.points_.offset.y)); editor_.graph_.rectangle({ editor_.text_area_.area.x, top, editor_.text_area_.area.width, editor_.line_height() }, true, API::bgcolor(editor_.window_)); @@ -1294,7 +1294,6 @@ namespace nana{ namespace widgets select_.move_to_end = false; select_.mode_selection = selection::mode::no_selected; select_.ignore_press = false; - select_.dragged = false; API::create_caret(wd, 1, line_height()); API::bgcolor(wd, colors::white); @@ -1693,13 +1692,10 @@ namespace nana{ namespace widgets if(left_button) { - auto caret_pos_before = caret(); mouse_caret(scrpos); - if(select_.mode_selection != selection::mode::no_selected) + if (selection::mode::mouse_selected == select_.mode_selection || selection::mode::method_selected == select_.mode_selection) set_end_caret(); - else if ((!select_.dragged) && (caret_pos_before != caret())) - select_.dragged = true; text_area_.border_renderer(graph_, _m_bgcolor()); return true; @@ -1722,26 +1718,34 @@ namespace nana{ namespace widgets API::set_capture(window_, true); text_area_.captured = true; - //Set caret pos by screen point and get the caret pos. - mouse_caret(arg.pos); - if (arg.shift) + + if (this->hit_select_area(behavior_->screen_to_caret(arg.pos), true)) { - if (points_.shift_begin_caret != points_.caret) - { - select_.a = points_.shift_begin_caret; - select_.b = points_.caret; - } + select_.mode_selection = selection::mode::move_selected; } else { - if (!select(false)) + //Set caret pos by screen point and get the caret pos. + mouse_caret(arg.pos); + if (arg.shift) { - select_.a = points_.caret; //Set begin caret - set_end_caret(); + if (points_.shift_begin_caret != points_.caret) + { + select_.a = points_.shift_begin_caret; + select_.b = points_.caret; + } } - points_.shift_begin_caret = points_.caret; + else + { + if (!select(false)) + { + select_.a = points_.caret; //Set begin caret + set_end_caret(); + } + points_.shift_begin_caret = points_.caret; + } + select_.mode_selection = selection::mode::mouse_selected; } - select_.mode_selection = selection::mode::mouse_selected; } text_area_.border_renderer(graph_, _m_bgcolor()); @@ -1750,19 +1754,19 @@ namespace nana{ namespace widgets else if (event_code::mouse_up == arg.evt_code) { select_.ignore_press = false; - auto is_prev_no_selected = (select_.mode_selection == selection::mode::no_selected); + bool updated = false; if (select_.mode_selection == selection::mode::mouse_selected) { select_.mode_selection = selection::mode::no_selected; set_end_caret(); } - else if (is_prev_no_selected) + else if (selection::mode::move_selected == select_.mode_selection) { - if ((!select_.dragged) || (!move_select())) + if (!move_select()) select(false); + updated = true; } - select_.dragged = false; API::release_capture(window_); @@ -1772,8 +1776,7 @@ namespace nana{ namespace widgets text_area_.border_renderer(graph_, _m_bgcolor()); - //Redraw if is_prev_no_selected is true - return is_prev_no_selected; + return updated; } return false; } @@ -1913,11 +1916,21 @@ namespace nana{ namespace widgets return ((text_area_.area.x <= pos.x && pos.x < _m_end_pos(true)) && (text_area_.area.y <= pos.y && pos.y < _m_end_pos(false))); } - bool text_editor::hit_select_area(nana::upoint pos) const + bool text_editor::hit_select_area(nana::upoint pos, bool ignore_when_select_all) const { nana::upoint a, b; if(_m_get_sort_select_points(a, b)) { + if (ignore_when_select_all) + { + if (a.x == 0 && a.y == 0 && (b.y + 1) == static_cast(textbase_.lines())) + { + //is select all + if (b.x == static_cast(textbase_.getline(b.y).size())) + return false; + } + } + if((pos.y > a.y || (pos.y == a.y && pos.x >= a.x)) && ((pos.y < b.y) || (pos.y == b.y && pos.x < b.x))) return true; } @@ -1926,7 +1939,10 @@ namespace nana{ namespace widgets bool text_editor::move_select() { - if(hit_select_area(points_.caret) || (select_.b == points_.caret)) + if (! attributes_.editable) + return false; + + if(hit_select_area(points_.caret, true) || (select_.b == points_.caret)) { points_.caret = select_.b; diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index 477b1bd1..4dc0dd70 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -519,7 +519,7 @@ namespace nana impl_->render(); } - void drawer::focus(graph_reference, const arg_focus& arg) + void drawer::focus(graph_reference, const arg_focus&) { impl_->reset_text(); impl_->render(); @@ -579,7 +579,7 @@ namespace nana } } - void drawer::resized(graph_reference graph, const arg_resized& arg) + void drawer::resized(graph_reference, const arg_resized&) { impl_->reset_text_area(); impl_->render(); diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index a8e0cc5b..04426064 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -43,7 +43,7 @@ namespace nana : public item_renderer { private: - virtual void background(graph_reference graph, const nana::rectangle& r, const ::nana::color& bgcolor) + virtual void background(graph_reference graph, const nana::rectangle&, const ::nana::color& bgcolor) { if(bgcolor_ != bgcolor) { @@ -59,7 +59,6 @@ namespace nana virtual void item(graph_reference graph, const item_t& m, bool active, state_t sta) { - //* const nana::rectangle & r = m.r; color bgcolor; color blcolor; @@ -961,7 +960,8 @@ namespace nana auto bgcolor = API::bgcolor(basis_.wd); auto fgcolor = API::fgcolor(basis_.wd); - item_renderer::item_t m{ ::nana::rectangle{ basis_.graph->size() } }; + item_renderer::item_t m; + m.r = ::nana::rectangle{ basis_.graph->size() }; basis_.renderer->background(*basis_.graph, m.r, bgcolor); diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 4b5da90f..adb1a93a 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -87,7 +87,7 @@ namespace drawerbase { editor_ = nullptr; } - void drawer::refresh(graph_reference graph) + void drawer::refresh(graph_reference) { editor_->render(API::is_focus_ready(*widget_)); } @@ -115,7 +115,7 @@ namespace drawerbase { API::dev::lazy_refresh(); } - void drawer::mouse_up(graph_reference graph, const arg_mouse& arg) + void drawer::mouse_up(graph_reference, const arg_mouse& arg) { if(editor_->mouse_pressed(arg)) API::dev::lazy_refresh(); diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index cedca916..33f027f3 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -13,6 +13,11 @@ #include #include +#include +#include +#include + +//#define NANA_AUTOMATIC_GUI_TESTING namespace nana { namespace detail @@ -23,8 +28,67 @@ namespace nana } } - void exec() + void click(widget& w) + { + std::cout << "Automatically clicking widget "<f // = {} ///< emit events to mimics user actions and may asert results + ) + { + #ifdef NANA_AUTOMATIC_GUI_TESTING + + std::cout << "Will wait " << wait << " sec...\n"; + + std::thread t([wait, &f, wait_end]() + { + Wait( wait ); + std::cout << "running... \n" ; + if (f) + { + f(); + std::cout << "\nCongratulations, this was not trivial !" << std::endl; + }else + { + std::cout << "\nJust a trivial test." << std::endl; + } + std::cout << "Done... \n"; + std::cout << "Now again "; + Wait(wait_end); + std::cout << "Done... Now API::exit all ...\n"; + API::exit_all(); + }); + + pump(); + if (t.joinable()) + t.join(); + + #else + static_cast(wait); + static_cast(wait_end); + static_cast(f); //to eliminte unused parameter compiler warning. + + pump(); + #endif + } }//end namespace nana diff --git a/source/internationalization.cpp b/source/internationalization.cpp index 1210826e..8ac35899 100644 --- a/source/internationalization.cpp +++ b/source/internationalization.cpp @@ -10,6 +10,8 @@ * @file: nana/internationalization.cpp */ +#include + #include #include #include @@ -513,3 +515,5 @@ namespace nana } //end class i18n_eval } + +#include diff --git a/source/paint/detail/image_process_provider.cpp b/source/paint/detail/image_process_provider.cpp index 1c0c61ab..414d68dc 100644 --- a/source/paint/detail/image_process_provider.cpp +++ b/source/paint/detail/image_process_provider.cpp @@ -1,3 +1,4 @@ +#include #include #include diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 07153126..57d8138f 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -867,7 +867,7 @@ namespace paint ::DeleteObject(hBmp); ::DeleteDC(hdcMem); #elif defined(NANA_X11) - + static_cast(file_utf8); //eliminate unused parameter compil warning. #endif } } @@ -1201,6 +1201,10 @@ namespace paint if(solid) rectangle(::nana::rectangle(r).pare_off(1), true, solid_clr); } + + //eliminate unused parameter compiler warning. + static_cast(radius_x); + static_cast(radius_y); #endif } } diff --git a/source/paint/image.cpp b/source/paint/image.cpp index f14de479..529c5c44 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -11,7 +11,7 @@ * @contributors: * nabijaczleweli(pr#106) */ - +#include #include #include #include @@ -73,7 +73,8 @@ namespace paint return true; } #else - if(is_ico_){} //kill the unused compiler warning in Linux. + static_cast(is_ico_); //eliminate the unused compiler warning in Linux. + static_cast(file); //to eliminate the unused parameter compiler warning. #endif return false; } @@ -98,7 +99,9 @@ namespace paint } } #else - if(is_ico_){} //kill the unused compiler warning in Linux. + static_cast(is_ico_); //kill the unused compiler warning in Linux. + static_cast(data); //to eliminate unused parameter compiler warning. + static_cast(bytes); #endif return false; } @@ -129,6 +132,9 @@ namespace paint { #if defined(NANA_WINDOWS) ::DrawIconEx(graph.handle()->context, p_dst.x, p_dst.y, *ptr_, src_r.width, src_r.height, 0, 0, DI_NORMAL); +#else + static_cast(src_r); //eliminate unused parameter compiler warning. + static_cast(p_dst); #endif } } @@ -139,6 +145,8 @@ namespace paint { #if defined(NANA_WINDOWS) ::DrawIconEx(graph.handle()->context, r.x, r.y, *ptr_, r.width, r.height, 0, 0, DI_NORMAL); +#else + static_cast(r); //eliminate unused parameter compiler warning. #endif } } diff --git a/source/paint/image_process_selector.cpp b/source/paint/image_process_selector.cpp index f95ab20e..9dc76e23 100644 --- a/source/paint/image_process_selector.cpp +++ b/source/paint/image_process_selector.cpp @@ -1,3 +1,4 @@ +#include #include namespace nana diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index c3330c8d..574c8951 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -977,7 +977,7 @@ namespace nana{ namespace paint } } - void pixel_buffer::gradual_rectangle(const ::nana::rectangle& draw_rct, const ::nana::color& from, const ::nana::color& to, double fade_rate, bool vertical) + void pixel_buffer::gradual_rectangle(const ::nana::rectangle& draw_rct, const ::nana::color& from, const ::nana::color& to, double /*fade_rate*/, bool vertical) { auto sp = storage_.get(); if (nullptr == sp) return; diff --git a/source/system/dataexch.cpp b/source/system/dataexch.cpp index 992a76d3..cb8ecb97 100644 --- a/source/system/dataexch.cpp +++ b/source/system/dataexch.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #if defined(NANA_WINDOWS) #include @@ -82,31 +83,35 @@ namespace nana{ namespace system{ // Bitmaps are huge, so to avoid unnegligible extra copy, this routine does not use private _m_set method. HGLOBAL h_gmem = ::GlobalAlloc(GHND | GMEM_SHARE, header_size + bitmap_bytes); void * gmem = ::GlobalLock(h_gmem); - if (gmem) { - char* p = (char*)gmem; - // Fix BITMAPINFOHEADER obtained from GetDIBits WinAPI - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biHeight = ::abs(bmi.bmiHeader.biHeight); - memcpy(p, &bmi, header_size); - p += header_size; - // many programs do not support bottom-up DIB, so reversing row order is needed. - for (int y=0; y(g); //eliminate unused parameter compiler warning. throw "not implemented yet."; return false; #endif diff --git a/source/system/platform.cpp b/source/system/platform.cpp index 042c5892..092c53e5 100644 --- a/source/system/platform.cpp +++ b/source/system/platform.cpp @@ -93,6 +93,7 @@ namespace system return (::GetAsyncKeyState(button) != 0); #elif defined(NANA_LINUX) || defined(NANA_MACOS) + static_cast(button); //eliminate unused parameter compiler warning. return false; #endif } diff --git a/source/system/shared_wrapper.cpp b/source/system/shared_wrapper.cpp index dce6d621..124f2822 100644 --- a/source/system/shared_wrapper.cpp +++ b/source/system/shared_wrapper.cpp @@ -54,7 +54,7 @@ namespace system ::FreeLibrary(reinterpret_cast(handle)); #endif } - }; //end struct shared_helper + } //end namespace shared_helper }//end namespace detail diff --git a/source/unicode_bidi.cpp b/source/unicode_bidi.cpp index 5ef940ec..f92bd5ee 100644 --- a/source/unicode_bidi.cpp +++ b/source/unicode_bidi.cpp @@ -584,7 +584,7 @@ namespace nana _m_resolve_weak_types(); _m_resolve_neutral_types(); _m_resolve_implicit_levels(); - _m_reordering_resolved_levels(str, reordered); + _m_reordering_resolved_levels(reordered); } unsigned unicode_bidi::_m_paragraph_level(const char_type * begin, const char_type * end) @@ -885,7 +885,7 @@ namespace nana } } - void unicode_bidi::_m_reordering_resolved_levels(const char_type * str, std::vector & reordered) + void unicode_bidi::_m_reordering_resolved_levels(std::vector & reordered) { reordered = levels_;