diff --git a/.gitignore b/.gitignore index 53eee01b..71a1545a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ lib/ *.ninja* CMakeCache.txt CMakeFiles/ +.idea/ cmake_install.cmake *.DS_Store .idea/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..60697f01 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,51 @@ +sudo: false +language: generic + +cache: + apt: true + directories: + - /tmp/tools + +matrix: + include: + - env: CXX=g++-5 CC=gcc-5 + addons: + apt: + packages: + - g++-5 + - libjpeg8-dev + - libasound2-dev + - alsa-utils + - alsa-oss + sources: &sources + - ubuntu-toolchain-r-test + - llvm-toolchain-precise + - llvm-toolchain-precise-3.7 + - llvm-toolchain-precise-3.6 + - env: CXX=g++-4.9 CC=gcc-4.9 + addons: + apt: + packages: + - g++-4.9 + - libjpeg8-dev + - libasound2-dev + - alsa-utils + - alsa-oss + sources: *sources + +before_install: + - 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 + - chmod -R +x /tmp/tools + +install: + - /tmp/tools/cmake --prefix="$HOME" --exclude-subdir + +before_script : + - mkdir bld + - cd bld + +script: + - cmake -G"Unix Makefiles" .. -DENABLE_JPEG=ON + - make diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b65dadc..b30ebcea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,29 @@ -# CMake configuration for Nana +# CMake configuration for Nana # Author: Andrew Kornilov(https://github.com/ierofant) # Contributor: # Robert Hauck - Enable support for PNG/Freetype # Qiangqiang Wu - Add biicode support +# Ariel Vina-Rodriguez (qPCR4vir) + +#https://cmake.org/cmake-tutorial/ +#https://cmake.org/cmake/help/v3.3/module/CMakeDependentOption.html?highlight=cmakedependentoption +# use CACHE FORCE or set(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) # set compile flags if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # move this to the end ?? if(BIICODE) # prepare BII_LIB_SRC @@ -18,37 +32,45 @@ if(BIICODE) add_biicode_targets() return() -endif() +endif(BIICODE) project(nana) cmake_minimum_required(VERSION 2.8) +# Compatibility with CMake 3.1 +if(POLICY CMP0054) + # http://www.cmake.org/cmake/help/v3.1/policy/CMP0054.html + cmake_policy(SET CMP0054 OLD) +endif() + +add_definitions(-DNANA_IGNORE_CONF) -#Global MSVC definitions if(WIN32) - if(MSVC) + add_definitions(-DWIN32) + + #Global MSVC definitions + if(MSVC) option(WIN32_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON) # ?? if(WIN32_USE_MP) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") - endif() - + endif(WIN32_USE_MP) endif(MSVC) + + if(MINGW) + if(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + endif(ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) + endif(MINGW) endif(WIN32) -#Unicode -option(USE_UNICODE "Use Unicode Character Set") -if(USE_UNICODE) - add_definitions(-DNANA_UNICODE) -endif() - if(APPLE) add_definitions(-DAPPLE) include_directories(/opt/X11/include/) elseif(UNIX) add_definitions(-Dlinux) -endif() +endif(APPLE) @@ -56,19 +78,10 @@ if(UNIX) find_package(Freetype) if (FREETYPE_FOUND) include_directories( ${FREETYPE_INCLUDE_DIRS}) - endif() -endif() - -if(WIN32) - add_definitions(-DWIN32) - if(MINGW) - add_definitions(-DMINGW) - endif() -endif() + endif(FREETYPE_FOUND) +endif(UNIX) #Find PNG -option(ENABLE_PNG "Enable the use of PNG") -option(LIBPNG_FROM_OS "Use libpng from operating system.") if(ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG) if(LIBPNG_FROM_OS) @@ -76,13 +89,11 @@ if(ENABLE_PNG) if (PNG_FOUND) include_directories( ${PNG_INCLUDE_DIRS}) add_definitions(-DUSE_LIBPNG_FROM_OS) - endif() - endif() -endif() + endif(PNG_FOUND) + endif(LIBPNG_FROM_OS) +endif(ENABLE_PNG) #Find JPEG -option(ENABLE_JPEG "Enable the use of JPEG") -option(LIBJPEG_FROM_OS "Use libjpeg from operating system.") if(ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG) if(LIBJPEG_FROM_OS) @@ -90,14 +101,30 @@ if(ENABLE_JPEG) if (JPEG_FOUND) include_directories( ${JPEG_INCLUDE_DIRS}) add_definitions(-DUSE_LIBJPEG_FROM_OS) - endif() - endif() -endif() + endif(JPEG_FOUND) + endif(LIBJPEG_FROM_OS) +endif(ENABLE_JPEG) + +if(ENABLE_AUDIO) + add_definitions(-DNANA_ENABLE_AUDIO) + if(UNIX) + find_package(asound) + if (ASOUND_FOUND) + include_directories( ${ASOUND_INCLUDE_DIRS}) + else(ASOUND_FOUND) + message(FATAL_ERROR "libasound is not found") + endif(ASOUND_FOUND) + endif(UNIX) +endif(ENABLE_AUDIO) + +#Unicode +if(CMAKE_VERBOSE_PREPROCESSOR) + add_definitions(-DVERBOSE_PREPROCESSOR) +endif(CMAKE_VERBOSE_PREPROCESSOR) - -set(NANA_SOURCE_DIR ${CMAKE_SOURCE_DIR}/source) -set(NANA_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) +set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) +set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${NANA_INCLUDE_DIR}) aux_source_directory(${NANA_SOURCE_DIR} NANA_SOURCE) @@ -116,13 +143,15 @@ aux_source_directory(${NANA_SOURCE_DIR}/paint/detail NANA_PAINT_DETAIL_SOURCE) aux_source_directory(${NANA_SOURCE_DIR}/system NANA_SYSTEM_SOURCE) aux_source_directory(${NANA_SOURCE_DIR}/threads NANA_THREADS_SOURCE) +#To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library +#and Use SOURCE_GROUP if all your sources are in the same directory + +if(NOT APPLE) add_library(${PROJECT_NAME} ${NANA_SOURCE} ${NANA_DETAIL_SOURCE} ${NANA_FILESYSTEM_SOURCE} -#if(NOT APPLE) ${NANA_AUDIO_SOURCE} ${NANA_AUDIO_DETAIL_SOURCE} -#endif ${NANA_GUI_SOURCE} ${NANA_GUI_DETAIL_SOURCE} ${NANA_GUI_WIDGETS_SOURCE} @@ -130,19 +159,99 @@ add_library(${PROJECT_NAME} ${NANA_SOURCE} ${NANA_PAINT_SOURCE} ${NANA_PAINT_DETAIL_SOURCE} ${NANA_SYSTEM_SOURCE} - ${NANA_THREADS_SOURCE}) + ${NANA_THREADS_SOURCE}) +endif (NOT APPLE) + -#if(APPLE) -target_link_libraries(${PROJECT_NAME} -L/opt/X11/lib/ -lX11 -lXft -lpng -liconv) -#endif() +if(APPLE) +add_library(${PROJECT_NAME} ${NANA_SOURCE} + ${NANA_DETAIL_SOURCE} + ${NANA_FILESYSTEM_SOURCE} + ${NANA_AUDIO_SOURCE} + ${NANA_AUDIO_DETAIL_SOURCE} + ${NANA_GUI_SOURCE} + ${NANA_GUI_DETAIL_SOURCE} + ${NANA_GUI_WIDGETS_SOURCE} + ${NANA_GUI_WIDGETS_SKELETONS_SOURCE} + ${NANA_PAINT_SOURCE} + ${NANA_PAINT_DETAIL_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 + target_link_libraries(${PROJECT_NAME} -L/opt/X11/lib/ -lX11 -lXft -lpng -liconv) + +endif(APPLE) install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) +# ?? install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include) set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) -add_executable(nana_test test.cpp) -set_property( TARGET nana_test PROPERTY CXX_STANDARD 14 ) -target_link_libraries(nana_test ${PROJECT_NAME}) +if (BUILD_NANA_DEMOS) + set (CMAKE_INSTALL_PREFIX ${DEMO_BIN}) + set(DEMO_BIN ${NANA_SOURCE_DIR}../nana-demo/bin) + set(CMAKE_INSTALL_PREFIX ) + add_executable(file_explorer ../nana-demo/file_explorer.cpp) + set_property( TARGET file_explorer PROPERTY CXX_STANDARD 14 ) + target_link_libraries(file_explorer ${PROJECT_NAME}) + install(TARGETS file_explorer RUNTIME DESTINATION &{DEMO_BIN}) + + add_executable(calculator ../nana-demo/calculator.cpp) + set_property( TARGET calculator PROPERTY CXX_STANDARD 14 ) + target_link_libraries(calculator ${PROJECT_NAME}) + install(TARGETS calculator RUNTIME DESTINATION &{DEMO_BIN}) + + add_executable(FreeMe ../nana-demo/FreeMe.cpp) + set_property( TARGET FreeMe PROPERTY CXX_STANDARD 14 ) + target_link_libraries(FreeMe ${PROJECT_NAME}) + install(TARGETS FreeMe RUNTIME DESTINATION &{DEMO_BIN}) + + add_executable(notepad ../nana-demo/notepad.cpp) + set_property( TARGET notepad PROPERTY CXX_STANDARD 14 ) + target_link_libraries(notepad ${PROJECT_NAME}) + install(TARGETS notepad RUNTIME DESTINATION &{DEMO_BIN}) + + add_executable(widget_show ../nana-demo/widget_show.cpp) + set_property( TARGET widget_show PROPERTY CXX_STANDARD 14 ) + target_link_libraries(widget_show ${PROJECT_NAME}) + install(TARGETS widget_show RUNTIME DESTINATION &{DEMO_BIN}) + + add_executable(widget_show2 ../nana-demo/widget_show2.cpp) + set_property( TARGET widget_show2 PROPERTY CXX_STANDARD 14 ) + target_link_libraries(widget_show2 ${PROJECT_NAME}) + install(TARGETS widget_show2 RUNTIME DESTINATION &{DEMO_BIN}) + + add_executable(a_group_impl ../nana-demo/Examples/a_group_impl.cpp) + set_property( TARGET a_group_impl PROPERTY CXX_STANDARD 14 ) + target_link_libraries(a_group_impl ${PROJECT_NAME}) + + add_executable(animate-bmp ../nana-demo/Examples/animate-bmp.cpp) + set_property( TARGET animate-bmp PROPERTY CXX_STANDARD 14 ) + target_link_libraries(animate-bmp ${PROJECT_NAME}) + + add_executable(audio_player ../nana-demo/Examples/audio_player.cpp) + set_property( TARGET audio_player PROPERTY CXX_STANDARD 14 ) + target_link_libraries(audio_player ${PROJECT_NAME}) + + + #add_executable(nana_test test.cpp) + #set_property( TARGET nana_test PROPERTY CXX_STANDARD 14 ) + #target_link_libraries(nana_test ${PROJECT_NAME}) + + #set(NANA_DEMOS_DIR ${CMAKE_SOURCE_DIR}/../nana-demo) + #set(NANA_EXAMPLES_DIR ${CMAKE_SOURCE_DIR}/../Examples/nana-demo/) + # https://cmake.org/cmake/help/v3.3/command/file.html?highlight=glob#file + #file( GLOB_RECURSE DEMO_SOURCES RELATIVE ../nana-demo *.cpp ) + + #foreach( demofile ${DEMO_SOURCES} ) + # string( REPLACE ".cpp" "" demoname ${demofile} ) + # add_executable( ${demoname} ${demofile} ) + # set_property( TARGET ${demoname} PROPERTY CXX_STANDARD 14 ) + # target_link_libraries(${demoname} ${PROJECT_NAME}) + #endforeach( demofile ${DEMO_SOURCES} ) +endif(BUILD_NANA_DEMOS) + diff --git a/README.md b/README.md index 7b427aef..240581f8 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# Nana C++ Library -[![Build Status](https://webapi.biicode.com/v1/badges/qiangwu/qiangwu/nana/master)](https://www.biicode.com/qiangwu/nana) +# Nana C++ Library [![BiiCode build status](https://webapi.biicode.com/v1/badges/qiangwu/qiangwu/nana/master)](https://www.biicode.com/qiangwu/nana) [![TravisCI build status](https://travis-ci.org/cnjinhao/nana.svg)](https://travis-ci.org/cnjinhao/nana) [![Licence](https://img.shields.io/badge/license-BSL-blue.svg?style=flat)](LICENSE_1_0.txt) + Nana is a C++ library designed to allow developers to easily create cross-platform GUI applications with modern C++11 style, currently it can work on Linux(X11) and Windows. The nana repository contains the entire source of library, you can browse the source code and submit your pull request for contributing. ## License -Nana is licensed under the [Boost Software License]. - -[Boost Software License]: http://www.boost.org/LICENSE_1_0.txt +Nana is licensed under the [Boost Software License](http://www.boost.org/LICENSE_1_0.txt) ## Members diff --git a/build/codeblocks/nana.cbp b/build/codeblocks/nana.cbp index 49f61ad7..18e276ca 100644 --- a/build/codeblocks/nana.cbp +++ b/build/codeblocks/nana.cbp @@ -51,8 +51,7 @@ - - + @@ -119,7 +118,6 @@ - diff --git a/build/codeblocks/nana.depend b/build/codeblocks/nana.depend index bc77979b..8d95a36f 100644 --- a/build/codeblocks/nana.depend +++ b/build/codeblocks/nana.depend @@ -548,7 +548,7 @@ -1439496157 source:d:\git.repo\nana\source\audio\detail\audio_stream.cpp +1452100459 source:d:\git.repo\nana\source\audio\detail\audio_stream.cpp @@ -556,7 +556,7 @@ -1353253406 source:d:\git.repo\nana\source\audio\player.cpp +1452100459 source:d:\git.repo\nana\source\audio\player.cpp @@ -570,12 +570,13 @@ -1439496157 source:d:\git.repo\nana\source\charset.cpp +1452100459 source:d:\git.repo\nana\source\charset.cpp + @@ -585,12 +586,16 @@ -1439496157 source:d:\git.repo\nana\source\deploy.cpp +1452100459 source:d:\git.repo\nana\source\deploy.cpp + + + + 1439496157 source:d:\git.repo\nana\source\detail\platform_spec_selector.cpp @@ -636,9 +641,9 @@ 1365203878 source:d:\git.repo\nana\source\filesystem\file_iterator.cpp -1365203878 source:d:\git.repo\nana\source\filesystem\fs_utility.cpp +1453128389 source:d:\git.repo\nana\source\filesystem\fs_utility.cpp - + @@ -653,7 +658,7 @@ -1444647306 source:d:\git.repo\nana\source\gui\animation.cpp +1449510853 source:d:\git.repo\nana\source\gui\animation.cpp @@ -676,8 +681,8 @@ -1444585389 source:d:\git.repo\nana\source\gui\detail\bedrock_pi.cpp - +1447167067 source:d:\git.repo\nana\source\gui\detail\bedrock_pi.cpp + @@ -721,7 +726,7 @@ -1444567878 source:d:\git.repo\nana\source\gui\detail\color_schemes.cpp +1447167067 source:d:\git.repo\nana\source\gui\detail\color_schemes.cpp @@ -737,11 +742,11 @@ 1408986718 source:d:\git.repo\nana\source\gui\detail\element_store.cpp -1444470665 source:d:\git.repo\nana\source\gui\detail\events_operation.cpp +1447167067 source:d:\git.repo\nana\source\gui\detail\events_operation.cpp -1444647213 source:d:\git.repo\nana\source\gui\detail\native_window_interface.cpp - +1453137865 source:d:\git.repo\nana\source\gui\detail\native_window_interface.cpp + @@ -750,18 +755,20 @@ "../../paint/detail/image_ico.hpp" + -1439496158 d:\git.repo\nana\source\paint\detail\image_ico.hpp +1453189013 d:\git.repo\nana\source\paint\detail\image_ico.hpp + -1439496157 source:d:\git.repo\nana\source\gui\detail\window_layout.cpp +1451801884 source:d:\git.repo\nana\source\gui\detail\window_layout.cpp -1444657627 source:d:\git.repo\nana\source\gui\detail\window_manager.cpp +1451801884 source:d:\git.repo\nana\source\gui\detail\window_manager.cpp @@ -774,10 +781,11 @@ -1444585885 source:d:\git.repo\nana\source\gui\dragger.cpp +1452100459 source:d:\git.repo\nana\source\gui\dragger.cpp + -1444647322 source:d:\git.repo\nana\source\gui\drawing.cpp +1447167067 source:d:\git.repo\nana\source\gui\drawing.cpp @@ -786,7 +794,7 @@ -1444585885 source:d:\git.repo\nana\source\gui\element.cpp +1452100459 source:d:\git.repo\nana\source\gui\element.cpp @@ -796,10 +804,10 @@ -1439496157 source:d:\git.repo\nana\source\gui\filebox.cpp +1453222083 source:d:\git.repo\nana\source\gui\filebox.cpp - + @@ -808,7 +816,7 @@ - + @@ -816,7 +824,7 @@ 1439496157 source:d:\git.repo\nana\source\gui\layout_utility.cpp -1444585885 source:d:\git.repo\nana\source\gui\msgbox.cpp +1452100459 source:d:\git.repo\nana\source\gui\msgbox.cpp @@ -835,7 +843,7 @@ -1444647352 source:d:\git.repo\nana\source\gui\notifier.cpp +1452100459 source:d:\git.repo\nana\source\gui\notifier.cpp @@ -844,11 +852,11 @@ - + -1444657299 source:d:\git.repo\nana\source\gui\programming_interface.cpp +1453128389 source:d:\git.repo\nana\source\gui\programming_interface.cpp @@ -866,13 +874,13 @@ -1444647437 source:d:\git.repo\nana\source\gui\state_cursor.cpp +1447167068 source:d:\git.repo\nana\source\gui\state_cursor.cpp -1439496158 source:d:\git.repo\nana\source\gui\timer.cpp +1449510853 source:d:\git.repo\nana\source\gui\timer.cpp @@ -880,20 +888,21 @@ + -1444585886 source:d:\git.repo\nana\source\gui\tooltip.cpp +1452100459 source:d:\git.repo\nana\source\gui\tooltip.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\button.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\button.cpp -1439829040 source:d:\git.repo\nana\source\gui\widgets\categorize.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\categorize.cpp @@ -901,13 +910,13 @@ -1439829040 source:d:\git.repo\nana\source\gui\widgets\checkbox.cpp +1453214888 source:d:\git.repo\nana\source\gui\widgets\checkbox.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\combox.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\combox.cpp @@ -917,13 +926,13 @@ -1439829040 source:d:\git.repo\nana\source\gui\widgets\date_chooser.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\date_chooser.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\float_listbox.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\float_listbox.cpp @@ -933,13 +942,13 @@ 1408985395 source:d:\git.repo\nana\source\gui\widgets\frame.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\group.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\group.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\label.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\label.cpp @@ -947,7 +956,7 @@ -1439496158 source:d:\git.repo\nana\source\gui\widgets\listbox.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\listbox.cpp @@ -960,7 +969,7 @@ -1439828820 source:d:\git.repo\nana\source\gui\widgets\menu.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\menu.cpp @@ -968,11 +977,11 @@ -1439496158 source:d:\git.repo\nana\source\gui\widgets\menubar.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\menubar.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\panel.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\panel.cpp 1439496158 source:d:\git.repo\nana\source\gui\widgets\picture.cpp @@ -984,11 +993,11 @@ 1439496158 source:d:\git.repo\nana\source\gui\widgets\progress.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\scroll.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\scroll.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\skeletons\text_editor.cpp +1452536705 source:d:\git.repo\nana\source\gui\widgets\skeletons\text_editor.cpp @@ -1000,17 +1009,17 @@ -1439496158 source:d:\git.repo\nana\source\gui\widgets\slider.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\slider.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\spinbox.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\spinbox.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\textbox.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\textbox.cpp @@ -1018,12 +1027,12 @@ -1439496158 source:d:\git.repo\nana\source\gui\widgets\toolbar.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\toolbar.cpp -1439496158 source:d:\git.repo\nana\source\gui\widgets\treebox.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\treebox.cpp @@ -1031,36 +1040,38 @@ -1439746410 source:d:\git.repo\nana\source\gui\widgets\widget.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\widget.cpp -1408984042 source:d:\git.repo\nana\source\gui\wvl.cpp +1447167068 source:d:\git.repo\nana\source\gui\wvl.cpp + -1425221155 source:d:\git.repo\nana\source\internationalization.cpp +1452100459 source:d:\git.repo\nana\source\internationalization.cpp - - + + + 1423350893 source:d:\git.repo\nana\source\paint\detail\image_process_provider.cpp -1439496158 source:d:\git.repo\nana\source\paint\detail\native_paint_interface.cpp - +1452100459 source:d:\git.repo\nana\source\paint\detail\native_paint_interface.cpp + -1439746289 source:d:\git.repo\nana\source\paint\graphics.cpp - +1452100459 source:d:\git.repo\nana\source\paint\graphics.cpp + @@ -1071,8 +1082,8 @@ -1439496158 source:d:\git.repo\nana\source\paint\image.cpp - +1452100460 source:d:\git.repo\nana\source\paint\image.cpp + @@ -1080,78 +1091,81 @@ + "detail/image_jpeg.hpp" "detail/image_png.hpp" "detail/image_bmp.hpp" "detail/image_ico.hpp" -1439687843 d:\git.repo\nana\source\paint\detail\image_png.hpp - - +1447167068 d:\git.repo\nana\source\paint\detail\image_png.hpp + "image_pixbuf.hpp" + - -1439496158 d:\git.repo\nana\source\paint\detail\image_bmp.hpp - +1452100459 d:\git.repo\nana\source\paint\detail\image_bmp.hpp + "image_pixbuf.hpp" 1376313789 source:d:\git.repo\nana\source\paint\image_process_selector.cpp -1439496158 source:d:\git.repo\nana\source\paint\pixel_buffer.cpp - +1447167068 source:d:\git.repo\nana\source\paint\pixel_buffer.cpp + + -1423350893 source:d:\git.repo\nana\source\paint\text_renderer.cpp - +1452100460 source:d:\git.repo\nana\source\paint\text_renderer.cpp + -1439496158 source:d:\git.repo\nana\source\system\dataexch.cpp +1452100460 source:d:\git.repo\nana\source\system\dataexch.cpp + -1387007333 source:d:\git.repo\nana\source\system\platform.cpp +1452100460 source:d:\git.repo\nana\source\system\platform.cpp + -1365203879 source:d:\git.repo\nana\source\system\shared_wrapper.cpp +1447169804 source:d:\git.repo\nana\source\system\shared_wrapper.cpp -1342280997 source:d:\git.repo\nana\source\system\timepiece.cpp +1447168921 source:d:\git.repo\nana\source\system\timepiece.cpp -1386165989 source:d:\git.repo\nana\source\threads\pool.cpp +1449510853 source:d:\git.repo\nana\source\threads\pool.cpp - + @@ -1164,7 +1178,7 @@ 1439496158 source:d:\git.repo\nana\source\unicode_bidi.cpp -1439830958 source:d:\git.repo\nana\source\gui\widgets\tabbar.cpp +1452100459 source:d:\git.repo\nana\source\gui\widgets\tabbar.cpp @@ -1173,11 +1187,12 @@ -1444658359 source:d:\git.repo\nana\source\gui\place.cpp +1452100459 source:d:\git.repo\nana\source\gui\place.cpp + @@ -1190,7 +1205,7 @@ "place_parts.hpp" -1444585885 d:\git.repo\nana\source\gui\place_parts.hpp +1452100459 d:\git.repo\nana\source\gui\place_parts.hpp @@ -1198,3 +1213,661 @@ +1418083945 d:\git.repo\nana\include\nana\any.hpp + + + +1345180256 d:\git.repo\nana\include\nana\audio\detail\audio_device.hpp + + + + + + +1453135618 d:\git.repo\nana\include\nana\deploy.hpp + + + + + + + + + +1453135601 d:\git.repo\nana\include\nana\config.hpp + + + +1451801884 d:\git.repo\nana\include\nana\verbose_preprocessor.hpp + +1452100458 d:\git.repo\nana\include\nana\charset.hpp + + +1449510853 d:\git.repo\nana\include\nana\audio\detail\buffer_preparation.hpp + + + + + + + + + + + + +1452100458 d:\git.repo\nana\include\nana\audio\detail\audio_stream.hpp + + + +1449510853 d:\git.repo\nana\include\nana\std_thread.hpp + + + + +1449510853 d:\git.repo\nana\include\nana\std_mutex.hpp + + + + + + + + + + + + + + +1449510853 d:\git.repo\nana\include\nana\std_condition_variable.hpp + + + + +1452100458 d:\git.repo\nana\include\nana\system\platform.hpp + + +1452100458 d:\git.repo\nana\include\nana\audio\player.hpp + + + +1452100458 d:\git.repo\nana\include\nana\traits.hpp + + +1452100458 d:\git.repo\nana\include\nana\basic_types.hpp + + + +1439496155 d:\git.repo\nana\include\nana\datetime.hpp + + +1447169930 d:\git.repo\nana\include\nana\detail\platform_spec_selector.hpp + + + + +1452100458 d:\git.repo\nana\include\nana\detail\win32\platform_spec.hpp + + + + + + + + +1447694839 d:\git.repo\nana\include\nana\gui\basis.hpp + "../basic_types.hpp" + "../traits.hpp" + +1453215024 d:\git.repo\nana\include\nana\paint\image.hpp + "graphics.hpp" + +1452100458 d:\git.repo\nana\include\nana\paint\graphics.hpp + "../basic_types.hpp" + "../gui/basis.hpp" + "pixel_buffer.hpp" + + +1447167067 d:\git.repo\nana\include\nana\paint\pixel_buffer.hpp + + + +1453221913 d:\git.repo\nana\include\nana\filesystem\filesystem.hpp + + + + + + + + + +1409500994 d:\git.repo\nana\include\nana\gui\detail\event_code.hpp + +1452100458 d:\git.repo\nana\include\nana\detail\linux_x11\platform_spec.hpp + + + + + + + + + + + + + + + "msg_packet.hpp" + + + + +1452100458 d:\git.repo\nana\include\nana\detail\linux_x11\msg_packet.hpp + + + + +1452100459 source:d:\git.repo\nana\source\detail\platform_spec_posix.cpp + + + + + + + + + + + + + + "x11/msg_dispatcher.hpp" + +1447167067 d:\git.repo\nana\include\nana\gui\detail\bedrock.hpp + "general_events.hpp" + "color_schemes.hpp" + "internal_scope_guard.hpp" + +1453221339 d:\git.repo\nana\include\nana\gui\detail\general_events.hpp + + "event_code.hpp" + "internal_scope_guard.hpp" + + + + + +1410789890 d:\git.repo\nana\include\nana\gui\detail\internal_scope_guard.hpp + +1447167067 d:\git.repo\nana\include\nana\gui\detail\color_schemes.hpp + "widget_colors.hpp" + +1423350891 d:\git.repo\nana\include\nana\gui\detail\widget_colors.hpp + + + +1452100458 d:\git.repo\nana\include\nana\gui\detail\basic_window.hpp + "drawer.hpp" + "events_holder.hpp" + "widget_colors.hpp" + "widget_notifier_interface.hpp" + + + + +1447167067 d:\git.repo\nana\include\nana\gui\detail\drawer.hpp + + "general_events.hpp" + + + +1409768997 d:\git.repo\nana\include\nana\gui\detail\events_holder.hpp + + +1452100458 d:\git.repo\nana\include\nana\gui\detail\widget_notifier_interface.hpp + + + +1447167067 d:\git.repo\nana\include\nana\gui\effects.hpp + + + +1449510853 d:\git.repo\nana\include\nana\gui\detail\window_manager.hpp + + "window_layout.hpp" + "event_code.hpp" + "inner_fwd.hpp" + + + + +1413471439 d:\git.repo\nana\include\nana\gui\detail\window_layout.hpp + + + +1439496155 d:\git.repo\nana\include\nana\gui\detail\inner_fwd.hpp + + +1449510999 d:\git.repo\nana\source\detail\x11\msg_dispatcher.hpp + + + + + + + + + + +1452100459 source:d:\git.repo\nana\source\detail\platform_spec_windows.cpp + + + + + +1453128389 d:\git.repo\nana\include\nana\filesystem\fs_utility.hpp + + + +1447167067 d:\git.repo\nana\include\nana\gui\animation.hpp + + + + +1413449218 d:\git.repo\nana\include\nana\gui\drawing.hpp + "widgets/widget.hpp" + "../traits.hpp" + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\widget.hpp + "../basis.hpp" + "../programming_interface.hpp" + + + + +1453128389 d:\git.repo\nana\include\nana\gui\programming_interface.hpp + + "effects.hpp" + "detail/general_events.hpp" + "detail/color_schemes.hpp" + + + +1453116049 d:\git.repo\nana\include\nana\internationalization.hpp + "basic_types.hpp" + + + + + +1398298742 d:\git.repo\nana\include\nana\system\timepiece.hpp + +1452100458 d:\git.repo\nana\include\nana\gui\detail\native_window_interface.hpp + "../basis.hpp" + + +1447167067 d:\git.repo\nana\include\nana\gui\detail\bedrock_pi_data.hpp + + "color_schemes.hpp" + "events_operation.hpp" + "window_manager.hpp" + + +1449510853 d:\git.repo\nana\include\nana\gui\detail\events_operation.hpp + + + + + + +1447167067 d:\git.repo\nana\include\nana\gui\wvl.hpp + "programming_interface.hpp" + "screen.hpp" + "widgets/form.hpp" + "drawing.hpp" + "msgbox.hpp" + "place.hpp" + +1439496156 d:\git.repo\nana\include\nana\gui\screen.hpp + "basis.hpp" + + + +1439496156 d:\git.repo\nana\include\nana\gui\widgets\form.hpp + "widget.hpp" + +1452100458 d:\git.repo\nana\include\nana\gui\msgbox.hpp + + +1452100458 d:\git.repo\nana\include\nana\gui\place.hpp + + + + + +1439496155 d:\git.repo\nana\include\nana\gui\detail\inner_fwd_implement.hpp + "inner_fwd.hpp" + "basic_window.hpp" + "../../paint/graphics.hpp" + + +1439496155 d:\git.repo\nana\include\nana\gui\layout_utility.hpp + "basis.hpp" + +1412237320 d:\git.repo\nana\include\nana\gui\detail\element_store.hpp + + + + + +1447167067 d:\git.repo\nana\include\nana\gui\element.hpp + + + + + +1447167067 d:\git.repo\nana\include\nana\pat\cloneable.hpp + + + + +1452100459 source:d:\git.repo\nana\source\gui\detail\bedrock_posix.cpp + + + + + + + + + + + +1452100459 source:d:\git.repo\nana\source\gui\detail\bedrock_windows.cpp + + + + + + + + + + + + + + +1411474310 d:\git.repo\nana\include\nana\gui.hpp + "gui/wvl.hpp" + +1408991732 d:\git.repo\nana\include\nana\gui\detail\dynamic_drawing_object.hpp + + + +1447167067 d:\git.repo\nana\include\nana\gui\detail\effects_renderer.hpp + + + + + + +1453221942 source:d:\git.repo\nana\source\filesystem\filesystem.cpp + + + + + + + + + + + + + + + +1449510853 d:\git.repo\nana\include\nana\gui\detail\handle_manager.hpp + + + + + + + +1452100458 d:\git.repo\nana\include\nana\gui\dragger.hpp + "basis.hpp" + "../basic_types.hpp" + "../traits.hpp" + +1453128800 d:\git.repo\nana\include\nana\gui\filebox.hpp + + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\label.hpp + "widget.hpp" + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\button.hpp + "widget.hpp" + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\listbox.hpp + "widget.hpp" + "detail/inline_widget.hpp" + + + + + + +1439496156 d:\git.repo\nana\include\nana\gui\widgets\detail\inline_widget.hpp + "../../basis.hpp" + +1447167067 d:\git.repo\nana\include\nana\pat\abstract_factory.hpp + "cloneable.hpp" + + +1398298742 d:\git.repo\nana\include\nana\concepts.hpp + + +1439496157 d:\git.repo\nana\include\nana\key_type.hpp + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\categorize.hpp + + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\textbox.hpp + + "skeletons/textbase_export_interface.hpp" + "skeletons/text_editor_part.hpp" + +1423350891 d:\git.repo\nana\include\nana\gui\widgets\skeletons\textbase_export_interface.hpp + +1447167068 d:\git.repo\nana\include\nana\gui\widgets\skeletons\text_editor_part.hpp + "../../detail/widget_colors.hpp" + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\treebox.hpp + "widget.hpp" + "detail/compset.hpp" + "detail/tree_cont.hpp" + + + + + +1408985780 d:\git.repo\nana\include\nana\gui\widgets\detail\compset.hpp + + +1452100603 d:\git.repo\nana\include\nana\gui\widgets\detail\tree_cont.hpp + + +1423350891 d:\git.repo\nana\include\nana\gui\timer.hpp + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\combox.hpp + "widget.hpp" + "float_listbox.hpp" + "skeletons/text_editor_part.hpp" + + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\float_listbox.hpp + "widget.hpp" + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\spinbox.hpp + "widget.hpp" + "skeletons/text_editor_part.hpp" + +1439496156 d:\git.repo\nana\include\nana\gui\widgets\panel.hpp + "widget.hpp" + + +1439496156 d:\git.repo\nana\include\nana\gui\widgets\picture.hpp + "widget.hpp" + +1452100458 d:\git.repo\nana\include\nana\gui\notifier.hpp + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\tabbar.hpp + "widget.hpp" + + + +1452100458 d:\git.repo\nana\include\nana\paint\text_renderer.hpp + + +1415011754 d:\git.repo\nana\include\nana\gui\state_cursor.hpp + + +1452100757 d:\git.repo\nana\include\nana\gui\tooltip.hpp + "widgets/widget.hpp" + +1453214821 d:\git.repo\nana\include\nana\gui\widgets\checkbox.hpp + "widget.hpp" + + + +1452100458 d:\git.repo\nana\include\nana\system\dataexch.hpp + + +1452100621 d:\git.repo\nana\include\nana\gui\widgets\skeletons\text_editor.hpp + "textbase.hpp" + "text_editor_part.hpp" + + + +1452536138 d:\git.repo\nana\include\nana\gui\widgets\skeletons\textbase.hpp + + + + "textbase_export_interface.hpp" + + + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\scroll.hpp + "widget.hpp" + + +1385896991 d:\git.repo\nana\include\nana\unicode_bidi.hpp + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\date_chooser.hpp + "widget.hpp" + + +1439496156 d:\git.repo\nana\include\nana\gui\widgets\frame.hpp + "widget.hpp" + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\group.hpp + + + +1452100631 d:\git.repo\nana\include\nana\gui\widgets\skeletons\text_token_stream.hpp + + + + + + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\menu.hpp + "widget.hpp" + + + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\menubar.hpp + "widget.hpp" + "menu.hpp" + +1439496156 d:\git.repo\nana\include\nana\gui\widgets\progress.hpp + "widget.hpp" + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\slider.hpp + "widget.hpp" + + +1452100458 d:\git.repo\nana\include\nana\gui\widgets\toolbar.hpp + "widget.hpp" + +1382463882 d:\git.repo\nana\include\nana\paint\detail\image_process_provider.hpp + + + + + +1423350892 d:\git.repo\nana\include\nana\paint\image_process_interface.hpp + + + +1447167067 d:\git.repo\nana\include\nana\paint\detail\image_processor.hpp + "../image_process_interface.hpp" + + + + +1452100458 d:\git.repo\nana\include\nana\paint\detail\native_paint_interface.hpp + + +1453189097 d:\git.repo\nana\include\nana\paint\detail\image_impl_interface.hpp + "../image.hpp" + + +1447167068 d:\git.repo\nana\source\paint\detail\image_jpeg.hpp + "image_pixbuf.hpp" + + + + + +1447167068 d:\git.repo\nana\source\paint\detail\image_pixbuf.hpp + + + +1398298742 d:\git.repo\nana\include\nana\paint\image_process_selector.hpp + "detail/image_process_provider.hpp" + +1453136647 d:\git.repo\nana\include\nana\system\shared_wrapper.hpp + + + + +1399048525 d:\git.repo\nana\include\nana\threads\pool.hpp + + + + diff --git a/build/vc2013/nana.vcxproj b/build/vc2013/nana.vcxproj index 01db0e79..c52001e4 100644 --- a/build/vc2013/nana.vcxproj +++ b/build/vc2013/nana.vcxproj @@ -189,8 +189,6 @@ - - @@ -256,7 +254,6 @@ - @@ -276,8 +273,6 @@ - - diff --git a/build/vc2013/nana.vcxproj.filters b/build/vc2013/nana.vcxproj.filters index d2c700e8..dd9f87a2 100644 --- a/build/vc2013/nana.vcxproj.filters +++ b/build/vc2013/nana.vcxproj.filters @@ -111,12 +111,6 @@ Source Files\nana\filesystem - - Source Files\nana\filesystem - - - Source Files\nana\filesystem - Source Files\nana\gui\detail @@ -291,9 +285,6 @@ Source Files\nana - - Source Files\nana - Source Files\nana @@ -619,12 +610,6 @@ Header Files\filesystem - - Header Files\filesystem - - - Header Files\filesystem - Header Files\paint diff --git a/build/vc2015/nana.vcxproj b/build/vc2015/nana.vcxproj index 89ceaaa3..e9c0aa02 100644 --- a/build/vc2015/nana.vcxproj +++ b/build/vc2015/nana.vcxproj @@ -183,8 +183,6 @@ - - @@ -249,7 +247,6 @@ - diff --git a/build/vc2015/nana.vcxproj.filters b/build/vc2015/nana.vcxproj.filters index 8130c2bc..0f547b4e 100644 --- a/build/vc2015/nana.vcxproj.filters +++ b/build/vc2015/nana.vcxproj.filters @@ -69,9 +69,6 @@ Source Files - - Source Files - Source Files @@ -87,15 +84,9 @@ Source Files\audio - - Source Files\filesystem - Source Files\filesystem - - Source Files\filesystem - Source Files\gui\detail diff --git a/include/nana/any.hpp b/include/nana/any.hpp index de3e7703..491169fc 100644 --- a/include/nana/any.hpp +++ b/include/nana/any.hpp @@ -1,145 +1,159 @@ +/** + * Any + * 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/any.hpp + * + * @brief An implementation of experimental library any of C++ standard(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html#any) + */ + #ifndef NANA_ANY_HPP #define NANA_ANY_HPP #include -#include //C++11 for std::move +#include + +#include "c++defines.hpp" namespace nana { + class bad_any_cast + : public std::bad_cast + { + }; + class any { - struct super_type + class content_interface { - virtual ~super_type(); - super_type& operator=(const super_type&); - virtual super_type& assign(const super_type&) = 0; - virtual bool same(const super_type&) const = 0; - virtual super_type* clone() const = 0; - }; //end struct super_type - - template - struct object_type - : public super_type - { - object_type(){} + public: + virtual ~content_interface() = default; - object_type(T const & obj) - : object(obj) + virtual const std::type_info& type() const noexcept = 0; + virtual content_interface* clone() const = 0; + }; + + template + class holder : public content_interface + { + holder& operator=(const holder&) = delete; + public: + holder(const Value& other) + : value(other) {} - object_type(T && obj) - : object(std::move(obj)) + holder(Value&& other) + : value(static_cast(other)) {} - - object_type(const object_type& rhs) - :object(rhs.object) - {} - - virtual super_type& assign(const super_type& rhs) + public: + const std::type_info& type() const noexcept override { - if(this != &rhs) - { - auto other = dynamic_cast(&rhs); - if(other) - object = other->object; - } - return *this; + return typeid(Value); } - - virtual bool same(const super_type& rhs) const + + content_interface* clone() const override { - return (dynamic_cast(&rhs) != nullptr); + return new holder(value); } - - virtual super_type* clone() const - { - return new object_type(object); - } - - T object; - }; //end struct object_type + public: + Value value; //representation accessable for friend of any + }; public: - template - any(const T & obj) - : super_(new object_type::type>(obj)) - {} + //constructors and destructor + any() noexcept; - template - any(T && obj) - : super_(new object_type::type>(std::move(obj))) - {} + any(const any& other); + any(any&& other) noexcept; + + template + any(Value && value, + typename std::enable_if::value>::type * = nullptr, + typename std::enable_if::value>::type* = nullptr) + : content_(new holder::type>(static_cast(value))) + { + } - any(); - any(const any&); - any(any&&); ~any(); - - bool same(const any &) const; - any& operator=(const any&); - any& operator=(any&&); - - template - any& operator=(T const &rhs) + + //assignments + any& operator=(const any& other); + any& operator=(any&& other) noexcept; + + template + any& operator=(Value&& other) { - T * obj = get(); - if(nullptr == obj) - { - delete super_; - super_ = new object_type(rhs); - } - else - *obj = rhs; + any(other).swap(*this); return *this; } - template - any & operator=(T && rhs) - { - typedef typename std::remove_cv::type>::type type; - type* obj = get(); - if(nullptr == obj) - { - delete super_; - super_ = new object_type(std::move(rhs)); - } - else - *obj = std::move(rhs); - return *this; - } - - template - T * get() const - { - if(super_) - { - typedef typename std::remove_const::type type; - object_type* obj = dynamic_cast*>(super_); - if(obj) return &(obj->object); - } - return nullptr; - } - - template - operator T&() const - { - typedef typename std::remove_const::type type; - type *obj = get(); + //modifiers + void clear() noexcept; + void swap(any& other) noexcept; - if(nullptr == obj) - throw std::bad_cast(); - - return *obj; - } - - template - operator T*() const - { - typedef typename std::remove_const::type type; - return get(); - } + //observers + bool empty() const noexcept; + const std::type_info& type() const noexcept; private: - super_type * super_; + template + friend Value* any_cast(any*) noexcept; + private: + content_interface * content_; }; + + // Non-member functions + inline void swap(any& x, any& y) noexcept + { + x.swap(y); + } + + template + Value any_cast(const any& operand) + { + using value_type = typename std::remove_reference::type; + return any_cast(const_cast(operand)); + } + + template + Value any_cast(any& operand) + { + using value_type = typename std::remove_reference::type; + + auto value_ptr = any_cast(&operand); + if (!value_ptr) + throw bad_any_cast(); + + using ref_type = typename std::conditional::value, Value, typename std::add_lvalue_reference::type>::type; + return static_cast(*value_ptr); + } + + template + Value any_cast(any && operand) + { + static_assert(std::is_rvalue_reference::value || std::is_const::type>::value, "nana::any_cast shall not be used for getting non-const reference to temporary objects"); + return any_cast(operand); + } + + template + const Value* any_cast(const any* operand) noexcept + { + return any_cast(const_cast(operand)); + } + + template + Value* any_cast(any* operand) noexcept + { + if (!operand) + return nullptr; + + auto holder = dynamic_cast*>(operand->content_); + return (holder ? &holder->value : nullptr); + } + }//end namespace nana #endif diff --git a/include/nana/audio/detail/audio_device.hpp b/include/nana/audio/detail/audio_device.hpp index 375d1595..ef3b9934 100644 --- a/include/nana/audio/detail/audio_device.hpp +++ b/include/nana/audio/detail/audio_device.hpp @@ -2,6 +2,9 @@ #define NANA_AUDIO_DETAIL_AUDIO_DEVICE_HPP #include + +#ifdef NANA_ENABLE_AUDIO + #include #include #if defined(NANA_WINDOWS) @@ -50,4 +53,5 @@ namespace nana{ namespace audio }//end namespace audio }//end namespace nana -#endif +#endif //NANA_ENABLE_AUDIO +#endif \ No newline at end of file diff --git a/include/nana/audio/detail/audio_stream.hpp b/include/nana/audio/detail/audio_stream.hpp index 5fe9d39c..72734ec9 100644 --- a/include/nana/audio/detail/audio_stream.hpp +++ b/include/nana/audio/detail/audio_stream.hpp @@ -1,8 +1,12 @@ #ifndef NANA_AUDIO_DETAIL_AUDIO_STREAM_HPP #define NANA_AUDIO_DETAIL_AUDIO_STREAM_HPP -#include + #include +#ifdef NANA_ENABLE_AUDIO + +#include + namespace nana{ namespace audio{ namespace detail { @@ -59,7 +63,7 @@ namespace nana{ namespace audio{ unsigned cksize; }; public: - bool open(const nana::string& file); + bool open(const std::string& file); void close(); bool empty() const; const wave_spec::format_chunck & format() const; @@ -78,4 +82,5 @@ namespace nana{ namespace audio{ } }//end namespace audio }//end namespace nana -#endif +#endif //NANA_ENABLE_AUDIO +#endif \ No newline at end of file diff --git a/include/nana/audio/detail/buffer_preparation.hpp b/include/nana/audio/detail/buffer_preparation.hpp index c3e03d71..501b8736 100644 --- a/include/nana/audio/detail/buffer_preparation.hpp +++ b/include/nana/audio/detail/buffer_preparation.hpp @@ -1,6 +1,9 @@ #ifndef NANA_AUDIO_DETAIL_BUFFER_PREPARATION_HPP #define NANA_AUDIO_DETAIL_BUFFER_PREPARATION_HPP #include + +#ifdef NANA_ENABLE_AUDIO + #include #if defined(STD_THREAD_NOT_SUPPORTED) @@ -62,4 +65,5 @@ namespace nana{ namespace audio }//end namespace detail }//end namespace audio }//end namespace nana -#endif +#endif //NANA_ENABLE_AUDIO +#endif \ No newline at end of file diff --git a/include/nana/audio/player.hpp b/include/nana/audio/player.hpp index 24378214..c4fc3d87 100644 --- a/include/nana/audio/player.hpp +++ b/include/nana/audio/player.hpp @@ -1,8 +1,12 @@ #ifndef NANA_AUDIO_PLAYER_HPP #define NANA_AUDIO_PLAYER_HPP -#include + #include +#ifdef NANA_ENABLE_AUDIO + +#include + namespace nana{ namespace audio { /// class player /// \brief play an audio file in PCM Windows WAV format @@ -14,10 +18,10 @@ namespace nana{ namespace audio struct implementation; public: player(); - player(const nana::string& file); + player(const std::string& file); ~player(); - bool open(const nana::string& file); + bool open(const std::string& file); void play(); void close(); private: @@ -25,4 +29,6 @@ namespace nana{ namespace audio }; }//end namespace audio }//end namespace nana + +#endif //NANA_ENABLE_AUDIO #endif \ No newline at end of file diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index da37272d..e990a681 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -67,7 +67,8 @@ namespace nana } }; - typedef std::basic_string > cistring; + using cistring = std::basic_string>; + using ciwstring = std::basic_string>; namespace detail diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp new file mode 100644 index 00000000..a2cf5e0e --- /dev/null +++ b/include/nana/c++defines.hpp @@ -0,0 +1,171 @@ +/** + * Predefined Symbols for C++ + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 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/config.hpp + * + * @brief Provide switches to adapt to the target OS, use of external libraries or workarounds compiler errors or lack of std C++ support. + * + * To control target OS/compiler: + * - NANA_WINDOWS + * - NANA_MINGW + * - NANA_POSIX + * - NANA_LINUX + * - NANA_MACOS + * - NANA_X11 + * + * External libraries: + * - NANA_LIBPNG, USE_LIBPNG_FROM_OS + * - NANA_LIBJPEG, USE_LIBJPEG_FROM_OS + * + * (see: Feature-testing recommendations for C++ + * in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0096r0.html + * for example: __cpp_lib_experimental_filesystem = 201406 in is a known issue on libstdc++, it works on libc++) + * - STD_THREAD_NOT_SUPPORTED (GCC < 4.8.1) + * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) + * - STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED (MinGW with GCC < 4.8.1) + * - STD_TO_STRING_NOT_SUPPORTED (MinGW with GCC < 4.8) + */ + +#ifndef NANA_CXX_DEFINES_INCLUDED +#define NANA_CXX_DEFINES_INCLUDED + +//C++ language +#if defined(_MSC_VER) +# if (_MSC_VER < 1900) +# //Nana defines some macros for lack of support of keywords +# define _ALLOW_KEYWORD_MACROS +# +# define noexcept //no support of noexcept until Visual C++ 2015 +# define constexpr //no support of constexpr until Visual C++ 2015 +# endif +#elif defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ < 6) +# define noexcept //no support of noexcept until GCC 4.6 +# endif +#endif + +// Select platform ...... +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) //Microsoft Windows + #define NANA_WINDOWS + + // MINGW ... + #if defined(__MINGW32__) || defined(__MINGW64__) || defined(MINGW) + #define NANA_MINGW + #endif // MINGW + +#elif defined(APPLE) //Mac OS X + //Symbols for MACOS + + #define NANA_MACOS + #define NANA_X11 + +#elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) //Linux + #define NANA_LINUX + #define NANA_X11 +#else +# static_assert(false, "Only Windows and Unix are supported now (Mac OS is experimental)"); +#endif + +//Define a symbol for POSIX operating system. +#if defined(NANA_LINUX) || defined(NANA_MACOS) + #define NANA_POSIX +#endif + + + +// Select compiler ... +#if defined(_MSC_VER) //Microsoft Visual C++ + #define _SCL_SECURE_NO_WARNNGS + #define _CRT_SECURE_NO_DEPRECATE + #pragma warning(disable : 4996) + + #if (_MSC_VER == 1900) + // google: break any code that tries to use codecvt or codecvt. + // google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support. + // google: Those definitions are for codecvt::id, codecvt::id and codecvt::id respectively. + // However, the codecvt::id and codecvt::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all. + // google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources. + #define STD_CODECVT_NOT_SUPPORTED + #endif // _MSC_VER == 1900 + +#elif defined(__clang__) //Clang + + #include //Introduces some implement-specific flags of ISO C++ Library + #if defined(__GLIBCPP__) || defined(__GLIBCXX__) + // is a known issue on libstdc++, it works on libc++ + #define STD_CODECVT_NOT_SUPPORTED + + + #ifndef STD_MAKE_UNIQUE_NOT_SUPPORTED + #define STD_MAKE_UNIQUE_NOT_SUPPORTED + #endif + + #endif + +#elif defined(__GNUC__) //GCC + + #include //Introduces some implement-specific flags of ISO C++ Library + #if defined(__GLIBCPP__) || defined(__GLIBCXX__) + // is a known issue on libstdc++, it works on libc++ + #define STD_CODECVT_NOT_SUPPORTED + + //It's a known issue of libstdc++ on MinGW + //introduce to_string/to_wstring workarounds for disabled capacity of stdlib + #ifdef _GLIBCXX_HAVE_BROKEN_VSWPRINTF + #if (__GNUC__ < 5) + # define STD_TO_STRING_NOT_SUPPORTED + #endif + + #define STD_TO_WSTRING_NOT_SUPPORTED + #endif + #endif + + #if (__GNUC__ == 4) + #if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) + #define STD_THREAD_NOT_SUPPORTED + #endif + + #if (__GNUC_MINOR__ < 9) + #define STD_MAKE_UNIQUE_NOT_SUPPORTED + #endif + + #if defined(NANA_MINGW) + //It's a knonwn issue under MinGW + #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED + #endif + + #if (__GNUC_MINOR__ < 8) + //introduce to_string/to_wstring workaround for lack of stdlib definitions + #ifndef STD_TO_STRING_NOT_SUPPORTED + # define STD_TO_STRING_NOT_SUPPORTED + #endif + + #ifndef STD_TO_WSTRING_NOT_SUPPORTED + # define STD_TO_WSTRING_NOT_SUPPORTED + #endif + #endif + #endif +#endif + + +#if defined(NANA_WINDOWS) + #ifndef _UNICODE + #define _UNICODE + #endif + + #ifndef UNICODE + #define UNICODE + #endif +#endif + +#endif // NANA_CXX_DEFINES_INCLUDED diff --git a/include/nana/charset.hpp b/include/nana/charset.hpp index 6c36159b..41fa4d72 100644 --- a/include/nana/charset.hpp +++ b/include/nana/charset.hpp @@ -1,7 +1,7 @@ /** * The charset 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 @@ -18,6 +18,24 @@ namespace nana { + namespace utf + { + /// Attempt to get a pointer to a character of UTF-8 string by a specifed character index. + /// @param text_utf8 A string encoded as UTF-8. + /// @param pos The unicode character index. + /// @returns A pointer to the unicode character. It returns a null if pos is out of range. + const char* char_ptr(const char* text_utf8, unsigned pos); + const char* char_ptr(const ::std::string& text_utf8, unsigned pos); + + /// Get the unicode character by a specified character index. + /// @param text_utf8 A string encoded as UTF-8. + /// @param pos The unicode character index. + /// @param len A unsigned pointer to receive the number of bytes it takes in UTF-8 encoded. If len is a nullptr, it is ignored. + /// @returns A unicode character. '\0' if pos is out of range. + wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len); + wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len); + } + enum class unicode { utf8, utf16, utf32 diff --git a/include/nana/concepts.hpp b/include/nana/concepts.hpp index fb9fddf9..dea4637d 100644 --- a/include/nana/concepts.hpp +++ b/include/nana/concepts.hpp @@ -1,6 +1,6 @@ /* * A Concepts Definition of Nana C++ Library - * Copyright(C) 2003-2013 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 @@ -22,7 +22,7 @@ namespace nana class any_objective { public: - virtual ~any_objective(){} + virtual ~any_objective() = default; template void anyobj(const Target& t) @@ -37,7 +37,7 @@ namespace nana void anyobj(Target&& t) { nana::any * p = _m_anyobj(true); - if(nullptr == 0) + if(nullptr == p) throw std::runtime_error("Nana.any_objective: Object does not exist"); *p = std::move(t); @@ -46,8 +46,7 @@ namespace nana template Target * anyobj() const ///< Retrieves the attached object. Returns a nullptr if empty or if the type not match. { - nana::any * p = _m_anyobj(false); - return (p ? p->get() : nullptr); + return any_cast(_m_anyobj(false)); } private: virtual nana::any* _m_anyobj(bool allocate_if_empty) const = 0; @@ -60,7 +59,7 @@ namespace nana public: typedef IndexType anyobj_index_t; ///< The type of index. It is available if Dimension is greater than 0. - virtual ~any_objective(){} + virtual ~any_objective() = default; template void anyobj(anyobj_index_t i, const Target& t) @@ -83,8 +82,7 @@ namespace nana template Target * anyobj(anyobj_index_t i) const ///< Retrieves the attached object. Returns a nullptr if empty or if the type not match. { - nana::any * p = _m_anyobj(i, false); - return (p ? p->get() : nullptr); + return any_cast(_m_anyobj(i, false)); } private: virtual nana::any* _m_anyobj(anyobj_index_t i, bool allocate_if_empty) const = 0; @@ -121,8 +119,7 @@ namespace nana template Target * anyobj(anyobj_index_t i0, anyobj_index_t i1) const ///< Retrieves the attached object. Returns a nullptr if empty or if the type not match. { - nana::any * p = _m_anyobj(i0, i1, false); - return (p ? p->get() : nullptr); + return any_cast(_m_anyobj(i0, i1, false)); } private: virtual nana::any* _m_anyobj(anyobj_index_t i0, anyobj_index_t i1, bool allocate_if_empty) const = 0; diff --git a/include/nana/config.hpp b/include/nana/config.hpp index e97c70f6..194f0b9a 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -1,115 +1,48 @@ /** * Nana Configuration * 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/config.hpp + * @file nana/config.hpp + * + * @brief Provide switches to enable 3rd-party libraries for a certain feature. + * + * External libraries: + * - NANA_LIBPNG, USE_LIBPNG_FROM_OS + * - NANA_LIBJPEG, USE_LIBJPEG_FROM_OS + * + * messages: + * - VERBOSE_PREPROCESSOR, STOP_VERBOSE_PREPROCESSOR */ #ifndef NANA_CONFIG_HPP #define NANA_CONFIG_HPP -// Select platform ...... - - // Windows: - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) - - #define NANA_WINDOWS - - // MINGW ... - #if defined(__MINGW32__) || defined(__MINGW64__) || defined(MINGW) - #define NANA_MINGW - #endif // MINGW - - // end Windows - - - // MacOS: who define APPLE ?? - //#define APPLE - #elif defined(APPLE) - #define NANA_MACOS - #define NANA_X11 - // how to add this: include_directories(/opt/X11/include/) - // end MacOS - - // Linux: (not sure about __GNU__ ??) - #elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) - #define NANA_LINUX - #define NANA_X11 - // end Linux - #else - # static_assert(false, "Only Windows and Unix are supported now (Mac OS is experimental)"); - #endif // Select platform - - #if defined(NANA_LINUX) || defined(NANA_MACOS) - #define NANA_POSIX - #undef NANA_WINDOWS - #endif -// End Select platform ...... - -// compilers ... - -// MSVC++ versions -#if defined(_MSC_VER) - #define _SCL_SECURE_NO_WARNNGS - #define _CRT_SECURE_NO_DEPRECATE - #pragma warning(disable : 4996) - - #if (_MSC_VER == 1900) - // google: break any code that tries to use codecvt or codecvt. - // google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support. - // google: Those definitions are for codecvt::id, codecvt::id and codecvt::id respectively. - // However, the codecvt::id and codecvt::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all. - // google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources. - #define STD_CODECVT_NOT_SUPPORTED - #endif // _MSC_VER == 1900 -#endif // _MSVC - -#if defined(__clang__) - #if defined(__GLIBCPP__) || defined(__GLIBCXX__) - // is a known issue on libstdc++, it works on libc++ - #define STD_CODECVT_NOT_SUPPORTED - #endif - -#elif defined(__GNUC__) //GCC - #if defined(__GLIBCPP__) || defined(__GLIBCXX__) - // is a known issue on libstdc++, it works on libc++ - #define STD_CODECVT_NOT_SUPPORTED - #endif - - #if (__GNUC__ == 4) - #if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) - #define STD_THREAD_NOT_SUPPORTED - - //boost.thread is preferred - //but if USE_github_com_meganz_mingw_std_threads is enabled, - //boost.thread will be replaced with meganz's mingw-std-threads. - // https://github.com/meganz/mingw-std-threads - //#define USE_github_com_meganz_mingw_std_threads - #endif - - #if defined(NANA_MINGW) - //It's a known issue under MinGW - #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED - #endif - - #if ((__GNUC_MINOR__ < 8) || defined(NANA_MINGW)) - #define STD_TO_STRING_NOT_SUPPORTED - #endif - #endif -#endif - - - -// End compilers ... +#include "c++defines.hpp" +//The basic configurations are ignored when NANA_IGNORE_CONF is defined. +//The NANA_IGNORE_CONF may be specified by CMake generated makefile. +#ifndef NANA_IGNORE_CONF // Here defines some flags that tell Nana what features will be supported. + +//Support of std::thread +//Boost.Thread is preferred. +//NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ is only available on MinGW when STD_THREAD_NOT_SUPPORTED is defined. +//if NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ is enabled, Boost.Thread will be replaced with meganz's mingw-std-threads. +//https://github.com/meganz/mingw-std-threads +//#define NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ + +/////////////////// +//Support of PCM playback +// +//#define NANA_ENABLE_AUDIO + /////////////////// //Support for PNG // Define the NANA_ENABLE_PNG to enable the support of PNG. @@ -134,22 +67,13 @@ #endif #endif - - -// always define NANA_UNICODE ?? it will be deprecated ?. -#ifndef NANA_UNICODE - #define NANA_UNICODE +#if !defined(VERBOSE_PREPROCESSOR) +//#define VERBOSE_PREPROCESSOR #endif -#if defined(NANA_UNICODE) && defined(NANA_WINDOWS) - #ifndef _UNICODE - #define _UNICODE - #endif - - #ifndef UNICODE - #define UNICODE - #endif +#if !defined(STOP_VERBOSE_PREPROCESSOR) +#define STOP_VERBOSE_PREPROCESSOR #endif - -#endif //NANA_CONFIG_HPP +#endif // NANA_IGNORE_CONFIG +#endif // NANA_CONFIG_HPP diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 30d87935..35659972 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -1,10 +1,10 @@ /* * The Deploy 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 + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * @file: nana/deploy.hpp @@ -15,11 +15,13 @@ #ifndef NANA_DEPLOY_HPP #define NANA_DEPLOY_HPP -#include - #include -#include +#if defined(VERBOSE_PREPROCESSOR) + #include +#endif +#include +#include //Implement workarounds for GCC/MinGW which version is below 4.8.2 #if defined(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED) @@ -72,7 +74,12 @@ namespace std std::string to_string(long long); std::string to_string(unsigned long long); std::string to_string(float); - +} +#endif + +#ifdef STD_TO_WSTRING_NOT_SUPPORTED +namespace std +{ std::wstring to_wstring(long double); std::wstring to_wstring(double); std::wstring to_wstring(unsigned); @@ -85,56 +92,58 @@ namespace std } #endif - -#ifndef NANA_UNICODE - namespace nana - { - typedef char char_t; - typedef std::string string; ///< An alias of std::wstring or std::string, depending on the macro NANA_UNICODE - } - #define STR(string) string -#else - namespace nana - { - typedef wchar_t char_t; - typedef std::wstring string; ///< An alias of std::wstring or std::string, depending on the macro NANA_UNICODE - } - #define STR(string) L##string -#endif - namespace nana { - std::size_t strlen(const char_t* str); - char_t* strcpy(char_t* dest, const char_t* source); -#ifdef _MSC_VER - template - inline char* strcpy(char (&dest)[N], const char* source) - { - ::strncpy_s(dest, source, _TRUNCATE); - return dest; - } - template - inline wchar_t* strcpy(wchar_t (&dest)[N], const wchar_t* source) - { - ::wcsncpy_s(dest, source, _TRUNCATE); - return dest; - } -#endif // #ifdef _MSC_VER -} + /// Checks whether a specified text is utf8 encoding + bool is_utf8(const char* str, unsigned len); + void throw_not_utf8(const std::string& text); + void throw_not_utf8(const char*, unsigned len); + void throw_not_utf8(const char*); + + const std::string& to_utf8(const std::string&); + std::string to_utf8(const std::wstring&); + + std::wstring to_wstring(const std::string& utf8_str); + const std::wstring& to_wstring(const std::wstring& wstr); + std::wstring&& to_wstring(std::wstring&& wstr); #if defined(NANA_WINDOWS) - #define NANA_SHARED_EXPORT extern "C" _declspec(dllexport) -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - #define NANA_SHARED_EXPORT extern "C" + std::string to_osmbstr(const std::string& text_utf8); +#else + std::string to_osmbstr(std::string text_utf8); #endif + + namespace detail + { +#if defined(NANA_WINDOWS) + using native_string_type = std::wstring; +#else //POSIX + using native_string_type = std::string; +#endif + } + +#if defined(NANA_WINDOWS) + const detail::native_string_type to_nstring(const std::string&); + const detail::native_string_type& to_nstring(const std::wstring&); + detail::native_string_type to_nstring(std::string&&); + detail::native_string_type&& to_nstring(std::wstring&&); +#else //POSIX + const detail::native_string_type& to_nstring(const std::string&); + const detail::native_string_type to_nstring(const std::wstring&); + detail::native_string_type&& to_nstring(std::string&&); + detail::native_string_type to_nstring(std::wstring&&); +#endif + detail::native_string_type to_nstring(int); + detail::native_string_type to_nstring(double); + detail::native_string_type to_nstring(std::size_t); +} + + namespace nana { - bool is_incomplete(const nana::string& str, unsigned pos); - inline unsigned make_rgb(unsigned char red, unsigned char green, unsigned char blue) { - return ((unsigned(red) << 16)|((unsigned(green)<<8))|blue); } } @@ -142,4 +151,44 @@ namespace nana #define NANA_RGB(a) (((DWORD)(a) & 0xFF)<<16) | ((DWORD)(a) & 0xFF00) | (((DWORD)(a) & 0xFF0000) >> 16 ) +#ifdef STD_MAKE_UNIQUE_NOT_SUPPORTED +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm + +#include +#include +#include +#include + +namespace std { + template struct _Unique_if { + typedef unique_ptr _Single_object; + }; + + template struct _Unique_if { + typedef unique_ptr _Unknown_bound; + }; + + template struct _Unique_if { + typedef void _Known_bound; + }; + + template + typename _Unique_if::_Single_object + make_unique(Args&&... args) { + return unique_ptr(new T(std::forward(args)...)); + } + + template + typename _Unique_if::_Unknown_bound + make_unique(size_t n) { + typedef typename remove_extent::type U; + return unique_ptr(new U[n]()); + } + + template + typename _Unique_if::_Known_bound + make_unique(Args&&...) = delete; +} +#endif //STD_make_unique_NOT_SUPPORTED + #endif //NANA_MACROS_HPP diff --git a/include/nana/detail/linux_X11/msg_packet.hpp b/include/nana/detail/linux_X11/msg_packet.hpp index b1fc3dec..ea24091f 100644 --- a/include/nana/detail/linux_X11/msg_packet.hpp +++ b/include/nana/detail/linux_X11/msg_packet.hpp @@ -22,7 +22,7 @@ namespace detail Window window; int x; int y; - std::vector * files; + std::vector * files; }mouse_drop; }u; }; diff --git a/include/nana/detail/linux_X11/platform_spec.hpp b/include/nana/detail/linux_X11/platform_spec.hpp index 0a013ed6..c8866d9d 100644 --- a/include/nana/detail/linux_X11/platform_spec.hpp +++ b/include/nana/detail/linux_X11/platform_spec.hpp @@ -1,7 +1,7 @@ /* * Platform Specification 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 @@ -34,7 +34,9 @@ #include #include #include "msg_packet.hpp" -#if defined(NANA_UNICODE) + +#define NANA_USE_XFT +#if defined(NANA_USE_XFT) #include #include #include @@ -45,7 +47,7 @@ namespace nana namespace detail { class msg_dispatcher; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) class conf { public: @@ -70,13 +72,13 @@ namespace detail struct font_tag { - nana::string name; + std::string name; unsigned height; unsigned weight; bool italic; bool underline; bool strikeout; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) XftFont * handle; #else XFontSet handle; @@ -99,10 +101,10 @@ namespace detail unsigned tab_pixels; unsigned whitespace_pixels; }string; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) XftDraw * xftdraw{nullptr}; XftColor xft_fgcolor; - const std::string charset(const nana::string& str, const std::string& strcode); + const std::string charset(const std::wstring& str, const std::string& strcode); #endif drawable_impl_type(); ~drawable_impl_type(); @@ -120,7 +122,7 @@ namespace detail unsigned color_{ 0xFFFFFFFF }; unsigned text_color_{ 0xFFFFFFFF }; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) struct conv_tag { iconv_t handle; @@ -203,7 +205,7 @@ namespace detail void default_native_font(const font_ptr_t&); unsigned font_size_to_height(unsigned) const; unsigned font_height_to_size(unsigned) const; - font_ptr_t make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strick_out); + font_ptr_t make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strick_out); Display* open_display(); void close_display(); diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index b129406b..dc6329fe 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -80,7 +80,7 @@ namespace detail struct font_tag { - nana::string name; + native_string_type name; unsigned height; unsigned weight; bool italic; @@ -186,7 +186,7 @@ namespace detail void default_native_font(const font_ptr_t&); unsigned font_size_to_height(unsigned) const; unsigned font_height_to_size(unsigned) const; - font_ptr_t make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out); + font_ptr_t make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out); static platform_spec& instance(); diff --git a/include/nana/filesystem/file_iterator.hpp b/include/nana/filesystem/file_iterator.hpp deleted file mode 100644 index 94f37001..00000000 --- a/include/nana/filesystem/file_iterator.hpp +++ /dev/null @@ -1,255 +0,0 @@ -/* - * A File Iterator Implementation - * Copyright(C) 2003 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: stdex/filesystem/file_iterator.hpp - * @description: - * file_iterator is a toolkit for applying each file and directory in a - * specified path. - */ - -#ifndef NANA_FILESYSTEM_FILE_ITERATOR_HPP -#define NANA_FILESYSTEM_FILE_ITERATOR_HPP -#include -#include - -#include - -#ifdef NANA_WINDOWS - #include - typedef HANDLE find_handle_t; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - #include - #include - #include - typedef DIR* find_handle_t; -#endif - -namespace nana -{ -namespace filesystem -{ - struct fileinfo - { - fileinfo(); -#ifdef NANA_WINDOWS - fileinfo(const WIN32_FIND_DATA& wfd); -#elif defined(NANA_POSIX) - fileinfo(const nana::string& filename, const struct stat &); -#endif - nana::string name; - - unsigned long size; - bool directory; - }; - - template - class basic_file_iterator - :public std::iterator - { - public: - typedef FileInfo value_type; - - basic_file_iterator():end_(true), handle_(nullptr){} - - basic_file_iterator(const nana::string& file_path) - :end_(false), handle_(nullptr) - { - _m_prepare(file_path); - } - - const value_type& - operator*() const { return value_; } - - const value_type* - operator->() const { return &(operator*()); } - - basic_file_iterator& operator++() - { _m_read(); return *this; } - - basic_file_iterator operator++(int) - { - basic_file_iterator tmp = *this; - _m_read(); - return tmp; - } - - bool equal(const basic_file_iterator& x) const - { - if(end_ && (end_ == x.end_)) return true; - return (value_.name == x.value_.name); - } - private: - template - static bool _m_ignore(const Char * p) - { - while(*p == '.') - ++p; - return (*p == 0); - } - - void _m_prepare(const nana::string& file_path) - { - #if defined(NANA_WINDOWS) - path_ = file_path; - auto pat = file_path; - DWORD attr = ::GetFileAttributes(pat.data()); - if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY)) - pat += STR("\\*"); - - ::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_); - - if(handle == INVALID_HANDLE_VALUE) - { - end_ = true; - return; - } - - while(_m_ignore(wfd_.cFileName)) - { - if(::FindNextFile(handle, &wfd_) == 0) - { - end_ = true; - ::FindClose(handle); - return; - } - } - value_ = value_type(wfd_); - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - path_ = nana::charset(file_path); - if(path_.size() && (path_[path_.size() - 1] != '/')) - path_ += '/'; - find_handle_t handle = opendir(path_.c_str()); - end_ = true; - if(handle) - { - struct dirent * dnt = readdir(handle); - if(dnt) - { - while(_m_ignore(dnt->d_name)) - { - dnt = readdir(handle); - if(dnt == 0) - { - closedir(handle); - return; - } - } - - struct stat fst; - if(stat((path_ + dnt->d_name).c_str(), &fst) == 0) - { - value_ = value_type(nana::charset(dnt->d_name), fst); - } - else - { - value_.name = nana::charset(dnt->d_name); - value_.size = 0; - value_.directory = false; - } - end_ = false; - } - } - #endif - if(false == end_) - { - find_ptr_ = std::shared_ptr(new find_handle_t(handle), inner_handle_deleter()); - handle_ = handle; - } - } - - void _m_read() - { - if(handle_) - { - #if defined(NANA_WINDOWS) - if(::FindNextFile(handle_, &wfd_) != 0) - { - while(_m_ignore(wfd_.cFileName)) - { - if(::FindNextFile(handle_, &wfd_) == 0) - { - end_ = true; - return; - } - } - value_ = value_type(wfd_); - } - else - end_ = true; - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct dirent * dnt = readdir(handle_); - if(dnt) - { - while(_m_ignore(dnt->d_name)) - { - dnt = readdir(handle_); - if(dnt == 0) - { - end_ = true; - return; - } - } - struct stat fst; - if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0) - value_ = value_type(nana::charset(dnt->d_name), fst); - else - value_.name = nana::charset(dnt->d_name); - } - else - end_ = true; - #endif - } - } - private: - struct inner_handle_deleter - { - void operator()(find_handle_t * handle) - { - if(handle && *handle) - { - #if defined(NANA_WINDOWS) - ::FindClose(*handle); - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - ::closedir(*handle); - #endif - } - delete handle; - } - }; - private: - bool end_; - -#if defined(NANA_WINDOWS) - WIN32_FIND_DATA wfd_; - nana::string path_; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - std::string path_; -#endif - std::shared_ptr find_ptr_; - - find_handle_t handle_; - value_type value_; - }; - - template - inline bool operator==(const basic_file_iterator & x, const basic_file_iterator & y) - { - return x.equal(y); - } - - template - inline bool operator!=(const basic_file_iterator & x, const basic_file_iterator & y) - { - return !x.equal(y); - } - - typedef basic_file_iterator file_iterator; -}//end namespace filesystem -}//end namespace nana - -#endif diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index dda69c98..dc86d1e0 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -1,16 +1,13 @@ /* * A ISO C++ filesystem 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/filesystem/filesystem.hpp - * @description: - * file_iterator is a toolkit for applying each file and directory in a - * specified path. * 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 @@ -32,99 +29,74 @@ #ifndef NANA_FILESYSTEM_HPP #define NANA_FILESYSTEM_HPP +#include +#include #include #include #include #include +#include #include -#ifdef NANA_WINDOWS - #include - typedef HANDLE find_handle_t; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - #include - #include - #include - typedef DIR* find_handle_t; -#endif - // namespace std { namespace experimental { namespace filesystem { inline namespace v1 { namespace nana { namespace experimental { namespace filesystem { - 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 - regular = 1, - directory = 2 , - symlink =3, ///< Symbolic link file - block =4, ///< Block special file - character= 5 , ///< Character special file - fifo = 6 , ///< FIFO or pipe file - socket =7, - unknown= 8 ///< The file does exist, but is of an operating system dependent type not covered by any of the other - }; + 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 + regular = 1, + directory = 2 , + symlink =3, ///< Symbolic link file + block =4, ///< Block special file + character= 5 , ///< Character special file + fifo = 6 , ///< FIFO or pipe file + socket =7, + unknown= 8 ///< The file does exist, but is of an operating system dependent type not covered by any of the other + }; - enum class perms - { - none =0, ///< There are no permissions set for the file. - unknown = 0xFFFF ///< not known, such as when a file_status object is created without specifying the permissions - }; + enum class perms + { + none = 0, ///< There are no permissions set for the file. + all = 0x1FF, ///< owner_all | group_all | others_all + mask = 0xFFF, ///< all | set_uid | set_gid | sticky_bit. + unknown = 0xFFFF ///< not known, such as when a file_status object is created without specifying the permissions + }; //enum class copy_options; //enum class directory_options; - // class filesystem_error; - enum class error { none = 0 }; // deprecate ?? - - struct attribute // deprecate ?? - { - uintmax_t size {}; - bool directory{}; - tm modified {}; - - attribute() {} ; - attribute( uintmax_t size, bool is_directory) :size{size}, directory{is_directory} {} - }; - struct space_info { uintmax_t capacity; uintmax_t free; uintmax_t available; }; - using file_time_type = std::chrono::time_point< std::chrono::system_clock>;// trivial-clock> ; - class file_status - { - file_type m_ft = file_type::none; - perms m_prms = perms::unknown; + using file_time_type = std::chrono::time_point;// trivial-clock> ; - public: - explicit file_status(file_type ft = file_type::none, perms prms = perms::unknown) - :m_ft{ft}, m_prms{prms} - {} + class file_status + { + file_type m_ft = file_type::none; + perms m_prms = perms::unknown; - file_status(const file_status& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default; - file_status(file_status&& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default; + public: + explicit file_status(file_type ft = file_type::none, perms prms = perms::unknown); - ~file_status(){}; - file_status& operator=(const file_status&) = default; - file_status& operator=(file_status&&fs) // = default; - { - m_ft=fs.m_ft; m_prms = fs.m_prms; - return *this; - } - // observers - file_type type() const { return m_ft;} - perms permissions() const { return m_prms;} - // modifiers - void type (file_type ft) { m_ft=ft ;} - void permissions(perms prms) { m_prms = prms; } - }; + // observers + file_type type() const; + perms permissions() const; + + // modifiers + void type(file_type ft); + void permissions(perms prms); + private: + file_type value_; + perms perms_; + }; /// concerned only with lexical and syntactic aspects and does not necessarily exist in /// external storage, and the pathname is not necessarily valid for the current operating system @@ -136,55 +108,118 @@ namespace filesystem class path { public: - path(); - path(const nana::string&); +#if defined(NANA_WINDOWS) + using value_type = wchar_t; + const static value_type preferred_separator = '\\'; +#else + using value_type = char; + const static value_type preferred_separator = '/'; +#endif + using string_type = std::basic_string; + + path() = default; + + template + path(const Source& source) + { + _m_assign(source); + } + + + int compare(const path& other) const; bool empty() const; - path root() const; + path extension() const; + + path parent_path() const; file_type what() const; - nana::string filename() const; -#if defined(NANA_WINDOWS) - public: - nana::string to_string() const { return text_; } - operator nana::string() const { return text_; } + //decomposition + path filename() const; + + //modifiers + path& remove_filename(); + + + + const value_type*c_str() const; + const string_type& native() const; + operator string_type() const; + + std::string string() const; + std::wstring wstring() const; + std::string u8string() const; + + //appends + path& operator/=(const path& other); + + template + path& operator/=(const Source& source) + { + path other(source); + return this->operator/=(other); + } + + template + path& append(const Source& source) + { + path other(source); + return this->operator/=(other); + } private: - nana::string text_; -#else - public: - std::string to_string() const { return text_; } - operator std::string() const { return text_; } + void _m_assign(const std::string& source_utf8); + void _m_assign(const std::wstring& source); private: - std::string text_; -#endif + string_type pathstr_; }; - struct directory_entry + bool operator==(const path& lhs, const path& rhs); + bool operator!=(const path& lhs, const path& rhs); + bool operator<(const path& lhs, const path& rhs); + bool operator>(const path& lhs, const path& rhs); + path operator/(const path& lhs, const path& rhs); + + + class filesystem_error + : public std::system_error { - using path_type = filesystem::path; - path_type m_path; + public: + explicit filesystem_error(const std::string& msg, std::error_code); - attribute attr{}; - //file_status m_status; + 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); - directory_entry(){} - directory_entry(const path_type& p, bool is_directory, uintmax_t size) - :m_path{p}, attr{size, is_directory} - {} + const path& path1() const; //noexcept + const path& path2() const; //noexcept + private: + path path1_; + path path2_; + }; - void assign (const path_type& p){ m_path=p;} - void replace_filename(const path_type& p){ m_path=p;} - //file_status status() const; + class directory_entry + { + public: + directory_entry() = default; + explicit directory_entry(const path&); - operator const path_type&() const {return m_path;}; - const path_type& path() const {return m_path;} + //modifiers + void assign(const path&); + void replace_filename(const path&); + + //observers + file_status status() const; + operator const filesystem::path&() const; + const filesystem::path& path() const; + private: + filesystem::path path_; }; /// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator //template class directory_iterator :public std::iterator { + using find_handle = void*; public: using value_type = directory_entry ; typedef ptrdiff_t difference_type; @@ -192,37 +227,20 @@ namespace filesystem typedef const directory_entry& reference; typedef std::input_iterator_tag iterator_category; - directory_iterator():end_(true), handle_(nullptr){} + directory_iterator(); + directory_iterator(const path& file_path); - directory_iterator(const nana::string& file_path) { _m_prepare(file_path); } - directory_iterator(const path& file_path) { _m_prepare(file_path.filename()); } + const value_type& operator*() const; + const value_type* operator->() const; - const value_type& - operator*() const { return value_; } + directory_iterator& operator++(); + directory_iterator operator++(int); - const value_type* - operator->() const { return &(operator*()); } - - directory_iterator& operator++() - { _m_read(); return *this; } - - directory_iterator operator++(int) - { - directory_iterator tmp = *this; - _m_read(); - return tmp; - } - - bool equal(const directory_iterator& x) const - { - if(end_ && (end_ == x.end_)) return true; - return (value_.path().filename() == x.value_.path().filename()); - } + bool equal(const directory_iterator& x) const; - // enable directory_iterator range-based for statements - directory_iterator begin( ) { return *this; } - directory_iterator end( ) { return {}; } + directory_iterator begin(); + directory_iterator end(); private: template @@ -233,152 +251,14 @@ namespace filesystem return (*p == 0); } - void _m_prepare(const nana::string& file_path) - { - #if defined(NANA_WINDOWS) - path_ = file_path; - auto pat = file_path; - DWORD attr = ::GetFileAttributes(pat.data()); - if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY)) - pat += STR("\\*"); - - ::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_); - - if(handle == INVALID_HANDLE_VALUE) - { - end_ = true; - return; - } - - while(_m_ignore(wfd_.cFileName)) - { - if(::FindNextFile(handle, &wfd_) == 0) - { - end_ = true; - ::FindClose(handle); - return; - } - } - - value_ = value_type(path(wfd_.cFileName), - (FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY, - wfd_.nFileSizeLow); - - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - path_ = nana::charset(file_path); - if(path_.size() && (path_[path_.size() - 1] != '/')) - path_ += '/'; - find_handle_t handle = opendir(path_.c_str()); - end_ = true; - if(handle) - { - struct dirent * dnt = readdir(handle); - if(dnt) - { - while(_m_ignore(dnt->d_name)) - { - dnt = readdir(handle); - if(dnt == 0) - { - closedir(handle); - return; - } - } - - struct stat fst; - bool is_directory = false; - unsigned size = 0; - if(stat((path_ + dnt->d_name).c_str(), &fst) == 0) - { - is_directory = (0 != S_ISDIR(fst.st_mode)); - size = fst.st_size; - } - value_ = value_type(static_cast(nana::charset(dnt->d_name)), is_directory, size); - end_ = false; - } - } - #endif - if(false == end_) - { - find_ptr_ = std::shared_ptr(new find_handle_t(handle), inner_handle_deleter()); - handle_ = handle; - } - } - - void _m_read() - { - if(handle_) - { - #if defined(NANA_WINDOWS) - if(::FindNextFile(handle_, &wfd_) != 0) - { - while(_m_ignore(wfd_.cFileName)) - { - if(::FindNextFile(handle_, &wfd_) == 0) - { - end_ = true; - return; - } - } - value_ = value_type(path(wfd_.cFileName), - (FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY, - wfd_.nFileSizeLow); - } - else - end_ = true; - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct dirent * dnt = readdir(handle_); - if(dnt) - { - while(_m_ignore(dnt->d_name)) - { - dnt = readdir(handle_); - if(dnt == 0) - { - end_ = true; - return; - } - } - - nana::string d_name = nana::charset(dnt->d_name); - struct stat fst; - if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0) - value_ = value_type(std::move(d_name), (0 != S_ISDIR(fst.st_mode)), fst.st_size); - else - value_.m_path = path(std::move(d_name)); - } - else - end_ = true; - #endif - } - } - private: - struct inner_handle_deleter - { - void operator()(find_handle_t * handle) - { - if(handle && *handle) - { - #if defined(NANA_WINDOWS) - ::FindClose(*handle); - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - ::closedir(*handle); - #endif - } - delete handle; - } - }; + void _m_prepare(const path& file_path); + void _m_read(); private: bool end_{false}; + path::string_type path_; -#if defined(NANA_WINDOWS) - WIN32_FIND_DATA wfd_; - nana::string path_; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - std::string path_; -#endif - std::shared_ptr find_ptr_; - find_handle_t handle_{nullptr}; + std::shared_ptr find_ptr_; + find_handle handle_{nullptr}; value_type value_; }; @@ -401,68 +281,89 @@ namespace filesystem } - // file_status status(const path& p); - bool file_attrib(const nana::string& file, attribute&); + file_status status(const path& p); + file_status status(const path& p, std::error_code&); + + 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(const path& p) { return directory_iterator(p)->attr.directory; }//works?? - inline bool is_directory(const directory_entry& d) { return d.attr.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_empty(const path& p) { - directory_iterator d(p) ; - return d->attr.directory ? d == directory_iterator() - : d->attr.size == 0; + auto fs = status(p); + + if (is_directory(fs)) + return (directory_iterator() == directory_iterator(p)); + + return (file_size(p) == 0); } //bool is_empty(const path& p, error_code& ec) noexcept; - uintmax_t file_size(const nana::string& file); // deprecate? - inline uintmax_t file_size(const path& p){return file_size(p.filename());} - //uintmax_t file_size(const path& p, error_code& ec) noexcept; - //long long filesize(const nana::string& file); - - bool create_directories(const path& p); - //bool create_directories(const path& p, error_code& ec) noexcept; - bool create_directory(const path& p); - //bool create_directory(const path& p, error_code& ec) noexcept; - bool create_directory(const path& p, const path& attributes); - //bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept; - bool create_directory(const nana::string& dir, bool & if_exist); - inline bool create_directory(const path& p, bool & if_exist) - { - return create_directory(p.filename(), if_exist); - }; - - - bool modified_file_time(const nana::string& file, struct tm&); - - - nana::string path_user(); + bool create_directories(const path& p); + //bool create_directories(const path& p, error_code& ec) noexcept; + bool create_directory(const path& p); + //bool create_directory(const path& p, error_code& ec) noexcept; + bool create_directory(const path& p, const path& attributes); + //bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept; - - path current_path(); - //path current_path(error_code& ec); - void current_path(const path& p); - //void current_path(const path& p, error_code& ec) noexcept; - //nana::string path_current(); + bool modified_file_time(const path& p, struct tm&); + + path path_user(); + + path current_path(); + //path current_path(error_code& ec); + void current_path(const path& p); + //void current_path(const path& p, error_code& ec) noexcept; - //bool remove(const path& p); - //bool remove(const path& p, error_code& ec) noexcept; - bool rmfile(const nana::char_t* file); + bool remove(const path& p); + bool remove(const path& p, std::error_code& ec); // noexcept; - //uintmax_t remove_all(const path& p); - //uintmax_t remove_all(const path& p, error_code& ec) noexcept; - bool rmdir(const nana::char_t* dir, bool fails_if_not_empty); - nana::string root(const nana::string& path); + //uintmax_t remove_all(const path& p); + //uintmax_t remove_all(const path& p, error_code& ec) noexcept; + + template + std::basic_string parent_path(const std::basic_string& path) + { + auto index = path.size(); + + if (index) + { + auto str = path.c_str(); + + for (--index; index > 0; --index) + { + auto c = str[index]; + if (c != '\\' && c != '/') + break; + } + + for (--index; index > 0; --index) + { + auto c = str[index]; + if (c == '\\' || c == '/') + break; + } + } + + return index ? path.substr(0, index + 1) : std::basic_string(); + } }//end namespace filesystem } //end namespace experimental + + namespace filesystem = experimental::filesystem; }//end namespace nana #endif diff --git a/include/nana/filesystem/fs_utility.hpp b/include/nana/filesystem/fs_utility.hpp deleted file mode 100644 index d52e54dd..00000000 --- a/include/nana/filesystem/fs_utility.hpp +++ /dev/null @@ -1,65 +0,0 @@ - -#ifndef NANA_FILESYSTEM_FS_UTILITY_HPP -#define NANA_FILESYSTEM_FS_UTILITY_HPP - -#include -#include - -namespace nana -{ -namespace filesystem -{ - struct error - { - enum - { - none = 0 - }; - }; - - struct attribute - { - long long bytes; - bool is_directory; - tm modified; - }; - - bool file_attrib(const nana::string& file, attribute&); - long long filesize(const nana::string& file); - - bool mkdir(const nana::string& dir, bool & if_exist); - bool modified_file_time(const nana::string& file, struct tm&); - - nana::string path_user(); - nana::string path_current(); - - bool rmfile(const nana::char_t* file); - bool rmdir(const nana::char_t* dir, bool fails_if_not_empty); - nana::string root(const nana::string& path); - - class path - { - public: - struct type - { enum{not_exist, file, directory}; - }; - - path(); - path(const nana::string&); - - bool empty() const; - path root() const; - int what() const; - - nana::string name() const; - private: -#if defined(NANA_WINDOWS) - nana::string text_; -#else - std::string text_; -#endif - }; -}//end namespace filesystem -}//end namespace nana - -#endif diff --git a/include/nana/fwd.hpp b/include/nana/fwd.hpp index 62d824cb..c3795e3a 100644 --- a/include/nana/fwd.hpp +++ b/include/nana/fwd.hpp @@ -1,7 +1,7 @@ /* * Forward Declarations * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index ac5db7c1..ed2e1db4 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -1,7 +1,7 @@ /* * A Basic Window Widget 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 @@ -145,7 +145,7 @@ namespace detail basic_window *parent; basic_window *owner; - ::nana::string title; + 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 @@ -167,7 +167,8 @@ namespace detail 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 - unsigned Reserved :19; + 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 mouse_action action; }flags; diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index a6f17bc6..8d75dc9e 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -1,7 +1,7 @@ /** * Definition of General Events * 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 @@ -111,7 +111,7 @@ namespace nana evt_->deleted_flags_ = false; for (auto i = evt_->dockers_->begin(); i != evt_->dockers_->end();) { - if (i->get()->flag_deleted) + if (static_cast(i->get())->flag_deleted) i = evt_->dockers_->erase(i); else ++i; @@ -128,11 +128,11 @@ namespace nana { internal_scope_guard lock; if (nullptr == dockers_) - dockers_.reset(new std::vector>); + dockers_.reset(new std::vector>); using prototype = typename std::remove_reference::type; - std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); - auto evt = reinterpret_cast(static_cast(dck.get())); + std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); + auto evt = reinterpret_cast(dck.get()); dockers_->emplace(dockers_->begin(), std::move(dck)); detail::events_operation_register(evt); return evt; @@ -151,11 +151,11 @@ namespace nana { internal_scope_guard lock; if (nullptr == dockers_) - dockers_.reset(new std::vector>); + dockers_.reset(new std::vector>); using prototype = typename std::remove_reference::type; - std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); - auto evt = reinterpret_cast(static_cast(dck.get())); + std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), false)); + auto evt = reinterpret_cast(dck.get()); dockers_->emplace_back(std::move(dck)); detail::events_operation_register(evt); return evt; @@ -174,11 +174,11 @@ namespace nana { internal_scope_guard lock; if (nullptr == dockers_) - dockers_.reset(new std::vector>); + dockers_.reset(new std::vector>); using prototype = typename std::remove_reference::type; - std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), true)); - auto evt = reinterpret_cast(static_cast(dck.get())); + std::unique_ptr dck(new docker(this, factory::value>::build(std::forward(fn)), true)); + auto evt = reinterpret_cast(dck.get()); if (in_front) dockers_->emplace(dockers_->begin(), std::move(dck)); else @@ -208,7 +208,7 @@ namespace nana //Traverses with position can avaid crash error which caused by a iterator which becomes invalid. for (std::size_t pos = 0; pos < dockers_len; ++pos) { - auto docker_ptr = dockers[pos].get(); + auto docker_ptr = static_cast(dockers[pos].get()); if (docker_ptr->flag_deleted) continue; @@ -217,7 +217,7 @@ namespace nana { for (++pos; pos < dockers_len; ++pos) { - auto docker_ptr = dockers[pos].get(); + auto docker_ptr = static_cast(dockers[pos].get()); if (!docker_ptr->unignorable || docker_ptr->flag_deleted) continue; @@ -247,7 +247,7 @@ namespace nana //Checks whether this event is working now. if (emitting_count_ > 1) { - i->get()->flag_deleted = true; + static_cast(i->get())->flag_deleted = true; deleted_flags_ = true; } else @@ -416,7 +416,7 @@ namespace nana private: unsigned emitting_count_{ 0 }; bool deleted_flags_{ false }; - std::unique_ptr>> dockers_; + std::unique_ptr>> dockers_; }; struct arg_mouse @@ -460,7 +460,7 @@ namespace nana { ::nana::window window_handle; ///< A handle to the event window ::nana::point pos; ///< cursor position in the event window - std::vector files; ///< external filenames + std::vector files; ///< external filenames }; struct arg_expose : public event_arg @@ -480,7 +480,7 @@ namespace nana { event_code evt_code; ///< it is event_code::key_press in current event ::nana::window window_handle; ///< A handle to the event window - mutable nana::char_t key; ///< the key corresponding to the key pressed + mutable wchar_t key; ///< the key corresponding to the key pressed mutable bool ignore; ///< this member is not used bool ctrl; ///< keyboard Ctrl is pressed? bool shift; ///< keyboard Shift is pressed @@ -528,7 +528,7 @@ namespace nana /// provides some fundamental events that every widget owns. struct general_events { - virtual ~general_events(){} + virtual ~general_events() = default; basic_event mouse_enter; ///< the cursor enters the window basic_event mouse_move; ///< the cursor moves on the window basic_event mouse_leave; ///< the cursor leaves the window diff --git a/include/nana/gui/detail/inner_fwd_implement.hpp b/include/nana/gui/detail/inner_fwd_implement.hpp index e420c554..90589d3c 100644 --- a/include/nana/gui/detail/inner_fwd_implement.hpp +++ b/include/nana/gui/detail/inner_fwd_implement.hpp @@ -119,8 +119,9 @@ namespace nana{ struct condition_tag { - core_window_t* pressed{nullptr}; //The handle to a window which is being pressed - core_window_t* hovered{nullptr}; //the latest window that mouse moved + core_window_t* pressed{nullptr}; //The handle to a window which has been pressed by pressing left button of mouse. + core_window_t* pressed_by_space{ nullptr }; //The handle to a window which has been pressed by pressing spacebar. + core_window_t* hovered{nullptr}; //the latest window that mouse moved }condition; root_misc(core_window_t * wd, unsigned width, unsigned height) diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index 5db4a645..aade67a5 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -34,6 +34,8 @@ namespace detail unsigned extra_height; //extra border size, it is useful in Windows, ignore in X11 always 0 }; + using native_string_type = ::nana::detail::native_string_type; + 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&); @@ -65,15 +67,17 @@ namespace detail static void window_size(native_window_type, const size&); static void get_window_rect(native_window_type, rectangle&); - static void window_caption(native_window_type, const nana::string&); - static nana::string window_caption(native_window_type); + static void window_caption(native_window_type, const native_string_type&); + static native_string_type window_caption(native_window_type); static void capture_window(native_window_type, bool); static nana::point cursor_position(); static native_window_type get_owner_window(native_window_type); + static native_window_type parent_window(native_window_type); + static native_window_type parent_window(native_window_type child, native_window_type new_parent, bool returns_previous); //For Caret - static void caret_create(native_window_type, const ::nana::size&); + static void caret_create(native_window_type, const ::nana::size&); static void caret_destroy(native_window_type); - static void caret_pos(native_window_type, const ::nana::point&); + static void caret_pos(native_window_type, const ::nana::point&); static void caret_visible(native_window_type, bool); static void set_focus(native_window_type); diff --git a/include/nana/gui/detail/widget_notifier_interface.hpp b/include/nana/gui/detail/widget_notifier_interface.hpp index 204bdeea..81a0a28f 100644 --- a/include/nana/gui/detail/widget_notifier_interface.hpp +++ b/include/nana/gui/detail/widget_notifier_interface.hpp @@ -30,8 +30,8 @@ namespace nana virtual widget* widget_ptr() const = 0; virtual void destroy() = 0; - virtual std::wstring caption() = 0; - virtual void caption(std::wstring) = 0; + virtual ::nana::detail::native_string_type caption() = 0; + virtual void caption(::nana::detail::native_string_type) = 0; }; } } diff --git a/include/nana/gui/dragger.hpp b/include/nana/gui/dragger.hpp index 9846b672..e34094ef 100644 --- a/include/nana/gui/dragger.hpp +++ b/include/nana/gui/dragger.hpp @@ -1,6 +1,20 @@ +/* +* A Dragger Implementation +* 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/gui/dragger.hpp +*/ + #ifndef NANA_GUI_DRAGGER_HPP #define NANA_GUI_DRAGGER_HPP -#include "programming_interface.hpp" +#include "basis.hpp" +#include "../basic_types.hpp" +#include "../traits.hpp" namespace nana { @@ -18,6 +32,10 @@ namespace nana public: dragger(); ~dragger(); + + dragger(dragger&&); + dragger& operator=(dragger&&); + void target(window); void target(window, const rectangle& restrict_area, nana::arrange); void remove_target(window); diff --git a/include/nana/gui/filebox.hpp b/include/nana/gui/filebox.hpp index d60ec5c2..3a9b9f4c 100644 --- a/include/nana/gui/filebox.hpp +++ b/include/nana/gui/filebox.hpp @@ -1,7 +1,7 @@ /* * Filebox * 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,7 +25,7 @@ namespace nana filebox(filebox&&) = delete; filebox& operator=(filebox&&) = delete; public: - using filters = std::vector>; + using filters = std::vector>; filebox(bool is_open_mode); filebox(window owner, bool is_open_mode); @@ -37,21 +37,21 @@ namespace nana /// Change owner window void owner(window); - /** @brief specify a title for the dialog - * @param string a text for title - */ - nana::string title( nana::string new_title); ///< . Set a new title for the dialog and \return the old title + /// specify a title for the dialog + /// @param string a text for title + /// @return old title. + ::std::string title( ::std::string new_title); ///< . Set a new title for the dialog and \return the old title /** @brief specify a suggestion directory * @param string a path of initial directory * @note the behavior of init_path is different between Win7 and Win2K/XP/Vista, but its behavior under Linux is conformed with Win7. */ - filebox& init_path(const nana::string&); ///< Suggested init path used to locate a directory when the filebox starts. - filebox& init_file(const nana::string&); ///< Init file, if it contains a path, the init path is replaced by the path of init file. + filebox& init_path(const ::std::string&); ///< Suggested init path used to locate a directory when the filebox starts. + filebox& init_file(const ::std::string&); ///< Init file, if it contains a path, the init path is replaced by the path of init file. /// \brief Add a filetype filter. /// To specify multiple filter in a single description, use a semicolon to separate the patterns(for example,"*.TXT;*.DOC;*.BAK"). - filebox& add_filter(const nana::string& description, ///< for example. "Text File" - const nana::string& filetype ///< filter pattern(for example, "*.TXT") + filebox& add_filter(const ::std::string& description, ///< for example. "Text File" + const ::std::string& filetype ///< filter pattern(for example, "*.TXT") ); filebox& add_filter(const filters &ftres) @@ -62,16 +62,14 @@ namespace nana }; - nana::string path() const; - nana::string file() const; + ::std::string path() const; + ::std::string file() const; - /** @brief Display the filebox dialog - */ + /// Display the filebox dialog bool show() const; - /** @brief Display the filebox dialog - * @note A function object method alternative to show() - */ + /// Display the filebox dialog + /// A function object method alternative to show() bool operator()() const { return show(); diff --git a/include/nana/gui/msgbox.hpp b/include/nana/gui/msgbox.hpp index 3bebcf79..af5a1437 100644 --- a/include/nana/gui/msgbox.hpp +++ b/include/nana/gui/msgbox.hpp @@ -43,10 +43,10 @@ namespace nana msgbox& operator=(const msgbox&); /// Construct that creates a message box with a specified title and default button. - msgbox(const nana::string&); + msgbox(const ::std::string&); /// Construct that creates a message box with an owner windoow, a specified title and buttons. - msgbox(window, const nana::string&, button_t = ok); + msgbox(window, const ::std::string&, button_t = ok); /// Sets an icon for informing user. msgbox& icon(icon_t); @@ -55,10 +55,10 @@ namespace nana void clear(); /// Writes a string to the buffer. - msgbox & operator<<(const nana::string&); + msgbox & operator<<(const std::wstring&); /// Writes a string to the buffer. - msgbox & operator<<(const nana::char_t*); + msgbox & operator<<(const wchar_t*); /// Writes a string to the buffer. msgbox & operator<<(const nana::charset&); @@ -86,7 +86,7 @@ namespace nana private: std::stringstream sstream_; window wd_; - nana::string title_; + std::string title_; button_t button_; icon_t icon_; }; @@ -97,7 +97,7 @@ namespace nana { virtual ~abstract_content() = default; - virtual const ::nana::string& label() const = 0; + virtual const ::std::string& label() const = 0; virtual window create(window, unsigned label_px) = 0; virtual unsigned fixed_pixels() const; }; @@ -107,13 +107,13 @@ namespace nana { struct implement; public: - integer(::nana::string label, int init_value, int begin, int last, int step); + integer(::std::string label, int init_value, int begin, int last, int step); ~integer(); int value() const; private: //Implementation of abstract_content - const ::nana::string& label() const override; + const ::std::string& label() const override; window create(window, unsigned label_px) override; private: std::unique_ptr impl_; @@ -124,13 +124,13 @@ namespace nana { struct implement; public: - real(::nana::string label, double init_value, double begin, double last, double step); + real(::std::string label, double init_value, double begin, double last, double step); ~real(); double value() const; private: //Implementation of abstract_content - const ::nana::string& label() const override; + const ::std::string& label() const override; window create(window, unsigned label_px) override; private: std::unique_ptr impl_; @@ -144,8 +144,8 @@ namespace nana text(const text&) = delete; text& operator=(const text&) = delete; public: - text(::nana::string label, ::nana::string init_text = ::nana::string()); - text(::nana::string label, std::vector<::nana::string>); + text(::std::string label, ::std::string init_text = ::std::string()); + text(::std::string label, std::vector<::std::string>); ~text(); @@ -154,10 +154,10 @@ namespace nana void mask_character(wchar_t ch); - ::nana::string value() const; + ::std::string value() const; private: //Implementation of abstract_content - const ::nana::string& label() const override; + const ::std::string& label() const override; window create(window, unsigned label_px) override; private: std::unique_ptr impl_; @@ -168,17 +168,17 @@ namespace nana { struct implement; public: - date(::nana::string label); + date(::std::string label); ~date(); - ::nana::string value() const; + ::std::string value() const; int year() const; int month() const; //[1, 12] int day() const; //[1, 31] private: //Implementation of abstract_content - const ::nana::string& label() const override; + const ::std::string& label() const override; window create(window, unsigned label_px) override; unsigned fixed_pixels() const override; private: @@ -190,19 +190,19 @@ namespace nana { struct implement; public: - path(::nana::string label, const ::nana::filebox&); + path(::std::string label, const ::nana::filebox&); ~path(); - ::nana::string value() const; + ::std::string value() const; private: //Implementation of abstract_content - const ::nana::string& label() const override; + const ::std::string& label() const override; window create(window, unsigned label_px) override; private: std::unique_ptr impl_; }; - inputbox(window, ::nana::string description, ::nana::string title = ::nana::string()); + inputbox(window, ::std::string description, ::std::string title = ::std::string()); void image(::nana::paint::image, bool is_left, const rectangle& valid_area = {}); void image_v(::nana::paint::image, bool is_top, const rectangle& valid_area = {}); @@ -246,8 +246,8 @@ namespace nana bool _m_open(std::vector&, bool modal); private: window owner_; - ::nana::string description_; - ::nana::string title_; + ::std::string description_; + ::std::string title_; std::function verifier_; ::nana::paint::image images_[4]; ::nana::rectangle valid_areas_[4]; diff --git a/include/nana/gui/notifier.hpp b/include/nana/gui/notifier.hpp index c6eea9da..a557fd45 100644 --- a/include/nana/gui/notifier.hpp +++ b/include/nana/gui/notifier.hpp @@ -55,9 +55,9 @@ namespace nana notifier(window); ~notifier(); void close(); - void text(const nana::string&); - void icon(const nana::string& icon_file); - void insert_icon(const nana::string& icon_file); + void text(const ::std::string&); + void icon(const ::std::string& icon_file); + void insert_icon(const ::std::string& icon_file); void period(unsigned millisecond); detail::notifier_events& events(); window handle() const; diff --git a/include/nana/gui/place.hpp b/include/nana/gui/place.hpp index 2e3676de..8f32545b 100644 --- a/include/nana/gui/place.hpp +++ b/include/nana/gui/place.hpp @@ -42,13 +42,17 @@ namespace nana : init_(std::move(initializer)) {} - agent(const nana::char_t* text) + agent(const char* text) : text_(text) - {} + { + throw_not_utf8(text); + } - agent(nana::string text, std::function initializer = {}) + agent(std::string text, std::function initializer = {}) : text_(std::move(text)), init_(std::move(initializer)) - {} + { + throw_not_utf8(text_); + } private: std::unique_ptr create(nana::window handle) const override @@ -60,7 +64,7 @@ namespace nana return std::move(ptr); } private: - nana::string text_; + std::string text_; std::function init_; }; @@ -79,8 +83,8 @@ namespace nana public: field_interface() = default; virtual ~field_interface() = default; - virtual field_interface& operator<<(const nana::char_t* label) = 0; - virtual field_interface& operator<<(nana::string label) = 0; + virtual field_interface& operator<<(const char* label) = 0; + virtual field_interface& operator<<(std::string label) = 0; virtual field_interface& operator<<(window) = 0; virtual field_interface& fasten(window) = 0; diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 6227f6bb..8adfd2eb 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -1,7 +1,7 @@ /* * Nana GUI Programming Interface 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 @@ -72,8 +72,8 @@ namespace API widget_colors* get_scheme(window); void attach_drawer(widget&, drawer_trigger&); - nana::string window_caption(window) throw(); - void window_caption(window, nana::string); + ::nana::detail::native_string_type window_caption(window) throw(); + void window_caption(window, ::nana::detail::native_string_type); window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached); window create_widget(window, const rectangle&, widget* attached); @@ -83,6 +83,11 @@ namespace API paint::graphics* window_graphics(window); void delay_restore(bool); + + void register_menu_window(window, bool has_keyboard); + void set_menubar(window wd, bool attach); + + void enable_space_click(window, bool enable); }//end namespace dev @@ -140,7 +145,7 @@ namespace API void exit(); - nana::string transform_shortkey_text(nana::string text, nana::string::value_type &shortkey, nana::string::size_type *skpos); + std::string transform_shortkey_text(std::string text, wchar_t &shortkey, std::string::size_type *skpos); bool register_shortkey(window, unsigned long); void unregister_shortkey(window); @@ -271,8 +276,8 @@ namespace API void update_window(window); ///< Copies the off-screen buffer to the screen for immediate display. void window_caption(window, const std::string& title_utf8); - void window_caption(window, const nana::string& title); - nana::string window_caption(window); + void window_caption(window, const std::wstring& title); + ::std::string window_caption(window); void window_cursor(window, cursor); cursor window_cursor(window); @@ -310,9 +315,6 @@ namespace API void eat_tabstop(window, bool); window move_tabstop(window, bool next); ///< Sets the focus to the window which tabstop is near to the specified window. - bool glass_window(window); /// \deprecated - bool glass_window(window, bool); /// \deprecated - /// Sets the window active state. If a window active state is false, the window will not obtain the focus when a mouse clicks on it wich will be obteined by take_if_has_active_false. void take_active(window, bool has_active, window take_if_has_active_false); @@ -328,10 +330,6 @@ namespace API window find_window(const nana::point& mspos); - void register_menu_window(window, bool has_keyboard); - bool attach_menubar(window menubar); - void detach_menubar(window menubar); - bool is_window_zoomed(window, bool ask_for_max); ///(); + auto vp = any_cast(&var); T null_val; arg_categorize arg(widget_, vp ? *vp : null_val); @@ -94,7 +94,7 @@ namespace nana virtual ~renderer() = 0; virtual void background(graph_reference, window wd, const nana::rectangle&, const ui_element&) = 0; virtual void root_arrow(graph_reference, const nana::rectangle&, mouse_action) = 0; - virtual void item(graph_reference, const nana::rectangle&, std::size_t index, const nana::string& name, unsigned textheight, bool has_child, mouse_action) = 0; + virtual void item(graph_reference, const nana::rectangle&, std::size_t index, const ::std::string& name, unsigned textheight, bool has_child, mouse_action) = 0; virtual void border(graph_reference) = 0; }; @@ -108,18 +108,18 @@ namespace nana trigger(); ~trigger(); - void insert(const nana::string&, nana::any); - bool childset(const nana::string&, nana::any); - bool childset_erase(const nana::string&); + void insert(const ::std::string&, nana::any); + bool childset(const ::std::string&, nana::any); + bool childset_erase(const ::std::string&); bool clear(); //splitstr //@brief: Sets the splitstr. If the parameter will be ingored if it is an empty string. - void splitstr(const nana::string&); - const nana::string& splitstr() const; + void splitstr(const ::std::string&); + const ::std::string& splitstr() const; - void path(const nana::string&); - nana::string path() const; + void path(const ::std::string&); + ::std::string path() const; template void create_event_agent(::nana::categorize& wdg) @@ -155,8 +155,9 @@ namespace nana : public widget_object> { public: - typedef T value_type; ///< The type of objects stored - typedef drawerbase::categorize::renderer renderer; ///< The interface for user-defined renderer. + using native_string_type = widget::native_string_type; + using value_type = T; ///< The type of objects stored + using renderer = drawerbase::categorize::renderer; ///< The interface for user-defined renderer. categorize() { @@ -174,13 +175,25 @@ namespace nana { } - categorize(window wd, const nana::string& text, bool visible = true) + categorize(window wd, const std::string& text_utf8, bool visible = true) + : categorize(wd, ::nana::rectangle(), visible) + { + this->caption(text_utf8); + } + + categorize(window wd, const char* text_utf8, bool visible = true) + : categorize(wd, ::nana::rectangle(), visible) + { + this->caption(text_utf8); + } + + categorize(window wd, const std::wstring& text, bool visible = true) : categorize(wd, ::nana::rectangle(), visible) { this->caption(text); } - categorize(window wd, const nana::char_t* text, bool visible = true) + categorize(window wd, const wchar_t* text, bool visible = true) : categorize(wd, ::nana::rectangle(), visible) { this->caption(text); @@ -189,7 +202,7 @@ namespace nana /// Insert a new category with a specified name and the object of value type. /// The new category would be inserted as a child in current category, /// and after inserting, the new category is replaced of the current category as a new current one. - categorize& insert(const nana::string& name, const value_type& value) + categorize& insert(const std::string& name, const value_type& value) { this->get_drawer_trigger().insert(name, value); API::update_window(*this); @@ -197,15 +210,16 @@ namespace nana } /// Inserts a child category into current category. - categorize& childset(const nana::string& name, const value_type& value) + categorize& childset(const std::string& name, const value_type& value) { + throw_not_utf8(name); if(this->get_drawer_trigger().childset(name, value)) API::update_window(*this); return *this; } /// Erases a child category with a specified name from current category. - categorize& childset_erase(const nana::string& name) + categorize& childset_erase(const std::string& name) { if(this->get_drawer_trigger().childset_erase(name)) API::update_window(*this); @@ -219,13 +233,13 @@ namespace nana } /// Sets the splitter string - categorize& splitstr(const nana::string& sstr) + categorize& splitstr(const std::string& sstr) { this->get_drawer_trigger().splitstr(sstr); return *this; } - nana::string splitstr() const + std::string splitstr() const { return this->get_drawer_trigger().splitstr(); } @@ -237,10 +251,10 @@ namespace nana } private: //Overrides widget's virtual functions - void _m_caption(nana::string&& str) override + void _m_caption(native_string_type&& str) override { - this->get_drawer_trigger().path(str); - API::dev::window_caption(*this, this->get_drawer_trigger().path()); + this->get_drawer_trigger().path(to_utf8(str)); + API::dev::window_caption(*this, to_nstring(this->get_drawer_trigger().path()) ); } }; }//end namespace nana diff --git a/include/nana/gui/widgets/checkbox.hpp b/include/nana/gui/widgets/checkbox.hpp index 7af58e72..8d458be3 100644 --- a/include/nana/gui/widgets/checkbox.hpp +++ b/include/nana/gui/widgets/checkbox.hpp @@ -1,7 +1,7 @@ /** * A CheckBox 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 @@ -17,10 +17,30 @@ #include namespace nana { + + //forward-declaration + class checkbox; + + struct arg_checkbox + : public event_arg + { + checkbox * const widget; + + arg_checkbox(checkbox* wdg) + : widget(wdg) + {} + }; + namespace drawerbase { namespace checkbox { + struct events_type + : public general_events + { + basic_event checked; + }; + class drawer : public drawer_trigger { @@ -36,14 +56,8 @@ namespace drawerbase void mouse_up(graph_reference, const arg_mouse&) override; public: implement * impl() const; - private: - void _m_draw_background(graph_reference); - void _m_draw_checkbox(graph_reference, unsigned first_line_height); - void _m_draw_title(graph_reference); private: static const int interval = 4; - widget* widget_; - std::unique_ptr imptr_; implement * impl_; }; }//end namespace checkbox @@ -51,13 +65,13 @@ namespace drawerbase class checkbox - : public widget_object + : public widget_object { public: checkbox(); checkbox(window, bool visible); - checkbox(window, const nana::string& text, bool visible = true); - checkbox(window, const nana::char_t* text, bool visible = true); + checkbox(window, const std::string& text, bool visible = true); + checkbox(window, const char* text, bool visible = true); checkbox(window, const rectangle& = rectangle(), bool visible = true); void element_set(const char* name); @@ -81,6 +95,7 @@ namespace drawerbase checkbox * uiobj; event_handle eh_checked; event_handle eh_destroy; + event_handle eh_keyboard; }; public: ~radio_group(); diff --git a/include/nana/gui/widgets/combox.hpp b/include/nana/gui/widgets/combox.hpp index b7e9286e..4d22a30e 100644 --- a/include/nana/gui/widgets/combox.hpp +++ b/include/nana/gui/widgets/combox.hpp @@ -1,7 +1,7 @@ /** * A Combox 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 @@ -75,8 +75,8 @@ namespace nana { public: item_proxy(drawer_impl*, std::size_t pos); - item_proxy& text(const nana::string&); - nana::string text() const; + item_proxy& text(const ::std::string&); + ::std::string text() const; item_proxy& select(); bool selected() const; item_proxy& icon(const nana::paint::image&); @@ -85,8 +85,7 @@ namespace nana template T * value_ptr() const { - auto p = _m_anyobj(false); - return (p ? p->get() : nullptr); + return any_cast(_m_anyobj(false)); } template @@ -96,7 +95,7 @@ namespace nana if (nullptr == pany) throw std::runtime_error("combox::item_proxy.value() is empty"); - T * p = pany->get(); + T * p = any_cast(pany); if (nullptr == p) throw std::runtime_error("combox::item_proxy.value() invalid type of value"); return *p; @@ -112,14 +111,13 @@ namespace nana template item_proxy& value(T&& t) { - *_m_anyobj(true) = std::move(t); + *_m_anyobj(true) = ::std::move(t); return *this; } public: /// Behavior of Iterator's value_type - bool operator==(const nana::string&) const; + bool operator==(const ::std::string&) const; bool operator==(const char*) const; - bool operator==(const wchar_t*) const; /// Behavior of Iterator item_proxy & operator=(const item_proxy&); @@ -166,19 +164,19 @@ namespace nana combox(); combox(window, bool visible); - combox(window, nana::string, bool visible = true); - combox(window, const nana::char_t*, bool visible = true); + combox(window, ::std::string, bool visible = true); + combox(window, const char*, bool visible = true); combox(window, const rectangle& r = rectangle(), bool visible = true); void clear(); void editable(bool); bool editable() const; - void set_accept(std::function); - combox& push_back(nana::string); + void set_accept(std::function); + combox& push_back(std::string); std::size_t the_number_of_options() const; std::size_t option() const; ///< Index of the last selected, from drop-down list, item. void option(std::size_t); ///< Select the text specified by index - nana::string text(std::size_t) const; + ::std::string text(std::size_t) const; void erase(std::size_t pos); template @@ -224,8 +222,8 @@ namespace nana const drawerbase::combox::drawer_impl& _m_impl() const; private: //Overrides widget's virtual functions - nana::string _m_caption() const throw() override; - void _m_caption(nana::string&&) override; + native_string_type _m_caption() const throw() override; + void _m_caption(native_string_type&&) override; nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override; }; } diff --git a/include/nana/gui/widgets/date_chooser.hpp b/include/nana/gui/widgets/date_chooser.hpp index 9a168bfb..a4e685e1 100644 --- a/include/nana/gui/widgets/date_chooser.hpp +++ b/include/nana/gui/widgets/date_chooser.hpp @@ -42,12 +42,12 @@ namespace nana trigger(); bool chose() const; nana::date read() const; - void week_name(unsigned index, const nana::string&); + void week_name(unsigned index, const std::string&); private: where _m_pos_where(graph_reference, const ::nana::point& pos); void _m_draw_topbar(graph_reference); void _m_make_drawing_basis(drawing_basis&, graph_reference, const nana::point& refpos); - void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, const nana::string&, bool primary, bool sel); + void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, const ::std::string&, bool primary, bool sel); void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, int number, bool primary, bool sel); void _m_draw_ex_days(drawing_basis &, graph_reference, int begx, int begy, bool before); void _m_draw_days(const nana::point& refpos, graph_reference); @@ -61,7 +61,7 @@ namespace nana void mouse_leave(graph_reference, const arg_mouse&) override; void mouse_up(graph_reference, const arg_mouse&) override; private: - nana::string weekstr_[7]; + ::std::string weekstr_[7]; widget * widget_; @@ -105,13 +105,13 @@ namespace nana public: date_chooser(); date_chooser(window, bool visible); - date_chooser(window, const nana::string& text, bool visible = true); - date_chooser(window, const nana::char_t* text, bool visible = true); + date_chooser(window, const ::std::string& text, bool visible = true); + date_chooser(window, const char* text, bool visible = true); date_chooser(window, const nana::rectangle& r = rectangle(), bool visible = true); bool chose() const; nana::date read() const; - void weekstr(unsigned index, const nana::string&);/// struct tree_node { - typedef std::pair value_type; + typedef std::pair value_type; value_type value; @@ -108,7 +108,7 @@ namespace detail return (verify(node) && (node->owner != &root_) ? node->owner : nullptr); } - node_type * node(node_type* node, const nana::string& key) + node_type * node(node_type* node, const std::string& key) { if(node) { @@ -121,7 +121,7 @@ namespace detail return nullptr; } - node_type* insert(node_type* node, const nana::string& key, const element_type& elem) + node_type* insert(node_type* node, const std::string& key, const element_type& elem) { if(nullptr == node) return insert(key, elem); @@ -159,7 +159,7 @@ namespace detail return nullptr; } - node_type* insert(const nana::string& key, const element_type& elem) + node_type* insert(const std::string& key, const element_type& elem) { auto node = _m_locate(key); if(node) @@ -173,12 +173,12 @@ namespace detail delete node; } - node_type* find(const nana::string& path) const + node_type* find(const std::string& path) const { return _m_locate(path); } - node_type* ref(const nana::string& path) + node_type* ref(const std::string& path) { return _m_locate(path); } @@ -303,7 +303,7 @@ namespace detail } template - unsigned child_size_if(const nana::string& key, PredAllowChild pac) const + unsigned child_size_if(const ::std::string& key, PredAllowChild pac) const { auto node = _m_locate(key); return (node ? child_size_if(*node, pac) : 0); @@ -392,7 +392,7 @@ namespace detail :node(&(self.root_)) {} - bool operator()(const nana::string& key_node) + bool operator()(const ::std::string& key_node) { node_type *child = node->child; node_type *tail = nullptr; @@ -428,7 +428,7 @@ namespace detail :node(&self.root_) {} - bool operator()(const nana::string& key_node) + bool operator()(const ::std::string& key_node) { return ((node = _m_find(node->child, key_node)) != nullptr); } @@ -436,7 +436,7 @@ namespace detail node_type *node; }; private: - static node_type* _m_find(node_type* node, const nana::string& key_node) + static node_type* _m_find(node_type* node, const ::std::string& key_node) { while(node) { @@ -449,14 +449,14 @@ namespace detail } template - void _m_for_each(const nana::string& key, Function function) const + void _m_for_each(const ::std::string& key, Function function) const { if(key.size()) { - nana::string::size_type beg = 0; - auto end = key.find_first_of(STR("\\/")); + ::std::string::size_type beg = 0; + auto end = key.find_first_of("\\/"); - while(end != nana::string::npos) + while(end != ::std::string::npos) { if(beg != end) { @@ -464,11 +464,11 @@ namespace detail return; } - auto next = key.find_first_not_of(STR("\\/"), end); - if(next != nana::string::npos) + auto next = key.find_first_not_of("\\/", end); + if(next != ::std::string::npos) { beg = next; - end = key.find_first_of(STR("\\/"), beg); + end = key.find_first_of("\\/", beg); } else return; @@ -479,7 +479,7 @@ namespace detail } template - node_type* _m_locate(const nana::string& key) + node_type* _m_locate(const ::std::string& key) { if(key.size()) { @@ -499,7 +499,7 @@ namespace detail return &root_; } - node_type* _m_locate(const nana::string& key) const + node_type* _m_locate(const std::string& key) const { if(key.size()) { diff --git a/include/nana/gui/widgets/float_listbox.hpp b/include/nana/gui/widgets/float_listbox.hpp index f28840ea..79a66e2f 100644 --- a/include/nana/gui/widgets/float_listbox.hpp +++ b/include/nana/gui/widgets/float_listbox.hpp @@ -28,7 +28,7 @@ namespace nana virtual ~item_interface(){} virtual const nana::paint::image & image() const = 0; - virtual const nana::char_t* text() const = 0; + virtual const char* text() const = 0; }; //struct module_def diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index 82f34a5b..79162f06 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -37,7 +37,7 @@ namespace nana{ /// The construction that creates the widget and set the titel or caption group(window parent, ///< a handle to the parent - ::nana::string titel, ///< caption of the group + ::std::string titel, ///< caption of the group bool formatted = false, ///< Enable/disable the formatted text for the title unsigned gap = 2, ///< betwen the content and the external limit const rectangle& r = {} , @@ -49,7 +49,7 @@ namespace nana{ ~group(); /// Adds an option for user selection - group& add_option(::nana::string); + group& add_option(::std::string); /// Enables/disables the radio mode which is single selection group& radio_mode(bool); @@ -77,8 +77,8 @@ namespace nana{ void _m_add_child(const char* field, widget*); void _m_init(); void _m_complete_creation() override; - ::nana::string _m_caption() const throw() override; - void _m_caption(::nana::string&&) override; + native_string_type _m_caption() const throw() override; + void _m_caption(native_string_type&&) override; private: std::unique_ptr impl_; }; diff --git a/include/nana/gui/widgets/label.hpp b/include/nana/gui/widgets/label.hpp index aa28effc..6b71bd88 100644 --- a/include/nana/gui/widgets/label.hpp +++ b/include/nana/gui/widgets/label.hpp @@ -57,26 +57,27 @@ namespace nana typedef drawerbase::label::command command; label(); label(window, bool visible); - label(window, const nana::string& text, bool visible = true); - label(window parent, const nana::char_t* text, bool visible = true) :label(parent, nana::string(text),visible) {}; + label(window, const std::string& text, bool visible = true); + label(window parent, const char* text, bool visible = true) :label(parent, std::string(text),visible) {}; label(window, const rectangle& = {}, bool visible = true); label& transparent(bool); ///< Switchs the label widget to the transparent background mode. bool transparent() const throw(); label& format(bool); ///< Switches the format mode of the widget. - label& add_format_listener(std::function); + label& add_format_listener(std::function); - label& click_for(window associated_window) throw(); // as same as the "for" attribute of a label + /// as same as the HTML "for" attribute of a label + label& click_for(window associated_window) throw(); /// Returns the size of the text. If *allowed_width_in_pixel* is not zero, returns a /// "corrected" size that changes lines to fit the text into the specified width nana::size measure(unsigned allowed_width_in_pixel) const; - static ::nana::size measure(::nana::paint::graphics&, const ::nana::string&, unsigned allowed_width_in_pixel, bool format_enabled, align h_align, align_v v_align); + static ::nana::size measure(::nana::paint::graphics&, const ::std::string&, unsigned allowed_width_in_pixel, bool format_enabled, align h_align, align_v v_align); label& text_align(align horizontal_align, align_v vertical_align= align_v::top); private: //Overrides widget's virtual function - void _m_caption(nana::string&&) override; + void _m_caption(native_string_type&&) override; }; }//end namespace nana #endif diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 59324ef2..42ac9123 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -1,15 +1,18 @@ /** * A List Box 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/widgets/listbox.hpp - * @contributors: Ariel Vina-Rodriguez - * + * @contributors: + * Hiroshi Seki + * Ariel Vina-Rodriguez + * leobackes + * Benjamin Navarro */ #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP @@ -31,6 +34,7 @@ namespace nana namespace listbox { using size_type = std::size_t; + using native_string_type = ::nana::detail::native_string_type; /// usefull for both absolute and display (sorted) positions struct index_pair @@ -81,7 +85,7 @@ namespace nana using selection = std::vector; - using inline_notifier_interface = detail::inline_widget_notifier_interface; + using inline_notifier_interface = detail::inline_widget_notifier_interface; struct cell { @@ -94,17 +98,17 @@ namespace nana format(const ::nana::color& bgcolor, const ::nana::color& fgcolor); }; - using format_ptr = std::unique_ptr < format > ; + using format_ptr = ::std::unique_ptr; - ::nana::string text; - format_ptr custom_format; + ::std::string text; + format_ptr custom_format; cell() = default; cell(const cell&); cell(cell&&); - cell(nana::string); - cell(nana::string, const format&); - cell(nana::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor); + cell(::std::string); + cell(::std::string, const format&); + cell(::std::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor); cell& operator=(const cell&); cell& operator=(cell&&); @@ -126,9 +130,9 @@ namespace nana oresolver& operator<<(double); oresolver& operator<<(long double); - oresolver& operator<<(const char*); + oresolver& operator<<(const char* text_utf8); oresolver& operator<<(const wchar_t*); - oresolver& operator<<(const std::string&); + oresolver& operator<<(const std::string& text_utf8); oresolver& operator<<(const std::wstring&); oresolver& operator<<(std::wstring&&); oresolver& operator<<(cell); @@ -157,7 +161,7 @@ namespace nana iresolver& operator>>(double&); iresolver& operator>>(long double&); - iresolver& operator>>(std::string&); + iresolver& operator>>(std::string& text_utf8); iresolver& operator>>(std::wstring&); iresolver& operator>>(cell&); iresolver& operator>>(std::nullptr_t); @@ -241,8 +245,9 @@ namespace nana size_type columns() const; item_proxy& text(size_type col, cell); - item_proxy& text(size_type col, nana::string); - nana::string text(size_type col) const; + item_proxy& text(size_type col, std::string); + item_proxy& text(size_type col, std::wstring); + std::string text(size_type col) const; void icon(const nana::paint::image&); @@ -257,7 +262,7 @@ namespace nana for (auto pos = 0u; pos < cols; ++pos) { auto & el = cells[pos]; - if (el.text.size() == 1 && el.text[0] == nana::char_t(0)) + if (el.text.size() == 1 && el.text[0] == '\0') continue; text(pos, std::move(el)); } @@ -275,8 +280,7 @@ namespace nana template T* value_ptr() const { - auto * pany = _m_value(); - return (pany ? pany->get() : nullptr); + return any_cast(_m_value()); } template @@ -286,7 +290,7 @@ namespace nana if(nullptr == pany) throw std::runtime_error("listbox::item_proxy.value() is empty"); - T * p = pany->get(); + T * p = any_cast(_m_value()); if(nullptr == p) throw std::runtime_error("listbox::item_proxy.value() invalid type of value"); return *p; @@ -300,9 +304,10 @@ namespace nana } /// Behavior of Iterator's value_type - bool operator==(const nana::string& s) const; bool operator==(const char * s) const; bool operator==(const wchar_t * s) const; + bool operator==(const ::std::string& s) const; + bool operator==(const ::std::wstring& s) const; /// Behavior of Iterator item_proxy & operator=(const item_proxy&); @@ -375,18 +380,20 @@ namespace nana } /// Appends one item at the end of this category with the specifies text in the column fields - void append(std::initializer_list); + void append(std::initializer_list texts_utf8); + void append(std::initializer_list texts); size_type columns() const; - cat_proxy& text(nana::string); - nana::string text() const; + cat_proxy& text(std::string); + cat_proxy& text(std::wstring); + std::string text() const; cat_proxy & select(bool); bool selected() const; /// Behavior of a container - void push_back(nana::string); + void push_back(std::string text_utf8); item_proxy begin() const; item_proxy end() const; @@ -449,8 +456,8 @@ namespace nana struct export_options { - nana::string sep = nana::string {STR("\t" )}, - endl= nana::string {STR("\n")}; + std::string sep = ::std::string {"\t"}, + endl= ::std::string {"\n"}; bool only_selected_items{true}, only_checked_items {false}, only_visible_columns{true}; @@ -461,13 +468,30 @@ namespace nana } }//end namespace drawerbase - struct arg_listbox + struct arg_listbox + : public event_arg + { + mutable drawerbase::listbox::item_proxy item; + bool selected; + + arg_listbox(const drawerbase::listbox::item_proxy&, bool selected) noexcept; + }; + + /// The event argument type for listbox's category_dbl_click + struct arg_category : public event_arg { - mutable drawerbase::listbox::item_proxy item; - bool selected; + drawerbase::listbox::cat_proxy category; - arg_listbox(const drawerbase::listbox::item_proxy&, bool selected); + /// Block expension/shrink of category + void block_category_change() const noexcept; + + /// Determines whether expension/shrink of category is blocked + bool category_change_blocked() const noexcept; + + arg_category(const drawerbase::listbox::cat_proxy&) noexcept; + private: + mutable bool block_change_; }; namespace drawerbase @@ -479,6 +503,9 @@ namespace nana { basic_event checked; basic_event selected; + + /// An event occurs when a listbox category is double clicking. + basic_event category_dbl_click; }; struct scheme @@ -510,16 +537,16 @@ By \a clicking on one header the list get \a reordered, first up, and then down and antisymmetry(comp(a, b) != comp(b, a) returns true) A simple example. - bool sort_compare( const nana::string& s1, nana::any*, - const nana::string& s2, nana::any*, bool reverse) + bool sort_compare( const std::string& s1, nana::any*, + const std::string& s2, nana::any*, bool reverse) { return (reverse ? s1 > s2 : s1 < s2); } listbox.set_sort_compare(0, sort_compare); The listbox supports attaching a customer's object for each item, therefore the items can be sorted by comparing these customer's object. - bool sort_compare( const nana::string&, nana::any* o1, - const nana::string&, nana::any* o2, bool reverse) + bool sort_compare( const std::string&, nana::any* o1, + const std::string&, nana::any* o2, bool reverse) { if(o1 && o2) //some items may not attach a customer object. { @@ -565,15 +592,20 @@ By \a clicking on one header the list get \a reordered, first up, and then down void scroll(bool to_bottom, const index_pair& pos); /// Appends a new column with a header text and the specified width at the end, and return it position - size_type append_header(nana::string header_text, unsigned width = 120); + size_type append_header(std::string text_utf8, unsigned width = 120); + size_type append_header(std::wstring text, unsigned width = 120); listbox& header_width(size_type position, unsigned pixels); unsigned header_width(size_type position) const; unsigned auto_width(size_type position, unsigned max=3000); - cat_proxy append(nana::string); ///< Appends a new category at the end - void append(std::initializer_list); ///< Appends categories at the end - cat_proxy insert(cat_proxy, nana::string); + cat_proxy append(std::string); ///< Appends a new category to the end + cat_proxy append(std::wstring); ///< Appends a new category to the end + void append(std::initializer_list); ///< Appends categories to the end + void append(std::initializer_list); ///< Appends categories to the end + + cat_proxy insert(cat_proxy, ::std::string); + cat_proxy insert(cat_proxy, ::std::wstring); cat_proxy at(size_type pos) const; /// add categories in order when use a key? @@ -604,9 +636,18 @@ By \a clicking on one header the list get \a reordered, first up, and then down return cat_proxy(&_m_ess(), _m_at_key(p)); } + /// Returns an item by the specified absolute position item_proxy at(const index_pair &abs_pos) const; - void insert(const index_pair&, nana::string); /// strick_ordering); + void set_sort_compare(size_type col, std::function strick_ordering); /// sort() and ivalidate any existing reference from display position to absolute item, that is: after sort() display offset point to different items void sort_col(size_type col, bool reverse = false); diff --git a/include/nana/gui/widgets/menu.hpp b/include/nana/gui/widgets/menu.hpp index 512d30d7..335796d4 100644 --- a/include/nana/gui/widgets/menu.hpp +++ b/include/nana/gui/widgets/menu.hpp @@ -25,6 +25,8 @@ namespace nana { struct menu_type; //declaration + using native_string_type = ::nana::detail::native_string_type; + enum class checks { none, @@ -56,7 +58,7 @@ namespace nana //Default constructor initializes the item as a splitter menu_item_type(); - menu_item_type(nana::string, const event_fn_t&); + menu_item_type(std::string, const event_fn_t&); struct { @@ -66,11 +68,11 @@ namespace nana }flags; menu_type *sub_menu{nullptr}; - nana::string text; + std::string text; event_fn_t functor; checks style{checks::none}; paint::image image; - mutable nana::char_t hotkey{0}; + mutable wchar_t hotkey{0}; }; struct menu_type @@ -89,7 +91,7 @@ namespace nana class renderer_interface { public: - typedef nana::paint::graphics & graph_reference; + using graph_reference = nana::paint::graphics &; enum class state { @@ -109,7 +111,7 @@ namespace nana virtual void background(graph_reference, window) = 0; virtual void item(graph_reference, const nana::rectangle&, const attr&) = 0; virtual void item_image(graph_reference, const nana::point&, unsigned image_px, const paint::image&) = 0; - virtual void item_text(graph_reference, const nana::point&, const nana::string&, unsigned text_pixels, const attr&) = 0; + virtual void item_text(graph_reference, const nana::point&, const std::string&, unsigned text_pixels, const attr&) = 0; virtual void sub_arrow(graph_reference, const nana::point&, unsigned item_pixels, const attr&) = 0; }; }//end namespace menu @@ -134,7 +136,7 @@ namespace nana ~menu(); /// Appends an item to the menu. - item_proxy append(const nana::string& text, const event_fn_t& callback= event_fn_t()); + item_proxy append(const std::string& text, const event_fn_t& callback= event_fn_t()); void append_splitter(); void clear(); ///< Erases all of the items. /// Closes the menu. It does not destroy the menu; just close the window for the menu. @@ -158,7 +160,7 @@ namespace nana bool goto_submen();///< Popup the submenu of the current item if it has a sub menu. Returns true if succeeds. bool exit_submenu(); ///< Closes the current window of the sub menu. std::size_t size() const; ///< Return the number of items. - int send_shortkey(nana::char_t key); + int send_shortkey(wchar_t key); void pick(); menu& max_pixels(unsigned); ///< Sets the max width in pixels of the item. diff --git a/include/nana/gui/widgets/menubar.hpp b/include/nana/gui/widgets/menubar.hpp index 8e7270bc..365d9b1c 100644 --- a/include/nana/gui/widgets/menubar.hpp +++ b/include/nana/gui/widgets/menubar.hpp @@ -21,6 +21,8 @@ namespace nana { namespace menubar { + using native_string_type = ::nana::detail::native_string_type; + class item_renderer { public: @@ -33,7 +35,7 @@ namespace nana item_renderer(window, graph_reference); virtual void background(const point&, const ::nana::size&, state); - virtual void caption(const point&, const ::nana::string&); + virtual void caption(const point&, const native_string_type&); private: window handle_; graph_reference graph_; @@ -46,7 +48,7 @@ namespace nana public: trigger(); ~trigger(); - nana::menu* push_back(const nana::string&); + nana::menu* push_back(const std::string&); nana::menu* at(size_t) const; std::size_t size() const; private: @@ -108,7 +110,7 @@ namespace nana menubar(window); ///< Create a menubar at the top of the specified window. ~menubar(); void create(window); ///< Create a menubar at the top of the specified window. - menu& push_back(const nana::string&); ///< Appends a new (empty) menu. + menu& push_back(const std::string&); ///< Appends a new (empty) menu. menu& at(size_t index) const; ///< Gets the menu specified by index. std::size_t length() const; ///< Number of menus. private: diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index f09b2046..96d1b023 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -186,7 +186,7 @@ namespace nana { graph_ = &graph; widget_ = static_cast< ::nana::scroll*>(&widget); - widget.caption(STR("Nana Scroll")); + widget.caption("nana scroll"); timer_.stop(); timer_.elapse(std::bind(&trigger::_m_tick, this)); diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index cf1f207a..3189cd18 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -1,7 +1,7 @@ /* * A text editor 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 @@ -131,7 +131,7 @@ namespace nana{ namespace widgets struct keywords; class keyword_parser; public: - using char_type = ::nana::char_t; + using char_type = wchar_t; using size_type = textbase::size_type; using string_type = textbase::string_type; @@ -152,10 +152,10 @@ namespace nana{ namespace widgets text_editor(window, graph_reference, const text_editor_scheme*); ~text_editor(); - void set_highlight(const std::string& name, const ::nana::color&, const ::nana::color&); - void erase_highlight(const std::string& name); - void set_keyword(const ::nana::string& kw, const std::string& name, bool case_sensitive, bool whole_word_matched); - void erase_keyword(const ::nana::string& kw); + void set_highlight(const ::std::string& name, const ::nana::color&, const ::nana::color&); + void erase_highlight(const ::std::string& name); + void set_keyword(const ::std::wstring& kw, const std::string& name, bool case_sensitive, bool whole_word_matched); + void erase_keyword(const ::std::wstring& kw); void set_accept(std::function); void set_accept(accepts); @@ -164,7 +164,7 @@ namespace nana{ namespace widgets void typeface_changed(); - void indent(bool, std::function generator); + void indent(bool, std::function generator); void set_event(event_interface*); /// Determine whether the text_editor is line wrapped. @@ -174,7 +174,7 @@ namespace nana{ namespace widgets void border_renderer(std::function); - bool load(const nana::char_t*); + bool load(const char*); /// Sets the text area. /// @return true if the area is changed with the new value. @@ -183,7 +183,7 @@ namespace nana{ namespace widgets /// Returns the text area rectangle text_area(bool including_scroll) const; - bool tip_string(nana::string&&); + bool tip_string(::std::string&&); const attributes & attr() const; bool multi_lines(bool); @@ -201,9 +201,9 @@ namespace nana{ namespace widgets unsigned line_height() const; unsigned screen_lines() const; - bool getline(std::size_t pos, nana::string&) const; - void text(nana::string); - nana::string text() const; + bool getline(std::size_t pos, ::std::wstring&) const; + void text(std::wstring); + std::wstring text() const; /// Sets caret position through text coordinate. void move_caret(const upoint&); @@ -221,7 +221,7 @@ namespace nana{ namespace widgets bool hit_select_area(nana::upoint pos) const; bool move_select(); - bool mask(char_t); + bool mask(wchar_t); /// Returns width of text area excluding the vscroll size. unsigned width_pixels() const; @@ -233,8 +233,8 @@ namespace nana{ namespace widgets void draw_corner(); void render(bool focused); public: - void put(nana::string); - void put(nana::char_t); + void put(std::wstring); + void put(wchar_t); void copy() const; void cut(); void paste(); @@ -253,8 +253,8 @@ namespace nana{ namespace widgets bool mouse_move(bool left_button, const point& screen_pos); bool mouse_pressed(const arg_mouse& arg); - skeletons::textbase& textbase(); - const skeletons::textbase& textbase() const; + skeletons::textbase& textbase(); + const skeletons::textbase& textbase() const; private: bool _m_accepts(char_type) const; ::nana::color _m_bgcolor() const; @@ -264,11 +264,11 @@ namespace nana{ namespace widgets ::nana::size _m_text_area() const; void _m_get_scrollbar_size(); void _m_reset(); - ::nana::upoint _m_put(nana::string); + ::nana::upoint _m_put(::std::wstring); ::nana::upoint _m_erase_select(); - bool _m_make_select_string(nana::string&) const; - static bool _m_resolve_text(const nana::string&, std::vector> & lines); + bool _m_make_select_string(::std::wstring&) const; + static bool _m_resolve_text(const ::std::wstring&, std::vector> & lines); bool _m_cancel_select(int align); unsigned _m_tabs_pixels(size_type tabs) const; @@ -283,10 +283,10 @@ namespace nana{ namespace widgets /// Returns the right/bottom point of text area. int _m_end_pos(bool right) const; - void _m_draw_parse_string(const keyword_parser&, bool rtl, ::nana::point pos, const ::nana::color& fgcolor, const ::nana::char_t*, std::size_t len) const; + void _m_draw_parse_string(const keyword_parser&, bool rtl, ::nana::point pos, const ::nana::color& fgcolor, const wchar_t*, std::size_t len) const; //_m_draw_string //@brief: Draw a line of string - void _m_draw_string(int top, const ::nana::color&, const nana::upoint& str_pos, const nana::string&, bool if_mask) const; + void _m_draw_string(int top, const ::nana::color&, const nana::upoint& str_pos, const ::std::wstring&, bool if_mask) const; //_m_update_caret_line //@brief: redraw whole line specified by caret pos. //@return: true if caret overs the border @@ -295,8 +295,8 @@ namespace nana{ namespace widgets void _m_offset_y(int y); - unsigned _m_char_by_pixels(const nana::char_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl); - unsigned _m_pixels_by_char(const nana::string&, std::size_t pos) const; + unsigned _m_char_by_pixels(const wchar_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl); + unsigned _m_pixels_by_char(const ::std::wstring&, std::size_t pos) const; void _handle_move_key(const arg_keyboard& arg); private: @@ -308,8 +308,8 @@ namespace nana{ namespace widgets event_interface * event_handler_{ nullptr }; std::unique_ptr keywords_; - skeletons::textbase textbase_; - nana::char_t mask_char_{0}; + skeletons::textbase textbase_; + wchar_t mask_char_{0}; mutable ext_renderer_tag ext_renderer_; @@ -318,7 +318,7 @@ namespace nana{ namespace widgets struct indent_rep { bool enabled{ false }; - std::function generator; + std::function generator; }indent_; struct attributes @@ -326,7 +326,7 @@ namespace nana{ namespace widgets accepts acceptive{ accepts::no_restrict }; std::function pred_acceptive; - nana::string tip_string; + ::std::string tip_string; bool line_wrapped{false}; bool multi_lines{true}; diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index eef80358..7fbd3801 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -1,7 +1,7 @@ /* * Text Token Stream * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2013 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 @@ -42,7 +42,7 @@ namespace nana{ namespace widgets{ namespace skeletons class tokenizer { public: - tokenizer(const nana::string& s, bool format_enabled) + tokenizer(const std::wstring& s, bool format_enabled) : iptr_(s.data()), endptr_(s.data() + s.size()), format_enabled_(format_enabled) @@ -74,12 +74,12 @@ namespace nana{ namespace widgets{ namespace skeletons return _m_token(); } - const nana::string& idstr() const + const ::std::wstring& idstr() const { return idstr_; } - const std::pair& binary() const + const std::pair& binary() const { return binary_; } @@ -108,7 +108,7 @@ namespace nana{ namespace widgets{ namespace skeletons return n; } private: - static bool _m_unicode_word_breakable(nana::char_t ch) + static bool _m_unicode_word_breakable(wchar_t ch) { return ((0x4E00 <= ch) && (ch <= 0x9FFF)); } @@ -116,7 +116,7 @@ namespace nana{ namespace widgets{ namespace skeletons //Read the data token token _m_token() { - nana::char_t ch = *iptr_; + wchar_t ch = *iptr_; if(ch > 0xFF) { @@ -150,7 +150,7 @@ namespace nana{ namespace widgets{ namespace skeletons if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) { - const nana::char_t * idstr = iptr_; + auto idstr = iptr_; do { ch = *(++iptr_); @@ -172,7 +172,7 @@ namespace nana{ namespace widgets{ namespace skeletons { //pos keeps the current position, and it used for restring //iptr_ when the search is failed. - const nana::char_t * pos = ++iptr_; + auto pos = ++iptr_; _m_eat_whitespace(); if(*iptr_ == '/') { @@ -219,7 +219,7 @@ namespace nana{ namespace widgets{ namespace skeletons { _m_eat_whitespace(); - nana::char_t ch = *iptr_++; + auto ch = *iptr_++; switch(ch) { @@ -232,7 +232,7 @@ namespace nana{ namespace widgets{ namespace skeletons case '"': //Here is a string and all the meta characters will be ignored except " { - const nana::char_t * str = iptr_; + auto str = iptr_; while((iptr_ != endptr_) && (*iptr_ != '"')) ++iptr_; @@ -244,7 +244,7 @@ namespace nana{ namespace widgets{ namespace skeletons _m_eat_whitespace(); if((iptr_ < endptr_) && _m_is_idstr_element(*iptr_)) { - const nana::char_t * pbegin = iptr_; + auto pbegin = iptr_; while((iptr_ < endptr_) && _m_is_idstr_element(*iptr_)) ++iptr_; @@ -281,45 +281,45 @@ namespace nana{ namespace widgets{ namespace skeletons //Here is a identifier _m_read_idstr(); - if(STR("font") == idstr_) + if(L"font" == idstr_) return token::font; - else if(STR("bold") == idstr_) + else if(L"bold" == idstr_) return token::bold; - else if(STR("size") == idstr_) + else if(L"size" == idstr_) return token::size; - else if(STR("baseline") == idstr_) + else if(L"baseline" == idstr_) return token::baseline; - else if(STR("top") == idstr_) + else if(L"top" == idstr_) return token::top; - else if(STR("center") == idstr_) + else if(L"center" == idstr_) return token::center; - else if(STR("bottom") == idstr_) + else if(L"bottom" == idstr_) return token::bottom; - else if(STR("color") == idstr_) + else if(L"color" == idstr_) return token::color; - else if(STR("image") == idstr_) + else if(L"image" == idstr_) return token::image; - else if(STR("true") == idstr_) + else if(L"true" == idstr_) return token::_true; - else if(STR("url") == idstr_) + else if(L"url" == idstr_) return token::url; - else if(STR("target") == idstr_) + else if(L"target" == idstr_) return token::target; - else if(STR("false") == idstr_) + else if(L"false" == idstr_) return token::_false; - else if(STR("red") == idstr_) + else if(L"red" == idstr_) return token::red; - else if(STR("green") == idstr_) + else if(L"green" == idstr_) return token::green; - else if(STR("blue") == idstr_) + else if(L"blue" == idstr_) return token::blue; - else if(STR("white") == idstr_) + else if(L"white" == idstr_) return token::white; - else if(STR("black") == idstr_) + else if(L"black" == idstr_) return token::black; - else if(STR("min_limited") == idstr_) + else if(L"min_limited" == idstr_) return token::min_limited; - else if(STR("max_limited") == idstr_) + else if(L"max_limited" == idstr_) return token::max_limited; return token::string; @@ -335,7 +335,7 @@ namespace nana{ namespace widgets{ namespace skeletons return token::eof; } - static bool _m_is_idstr_element(nana::char_t ch) + static bool _m_is_idstr_element(wchar_t ch) { return (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('_' == ch) || ('0' <= ch && ch <= '9')); } @@ -343,9 +343,9 @@ namespace nana{ namespace widgets{ namespace skeletons //Read the identifier. void _m_read_idstr() { - const nana::char_t * idstr = iptr_; + auto idstr = iptr_; - nana::char_t ch; + wchar_t ch; do { ch = *(++iptr_); @@ -360,7 +360,7 @@ namespace nana{ namespace widgets{ namespace skeletons { idstr_.clear(); - nana::char_t ch = *iptr_; + wchar_t ch = *iptr_; idstr_ += ch; @@ -412,13 +412,13 @@ namespace nana{ namespace widgets{ namespace skeletons } } private: - const ::nana::char_t * iptr_; - const ::nana::char_t * endptr_; + const wchar_t * iptr_; + const wchar_t * endptr_; const bool format_enabled_; bool format_state_{false}; - ::nana::string idstr_; - std::pair binary_; + std::wstring idstr_; + std::pair binary_; token revert_token_{token::eof}; }; @@ -434,7 +434,7 @@ namespace nana{ namespace widgets{ namespace skeletons }; }; - ::nana::string font; + ::std::string font; std::size_t font_size; bool bold; bool bold_empty; //bold should be ignored if bold_empty is true @@ -442,8 +442,8 @@ namespace nana{ namespace widgets{ namespace skeletons ::nana::color bgcolor; //If the color is not specified, it will be ignored, and the system will search for its parent. ::nana::color fgcolor; //ditto - ::nana::string target; - ::nana::string url; + ::std::wstring target; + ::std::wstring url; fblock * parent; }; @@ -458,7 +458,7 @@ namespace nana{ namespace widgets{ namespace skeletons virtual bool is_text() const = 0; virtual bool is_whitespace() const = 0; - virtual const nana::string& text() const = 0; + virtual const std::wstring& text() const = 0; virtual void measure(graph_reference) = 0; virtual void nontext_render(graph_reference, int x, int y) = 0; virtual const nana::size & size() const = 0; @@ -470,7 +470,7 @@ namespace nana{ namespace widgets{ namespace skeletons : public data { public: - data_text(const nana::string& s) + data_text(const std::wstring& s) : str_(s) {} private: @@ -484,7 +484,7 @@ namespace nana{ namespace widgets{ namespace skeletons return false; } - virtual const nana::string& text() const override + virtual const std::wstring& text() const override { return str_; } @@ -513,7 +513,7 @@ namespace nana{ namespace widgets{ namespace skeletons return ascent_; } private: - nana::string str_; + std::wstring str_; nana::size size_; std::size_t ascent_; }; @@ -522,7 +522,7 @@ namespace nana{ namespace widgets{ namespace skeletons : public data { public: - data_image(const nana::string& imgpath, const nana::size & sz, std::size_t limited) + data_image(const std::wstring& imgpath, const nana::size & sz, std::size_t limited) : image_(imgpath)//, limited_(limited) { size_ = image_.size(); @@ -562,7 +562,7 @@ namespace nana{ namespace widgets{ namespace skeletons return false; } - virtual const nana::string& text() const override + virtual const std::wstring& text() const override { return str_; } @@ -589,7 +589,7 @@ namespace nana{ namespace widgets{ namespace skeletons return size_.height; } private: - nana::string str_; + std::wstring str_; nana::paint::image image_; nana::size size_; }; @@ -626,7 +626,7 @@ namespace nana{ namespace widgets{ namespace skeletons fblocks_.clear(); } - void parse(const nana::string& s, bool format_enabled) + void parse(const std::wstring& s, bool format_enabled) { close(); @@ -706,7 +706,7 @@ namespace nana{ namespace widgets{ namespace skeletons if(token::string != tknizer.read()) throw std::runtime_error(""); - fp->font = tknizer.idstr(); + fp->font = to_utf8(tknizer.idstr()); break; case token::size: if(token::equal != tknizer.read()) @@ -893,7 +893,7 @@ namespace nana{ namespace widgets{ namespace skeletons return fbp; } - void _m_data_factory(token tk, const nana::string& idstr, fblock* fp, std::deque& line) + void _m_data_factory(token tk, const std::wstring& idstr, fblock* fp, std::deque& line) { value v; v.fblock_ptr = fp; @@ -926,7 +926,7 @@ namespace nana{ namespace widgets{ namespace skeletons struct attr_image_tag { - nana::string path; + std::wstring path; nana::size size; std::size_t limited; diff --git a/include/nana/gui/widgets/skeletons/textbase.hpp b/include/nana/gui/widgets/skeletons/textbase.hpp index 32527879..99cc5799 100644 --- a/include/nana/gui/widgets/skeletons/textbase.hpp +++ b/include/nana/gui/widgets/skeletons/textbase.hpp @@ -1,7 +1,7 @@ /* * A textbase class 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 @@ -57,13 +57,12 @@ namespace skeletons ((text_cont_.size() == 1) && (text_cont_[0].empty()))); } - bool load(const nana::char_t* fs) + bool load(const char* file_utf8) { - if (nullptr == fs) + if (!file_utf8) return false; - std::string fs_mbs = nana::charset(fs); - std::ifstream ifs(fs_mbs.data()); + std::ifstream ifs(to_osmbstr(file_utf8)); if (!ifs) return false; @@ -81,7 +80,7 @@ namespace skeletons if(0xBB == ch && 0xBF == ifs.get()) { ifs.close(); - return load(fs, nana::unicode::utf8); + return load(file_utf8, nana::unicode::utf8); } } else if(0xFF == ch) @@ -94,11 +93,11 @@ namespace skeletons if(ifs.get() == 0 && ifs.get() == 0) { ifs.close(); - return load(fs, nana::unicode::utf32); + return load(file_utf8, nana::unicode::utf32); } } ifs.close(); - return load(fs, nana::unicode::utf16); + return load(file_utf8, nana::unicode::utf16); } } else if(0xFE == ch) @@ -107,7 +106,7 @@ namespace skeletons { //UTF16(big-endian) ifs.close(); - return load(fs, nana::unicode::utf16); + return load(file_utf8, nana::unicode::utf16); } } else if(0 == ch) @@ -119,7 +118,7 @@ namespace skeletons { //UTF32(big_endian) ifs.close(); - return load(fs, nana::unicode::utf32); + return load(file_utf8, nana::unicode::utf32); } } } @@ -143,7 +142,7 @@ namespace skeletons } } - _m_saved(fs); + _m_saved(file_utf8); return true; } @@ -175,13 +174,12 @@ namespace skeletons } } - bool load(const nana::char_t * fs, nana::unicode encoding) + bool load(const char* file_utf8, nana::unicode encoding) { - if (nullptr == fs) + if (!file_utf8) return false; - std::string fs_mbs = nana::charset(fs); - std::ifstream ifs(fs_mbs.data()); + std::ifstream ifs(to_osmbstr(file_utf8)); if (!ifs) return false; @@ -245,14 +243,13 @@ namespace skeletons } } - _m_saved(fs); + _m_saved(file_utf8); return true; } - void store(nana::string fs, bool is_unicode, ::nana::unicode encoding) const + void store(std::string fs, bool is_unicode, ::nana::unicode encoding) const { - std::string fs_mbs = nana::charset(fs); - std::ofstream ofs(fs_mbs.data(), std::ios::binary); + std::ofstream ofs(to_osmbstr(fs), std::ios::binary); if(ofs && text_cont_.size()) { std::string last_mbs; @@ -410,7 +407,9 @@ namespace skeletons { std::deque().swap(text_cont_); attr_max_.reset(); - _m_saved(nana::string()); + text_cont_.emplace_back(); //text_cont_ must not be empty + + _m_saved(std::string()); } void merge(size_type pos) @@ -427,7 +426,7 @@ namespace skeletons } } - const nana::string& filename() const + const std::string& filename() const { return filename_; } @@ -489,7 +488,7 @@ namespace skeletons evt_agent_->first_change(); } - void _m_saved(nana::string && filename) const + void _m_saved(std::string && filename) const { if(filename_ != filename) { @@ -518,7 +517,7 @@ namespace skeletons textbase_event_agent_interface* evt_agent_{ nullptr }; mutable bool changed_{ false }; - mutable nana::string filename_; //A string for the saved filename. + mutable std::string filename_; //A string for the saved filename. const string_type nullstr_; struct attr_max diff --git a/include/nana/gui/widgets/slider.hpp b/include/nana/gui/widgets/slider.hpp index 0e32237d..c5372034 100644 --- a/include/nana/gui/widgets/slider.hpp +++ b/include/nana/gui/widgets/slider.hpp @@ -45,7 +45,7 @@ namespace nana { public: virtual ~provider() = default; - virtual nana::string adorn_trace(unsigned vmax, unsigned vadorn) const = 0; + virtual std::string adorn_trace(unsigned vmax, unsigned vadorn) const = 0; }; class renderer @@ -81,7 +81,7 @@ namespace nana virtual void background(window, graph_reference, bool isglass) = 0; virtual void adorn(window, graph_reference, const adorn_t&) = 0; - virtual void adorn_textbox(window, graph_reference, const nana::string&, const nana::rectangle&) = 0; + virtual void adorn_textbox(window, graph_reference, const ::std::string&, const nana::rectangle&) = 0; virtual void bar(window, graph_reference, const bar_t&) = 0; virtual void slider(window, graph_reference, const slider_t&) = 0; }; diff --git a/include/nana/gui/widgets/spinbox.hpp b/include/nana/gui/widgets/spinbox.hpp index dc081018..e3d28505 100644 --- a/include/nana/gui/widgets/spinbox.hpp +++ b/include/nana/gui/widgets/spinbox.hpp @@ -97,17 +97,17 @@ namespace nana void range(std::initializer_list values); /// Gets the spined value - ::nana::string value() const; - void value(const ::nana::string&); + ::std::string value() const; + void value(const ::std::string&); int to_int() const; double to_double() const; /// Sets the modifiers - void modifier(std::wstring prefix, std::wstring suffix); - void modifier(const std::string & prefix_utf8, const std::string& suffix_utf8); + void modifier(std::string prefix_utf8, std::string suffix_utf8); + void modifier(const std::wstring & prefix, const std::wstring& suffix); private: - ::nana::string _m_caption() const throw(); - void _m_caption(::nana::string&&); + native_string_type _m_caption() const throw(); + void _m_caption(native_string_type&&); }; //end class spinbox }//end namespace nana diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index 8236f639..79ed46f2 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -1,7 +1,7 @@ /** * A Tabbar 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 @@ -144,12 +144,14 @@ namespace nana : public drawer_trigger { public: + using native_string_type = ::nana::detail::native_string_type; + enum class kits { - add, - scroll, - list, - close + add, ///< The type identifies the add button of the tabbar's toolbox. + scroll, ///< The type identifies the scroll button of the tabbar's toolbox + list, ///< The type identifies the list button of the tabbar's toolbox + close ///< The type identifies the close button of the tabbar's toolbox }; trigger(); @@ -161,15 +163,15 @@ namespace nana const pat::cloneable & ext_renderer() const; void ext_renderer(const pat::cloneable&); void set_event_agent(event_agent_interface*); - void insert(std::size_t, nana::string&&, nana::any&&); + void insert(std::size_t, native_string_type&&, nana::any&&); std::size_t length() const; bool close_fly(bool); void attach(std::size_t, window); void erase(std::size_t); void tab_color(std::size_t, bool is_bgcolor, const ::nana::color&); void tab_image(size_t, const nana::paint::image&); - void text(std::size_t, const nana::string&); - nana::string text(std::size_t) const; + void text(std::size_t, const native_string_type&); + native_string_type text(std::size_t) const; bool toolbox(kits, bool); private: void attached(widget_reference, graph_reference) override; @@ -191,30 +193,9 @@ namespace nana { typedef drawerbase::tabbar::trigger drawer_trigger_t; public: - typedef Type value_type; ///< The type of element data which is stored in the tabbar. - typedef drawerbase::tabbar::item_renderer item_renderer; ///< A user-defined item renderer should be derived from this interface. - - //These member types is deprecated, they will be removed in Nana 1.3 - struct button_add{}; ///< The type identifies the add button of the tabbar's toolbox. - struct button_scroll{}; ///< The type identifies the scroll button of the tabbar's toolbox. - struct button_list{}; ///< The type identifies the list button of the tabbar's toolbox. - struct button_close{}; ///< The type identifies the close button of the tabbar's toolbox. - - //This template class is deprecated, it will be removed in 1.3 - /// A template class identifies the buttons of the tabbar's toolbox. Refer to notes for more details. - template - struct button_container - { - typedef meta::fixed_type_set type_set; - }; - - enum class kits - { - add, ///< The type identifies the add button of the tabbar's toolbox. - scroll, ///< The type identifies the scroll button of the tabbar's toolbox - list, ///< The type identifies the list button of the tabbar's toolbox - close ///< The type identifies the close button of the tabbar's toolbox - }; + using value_type = Type; ///< The type of element data which is stored in the tabbar. + using item_renderer = drawerbase::tabbar::item_renderer; ///< A user-defined item renderer should be derived from this interface. + using kits = drawer_trigger_t::kits; tabbar() { @@ -241,7 +222,7 @@ namespace nana value_type & operator[](std::size_t pos) const { - return static_cast(this->get_drawer_trigger().at_no_bound_check(pos)); + return any_cast(this->get_drawer_trigger().at_no_bound_check(pos)); } void activated(std::size_t pos) /// Activates a tab specified by pos. @@ -298,15 +279,19 @@ namespace nana return *this; } - void push_back(nana::string text) /// Append a new item. + void push_back(std::string text) /// Append a new item. { - this->get_drawer_trigger().insert(::nana::npos, std::move(text), value_type()); + this->get_drawer_trigger().insert(::nana::npos, to_nstring(std::move(text)), value_type()); API::update_window(*this); } void insert(std::size_t pos, std::string text, value_type value = {}) { - return this->insert(pos, static_cast(nana::charset(text, nana::unicode::utf8)), std::move(value)); + if (pos > length()) + throw std::out_of_range("tabbar::insert invalid position"); + + this->get_drawer_trigger().insert(pos, to_nstring(text), std::move(value)); + API::update_window(*this); } void insert(std::size_t pos, std::wstring text, value_type value = {}) @@ -314,16 +299,10 @@ namespace nana if (pos > length()) throw std::out_of_range("tabbar::insert invalid position"); - this->get_drawer_trigger().insert(pos, std::move(text), std::move(value)); + this->get_drawer_trigger().insert(pos, to_nstring(text), std::move(value)); API::update_window(*this); } - //deprecated from 1.2.1, removed from 1.3 - void relate(std::size_t pos, window wd) /// Binds a window to an item specified by pos, if the item is selected, shows the window, otherwise, hides it. - { - this->get_drawer_trigger().attach(pos, wd); - } - void attach(std::size_t pos, window attach_wd) { if (attach_wd && API::empty_window(attach_wd)) @@ -351,46 +330,22 @@ namespace nana { this->get_drawer_trigger().tab_image(pos, img); } + /// Sets buttons of the tabbar's toolbox, refer to notes for more details. - template - void toolbox(const button_container&, bool enable) - { - typedef typename button_container::type_set type_set; - auto & tg = this->get_drawer_trigger(); - bool redraw = false; - - using inner_kits = drawerbase::tabbar::trigger::kits; - - if(type_set::template count::value) - redraw |= tg.toolbox(inner_kits::add, enable); - - if(type_set::template count::value) - redraw |= tg.toolbox(inner_kits::scroll, enable); - - if(type_set::template count::value) - redraw |= tg.toolbox(inner_kits::add, enable); - - if(type_set::template count::value) - redraw |= tg.toolbox(inner_kits::close, enable); - - if(redraw) - API::refresh_window(this->handle()); - } - void toolbox(kits kit, bool enable) { if (this->get_drawer_trigger().toolbox(kit, enable)) API::refresh_window(this->handle()); } - void text(std::size_t pos, const nana::string& str) /// Sets the title of the specified item, If pos is invalid, the method throws an std::out_of_range object. + void text(std::size_t pos, const std::string& str) /// Sets the title of the specified item, If pos is invalid, the method throws an std::out_of_range object. { - this->get_drawer_trigger().text(pos, str); + this->get_drawer_trigger().text(pos, to_nstring(str)); } - nana::string text(std::size_t pos) const /// Returns a title of a specified item, If pos is invalid, the method trhows a std::out_of_range object. + std::string text(std::size_t pos) const /// Returns a title of a specified item, If pos is invalid, the method trhows a std::out_of_range object. { - return this->get_drawer_trigger().text(pos); + return to_utf8(this->get_drawer_trigger().text(pos)); } private: std::unique_ptr > evt_agent_; diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index f0d8ff02..69fda830 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -111,13 +111,13 @@ namespace nana /// @param window A handle to the parent window of the widget being created. /// @param text the text that will be displayed. /// @param visible specifying the visible after creating. - textbox(window, const nana::string& text, bool visible = true); + textbox(window, const std::string& text, bool visible = true); /// \brief The construct that creates a widget with a specified text. /// @param window A handle to the parent window of the widget being created. /// @param text the text that will be displayed. /// @param visible specifying the visible after creating. - textbox(window, const nana::char_t* text, bool visible = true); + textbox(window, const char* text, bool visible = true); /// \brief The construct that creates a widget. /// @param window A handle to the parent window of the widget being created. @@ -126,19 +126,19 @@ namespace nana textbox(window, const rectangle& = rectangle(), bool visible = true); /// \brief Loads a text file. When attempt to load a unicode encoded text file, be sure the file have a BOM header. - void load(nana::string file); - void store(nana::string file); - void store(nana::string file, nana::unicode encoding); + void load(std::string file); + void store(std::string file); + void store(std::string file, nana::unicode encoding); /// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter. /// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line. - textbox& indention(bool, std::function generator = {}); + textbox& indention(bool, std::function generator = {}); //A workaround for reset, explicit default constructor syntax, because VC2013 incorrectly treats {} as {0}. - textbox& reset(nana::string = nana::string()); ///< discard the old text and set a new text + textbox& reset(const std::string& = std::string()); ///< discard the old text and set a new text /// The file of last store operation. - nana::string filename() const; + std::string filename() const; /// Determine whether the text was edited. bool edited() const; @@ -150,7 +150,7 @@ namespace nana bool saved() const; /// Read the text from a specified line. It returns true for success. - bool getline(std::size_t pos, nana::string&) const; + bool getline(std::size_t pos, std::string&) const; /// Gets the caret position /// Returns true if the caret is in the area of display, false otherwise. @@ -160,7 +160,7 @@ namespace nana textbox& caret_pos(const upoint&); /// Appends an string. If `at_caret` is `true`, the string is inserted at the position of caret, otherwise, it is appended at end of the textbox. - textbox& append(const nana::string& text, bool at_caret); + textbox& append(const std::string& text, bool at_caret); /// Determine wheter the text is line wrapped. bool line_wrapped() const; @@ -171,12 +171,12 @@ namespace nana textbox& multi_lines(bool); bool editable() const; textbox& editable(bool); - void set_accept(std::function); + void set_accept(std::function); - textbox& tip_string(nana::string); + textbox& tip_string(::std::string); /// Set a mask character. Text is displayed as mask character if a mask character is set. This is used for hiding some special text, such as password. - textbox& mask(nana::char_t); + textbox& mask(wchar_t); /// Returns true if some text is selected. bool selected() const; @@ -195,10 +195,9 @@ namespace nana void set_highlight(const std::string& name, const ::nana::color& fgcolor, const ::nana::color& bgcolor); void erase_highlight(const std::string& name); - void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list kw_list); + void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list kw_list); void set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list kw_list_utf8); - void erase_keyword(const nana::string& kw); - + void erase_keyword(const std::string& kw); /// Returns the text position of each line that currently displays on screen. text_positions text_position() const; @@ -210,8 +209,8 @@ namespace nana unsigned line_pixels() const; protected: //Overrides widget's virtual functions - ::nana::string _m_caption() const throw() override; - void _m_caption(::nana::string&&) override; + native_string_type _m_caption() const throw() override; + void _m_caption(native_string_type&&) override; void _m_typeface(const paint::font&) override; }; }//end namespace nana diff --git a/include/nana/gui/widgets/toolbar.hpp b/include/nana/gui/widgets/toolbar.hpp index 0b097676..8a4d3a40 100644 --- a/include/nana/gui/widgets/toolbar.hpp +++ b/include/nana/gui/widgets/toolbar.hpp @@ -1,7 +1,7 @@ /** * A Toolbar 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 @@ -83,15 +83,22 @@ namespace nana using size_type = std::size_t; ///< A type to count the number of elements. toolbar() = default; - toolbar(window, bool visible); - toolbar(window, const rectangle& = rectangle(), bool visible = true); + toolbar(window, bool visible, bool detached=false); + toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false); void separate(); ///< Adds a separator. - void append(const nana::string& text, const nana::paint::image& img); ///< Adds a control button. - void append(const nana::string& text); ///< Adds a control button. + void append(const ::std::string& text, const nana::paint::image& img); ///< Adds a control button. + void append(const ::std::string& text); ///< Adds a control button. bool enable(size_type index) const; void enable(size_type index, bool enable_state); void scale(unsigned s); ///< Sets the scale of control button. + + void go_right(); + + bool detached() { return detached_; }; + + private: + bool detached_; }; }//end namespace nana #endif diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp index db445daf..f0cc4cd1 100644 --- a/include/nana/gui/widgets/treebox.hpp +++ b/include/nana/gui/widgets/treebox.hpp @@ -1,7 +1,7 @@ /** * A Tree Box 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 @@ -55,7 +55,7 @@ namespace nana nana::paint::image icon_normal; nana::paint::image icon_hover; nana::paint::image icon_expanded; - nana::string text; + ::std::string text; }; typedef widgets::detail::compset compset_interface; @@ -98,14 +98,14 @@ namespace nana struct treebox_node_type { treebox_node_type(); - treebox_node_type(nana::string); + treebox_node_type(std::string); treebox_node_type& operator=(const treebox_node_type&); - nana::string text; + ::std::string text; nana::any value; bool expanded; checkstate checked; - nana::string img_idstr; + ::std::string img_idstr; }; struct pseudo_node_type{}; @@ -133,8 +133,8 @@ namespace nana const ::nana::pat::cloneable& placer() const; nana::any & value(node_type*) const; - node_type* insert(node_type*, const nana::string& key, nana::string&&); - node_type* insert(const nana::string& path, nana::string&&); + node_type* insert(node_type*, const std::string& key, std::string&&); + node_type* insert(const std::string& path, std::string&&); bool verify(const void*) const; bool verify_kinship(node_type* parent, node_type* child) const; @@ -143,16 +143,15 @@ namespace nana node_type * selected() const; void selected(node_type*); void set_expand(node_type*, bool); - void set_expand(const nana::string& path, bool); + void set_expand(const ::std::string& path, bool); - //void image(const nana::string& id, const node_image_tag&); - node_image_tag& icon(const nana::string&) const; - void icon_erase(const nana::string&); - void node_icon(node_type*, const nana::string& id); + node_image_tag& icon(const ::std::string&) const; + void icon_erase(const ::std::string&); + void node_icon(node_type*, const ::std::string& id); unsigned node_width(const node_type*) const; - bool rename(node_type*, const nana::char_t* key, const nana::char_t* name); + bool rename(node_type*, const char* key, const char* name); private: //Overrides drawer_trigger methods void attached(widget_reference, graph_reference) override; @@ -182,11 +181,11 @@ namespace nana item_proxy(trigger*, trigger::node_type*); /// Append a child. - item_proxy append(const nana::string& key, nana::string name); + item_proxy append(const ::std::string& key, ::std::string name); /// Append a child with a specified value (user object.). template - item_proxy append(const nana::string& key, nana::string name, const T&t) + item_proxy append(const ::std::string& key, ::std::string name, const T&t) { item_proxy ip = append(key, std::move(name)); if(false == ip.empty()) @@ -220,22 +219,22 @@ namespace nana item_proxy& select(bool); /// Return the icon. - const nana::string& icon() const; + const ::std::string& icon() const; /// Set the icon, and returns itself.. - item_proxy& icon(const nana::string& id); + item_proxy& icon(const ::std::string& id); /// Return the text. - const nana::string& text() const; - - /// Set a new key, and returns itself.. - item_proxy& key(const nana::string& s); - - /// Return the key. - const nana::string& key() const; + const ::std::string& text() const; /// Set the text, and returns itself. - item_proxy& text(const nana::string&); + item_proxy& text(const ::std::string&); + + /// Set a new key, and returns itself.. + item_proxy& key(const ::std::string& s); + + /// Return the key. + const ::std::string& key() const; std::size_t size() const; ///< Returns the number of child nodes. @@ -257,7 +256,7 @@ namespace nana /// Makes an action for each sub item recursively, returns the item that stops the action where action returns false. item_proxy visit_recursively(std::function action); - bool operator==(const nana::string& s) const; ///< Compare the text of node with s. + bool operator==(const ::std::string& s) const; ///< Compare the text of node with s. bool operator==(const char* s ) const; ///< Compare the text of node with s. bool operator==(const wchar_t* s ) const; ///< Compare the text of node with s. @@ -289,15 +288,15 @@ namespace nana bool operator!=(const item_proxy&) const; template - T * value_ptr() const + const T * value_ptr() const { - return _m_value().get(); + return any_cast(&_m_value()); } template - T& value() const + const T& value() const { - T* p = _m_value().get(); + auto p = any_cast(&_m_value()); if(nullptr == p) throw std::runtime_error("treebox::value() Invalid type of value."); return *p; @@ -428,28 +427,28 @@ namespace nana /// These states are 'normal', 'hovered' and 'expanded'. /// If 'hovered' or 'expanded' are not set, it uses 'normal' state image for these 2 states. /// See also in [documentation](http://nanapro.org/en-us/help/widgets/treebox.htm) - node_image_type& icon(const nana::string& id ///< the name of an icon scheme. If the name is not existing, it creates a new scheme for the name. + node_image_type& icon(const ::std::string& id ///< the name of an icon scheme. If the name is not existing, it creates a new scheme for the name. ) const; - void icon_erase(const nana::string& id); + void icon_erase(const ::std::string& id); - item_proxy find(const nana::string& keypath); ///< Find an item though a specified keypath. + item_proxy find(const ::std::string& keypath); ///< Find an item though a specified keypath. /// Inserts a new node to treebox, but if the keypath exists returns the existing node. - item_proxy insert(const nana::string& path_key, ///< specifies the node hierarchy - nana::string title ///< used for displaying + item_proxy insert(const ::std::string& path_key, ///< specifies the node hierarchy + ::std::string title ///< used for displaying ); /// Inserts a new node to treebox, but if the keypath exists returns the existing node. item_proxy insert( item_proxy pos, ///< the parent item node - const nana::string& key, ///< specifies the new node - nana::string title ///< title used for displaying in the new node. + const ::std::string& key, ///< specifies the new node + ::std::string title ///< title used for displaying in the new node. ); item_proxy erase(item_proxy i); ///< Removes the node at pos and return the Item proxy following the removed node - void erase(const nana::string& keypath); ///< Removes the node by the key path. + void erase(const ::std::string& keypath); ///< Removes the node by the key path. - nana::string make_key_path(item_proxy i, const nana::string& splitter) const;/// void i18n(std::string msgid, Args&&... args) @@ -88,10 +93,10 @@ namespace nana void umake_event(event_handle eh) const; ///< Deletes an event callback by a handle. - widget& register_shortkey(char_t); ///< Registers a shortkey. To remove a registered key, pass 0. + widget& register_shortkey(wchar_t); ///< Registers a shortkey. To remove a registered key, pass 0. widget& take_active(bool activated, window take_if_not_activated); - widget& tooltip(const nana::string&); + widget& tooltip(const ::std::string&); operator dummy_bool_type() const; operator window() const; @@ -105,8 +110,8 @@ namespace nana virtual void _m_complete_creation(); virtual general_events& _m_get_general_events() const = 0; - virtual nana::string _m_caption() const throw(); - virtual void _m_caption(nana::string&&); + virtual native_string_type _m_caption() const throw(); + virtual void _m_caption(native_string_type&&); virtual nana::cursor _m_cursor() const; virtual void _m_cursor(nana::cursor); virtual void _m_close(); diff --git a/include/nana/internationalization.hpp b/include/nana/internationalization.hpp index 341c8e97..3e6c967b 100644 --- a/include/nana/internationalization.hpp +++ b/include/nana/internationalization.hpp @@ -1,7 +1,7 @@ /* * An Implementation of i18n * 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 @@ -28,34 +28,34 @@ namespace nana void load_utf8(const std::string& file); template - nana::string get(std::string msgid_utf8, Args&&... args) const + ::std::string get(std::string msgid_utf8, Args&&... args) const { - std::vector arg_strs; + std::vector arg_strs; _m_fetch_args(arg_strs, std::forward(args)...); - nana::string msgstr; + ::std::string msgstr; if (_m_get(msgid_utf8, msgstr)) _m_replace_args(msgstr, &arg_strs); return msgstr; } - nana::string get(std::string msgid_utf8) const; - void set(std::string msgid_utf8, nana::string msgstr); + ::std::string get(std::string msgid_utf8) const; + void set(std::string msgid_utf8, ::std::string msgstr); template - nana::string operator()(std::string msgid_utf8, Args&&... args) const + ::std::string operator()(std::string msgid_utf8, Args&&... args) const { return get(msgid_utf8, std::forward(args)...); } private: - bool _m_get(std::string& msgid, nana::string& msgstr) const; - void _m_replace_args(nana::string& str, std::vector * arg_strs) const; + bool _m_get(std::string& msgid, ::std::string& msgstr) const; + void _m_replace_args(::std::string& str, std::vector<::std::string> * arg_strs) const; - void _m_fetch_args(std::vector&) const //Termination of _m_fetch_args + void _m_fetch_args(std::vector&) const //Termination of _m_fetch_args {} template - void _m_fetch_args(std::vector& v, Arg&& arg) const + void _m_fetch_args(std::vector& v, Arg&& arg) const { std::wstringstream ss; ss << arg; @@ -63,52 +63,39 @@ namespace nana } template - void _m_fetch_args(std::vector& v, const char* arg, Args&&... args) const + void _m_fetch_args(std::vector& v, const char* arg, Args&&... args) const { - std::wstringstream ss; - ss << nana::string(nana::charset(arg)); - v.emplace_back(ss.str()); - + v.emplace_back(arg); _m_fetch_args(v, std::forward(args)...); } template - void _m_fetch_args(std::vector& v, const std::string& arg, Args&&... args) const + void _m_fetch_args(std::vector& v, const std::string& arg, Args&&... args) const { - std::wstringstream ss; - ss << nana::string(nana::charset(arg)); - v.emplace_back(ss.str()); - + v.emplace_back(arg); _m_fetch_args(v, std::forward(args)...); } template - void _m_fetch_args(std::vector& v, std::string& arg, Args&&... args) const + void _m_fetch_args(std::vector& v, std::string& arg, Args&&... args) const { - std::wstringstream ss; - ss << nana::string(nana::charset(arg)); - v.emplace_back(ss.str()); - + v.emplace_back(arg); _m_fetch_args(v, std::forward(args)...); } template - void _m_fetch_args(std::vector& v, std::string&& arg, Args&&... args) const + void _m_fetch_args(std::vector& v, std::string&& arg, Args&&... args) const { - std::wstringstream ss; - ss << nana::string(nana::charset(arg)); - v.emplace_back(ss.str()); - + v.emplace_back(std::move(arg)); _m_fetch_args(v, std::forward(args)...); } template - void _m_fetch_args(std::vector& v, Arg&& arg, Args&&... args) const + void _m_fetch_args(std::vector& v, Arg&& arg, Args&&... args) const { - std::wstringstream ss; + std::stringstream ss; ss << arg; v.emplace_back(ss.str()); - _m_fetch_args(v, std::forward(args)...); } };//end class internationalization @@ -119,7 +106,7 @@ namespace nana { public: virtual ~eval_arg() = default; - virtual nana::string eval() const = 0; + virtual std::string eval() const = 0; virtual std::unique_ptr clone() const = 0; }; @@ -134,9 +121,9 @@ namespace nana : fn_(fn) {} - nana::string eval() const override + std::string eval() const override { - std::wstringstream ss; + std::stringstream ss; ss << fn_(); return ss.str(); } @@ -166,7 +153,7 @@ namespace nana i18n_eval& operator=(const i18n_eval&); i18n_eval& operator=(i18n_eval&& rhs); - nana::string operator()() const; + std::string operator()() const; private: void _m_fetch_args(){} //Termination of _m_fetch_args @@ -180,7 +167,7 @@ namespace nana template void _m_add_args(Arg&& arg) { - std::wstringstream ss; + std::stringstream ss; ss << arg; _m_add_args(ss.str()); } diff --git a/include/nana/paint/detail/image_impl_interface.hpp b/include/nana/paint/detail/image_impl_interface.hpp index 6cd604fb..4a0a1722 100644 --- a/include/nana/paint/detail/image_impl_interface.hpp +++ b/include/nana/paint/detail/image_impl_interface.hpp @@ -2,6 +2,7 @@ #define NANA_PAINT_DETAIL_IMAGE_IMPL_INTERFACE_HPP #include "../image.hpp" +#include namespace nana{ namespace paint{ @@ -15,7 +16,7 @@ namespace nana{ namespace paint{ public: typedef nana::paint::graphics& graph_reference; virtual ~image_impl_interface() = 0; //The destructor is defined in ../image.cpp - virtual bool open(const nana::char_t* filename) = 0; + virtual bool open(const nana::experimental::filesystem::path& file) = 0; virtual bool open(const void* data, std::size_t bytes) = 0; // reads image from memory virtual bool alpha_channel() const = 0; virtual bool empty() const = 0; diff --git a/include/nana/paint/detail/native_paint_interface.hpp b/include/nana/paint/detail/native_paint_interface.hpp index 4281aca1..4a3dba44 100644 --- a/include/nana/paint/detail/native_paint_interface.hpp +++ b/include/nana/paint/detail/native_paint_interface.hpp @@ -32,9 +32,9 @@ namespace detail void blend(drawable_type dw, const nana::rectangle& r, pixel_color_t, double fade_rate); - nana::size raw_text_extent_size(drawable_type, const nana::char_t*, std::size_t len); - nana::size text_extent_size(drawable_type, const nana::char_t*, std::size_t len); - void draw_string(drawable_type, const nana::point&, const nana::char_t *, std::size_t len); + nana::size raw_text_extent_size(drawable_type, const wchar_t*, std::size_t len); + nana::size text_extent_size(drawable_type, const wchar_t*, std::size_t len); + void draw_string(drawable_type, const nana::point&, const wchar_t *, std::size_t len); }//end namespace detail }//end namespace paint }//end namespace nana diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index a194aa7e..501d30fc 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -36,14 +36,14 @@ namespace nana font(); font(drawable_type); font(const font&); - font(const char_t* name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false); + font(const ::std::string& name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false); ~font(); bool empty() const; - void make(const char_t* name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false); - void make_raw(const char_t*, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out); + void make(const ::std::string& name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false); + void make_raw(const ::std::string& name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out); void set_default() const; - ::nana::string name() const; + ::std::string name() const; unsigned size() const; bool bold() const; unsigned height() const; @@ -89,13 +89,15 @@ namespace nana void resize(const ::nana::size&); void typeface(const font&); ///< Selects a specified font type into the graphics object. font typeface() const; - ::nana::size text_extent_size(const char_t*) const; ///< Computes the width and height of the specified string of text. - ::nana::size text_extent_size(const string&) const; ///< Computes the width and height of the specified string of text. - ::nana::size text_extent_size(const char_t*, std::size_t length) const; ///< Computes the width and height of the specified string of text with the specified length. - ::nana::size text_extent_size(const string&, std::size_t length) const; ///< Computes the width and height of the specified string of text with the specified length. - ::nana::size glyph_extent_size(const char_t*, std::size_t length, std::size_t begin, std::size_t end) const; - ::nana::size glyph_extent_size(const string&, std::size_t length, std::size_t begin, std::size_t end) const; - bool glyph_pixels(const char_t *, std::size_t length, unsigned* pxbuf) const; + ::nana::size text_extent_size(const ::std::string&) const; + ::nana::size text_extent_size(const char*, std::size_t len) const; + ::nana::size text_extent_size(const wchar_t*) const; ///< Computes the width and height of the specified string of text. + ::nana::size text_extent_size(const ::std::wstring&) const; ///< Computes the width and height of the specified string of text. + ::nana::size text_extent_size(const wchar_t*, std::size_t length) const; ///< Computes the width and height of the specified string of text with the specified length. + ::nana::size text_extent_size(const ::std::wstring&, std::size_t length) const; ///< Computes the width and height of the specified string of text with the specified length. + ::nana::size glyph_extent_size(const wchar_t*, std::size_t length, std::size_t begin, std::size_t end) const; + ::nana::size glyph_extent_size(const ::std::wstring&, std::size_t length, std::size_t begin, std::size_t end) const; + bool glyph_pixels(const wchar_t *, std::size_t length, unsigned* pxbuf) const; ::nana::size bidi_extent_size(const std::wstring&) const; ::nana::size bidi_extent_size(const std::string&) const; @@ -136,13 +138,10 @@ namespace nana /// @param file_utf8 A UTF-8 string to a filename void save_as_file(const char* file_utf8) const throw(); - void set_color(const ::nana::color&); //deprecated, graphics::palette() instead - void set_text_color(const ::nana::color&); //deprecated, graphics::palette() instead - ::nana::color palette(bool for_text) const; graphics& palette(bool for_text, const ::nana::color&); - unsigned bidi_string(const nana::point&, const char_t *, std::size_t len); + unsigned bidi_string(const nana::point&, const wchar_t *, std::size_t len); unsigned bidi_string(const point& pos, const char*, std::size_t len); void blend(const ::nana::rectangle& r, const ::nana::color&, double fade_rate); @@ -150,10 +149,13 @@ namespace nana void set_pixel(int x, int y, const ::nana::color&); void set_pixel(int x, int y); - void string(point, const char_t*, std::size_t len); - void string(const point&, const char_t*); - void string(const point&, const ::nana::string&); - void string(const point&, const ::nana::string&, const color&); + void string(const point&, const std::string& text_utf8); + void string(const point&, const std::string& text_utf8, const color&); + + void string(point, const wchar_t*, std::size_t len); + void string(const point&, const wchar_t*); + void string(const point&, const ::std::wstring&); + void string(const point&, const ::std::wstring&, const color&); void line(const point&, const point&); void line(const point&, const point&, const color&); diff --git a/include/nana/paint/image.hpp b/include/nana/paint/image.hpp index b1c237bc..5820ac33 100644 --- a/include/nana/paint/image.hpp +++ b/include/nana/paint/image.hpp @@ -1,7 +1,7 @@ /* * Paint Image 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 @@ -28,24 +28,26 @@ namespace paint public: class image_impl_interface; - image(); + image() noexcept; image(const image&); image(image&&); - image(const nana::char_t* file); - image(const nana::string& filename); + explicit image(const ::std::string& file); + explicit image(const ::std::wstring& file); + ~image(); image& operator=(const image& rhs); image& operator=(image&&); - bool open(const nana::string& filename); + bool open(const ::std::string& file); + bool open(const ::std::wstring& file); /// Opens an icon from a specified buffer - bool open_icon(const void* data, std::size_t bytes); - bool empty() const; + bool open(const void* data, std::size_t bytes); + bool empty() const noexcept; operator unspecified_bool_t() const; - void close(); + void close() noexcept; - bool alpha() const; - nana::size size() const; + bool alpha() const noexcept; + nana::size size() const noexcept; void paste(graphics& dst, const point& p_dst) const; void paste(const nana::rectangle& r_src, graphics& dst, const point& p_dst) const;///< Paste the area of picture specified by r_src into the destination graphics specified by dst at position p_dst. void stretch(const nana::rectangle& r_src, graphics& dst, const nana::rectangle& r_dst) const;/// #include #include #include + namespace nana{ namespace pat{ namespace detail @@ -99,9 +101,9 @@ namespace nana{ namespace pat{ : public std::enable_if<(!std::is_base_of::type>::value) && std::is_base_of::type>::value, int> {}; public: - cloneable() = default; + cloneable() noexcept = default; - cloneable(std::nullptr_t){} + cloneable(std::nullptr_t) noexcept{} template::type* = nullptr> cloneable(T&& t) @@ -166,22 +168,22 @@ namespace nana{ namespace pat{ return *fast_ptr_; } - const_base_ref operator*() const + const_base_ref operator*() const noexcept { return *fast_ptr_; } - base_t * operator->() + base_t * operator->() noexcept { return fast_ptr_; } - const_base_ptr operator->() const + const_base_ptr operator->() const noexcept { return fast_ptr_; } - base_t * get() const + base_t * get() const noexcept { return fast_ptr_; } @@ -192,7 +194,7 @@ namespace nana{ namespace pat{ cwrapper_.reset(); } - operator operator_bool_t() const volatile + operator operator_bool_t() const volatile noexcept { return (fast_ptr_ ? &inner_bool::true_stand : nullptr); } diff --git a/include/nana/std_condition_variable.hpp b/include/nana/std_condition_variable.hpp index 0c9813fc..5e202d9b 100644 --- a/include/nana/std_condition_variable.hpp +++ b/include/nana/std_condition_variable.hpp @@ -3,7 +3,7 @@ #include #if defined(STD_THREAD_NOT_SUPPORTED) -#if defined(USE_github_com_meganz_mingw_std_threads) +#if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #include #else #include @@ -11,6 +11,6 @@ namespace std { typedef boost::condition_variable condition_variable; } -#endif // (USE_github_com_meganz_mingw_std_threads) +#endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #endif // (STD_THREAD_NOT_SUPPORTED) #endif // NANA_STD_CONDITION_VARIABLE_HPP diff --git a/include/nana/std_mutex.hpp b/include/nana/std_mutex.hpp index 5eb6528a..b508548e 100644 --- a/include/nana/std_mutex.hpp +++ b/include/nana/std_mutex.hpp @@ -4,7 +4,7 @@ #if defined(STD_THREAD_NOT_SUPPORTED) -#if defined(USE_github_com_meganz_mingw_std_threads) +#if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #include #include #include @@ -32,6 +32,6 @@ namespace std typedef boost::mutex mutex; typedef boost::recursive_mutex recursive_mutex; } -#endif // (USE_github_com_meganz_mingw_std_threads) +#endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #endif // (STD_THREAD_NOT_SUPPORTED) #endif // NANA_STD_MUTEX_HPP diff --git a/include/nana/std_thread.hpp b/include/nana/std_thread.hpp index 321b3728..f3cf4bc0 100644 --- a/include/nana/std_thread.hpp +++ b/include/nana/std_thread.hpp @@ -4,7 +4,7 @@ #if defined(STD_THREAD_NOT_SUPPORTED) -#if defined(USE_github_com_meganz_mingw_std_threads) +#if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #include #else #include @@ -12,6 +12,6 @@ namespace std { typedef boost::thread thread; } -#endif // (USE_github_com_meganz_mingw_std_threads) +#endif // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) #endif // (STD_THREAD_NOT_SUPPORTED) #endif // NANA_STD_THREAD_HPP diff --git a/include/nana/system/dataexch.hpp b/include/nana/system/dataexch.hpp index ecfe9b22..575a79c3 100644 --- a/include/nana/system/dataexch.hpp +++ b/include/nana/system/dataexch.hpp @@ -1,6 +1,6 @@ /* * Data Exchanger Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -21,22 +21,26 @@ namespace paint{ } namespace system{ - /// a data exchange mechanism through Windows Clipboard, X11 Selection. + + /// a data exchange mechanism through Windows Clipboard, X11 Selection. class dataexch { public: - struct format + enum class format { - enum{ text, unicode, pixmap, end}; + text, pixmap }; - void set(const nana::char_t* text); - void set(const nana::string& text); + void set(const std::string & text_utf8); + void set(const std::wstring& text); + bool set(const nana::paint::graphics& g); - void get(nana::string& str); + + void get(std::string& text_utf8); + void get(std::wstring& text); private: - bool _m_set(unsigned type, const void* buf, std::size_t size); - void* _m_get(unsigned type, size_t& size); + bool _m_set(format, const void* buf, std::size_t size); + void* _m_get(format, size_t& size); }; }//end namespace system diff --git a/include/nana/system/platform.hpp b/include/nana/system/platform.hpp index fd74f757..6a5f4ffd 100644 --- a/include/nana/system/platform.hpp +++ b/include/nana/system/platform.hpp @@ -38,7 +38,7 @@ namespace system bool get_async_mouse_state(int button); //open an url through a default browser - void open_url(const nana::string& url); + void open_url(const std::string& url); }//end namespace system }//end namespace nana diff --git a/include/nana/system/shared_wrapper.hpp b/include/nana/system/shared_wrapper.hpp index 57754a6b..b1737cc2 100644 --- a/include/nana/system/shared_wrapper.hpp +++ b/include/nana/system/shared_wrapper.hpp @@ -1,6 +1,6 @@ /* * Operation System Shared Linkage Library Wrapper Implementation - * Copyright(C) 2003 Jinhao + * Copyright(C) 2003-2016 Jinhao * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -13,7 +13,7 @@ #define NANA_SYSTEM_SHARED_WRAPPER_HPP #include -#include +#include #include @@ -69,7 +69,8 @@ namespace system { typedef typename function_ptr::type fptr_type; - if(nana::traits::is_function_pointer::value == false) + //if(nana::traits::is_function_pointer::value == false) + if (::std::is_function::type>::value == false) throw std::invalid_argument("shared_wrapper::symbols, template<_Function> is not a function type or a function pointer type"); if(symbol == 0) diff --git a/include/nana/threads/pool.hpp b/include/nana/threads/pool.hpp index 410a4b01..16edac1f 100644 --- a/include/nana/threads/pool.hpp +++ b/include/nana/threads/pool.hpp @@ -1,6 +1,6 @@ /* * A Thread Pool Implementation - * Copyright(C) 2003-2013 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 diff --git a/include/nana/traits.hpp b/include/nana/traits.hpp index d1c5c56e..ae27f9ff 100644 --- a/include/nana/traits.hpp +++ b/include/nana/traits.hpp @@ -1,6 +1,6 @@ /* * Traits Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * * @file: nana/traits.hpp */ @@ -13,502 +13,24 @@ namespace nana { class null_type{}; - //The class noncopyable and nonmovable will be deprecated while the compiler - //supports the deleted functions - struct noncopyable + /// Prevent a class to be copyable + class noncopyable { noncopyable(const noncopyable&) = delete; noncopyable& operator=(const noncopyable&) = delete; - noncopyable(); + protected: + noncopyable() = default; }; - struct nonmovable + /// Prevent a class to be movable + class nonmovable { nonmovable(nonmovable&&) = delete; nonmovable& operator=(nonmovable&&) = delete; - nonmovable(); + protected: + nonmovable() = default; }; - namespace traits - { - //traits types for const-volatile specifier - - struct no_specifier{}; - struct const_specifier{}; - struct volatile_specifier{}; - struct const_volatile_specifier{}; - - template - struct cv_specifier - { - typedef no_specifier value_type; - }; - - template - struct cv_specifier - { - typedef const_specifier value_type; - }; - - template - struct cv_specifier - { - typedef volatile_specifier value_type; - }; - - template - struct cv_specifier - { - typedef const_volatile_specifier value_type; - }; - - template - struct is_function_pointer - : public std::integral_constant::value && std::is_function::type>::value> - {}; - - //The traits of pointer to member function - template - struct mfptr_traits - { - typedef void function(); - typedef void return_type; - typedef void concept_type; - enum{parameter = 0}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef return_type function(); - enum{parameter = 0}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef return_type function(); - enum{parameter = 0}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef return_type function(); - enum{parameter = 0}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef return_type function(); - enum{parameter = 0}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P param0_type; - typedef return_type function(param0_type); - enum{parameter = 1}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P param0_type; - typedef return_type function(param0_type); - enum{parameter = 1}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P param0_type; - typedef return_type function(param0_type); - enum{parameter = 1}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef return_type function(param0_type, param1_type); - enum{parameter = 2}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef return_type function(param0_type, param1_type); - enum{parameter = 2}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef return_type function(param0_type, param1_type); - enum{parameter = 2}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef return_type function(param0_type, param1_type, param2_type); - enum{parameter =3}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef return_type function(param0_type, param1_type, param2_type); - enum{parameter =3}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef return_type function(param0_type, param1_type, param2_type); - enum{parameter =3}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef return_type function(param0_type, param1_type, param2_type); - enum{parameter =3}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type); - enum{parameter = 4}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type); - enum{parameter = 4}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type); - enum{parameter = 4}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type); - enum{parameter = 4}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef P4 param4_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type, param4_type); - enum{parameter = 5}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef P4 param4_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type, param4_type); - enum{parameter = 5}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef P4 param4_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type, param4_type); - enum{parameter = 5}; - }; - - template - struct mfptr_traits - { - typedef Concept concept_type; - typedef R return_type; - typedef P0 param0_type; - typedef P1 param1_type; - typedef P2 param2_type; - typedef P3 param3_type; - typedef P4 param4_type; - typedef return_type function(param0_type, param1_type, param2_type, param3_type, param4_type); - enum{parameter = 5}; - }; - - - - template - struct make_mf - { - typedef int type; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(); - }; - - template - struct make_mf - { - typedef R(Concept::*type)() const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)() volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)() const volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0); - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0) const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0) volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0) const volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1); - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1) const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1) volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1) const volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2); - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2) const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2) volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2) const volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3); - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3) const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3) volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3) const volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4); - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4) const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4) volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4) const volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4, P5); - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4, P5) const; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4, P5) volatile; - }; - - template - struct make_mf - { - typedef R(Concept::*type)(P0, P1, P2, P3, P4, P5) const volatile; - }; - }//end namespace traits - namespace meta { template< typename Param0 = null_type, typename Param1 = null_type, diff --git a/include/nana/verbose_preprocessor.hpp b/include/nana/verbose_preprocessor.hpp new file mode 100644 index 00000000..b62267f6 --- /dev/null +++ b/include/nana/verbose_preprocessor.hpp @@ -0,0 +1,56 @@ +/** + * Nana Verbose preprocessor + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file nana/verbose_preprocessor.hpp + * + * @brief show the values of configuration constants during compilation to facilitate build debugging. + * + * Set VERBOSE_PREPROCESSOR to 1 to show the messages or to 0 for a normal build. + * Normally set to 0. Set to 1 only in case you want to debug the build system because it is extremely repetitive and slow. + * + * @authors Ariel Vina-Rodriguez (qPCR4vir) + * + */ +// Created by ariel.rodriguez on 08.12.2015. +// + +#ifndef NANA_VERBOSE_PREPROCESSOR_H +#define NANA_VERBOSE_PREPROCESSOR_H + +#if defined(VERBOSE_PREPROCESSOR) + + #define STRING2(x) #x + #define STRING(x) STRING2(x) + #pragma message ( "\nVerbose preprocessor =" STRING(VERBOSE_PREPROCESSOR)" , \n STOP_VERBOSE_PREPROCESSOR=" STRING(STOP_VERBOSE_PREPROCESSOR) ) + + #pragma message ( "\nWindows: \n _WIN32=" STRING(_WIN32) ", \n __WIN32__ =" STRING(__WIN32__) " , \n WIN32=" STRING(WIN32)" , \n NANA_WINDOWS=" STRING(NANA_WINDOWS) ) + + #pragma message ( "\nUNICODE: \n NANA_UNICODE=" STRING(NANA_UNICODE) ", \n _UNICODE =" STRING(_UNICODE) " , \n UNICODE=" STRING(UNICODE) ) + + #pragma message ( "\nMinGW: \n __MINGW32__=" STRING(__MINGW32__) ", \n __MINGW64__=" STRING(__MINGW64__) " , \n MINGW=" STRING(MINGW) ) + + #pragma message ( "\nGNU: \n __GNUC__=" STRING(__GNUC__) ", \n __GNUC_MINOR__=" STRING(__GNUC_MINOR__) " , \n __GNUC_PATCHLEVEL__=" STRING(__GNUC_PATCHLEVEL__) ) + + #pragma message ( "\nSTD: \nSTD_CODECVT_NOT_SUPPORTED=" STRING(STD_CODECVT_NOT_SUPPORTED) " , \nSTD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) + + #pragma message ( "\nSTD: \nUSE_github_com_meganz_mingw_std_threads=" STRING(USE_github_com_meganz_mingw_std_threads) " , \nSTD_THREAD_NOT_SUPPORTED=" STRING(STD_THREAD_NOT_SUPPORTED) ) + + #pragma message ( "\nClang compiler: \n__clang__=" STRING(__clang__) ", \n__GLIBCPP__=" STRING(__GLIBCPP__) " , \n__GLIBCXX__=" STRING(__GLIBCXX__) ) + + #pragma message ( "\nMSC: \n_MSC_VER=" STRING(_MSC_VER) ", \n_MSC_FULL_VER=" STRING(_MSC_FULL_VER ) ) + + #if defined(STOP_VERBOSE_PREPROCESSOR) + #error ("\nCompilation stopped to avoid annoying messages") + #endif + +#endif // VERBOSE_PREPROCESSOR + + + +#endif //NANA_VERBOSE_PREPROCESSOR_H diff --git a/source/any.cpp b/source/any.cpp index 4858d96b..3a656903 100644 --- a/source/any.cpp +++ b/source/any.cpp @@ -1,70 +1,87 @@ -#include +/** +* Any +* 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/any.cpp +* +* @brief An implementation of experimental library any of C++ standard(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html#any) +*/ +#include +#include namespace nana { + //constructors and destructor + any::any() noexcept + : content_(nullptr) + { + } - //class any - //struct super_type - any::super_type::~super_type(){} - - any::super_type& any::super_type::operator=(const super_type &rhs) - { - return assign(rhs); - } - //end struct super_type + any::any(const any& other) + : content_(other.content_ ? other.content_->clone() : nullptr) + {} - any::any() - :super_(nullptr) - {} - - any::any(const any& rhs) - :super_(rhs.super_ ? rhs.super_->clone() : nullptr) - {} + any::any(any && other) noexcept + : content_(other.content_) + { + other.content_ = nullptr; + } - any::any(any&& r) - :super_(r.super_) - { - r.super_ = nullptr; - } - - any::~any() - { - delete super_; - } - - any& any::operator=(const any& rhs) - { - if(this != &rhs) - { - delete super_; - super_ = (rhs.super_ ? rhs.super_->clone() : nullptr); - } - return *this; - } + any::~any() + { + delete content_; + } - any& any::operator=(any&& r) - { - if(this != &r) - { - delete super_; - super_ = r.super_; - r.super_ = nullptr; - } - return *this; - } + //assignments + any& any::operator=(const any& other) + { + if (this != &other) + any(other).swap(*this); - bool any::same(const any &rhs) const + return *this; + } + + any& any::operator=(any&& other) noexcept + { + if (this != &other) { - if(this != &rhs) - { - if(super_ && rhs.super_) - return super_->same(*rhs.super_); - else if(super_ || rhs.super_) - return false; - } - return true; + other.swap(*this); + other.clear(); } - //end class any + return *this; + } + + //modifiers + void any::clear() noexcept + { + if (content_) + { + auto cnt = content_; + content_ = nullptr; + delete cnt; + } + } + + void any::swap(any& other) noexcept + { + std::swap(content_, other.content_); + } + + //observers + bool any::empty() const noexcept + { + return (nullptr == content_); + } + + const std::type_info& any::type() const noexcept + { + return (content_ ? content_->type() : typeid(void)); + } }//end namespace nana diff --git a/source/audio/detail/audio_device.cpp b/source/audio/detail/audio_device.cpp index c2b1f72d..6ae40f2c 100644 --- a/source/audio/detail/audio_device.cpp +++ b/source/audio/detail/audio_device.cpp @@ -1,4 +1,8 @@ + #include + +#ifdef NANA_ENABLE_AUDIO + #include #if defined(NANA_LINUX) @@ -235,3 +239,5 @@ namespace nana{namespace audio }//end namespace detail }//end namespace audio }//end namespace nana + +#endif //NANA_ENABLE_AUDIO \ No newline at end of file diff --git a/source/audio/detail/audio_stream.cpp b/source/audio/detail/audio_stream.cpp index 902911a0..bcf3a1f9 100644 --- a/source/audio/detail/audio_stream.cpp +++ b/source/audio/detail/audio_stream.cpp @@ -1,4 +1,6 @@ #include +#ifdef NANA_ENABLE_AUDIO + #include namespace nana{ namespace audio @@ -6,9 +8,9 @@ namespace nana{ namespace audio namespace detail { //class audio_stream - bool audio_stream::open(const nana::string& file) + bool audio_stream::open(const std::string& file) { - fs_.open(static_cast(charset(file)), std::ios::binary); + fs_.open(to_osmbstr(file), std::ios::binary); if(fs_) { wave_spec::master_riff_chunk riff; @@ -92,3 +94,4 @@ namespace nana{ namespace audio }//end namespace audio }//end namespace nana +#endif //NANA_ENABLE_AUDIO diff --git a/source/audio/detail/buffer_preparation.cpp b/source/audio/detail/buffer_preparation.cpp index 7c340949..f9f830ff 100644 --- a/source/audio/detail/buffer_preparation.cpp +++ b/source/audio/detail/buffer_preparation.cpp @@ -1,4 +1,7 @@ #include + +#ifdef NANA_ENABLE_AUDIO + #include namespace nana{ namespace audio @@ -159,3 +162,5 @@ namespace nana{ namespace audio }//end namespace detail }//end namespace audio }//end namespace nana + +#endif //NANA_ENABLE_AUDIO \ No newline at end of file diff --git a/source/audio/player.cpp b/source/audio/player.cpp index 5941c073..e86f1798 100644 --- a/source/audio/player.cpp +++ b/source/audio/player.cpp @@ -1,4 +1,7 @@ #include + +#ifdef NANA_ENABLE_AUDIO + #include #include #include @@ -17,7 +20,7 @@ namespace nana{ namespace audio : impl_(new implementation) {} - player::player(const nana::string& file) + player::player(const std::string& file) : impl_(new implementation) { open(file); @@ -28,7 +31,7 @@ namespace nana{ namespace audio delete impl_; } - bool player::open(const nana::string& file) + bool player::open(const std::string& file) { if(impl_->stream.open(file)) { @@ -62,4 +65,6 @@ namespace nana{ namespace audio impl_->stream.close(); } }//end namespace audio -}//end namespace nana \ No newline at end of file +}//end namespace nana + +#endif //NANA_ENABLE_AUDIO \ No newline at end of file diff --git a/source/charset.cpp b/source/charset.cpp index 1b57ad29..ddf7207f 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1,7 +1,7 @@ /* * A Character Encoding Set 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 @@ -11,6 +11,7 @@ * @brief: A conversion between unicode characters and multi bytes characters * @contributions: * UTF16 4-byte decoding issue by Renke Yan. + * Pr0curo(pr#98) */ #include @@ -18,6 +19,7 @@ #include #include #include +#include //Added by Pr0curo(pr#98) //GCC 4.7.0 does not implement the and codecvt_utfx classes #ifndef STD_CODECVT_NOT_SUPPORTED @@ -30,6 +32,183 @@ namespace nana { + namespace utf + { + const char* char_ptr(const char* text, unsigned pos) + { + auto ustr = reinterpret_cast(text); + auto const end = ustr + std::strlen(text); + + for (unsigned i = 0; i != pos; ++i) + { + const auto uch = *ustr; + if (uch < 0x80) + { + ++ustr; + continue; + } + + if (uch < 0xC0) + return nullptr; + + if ((uch < 0xE0) && (ustr + 1 < end)) + ustr += 2; + else if (uch < 0xF0 && (ustr + 2 <= end)) + ustr += 3; + else if (uch < 0x1F && (ustr + 3 <= end)) + ustr += 4; + else + return nullptr; + } + + return reinterpret_cast(ustr); + } + + const char* char_ptr(const std::string& text_utf8, unsigned pos) + { + auto ustr = reinterpret_cast(text_utf8.c_str()); + auto const end = ustr + text_utf8.size(); + + for (unsigned i = 0; i != pos; ++i) + { + const auto uch = *ustr; + if (uch < 0x80) + { + ++ustr; + continue; + } + + if (uch < 0xC0) + return nullptr; + + if ((uch < 0xE0) && (ustr + 1 < end)) + ustr += 2; + else if (uch < 0xF0 && (ustr + 2 <= end)) + ustr += 3; + else if (uch < 0x1F && (ustr + 3 <= end)) + ustr += 4; + else + return nullptr; + } + + return reinterpret_cast(ustr); + } + + wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len) + { + if (!text_utf8) + return 0; + + if (pos) + { + text_utf8 = char_ptr(text_utf8, pos); + if (!text_utf8) + return 0; + } + + const wchar_t uch = *reinterpret_cast(text_utf8); + if (uch < 0x80) + { + if (len) + *len = 1; + + return *text_utf8; + } + + if (uch < 0xC0) + { + if (len) + *len = 0; + + return 0; + } + + const auto end = text_utf8 + std::strlen(text_utf8); + + if (uch < 0xE0 && (text_utf8 + 1 <= end)) + { + if (len) + *len = 2; + return (wchar_t(uch & 0x1F) << 6) | (reinterpret_cast(text_utf8)[1] & 0x3F); + } + else if (uch < 0xF0 && (text_utf8 + 2 <= end)) + { + if (len) + *len = 3; + + return ((((uch & 0xF) << 6) | (reinterpret_cast(text_utf8)[1] & 0x3F)) << 6) | (reinterpret_cast(text_utf8)[2] & 0x3F); + } + else if (uch < 0x1F && (text_utf8 + 3 <= end)) + { + if (len) + *len = 4; + return ((((((uch & 0x7) << 6) | (reinterpret_cast(text_utf8)[1] & 0x3F)) << 6) | (reinterpret_cast(text_utf8)[2] & 0x3F)) << 6) | (reinterpret_cast(text_utf8)[3] & 0x3F); + } + + if (len) + *len = 0; + + return 0; + } + + wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len) + { + const char* ptr; + if (pos) + { + ptr = char_ptr(text_utf8, pos); + if (!ptr) + return 0; + } + else + ptr = text_utf8.c_str(); + + const wchar_t uch = *reinterpret_cast(ptr); + if (uch < 0x80) + { + if (len) + *len = 1; + + return *ptr; + } + + if (uch < 0xC0) + { + if (len) + *len = 0; + + return 0; + } + + const auto end = text_utf8.c_str() + text_utf8.size(); + + if (uch < 0xE0 && (ptr + 1 <= end)) + { + if (len) + *len = 2; + return (wchar_t(uch & 0x1F) << 6) | (reinterpret_cast(ptr)[1] & 0x3F); + } + else if (uch < 0xF0 && (ptr + 2 <= end)) + { + if (len) + *len = 3; + + return ((((uch & 0xF) << 6) | (reinterpret_cast(ptr)[1] & 0x3F)) << 6) | (reinterpret_cast(ptr)[2] & 0x3F); + } + else if (uch < 0x1F && (ptr + 3 <= end)) + { + if (len) + *len = 4; + return ((((((uch & 0x7) << 6) | (reinterpret_cast(ptr)[1] & 0x3F)) << 6) | (reinterpret_cast(ptr)[2] & 0x3F)) << 6) | (reinterpret_cast(ptr)[3] & 0x3F); + } + + if (len) + *len = 0; + + return 0; + } + } + namespace detail { class locale_initializer diff --git a/source/deploy.cpp b/source/deploy.cpp index ce92982a..3592a3bf 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -14,6 +14,7 @@ #include #include +#include //std::strlen #include #if defined(NANA_WINDOWS) @@ -298,6 +299,7 @@ namespace std #endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED #ifdef STD_TO_STRING_NOT_SUPPORTED +#include namespace std { std::string to_string(double v) @@ -362,7 +364,13 @@ namespace std ss << v; return ss.str(); } +} +#endif // STD_TO_STRING_NOT_SUPPORTED +#ifdef STD_TO_WSTRING_NOT_SUPPORTED +#include +namespace std +{ std::wstring to_wstring(double v) { std::wstringstream ss; @@ -430,46 +438,164 @@ namespace std namespace nana { - std::size_t strlen(const char_t* str) + bool is_utf8(const char* str, unsigned len) { -#if defined(NANA_UNICODE) - return ::wcslen(str); -#else - return ::strlen(str); -#endif - } + auto ustr = reinterpret_cast(str); + auto end = ustr + len; - char_t* strcpy(char_t* dest, const char_t* source) - { -#if defined(NANA_UNICODE) - return ::wcscpy(dest, source); -#else - return ::strcpy(dest, source); -#endif - } -} - -namespace nana -{ - bool is_incomplete(const nana::string& str, unsigned pos) - { -#ifndef NANA_UNICODE - if(pos > str.size()) - pos = static_cast(str.size()); - const nana::char_t * pstr = str.c_str(); - if(pstr[pos] < 0) + while (ustr < end) { - bool incomp = false; - for(unsigned i = 0; i < pos; ++i) + const auto uv = *ustr; + if (uv < 0x80) { - if(pstr[i] < 0) - incomp = !incomp; - else - incomp = false; + ++ustr; + continue; } - return incomp; + + if (uv < 0xC0) + return false; + + if ((uv < 0xE0) && (ustr + 1 < end)) + ustr += 2; + else if (uv < 0xF0 && (ustr + 2 <= end)) + ustr += 3; + else if (uv < 0x1F && (ustr + 3 <= end)) + ustr += 4; + else + return false; } -#endif - return false; + + return true; } + + 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"); + } + + void throw_not_utf8(const char* text, unsigned len) + { + if (!is_utf8(text, len)) + 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"); + + } + + const std::string& to_utf8(const std::string& str) + { + return str; + } + + std::string to_utf8(const std::wstring& text) + { + return ::nana::charset(text).to_bytes(::nana::unicode::utf8); + } + + std::wstring to_wstring(const std::string& utf8_str) + { + return ::nana::charset(utf8_str, ::nana::unicode::utf8); + } + + const std::wstring& to_wstring(const std::wstring& wstr) + { + return wstr; + } + + std::wstring&& to_wstring(std::wstring&& wstr) + { + return static_cast(wstr); + } + +#if defined(NANA_WINDOWS) + std::string to_osmbstr(const std::string& text_utf8) + { + return ::nana::charset(text_utf8, ::nana::unicode::utf8); + } +#else + std::string to_osmbstr(std::string text_utf8) + { + return text_utf8; + } +#endif + +#if defined(NANA_WINDOWS) + const detail::native_string_type to_nstring(const std::string& text) + { + return ::nana::charset(text, ::nana::unicode::utf8); + } + + const detail::native_string_type& to_nstring(const std::wstring& text) + { + return text; + } + + detail::native_string_type to_nstring(std::string&& text) + { + return ::nana::charset(text, ::nana::unicode::utf8); + } + + detail::native_string_type&& to_nstring(std::wstring&& text) + { + return std::move(text); + } + + detail::native_string_type to_nstring(int n) + { + return std::to_wstring(n); + } + + detail::native_string_type to_nstring(double d) + { + return std::to_wstring(d); + } + + detail::native_string_type to_nstring(std::size_t d) + { + return std::to_wstring(d); + } +#else //POSIX + const detail::native_string_type& to_nstring(const std::string& text) + { + return text; + } + + const detail::native_string_type to_nstring(const std::wstring& text) + { + return ::nana::charset(text).to_bytes(::nana::unicode::utf8); + } + + detail::native_string_type&& to_nstring(std::string&& text) + { + return std::move(text); + } + + detail::native_string_type to_nstring(std::wstring&& text) + { + return ::nana::charset(text).to_bytes(::nana::unicode::utf8); + } + + detail::native_string_type to_nstring(int n) + { + return std::to_string(n); + } + + detail::native_string_type to_nstring(double d) + { + return std::to_string(d); + } + + detail::native_string_type to_nstring(std::size_t d) + { + return std::to_string(d); + } +#endif + + } + diff --git a/source/detail/platform_spec_posix.cpp b/source/detail/platform_spec_posix.cpp index 33d81a75..9713a0c9 100644 --- a/source/detail/platform_spec_posix.cpp +++ b/source/detail/platform_spec_posix.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 Nana Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -36,7 +36,7 @@ namespace nana namespace detail { typedef native_window_type native_window_type; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) //class conf conf::conf(const char * file) { @@ -290,7 +290,7 @@ namespace detail string.tab_length = 4; string.tab_pixels = 0; string.whitespace_pixels = 0; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) conv_.handle = ::iconv_open("UTF-8", "UTF-32"); conv_.code = "UTF-32"; #endif @@ -298,7 +298,7 @@ namespace detail drawable_impl_type::~drawable_impl_type() { -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) ::iconv_close(conv_.handle); #endif } @@ -366,7 +366,7 @@ namespace detail ::XSetForeground(spec.open_display(), context, col); ::XSetBackground(spec.open_display(), context, col); -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) xft_fgcolor.color.red = ((0xFF0000 & col) >> 16) * 0x101; xft_fgcolor.color.green = ((0xFF00 & col) >> 8) * 0x101; xft_fgcolor.color.blue = (0xFF & col) * 0x101; @@ -395,7 +395,7 @@ namespace detail } ::XSetForeground(spec.open_display(), context, rgb); ::XSetBackground(spec.open_display(), context, rgb); -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) xft_fgcolor.color.red = ((0xFF0000 & rgb) >> 16) * 0x101; xft_fgcolor.color.green = ((0xFF00 & rgb) >> 8) * 0x101; xft_fgcolor.color.blue = (0xFF & rgb) * 0x101; @@ -412,7 +412,7 @@ namespace detail if(fp && fp->handle) { platform_scope_guard psg; -#if defined(NANA_UNICODE) +#if defined(NANA_USE_XFT) ::XftFontClose(nana::detail::platform_spec::instance().open_display(), fp->handle); #else ::XFreeFontSet(nana::detail::platform_spec::instance().open_display(), fp->handle); @@ -515,7 +515,7 @@ namespace detail atombase_.xdnd_finished = ::XInternAtom(display_, "XdndFinished", False); //Create default font object. - def_font_ptr_ = make_native_font(0, font_size_to_height(10), 400, false, false, false); + def_font_ptr_ = make_native_font(nullptr, font_size_to_height(10), 400, false, false, false); msg_dispatcher_ = new msg_dispatcher(display_); } @@ -550,17 +550,16 @@ namespace detail return height; } - platform_spec::font_ptr_t platform_spec::make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out) + platform_spec::font_ptr_t platform_spec::make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out) { font_ptr_t ref; -#if defined(NANA_UNICODE) +#if 1 //Xft if(0 == name || *name == 0) - name = STR("*"); + name = "*"; - std::string nmstr = nana::charset(name); XftFont* handle = 0; std::stringstream ss; - ss< * files = new std::vector; + auto files = new std::vector; std::stringstream ss(reinterpret_cast(data)); while(true) { @@ -1235,7 +1234,7 @@ namespace detail break; } - files->push_back(nana::charset(file)); + files->push_back(file); } if(files->size()) { @@ -1244,6 +1243,8 @@ namespace detail msg.u.mouse_drop.y = self.xdnd_.pos.y; msg.u.mouse_drop.files = files; } + else + delete files; accepted = true; ::XFree(data); diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 0323dfc1..88317ede 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -158,7 +158,7 @@ namespace detail //class platform_spec platform_spec::co_initializer::co_initializer() - : ole32_(::LoadLibrary(STR("OLE32.DLL"))) + : ole32_(::LoadLibrary(L"OLE32.DLL")) { if(ole32_) { @@ -207,7 +207,7 @@ namespace detail #endif #endif ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0); - def_font_ptr_ = make_native_font(metrics.lfMessageFont.lfFaceName, font_size_to_height(9), 400, false, false, false); + def_font_ptr_ = make_native_font(to_utf8(metrics.lfMessageFont.lfFaceName).c_str(), font_size_to_height(9), 400, false, false, false); } const platform_spec::font_ptr_t& platform_spec::default_native_font() const @@ -238,12 +238,15 @@ namespace detail return height; } - platform_spec::font_ptr_t platform_spec::make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out) + platform_spec::font_ptr_t platform_spec::make_native_font(const char* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out) { ::LOGFONT logfont; memset(&logfont, 0, sizeof logfont); - strcpy(logfont.lfFaceName, (name && *name ? name : def_font_ptr_->name.c_str())); + if (name && *name) + std::wcscpy(logfont.lfFaceName, to_wstring(name).c_str()); + else + std::wcscpy(logfont.lfFaceName, def_font_ptr_->name.c_str()); logfont.lfCharSet = DEFAULT_CHARSET; HDC hdc = ::GetDC(0); diff --git a/source/filesystem/file_iterator.cpp b/source/filesystem/file_iterator.cpp deleted file mode 100644 index 8880f77d..00000000 --- a/source/filesystem/file_iterator.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * A File Iterator Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)(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/file_iterator.cpp - * @description: - * file_iterator is a toolkit for applying each file and directory in a - * specified path. - */ - -#include - -namespace nana -{ -namespace filesystem -{ - //struct fileinfo - fileinfo::fileinfo() - :size(0), directory(false) - {} -#if defined(NANA_WINDOWS) - fileinfo::fileinfo(const WIN32_FIND_DATA& wfd) - : name(wfd.cFileName), size(wfd.nFileSizeLow), - directory((FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY) - { - } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - fileinfo::fileinfo(const nana::string& name, const struct stat& fst) - :name(name), size(fst.st_size), directory(0 != S_ISDIR(fst.st_mode)) - { - } -#endif - //end struct fileinfo - -}//end namespace filesystem -}//end namespace nana - diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index f83647af..59c848cf 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -1,6 +1,6 @@ /* * A ISO C++ FileSystem Implementation - * 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 @@ -24,7 +24,7 @@ #include #include -#elif defined(NANA_LINUX) || defined(NANA_MACOS) +#elif defined(NANA_POSIX) #include #include #include @@ -36,418 +36,821 @@ #include #endif -namespace nana { - namespace experimental + +namespace nana { namespace experimental { + namespace filesystem { - namespace filesystem - { - //Because of No wide character version of POSIX + //class filesystem_error + filesystem_error::filesystem_error(const std::string& msg, std::error_code err) + : std::system_error(err, msg) + {} + + filesystem_error::filesystem_error(const std::string& msg, const path& path1, std::error_code err) + : std::system_error(err, msg), + path1_(path1) + {} + + filesystem_error::filesystem_error(const std::string& msg, const path& path1, const path& path2, std::error_code err) + : std::system_error(err, msg), + path1_(path1), + path2_(path2) + {} + + const path& filesystem_error::path1() const + { + return path1_; + } + + const path&filesystem_error::path2() const + { + return path2_; + } + //end class filesystem_error + + + //Because of No wide character version of POSIX #if defined(NANA_LINUX) || defined(NANA_MACOS) - typedef std::string string_t; - const char* splstr = "/\\"; + const char* splstr = "/"; #else - typedef nana::string string_t; - const nana::char_t* splstr = STR("/\\"); + const wchar_t* splstr = L"/\\"; #endif - //class path - path::path() {} - path::path(const nana::string& text) + //class file_status + file_status::file_status(file_type ft, perms prms) + : value_{ft}, perms_{prms} + {} + + file_type file_status::type() const + { + return value_; + } + + void file_status::type(file_type ft) + { + value_ = ft; + } + + perms file_status::permissions() const + { + return perms_; + } + + void file_status::permissions(perms prms) + { + perms_ = prms; + } + //end filestatus + + //class path + int path::compare(const path& p) const + { + return pathstr_.compare(p.pathstr_); + } + + bool path::empty() const + { #if defined(NANA_WINDOWS) - : text_(text) - { + return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES); +#elif defined(NANA_LINUX) || defined(NANA_MACOS) + struct stat sta; + return (::stat(pathstr_.c_str(), &sta) == -1); +#endif + } + + path path::extension() const + { +#if defined(NANA_WINDOWS) + auto pos = pathstr_.find_last_of(L"\\/."); #else - :text_(nana::charset(text)) - { + auto pos = pathstr_.find_last_of("\\/."); #endif - auto pos = text_.find_last_of(splstr); - for (; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr)) - text_.erase(pos); - } + if ((pos == pathstr_.npos) || (pathstr_[pos] != '.')) + return path(); - bool path::empty() const - { + + if (pos + 1 == pathstr_.size()) + return path(); + + return path(pathstr_.substr(pos)); + } + + path path::parent_path() const + { + return{filesystem::parent_path(pathstr_)}; + } + + file_type path::what() const + { #if defined(NANA_WINDOWS) - return (::GetFileAttributes(text_.c_str()) == INVALID_FILE_ATTRIBUTES); + unsigned long attr = ::GetFileAttributes(pathstr_.c_str()); + if (INVALID_FILE_ATTRIBUTES == attr) + return file_type::not_found; //?? + + if (FILE_ATTRIBUTE_DIRECTORY & attr) + return file_type::directory; + + return file_type::regular; #elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat sta; - return (::stat(text_.c_str(), &sta) == -1); -#endif - } + struct stat sta; + if (-1 == ::stat(pathstr_.c_str(), &sta)) + return file_type::not_found; //?? - path path::root() const - { -#if defined(NANA_WINDOWS) - return path(filesystem::root(text_)); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - return path(filesystem::root(nana::charset(text_))); -#endif - } - - file_type path::what() const - { -#if defined(NANA_WINDOWS) - unsigned long attr = ::GetFileAttributes(text_.c_str()); - if (INVALID_FILE_ATTRIBUTES == attr) - return file_type::not_found; //?? - - if (FILE_ATTRIBUTE_DIRECTORY & attr) - return file_type::directory; + if ((S_IFDIR & sta.st_mode) == S_IFDIR) + return file_type::directory; + if ((S_IFREG & sta.st_mode) == S_IFREG) return file_type::regular; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat sta; - if (-1 == ::stat(text_.c_str(), &sta)) - return file_type::not_found; //?? - if ((S_IFDIR & sta.st_mode) == S_IFDIR) - return file_type::directory; - - if ((S_IFREG & sta.st_mode) == S_IFREG) - return file_type::regular; - - return file_type::none; + return file_type::none; #endif - } + } - nana::string path::filename() const + path path::filename() const + { + auto pos = pathstr_.find_last_of(splstr); + if (pos != pathstr_.npos) { - string_t::size_type pos = text_.find_last_of(splstr); -#if defined(NANA_WINDOWS) - return text_.substr(pos + 1); -#else - return nana::charset(text_.substr(pos + 1)); -#endif - } - //end class path - - namespace detail - { - //rm_dir_recursive - //@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories - bool rm_dir_recursive(nana::string&& dir) + if (pos + 1 == pathstr_.size()) { - std::vector files; - nana::string path = dir; - path += '\\'; + value_type tmp[2] = {preferred_separator, 0}; - std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files)); + if (pathstr_.npos != pathstr_.find_last_not_of(splstr, pos)) + tmp[0] = '.'; - for (auto & f : files) + return{ tmp }; + } + return{ pathstr_.substr(pos + 1) }; + } + + return{ pathstr_ }; + } + + path& path::remove_filename() + { +#ifdef NANA_WINDOWS + wchar_t seps[] = L"/\\"; +#else + char seps[] = "/\\"; +#endif + auto pos = pathstr_.find_last_of(seps); + if (pos != pathstr_.npos) + { + pos = pathstr_.find_last_not_of(seps, pos); + if (pos != pathstr_.npos) + { +#ifdef NANA_WINDOWS + if (pathstr_[pos] == L':') { - if (f.attr.directory) - rm_dir_recursive(path + f.path().filename()); - else - rmfile((path + f.path().filename()).c_str()); - } + pathstr_.erase(pos + 1); + pathstr_ += L'\\'; - return rmdir(dir.c_str(), true); + return *this; + } +#endif + ++pos; + } + else + pos = 0; + } + else + pos = 0; + + pathstr_.erase(pos); + + return *this; + } + + const path::value_type* path::c_str() const + { + return native().c_str(); + } + + const path::string_type& path::native() const + { + return pathstr_; + } + + path::operator string_type() const + { + return native(); + } + + std::string path::string() const + { + return to_osmbstr(to_utf8(pathstr_)); + } + + std::wstring path::wstring() const + { + return to_wstring(pathstr_); + } + + std::string path::u8string() const + { + return to_utf8(pathstr_); + } + + path & path::operator/=(const path& p) + { + if (p.empty()) + return *this; + + if (this == &p) + { + auto other = p.pathstr_; + if ((other.front() != '/') && (other.front() == path::preferred_separator)) + { + if (!this->pathstr_.empty() && (pathstr_.back() != '/' && pathstr_.back() == path::preferred_separator)) + pathstr_.append(path::preferred_separator, 1); } - bool mkdir_helper(const nana::string& dir, bool & if_exist) + pathstr_ += other; + } + else + { + auto & other = p.pathstr_; + if ((other.front() != '/') && (other.front() == path::preferred_separator)) + { + if (!this->pathstr_.empty() && (pathstr_.back() != '/' && pathstr_.back() == path::preferred_separator)) + pathstr_.append(path::preferred_separator, 1); + } + + pathstr_ += p.pathstr_; + } + return *this; + } + + void path::_m_assign(const std::string& source_utf8) + { + pathstr_ = to_nstring(source_utf8); + } + + void path::_m_assign(const std::wstring& source) + { + pathstr_ = to_nstring(source); + } + //end class path + + bool operator==(const path& lhs, const path& rhs) + { + return (lhs.compare(rhs) == 0); + } + + bool operator!=(const path& lhs, const path& rhs) + { + return (lhs.native() != rhs.native()); + } + + bool operator<(const path& lhs, const path& rhs) + { + return (lhs.compare(rhs) < 0); + } + + bool operator>(const path& lhs, const path& rhs) + { + return (rhs.compare(lhs) < 0); + } + + path operator/(const path& lhs, const path& rhs) + { + auto path = lhs; + return (path /= rhs); + } + + //class directory_entry + directory_entry::directory_entry(const filesystem::path& p) + :path_{ p } + {} + + //modifiers + void directory_entry::assign(const filesystem::path& p) + { + path_ = p; + } + + void directory_entry::replace_filename(const filesystem::path& p) + { + path_ = path_.parent_path() / p; + } + + //observers + file_status directory_entry::status() const + { + return filesystem::status(path_); + } + + directory_entry::operator const filesystem::path&() const + { + return path_; + } + + const path& directory_entry::path() const + { + return path_; + } + //end class directory_entry + + + //class directory_iterator + struct inner_handle_deleter + { + void operator()(void** handle) { #if defined(NANA_WINDOWS) - if (::CreateDirectory(dir.c_str(), 0)) - { - if_exist = false; - return true; - } - - if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS); + ::FindClose(*handle); #elif defined(NANA_LINUX) || defined(NANA_MACOS) - if (0 == ::mkdir(static_cast(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) + ::closedir(*reinterpret_cast(handle)); +#endif + } + }; + + directory_iterator::directory_iterator() + : end_(true), + handle_(nullptr) + {} + + directory_iterator::directory_iterator(const path& file_path) + { + _m_prepare(file_path); + } + + const directory_iterator::value_type& directory_iterator::operator*() const { return value_; } + + const directory_iterator::value_type* + directory_iterator::operator->() const { return &(operator*()); } + + directory_iterator& directory_iterator::operator++() + { + _m_read(); return *this; + } + + directory_iterator directory_iterator::operator++(int) + { + directory_iterator tmp = *this; + _m_read(); + return tmp; + } + + bool directory_iterator::equal(const directory_iterator& x) const + { + if (end_ && (end_ == x.end_)) return true; + 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(); +#if defined(NANA_WINDOWS) + if (!path_.empty() && (path_.back() != L'/' && path_.back() != L'\\')) + path_ += L'\\'; + + auto pat = path_; + DWORD attr = ::GetFileAttributes(pat.data()); + if ((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY)) + pat += L"*"; + + WIN32_FIND_DATAW wfd; + ::HANDLE handle = ::FindFirstFile(pat.data(), &wfd); + + if (handle == INVALID_HANDLE_VALUE) { - if_exist = false; - return true; + end_ = true; + return; } - if_exist = (errno == EEXIST); + while (_m_ignore(wfd.cFileName)) + { + if (::FindNextFile(handle, &wfd) == 0) + { + end_ = true; + ::FindClose(handle); + return; + } + } + + value_ = value_type(path(path_ + wfd.cFileName)); + +#elif defined(NANA_POSIX) + if (path_.size() && (path_.back() != '/')) + path_ += '/'; + auto handle = opendir(path_.c_str()); + end_ = true; + if (handle) + { + struct dirent * dnt = readdir(handle); + if (dnt) + { + while (_m_ignore(dnt->d_name)) + { + dnt = readdir(handle); + if (dnt == 0) + { + closedir(handle); + return; + } + } + + value_ = value_type(path_ + dnt->d_name); + end_ = false; + } + } #endif + if (false == end_) + { + find_ptr_ = std::shared_ptr(new find_handle(handle), inner_handle_deleter()); + handle_ = handle; + } + } + + void directory_iterator::_m_read() + { + if (handle_) + { +#if defined(NANA_WINDOWS) + WIN32_FIND_DATAW wfd; + if (::FindNextFile(handle_, &wfd) != 0) + { + while (_m_ignore(wfd.cFileName)) + { + if (::FindNextFile(handle_, &wfd) == 0) + { + end_ = true; + return; + } + } + value_ = value_type(path(path_ + wfd.cFileName)); + } + else + end_ = true; +#elif defined(NANA_POSIX) + struct dirent * dnt = readdir(reinterpret_cast(handle_)); + if (dnt) + { + while (_m_ignore(dnt->d_name)) + { + dnt = readdir(reinterpret_cast(handle_)); + if (!dnt) + { + end_ = true; + return; + } + } + + value_ = value_type(path(path_ + dnt->d_name)); + } + else + end_ = true; +#endif + } + } + //end class directory_iterator + + bool not_found_error(int errval) + { +#if defined(NANA_WINDOWS) + switch (errval) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_INVALID_NAME: + case ERROR_INVALID_DRIVE: + case ERROR_NOT_READY: + case ERROR_INVALID_PARAMETER: + case ERROR_BAD_PATHNAME: + case ERROR_BAD_NETPATH: + return true; + } + return false; +#elif defined(NANA_POSIX) + return (errval == ENOENT || errval == ENOTDIR); +#else + static_assert(false, "Only Windows and Unix are supported now (Mac OS is experimental)"); +#endif + } + + namespace detail + { + bool rm_file(const path& p) + { + if (p.empty()) + return false; +#if defined(NANA_WINDOWS) + return (FALSE != ::DeleteFileW(p.c_str())); +#elif defined(NANA_POSIX) + return (!std::remove(p.c_str())); +#endif + } + + bool rm_dir(const path& p) + { +#if defined(NANA_WINDOWS) + return (FALSE != ::RemoveDirectoryW(p.c_str())) || not_found_error(static_cast(::GetLastError())); +#elif defined(NANA_POSIX) + return (!::rmdir(p.c_str())) || not_found_error(errno); +#endif + } + + bool rm_dir(const path& p, bool fails_if_not_empty); + + //rm_dir_recursive + //@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories + template + bool rm_dir_recursive(const CharT* dir) + { + std::vector files; + std::basic_string path = dir; + path += '\\'; + + std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files)); + + for (auto & f : files) + { + auto subpath = path + f.path().filename().native(); + + if (is_directory(f)) + rm_dir_recursive(subpath.c_str()); + else + rm_file(subpath.c_str()); + } + return rm_dir(dir, true); + } + + bool rm_dir(const path& p, bool fails_if_not_empty) + { + if (p.empty()) + return false; + +#if defined(NANA_WINDOWS) + if (FALSE != ::RemoveDirectoryW(p.c_str())) + return true; + + if (!fails_if_not_empty && (ERROR_DIR_NOT_EMPTY == ::GetLastError())) + return detail::rm_dir_recursive(p.c_str()); + + return false; +#elif defined(NANA_POSIX) + if (::rmdir(p.c_str())) + { + if (!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY)) + return detail::rm_dir_recursive(p.c_str()); + return false; } - -#if defined(NANA_WINDOWS) - void filetime_to_c_tm(FILETIME& ft, struct tm& t) - { - FILETIME local_file_time; - if (::FileTimeToLocalFileTime(&ft, &local_file_time)) - { - SYSTEMTIME st; - ::FileTimeToSystemTime(&local_file_time, &st); - t.tm_year = st.wYear - 1900; - t.tm_mon = st.wMonth - 1; - t.tm_mday = st.wDay; - t.tm_wday = st.wDayOfWeek - 1; - t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); - - t.tm_hour = st.wHour; - t.tm_min = st.wMinute; - t.tm_sec = st.wSecond; - } - } -#endif - }//end namespace detail - - bool file_attrib(const nana::string& file, attribute& attr) - { -#if defined(NANA_WINDOWS) - WIN32_FILE_ATTRIBUTE_DATA fad; - if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad)) - { - LARGE_INTEGER li; - li.u.LowPart = fad.nFileSizeLow; - li.u.HighPart = fad.nFileSizeHigh; - attr.size = li.QuadPart; - attr.directory = (0 != (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); - detail::filetime_to_c_tm(fad.ftLastWriteTime, attr.modified); - return true; - } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat fst; - if (0 == ::stat(static_cast(nana::charset(file)).c_str(), &fst)) - { - attr.size = fst.st_size; - attr.directory = (0 != (040000 & fst.st_mode)); - attr.modified = *(::localtime(&fst.st_ctime)); - return true; - } -#endif - return false; - } - - uintmax_t file_size(const nana::string& file) - { -#if defined(NANA_WINDOWS) - //Some compilation environment may fail to link to GetFileSizeEx - typedef BOOL(__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER); - GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx")); - if (get_file_size_ex) - { - HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (INVALID_HANDLE_VALUE != handle) - { - LARGE_INTEGER li; - if (!get_file_size_ex(handle, &li)) - li.QuadPart = 0; - - ::CloseHandle(handle); - return li.QuadPart; - } - } - return 0; -#elif defined(NANA_LINUX) - FILE * stream = ::fopen(static_cast(nana::charset(file)).c_str(), "rb"); - long long size = 0; - if (stream) - { - fseeko64(stream, 0, SEEK_END); - size = ftello64(stream); - fclose(stream); - } - return size; -#elif defined(NANA_MACOS) - FILE * stream = ::fopen(static_cast(nana::charset(file)).c_str(), "rb"); - long long size = 0; - if (stream) - { - fseeko(stream, 0, SEEK_END); - size = ftello(stream); - fclose(stream); - } - return size; -#endif - } - - bool modified_file_time(const nana::string& file, struct tm& t) - { -#if defined(NANA_WINDOWS) - WIN32_FILE_ATTRIBUTE_DATA attr; - if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr)) - { - FILETIME local_file_time; - if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time)) - { - SYSTEMTIME st; - ::FileTimeToSystemTime(&local_file_time, &st); - t.tm_year = st.wYear - 1900; - t.tm_mon = st.wMonth - 1; - t.tm_mday = st.wDay; - t.tm_wday = st.wDayOfWeek - 1; - t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); - - t.tm_hour = st.wHour; - t.tm_min = st.wMinute; - t.tm_sec = st.wSecond; - return true; - } - } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat attr; - if (0 == ::stat(static_cast(nana::charset(file)).c_str(), &attr)) - { - t = *(::localtime(&attr.st_ctime)); - return true; - } -#endif - return false; - } - - bool create_directory(const nana::string& path, bool & if_exist) - { - if_exist = false; - if (path.size() == 0) return false; - - nana::string root; -#if defined(NANA_WINDOWS) - if (path.size() > 3 && path[1] == STR(':')) - root = path.substr(0, 3); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - if (path[0] == STR('/')) - root = '/'; -#endif - bool mkstat = false; - std::size_t beg = root.size(); - - while (true) - { - beg = path.find_first_not_of(STR("/\\"), beg); - if (beg == path.npos) - break; - - std::size_t pos = path.find_first_of(STR("/\\"), beg + 1); - if (pos != path.npos) - { - root += path.substr(beg, pos - beg); - - mkstat = detail::mkdir_helper(root, if_exist); - if (mkstat == false && if_exist == false) - return false; - -#if defined(NANA_WINDOWS) - root += STR('\\'); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - root += STR('/'); -#endif - } - else - { - if (beg + 1 < path.size()) - { - root += path.substr(beg); - mkstat = detail::mkdir_helper(root, if_exist); - } - break; - } - beg = pos + 1; - } - return mkstat; - } - - bool rmfile(const nana::char_t* file) - { -#if defined(NANA_WINDOWS) - bool ret = false; - if (file) - { - ret = (::DeleteFile(file) == TRUE); - if (!ret) - ret = (ERROR_FILE_NOT_FOUND == ::GetLastError()); - } - - return ret; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - if (std::remove(static_cast(nana::charset(file)).c_str())) - return (errno == ENOENT); return true; #endif } - bool rmdir(const nana::char_t* dir, bool fails_if_not_empty) - { - bool ret = false; - if (dir) - { #if defined(NANA_WINDOWS) - ret = (::RemoveDirectory(dir) == TRUE); - if (!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY)) - ret = detail::rm_dir_recursive(dir); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - std::string mbstr = nana::charset(dir); - if (::rmdir(mbstr.c_str())) - { - if (!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY)) - ret = detail::rm_dir_recursive(dir); - } - else - ret = true; -#endif + void filetime_to_c_tm(FILETIME& ft, struct tm& t) + { + FILETIME local_file_time; + if (::FileTimeToLocalFileTime(&ft, &local_file_time)) + { + SYSTEMTIME st; + ::FileTimeToSystemTime(&local_file_time, &st); + t.tm_year = st.wYear - 1900; + t.tm_mon = st.wMonth - 1; + t.tm_mday = st.wDay; + t.tm_wday = st.wDayOfWeek - 1; + t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); + + t.tm_hour = st.wHour; + t.tm_min = st.wMinute; + t.tm_sec = st.wSecond; } - return ret; + } +#endif + }//end namespace detail + + + file_status status(const path& p) + { + std::error_code err; + auto stat = status(p, err); + + if (err != std::error_code()) + throw filesystem_error("nana::filesystem::status", p, err); + + return stat; + } + + file_status status(const path& p, std::error_code& ec) + { + ec = std::error_code(); +#if defined(NANA_WINDOWS) + auto attr = ::GetFileAttributesW(p.c_str()); + if (INVALID_FILE_ATTRIBUTES == attr) + { + if (not_found_error(static_cast(::GetLastError()))) + return file_status{ file_type::not_found }; + return file_status{ file_type::unknown }; + } + return file_status{ (FILE_ATTRIBUTE_DIRECTORY & attr) ? file_type::directory : file_type::regular, perms::all }; +#elif defined(NANA_POSIX) + struct stat path_stat; + if (0 != ::stat(p.c_str(), &path_stat)) + { + if (errno == ENOENT || errno == ENOTDIR) + return file_status{ file_type::not_found }; + + return file_status{ file_type::unknown }; } - nana::string root(const nana::string& path) + auto prms = static_cast(path_stat.st_mode & static_cast(perms::mask)); + + if (S_ISREG(path_stat.st_mode)) + return file_status{ file_type::regular, prms }; + + if (S_ISDIR(path_stat.st_mode)) + return file_status{ file_type::directory, prms }; + + if (S_ISLNK(path_stat.st_mode)) + return file_status{ file_type::symlink, prms }; + + if (S_ISBLK(path_stat.st_mode)) + return file_status{ file_type::block, prms }; + + if (S_ISCHR(path_stat.st_mode)) + return file_status{ file_type::character, prms }; + + if (S_ISFIFO(path_stat.st_mode)) + return file_status{ file_type::fifo, prms }; + + if (S_ISSOCK(path_stat.st_mode)) + return file_status{ file_type::socket, prms }; + + return file_status{ file_type::unknown }; +#endif + } + + bool is_directory(const path& p) + { + return (status(p).type() == file_type::directory); + } + + std::uintmax_t file_size(const path& p) + { +#if defined(NANA_WINDOWS) + //Some compilation environment may fail to link to GetFileSizeEx + typedef BOOL(__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER); + GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx")); + if (get_file_size_ex) { - std::size_t index = path.size(); - - if (index) + HANDLE handle = ::CreateFile(p.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (INVALID_HANDLE_VALUE != handle) { - const nana::char_t * str = path.c_str(); + LARGE_INTEGER li; + if (!get_file_size_ex(handle, &li)) + li.QuadPart = 0; - for (--index; index > 0; --index) - { - nana::char_t c = str[index]; - if (c != '\\' && c != '/') - break; - } - - for (--index; index > 0; --index) - { - nana::char_t c = str[index]; - if (c == '\\' || c == '/') - break; - } + ::CloseHandle(handle); + return li.QuadPart; } - - return index ? path.substr(0, index + 1) : nana::string(); } + return 0; +#elif defined(NANA_POSIX) + FILE * stream = ::fopen(p.c_str(), "rb"); + long long size = 0; + if (stream) + { +# if defined(NANA_LINUX) + fseeko64(stream, 0, SEEK_END); + size = ftello64(stream); +# elif defined(NANA_MACOS) + fseeko(stream, 0, SEEK_END); + size = ftello(stream); +# endif + ::fclose(stream); + } + return size; +#endif + } - nana::string path_user() + bool modified_file_time(const path& p, struct tm& t) + { +#if defined(NANA_WINDOWS) + WIN32_FILE_ATTRIBUTE_DATA attr; + if (::GetFileAttributesEx(p.c_str(), GetFileExInfoStandard, &attr)) + { + FILETIME local_file_time; + if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time)) + { + SYSTEMTIME st; + ::FileTimeToSystemTime(&local_file_time, &st); + t.tm_year = st.wYear - 1900; + t.tm_mon = st.wMonth - 1; + t.tm_mday = st.wDay; + t.tm_wday = st.wDayOfWeek - 1; + t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); + + t.tm_hour = st.wHour; + t.tm_min = st.wMinute; + t.tm_sec = st.wSecond; + return true; + } + } +#elif defined(NANA_POSIX) + struct stat attr; + if (0 == ::stat(p.c_str(), &attr)) + { + t = *(::localtime(&attr.st_ctime)); + return true; + } +#endif + return false; + } + + + bool create_directory(const path& p) { #if defined(NANA_WINDOWS) - nana::char_t path[MAX_PATH]; - if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path))) - return path; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - const char * s = ::getenv("HOME"); - if (s) - return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8); + return (FALSE != ::CreateDirectoryW(p.c_str(), 0)); +#elif defined(NANA_POSIX) + return (0 == ::mkdir(p.c_str(), static_cast(perms::all))); #endif - return nana::string(); + } + + bool remove(const path& p) + { + auto stat = status(p); + if (stat.type() == file_type::directory) + return detail::rm_dir(p); + + return detail::rm_file(p); + } + + bool remove(const path& p, std::error_code & ec) + { + auto stat = status(p); + if (stat.type() == file_type::directory) + return detail::rm_dir(p); + + return detail::rm_file(p); + } + + path path_user() + { +#if defined(NANA_WINDOWS) + wchar_t pstr[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, pstr))) + return pstr; +#elif defined(NANA_LINUX) || defined(NANA_MACOS) + const char * pstr = ::getenv("HOME"); + if (pstr) + return pstr; +#endif + return path(); } path current_path() { #if defined(NANA_WINDOWS) - nana::char_t buf[MAX_PATH]; - DWORD len = ::GetCurrentDirectory(MAX_PATH, buf); + wchar_t buf[MAX_PATH]; + DWORD len = ::GetCurrentDirectoryW(MAX_PATH, buf); if (len) { if (len > MAX_PATH) { - nana::char_t * p = new nana::char_t[len + 1]; - ::GetCurrentDirectory(len + 1, p); - nana::string s = p; + wchar_t * p = new wchar_t[len + 1]; + ::GetCurrentDirectoryW(len + 1, p); + std::wstring s = p; delete[] p; return s; } - return nana::string(buf); + return buf; + } +#elif defined(NANA_POSIX) + char buf[260]; + auto pstr = ::getcwd(buf, 260); + if (pstr) + return pstr; + + int bytes = 260 + 260; + while (ERANGE == errno) + { + std::unique_ptr buf(new char[bytes]); + auto pstr = ::getcwd(buf.get(), bytes); + if (pstr) + return path(pstr); + + bytes += 260; } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - const char * s = ::getenv("PWD"); - if (s) - return static_cast(nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8)); #endif - return nana::string(); + return path(); + } + + void current_path(const path& p) + { +#if defined(NANA_WINDOWS) + ::SetCurrentDirectoryW(p.c_str()); +#elif defined(NANA_POSIX) + ::chdir(p.c_str()); +#endif } }//end namespace filesystem } //end namespace experimental diff --git a/source/filesystem/fs_utility.cpp b/source/filesystem/fs_utility.cpp deleted file mode 100644 index c9cfd677..00000000 --- a/source/filesystem/fs_utility.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/* - * A FileSystem Utility Implementation - * Copyright(C) 2003-2013 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/fs_utility.cpp - * @description: - * provide some interface for file managment - */ - -#include -#include -#include -#if defined(NANA_WINDOWS) - #include - - #if defined(NANA_MINGW) - #ifndef _WIN32_IE - #define _WIN32_IE 0x0500 - #endif - #endif - - #include - #include -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif - -namespace nana -{ -namespace filesystem -{ -//Because of No wide character version of POSIX -#if defined(NANA_LINUX) || defined(NANA_MACOS) - typedef std::string string_t; - const char* splstr = "/\\"; -#else - typedef nana::string string_t; - const nana::char_t* splstr = STR("/\\"); -#endif - //class path - path::path(){} - - path::path(const nana::string& text) -#if defined(NANA_WINDOWS) - :text_(text) - { -#else - :text_(nana::charset(text)) - { -#endif - auto pos = text_.find_last_of(splstr); - for(; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr)) - text_.erase(pos); - } - - bool path::empty() const - { -#if defined(NANA_WINDOWS) - return (::GetFileAttributes(text_.c_str()) == INVALID_FILE_ATTRIBUTES); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat sta; - return (::stat(text_.c_str(), &sta) == -1); -#endif - } - - path path::root() const - { - #if defined(NANA_WINDOWS) - return path(filesystem::root(text_)); - #elif defined(NANA_LINUX) || defined(NANA_MACOS) - return path(filesystem::root(nana::charset(text_))); - #endif - } - - int path::what() const - { -#if defined(NANA_WINDOWS) - unsigned long attr = ::GetFileAttributes(text_.c_str()); - if(INVALID_FILE_ATTRIBUTES == attr) - return type::not_exist; - - if(FILE_ATTRIBUTE_DIRECTORY & attr) - return type::directory; - - return type::file; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat sta; - if(-1 == ::stat(text_.c_str(), &sta)) - return type::not_exist; - - if((S_IFDIR & sta.st_mode) == S_IFDIR) - return type::directory; - - if((S_IFREG & sta.st_mode) == S_IFREG) - return type::file; - - return type::not_exist; -#endif - } - - nana::string path::name() const - { - string_t::size_type pos = text_.find_last_of(splstr); -#if defined(NANA_WINDOWS) - return text_.substr(pos + 1); -#else - return nana::charset(text_.substr(pos + 1)); -#endif - } - //end class path - - namespace detail - { - //rm_dir_recursive - //@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories - bool rm_dir_recursive(nana::string&& dir) - { - std::vector files; - nana::string path = dir; - path += '\\'; - - std::copy(file_iterator(dir), file_iterator(), std::back_inserter(files)); - - for(auto & f : files) - { - if(f.directory) - rm_dir_recursive(path + f.name); - else - rmfile((path + f.name).c_str()); - } - - return rmdir(dir.c_str(), true); - } - - bool mkdir_helper(const nana::string& dir, bool & if_exist) - { -#if defined(NANA_WINDOWS) - if(::CreateDirectory(dir.c_str(), 0)) - { - if_exist = false; - return true; - } - - if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - if(0 == ::mkdir(static_cast(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) - { - if_exist = false; - return true; - } - - if_exist = (errno == EEXIST); -#endif - return false; - } - -#if defined(NANA_WINDOWS) - void filetime_to_c_tm(FILETIME& ft, struct tm& t) - { - FILETIME local_file_time; - if(::FileTimeToLocalFileTime(&ft, &local_file_time)) - { - SYSTEMTIME st; - ::FileTimeToSystemTime(&local_file_time, &st); - t.tm_year = st.wYear - 1900; - t.tm_mon = st.wMonth - 1; - t.tm_mday = st.wDay; - t.tm_wday = st.wDayOfWeek - 1; - t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); - - t.tm_hour = st.wHour; - t.tm_min = st.wMinute; - t.tm_sec = st.wSecond; - } - } -#endif - }//end namespace detail - - bool file_attrib(const nana::string& file, attribute& attr) - { -#if defined(NANA_WINDOWS) - WIN32_FILE_ATTRIBUTE_DATA fad; - if(::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad)) - { - LARGE_INTEGER li; - li.u.LowPart = fad.nFileSizeLow; - li.u.HighPart = fad.nFileSizeHigh; - attr.bytes = li.QuadPart; - attr.is_directory = (0 != (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); - detail::filetime_to_c_tm(fad.ftLastWriteTime, attr.modified); - return true; - } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat fst; - if(0 == ::stat(static_cast(nana::charset(file)).c_str(), &fst)) - { - attr.bytes = fst.st_size; - attr.is_directory = (0 != (040000 & fst.st_mode)); - attr.modified = *(::localtime(&fst.st_ctime)); - return true; - } -#endif - return false; - } - - long long filesize(const nana::string& file) - { -#if defined(NANA_WINDOWS) - //Some compilation environment may fail to link to GetFileSizeEx - typedef BOOL (__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER); - GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx")); - if(get_file_size_ex) - { - HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if(INVALID_HANDLE_VALUE != handle) - { - LARGE_INTEGER li; - if(!get_file_size_ex(handle, &li)) - li.QuadPart = 0; - - ::CloseHandle(handle); - return li.QuadPart; - } - } - return 0; -#elif defined(NANA_LINUX) - FILE * stream = ::fopen(static_cast(nana::charset(file)).c_str(), "rb"); - long long size = 0; - if(stream) - { - fseeko64(stream, 0, SEEK_END); - size = ftello64(stream); - fclose(stream); - } - return size; -#elif defined(NANA_MACOS) - FILE * stream = ::fopen(static_cast(nana::charset(file)).c_str(), "rb"); - long long size = 0; - if (stream) - { - fseeko(stream, 0, SEEK_END); - size = ftello(stream); - fclose(stream); - } - return size; -#endif - } - - bool modified_file_time(const nana::string& file, struct tm& t) - { -#if defined(NANA_WINDOWS) - WIN32_FILE_ATTRIBUTE_DATA attr; - if(::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr)) - { - FILETIME local_file_time; - if(::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time)) - { - SYSTEMTIME st; - ::FileTimeToSystemTime(&local_file_time, &st); - t.tm_year = st.wYear - 1900; - t.tm_mon = st.wMonth - 1; - t.tm_mday = st.wDay; - t.tm_wday = st.wDayOfWeek - 1; - t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay); - - t.tm_hour = st.wHour; - t.tm_min = st.wMinute; - t.tm_sec = st.wSecond; - return true; - } - } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - struct stat attr; - if(0 == ::stat(static_cast(nana::charset(file)).c_str(), &attr)) - { - t = *(::localtime(&attr.st_ctime)); - return true; - } -#endif - return false; - } - - bool mkdir(const nana::string& path, bool & if_exist) - { - if_exist = false; - if(path.size() == 0) return false; - - nana::string root; -#if defined(NANA_WINDOWS) - if(path.size() > 3 && path[1] == STR(':')) - root = path.substr(0, 3); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - if(path[0] == STR('/')) - root = '/'; -#endif - bool mkstat = false; - std::size_t beg = root.size(); - - while(true) - { - beg = path.find_first_not_of(STR("/\\"), beg); - if(beg == path.npos) - break; - - std::size_t pos = path.find_first_of(STR("/\\"), beg + 1); - if(pos != path.npos) - { - root += path.substr(beg, pos - beg); - - mkstat = detail::mkdir_helper(root, if_exist); - if(mkstat == false && if_exist == false) - return false; - -#if defined(NANA_WINDOWS) - root += STR('\\'); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - root += STR('/'); -#endif - } - else - { - if(beg + 1 < path.size()) - { - root += path.substr(beg); - mkstat = detail::mkdir_helper(root, if_exist); - } - break; - } - beg = pos + 1; - } - return mkstat; - } - - bool rmfile(const nana::char_t* file) - { -#if defined(NANA_WINDOWS) - bool ret = false; - if(file) - { - ret = (::DeleteFile(file) == TRUE); - if(!ret) - ret = (ERROR_FILE_NOT_FOUND == ::GetLastError()); - } - - return ret; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - if(std::remove(static_cast(nana::charset(file)).c_str())) - return (errno == ENOENT); - return true; -#endif - } - - bool rmdir(const nana::char_t* dir, bool fails_if_not_empty) - { - bool ret = false; - if(dir) - { -#if defined(NANA_WINDOWS) - ret = (::RemoveDirectory(dir) == TRUE); - if(!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY)) - ret = detail::rm_dir_recursive(dir); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - std::string mbstr = nana::charset(dir); - if(::rmdir(mbstr.c_str())) - { - if(!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY)) - ret = detail::rm_dir_recursive(dir); - } - else - ret = true; -#endif - } - return ret; - } - - nana::string root(const nana::string& path) - { - std::size_t index = path.size(); - - if(index) - { - const nana::char_t * str = path.c_str(); - - for(--index; index > 0; --index) - { - nana::char_t c = str[index]; - if(c != '\\' && c != '/') - break; - } - - for(--index; index > 0; --index) - { - nana::char_t c = str[index]; - if(c == '\\' || c == '/') - break; - } - } - - return index?path.substr(0, index + 1):nana::string(); - } - - nana::string path_user() - { -#if defined(NANA_WINDOWS) - nana::char_t path[MAX_PATH]; - if(SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path))) - return path; -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - const char * s = ::getenv("HOME"); - if(s) - return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8); -#endif - return nana::string(); - } - - nana::string path_current() - { -#if defined(NANA_WINDOWS) - nana::char_t buf[MAX_PATH]; - DWORD len = ::GetCurrentDirectory(MAX_PATH, buf); - if(len) - { - if(len > MAX_PATH) - { - nana::char_t * p = new nana::char_t[len + 1]; - ::GetCurrentDirectory(len + 1, p); - nana::string s = p; - delete [] p; - return s; - } - return buf; - } -#elif defined(NANA_LINUX) || defined(NANA_MACOS) - const char * s = ::getenv("PWD"); - if(s) - return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8); -#endif - return nana::string(); - } -}//end namespace filesystem -}//end namespace nana diff --git a/source/gui/animation.cpp b/source/gui/animation.cpp index a82702e6..a6047b4e 100644 --- a/source/gui/animation.cpp +++ b/source/gui/animation.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(STD_THREAD_NOT_SUPPORTED) #include @@ -350,7 +351,7 @@ namespace nana struct animation::impl { bool looped{false}; - volatile bool paused{true}; + std::atomic paused{true}; std::size_t fps; std::list framesets; diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 6c7146eb..9c1a5ae0 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -1,3 +1,15 @@ +/* +* A Basic Window Widget Definition +* 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/gui/detail/basic_window.cpp +*/ + #include #include @@ -384,6 +396,7 @@ namespace nana flags.make_bground_declared = false; flags.ignore_menubar_focus = false; flags.ignore_mouse_focus = false; + flags.space_click_enabled = false; visible = false; diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index ad8a8508..a8f78c37 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -1,7 +1,7 @@ /* * A Bedrock 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 @@ -233,7 +233,7 @@ namespace detail { if(wd) { - internal_scope_guard isg; + internal_scope_guard lock; if(wd_manager().available(wd)) return wd->other.category; } @@ -656,12 +656,17 @@ namespace detail auto pre_event_window = context.event_window; auto pressed_wd = root_runtime->condition.pressed; + auto pressed_wd_space = root_runtime->condition.pressed_by_space; auto hovered_wd = root_runtime->condition.hovered; const int message = xevent.type; switch(xevent.type) { case EnterNotify: + //Ignore mouse events when a window has been pressed by pressing spacebar. + if(pressed_wd_space) + break; + msgwnd = brock.wd_manager().find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y); if(msgwnd) { @@ -733,6 +738,10 @@ namespace detail } break; case ButtonPress: + //Ignore mouse events when a window has been pressed by pressing spacebar + if(pressed_wd_space) + break; + if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5) break; @@ -788,6 +797,10 @@ namespace detail } break; case ButtonRelease: + //Ignore mouse events when a window has been pressed by pressing spacebar + if(pressed_wd_space) + break; + if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5) { //The hovered window receives the message, unlike in Windows, no redirection is required. @@ -898,6 +911,10 @@ namespace detail else break; + //Ignore mouse events when a window has been pressed by pressing spacebar + 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)) { @@ -993,7 +1010,7 @@ namespace detail if(input_context) { nana::detail::platform_scope_guard psg; -#if defined(NANA_UNICODE) +#if 1 //Utf8 len = ::Xutf8LookupString(input_context, &xevent.xkey, keybuf, 32, &keysym, &status); if(status == XBufferOverflow) { @@ -1017,7 +1034,8 @@ namespace detail } keybuf[len] = 0; - ::nana::char_t os_code = 0; + wchar_t os_code = 0; + auto & wd_manager = brock.wd_manager(); switch(status) { case XLookupKeySym: @@ -1027,11 +1045,37 @@ namespace detail { arg_keyboard argkey; brock.get_key_state(argkey); - auto tstop_wd = brock.wd_manager().tabstop(msgwnd, !argkey.shift); + auto tstop_wd = wd_manager.tabstop(msgwnd, !argkey.shift); if (tstop_wd) { - brock.wd_manager().set_focus(tstop_wd, false); - brock.wd_manager().do_lazy_refresh(tstop_wd, true); + wd_manager.set_focus(tstop_wd, false); + wd_manager.do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(tstop_wd, true); + } + } + else if((keyboard::space == os_code) && msgwnd->flags.space_click_enabled) + { + //Clicked by spacebar + if((nullptr == pressed_wd) && (nullptr == pressed_wd_space)) + { + arg_mouse arg; + arg.alt = false; + arg.button = ::nana::mouse::left_button; + arg.ctrl = false; + arg.evt_code = event_code::mouse_down; + arg.left_button = true; + arg.mid_button = false; + arg.pos.x = 0; + arg.pos.y = 0; + arg.window_handle = reinterpret_cast(msgwnd); + + msgwnd->flags.action = mouse_action::pressed; + + pressed_wd_space = msgwnd; + auto retain = msgwnd->together.events_ptr; + + emit_drawer(&drawer::mouse_down, msgwnd, arg, &context); + wd_manager.do_lazy_refresh(msgwnd, false); } } else if(keyboard::alt == os_code) @@ -1074,28 +1118,26 @@ namespace detail if(brock.wd_manager().available(msgwnd) && (msgwnd->root_widget->other.attribute.root->menubar == msgwnd)) { - int cmd = (menu_wd && (keyboard::escape == static_cast(arg.key)) ? 1 : 0 ); + int cmd = (menu_wd && (keyboard::escape == static_cast(arg.key)) ? 1 : 0 ); brock.delay_restore(cmd); } } if(XLookupKeySym == status) { - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); break; } case XLookupChars: if (msgwnd->flags.enabled) { - const ::nana::char_t* charbuf; -#if defined(NANA_UNICODE) + const wchar_t* charbuf; + nana::detail::charset_conv charset("UTF-32", "UTF-8"); const std::string& str = charset.charset(std::string(keybuf, keybuf + len)); - charbuf = reinterpret_cast(str.c_str()) + 1; + charbuf = reinterpret_cast(str.c_str()) + 1; len = str.size() / sizeof(wchar_t) - 1; -#else - charbuf = keybuf; -#endif + for(int i = 0; i < len; ++i) { arg_keyboard arg; @@ -1111,7 +1153,7 @@ namespace detail arg.ctrl = arg.shift = false; arg.evt_code = event_code::shortkey; brock.set_keyboard_shortkey(true); - auto shr_wd = brock.wd_manager().find_shortkey(native_window, arg.key); + auto shr_wd = wd_manager.find_shortkey(native_window, arg.key); if(shr_wd) { arg.window_handle = reinterpret_cast(shr_wd); @@ -1123,7 +1165,7 @@ namespace detail arg.window_handle = reinterpret_cast(msgwnd); brock.get_key_state(arg); msgwnd->together.events_ptr->key_char.emit(arg); - if(arg.ignore == false && brock.wd_manager().available(msgwnd)) + if(arg.ignore == false && wd_manager.available(msgwnd)) brock.emit_drawer(event_code::key_char, msgwnd, arg, &context); } @@ -1133,7 +1175,7 @@ namespace detail break; } - brock.wd_manager().do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(msgwnd, false); if(keybuf != fixbuf) delete [] keybuf; } @@ -1151,13 +1193,43 @@ namespace detail msgwnd = brock.focus(); if(msgwnd) { - arg_keyboard arg; - arg.evt_code = event_code::key_release; - arg.window_handle = reinterpret_cast(msgwnd); - arg.ignore = false; - arg.key = os_code; - brock.get_key_state(arg); - brock.emit(event_code::key_release, msgwnd, arg, true, &context); + if(msgwnd == pressed_wd_space) + { + msgwnd->flags.action = mouse_action::normal; + + arg_click click_arg; + click_arg.mouse_args = nullptr; + click_arg.window_handle = reinterpret_cast(msgwnd); + + auto retain = msgwnd->together.events_ptr; + if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) + { + arg_mouse arg; + arg.alt = false; + arg.button = ::nana::mouse::left_button; + arg.ctrl = false; + arg.evt_code = event_code::mouse_up; + arg.left_button = true; + arg.mid_button = false; + arg.pos.x = 0; + arg.pos.y = 0; + arg.window_handle = reinterpret_cast(msgwnd); + + emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + brock.wd_manager().do_lazy_refresh(msgwnd, false); + } + pressed_wd_space = nullptr; + } + else + { + arg_keyboard arg; + arg.evt_code = event_code::key_release; + arg.window_handle = reinterpret_cast(msgwnd); + arg.ignore = false; + arg.key = os_code; + brock.get_key_state(arg); + brock.emit(event_code::key_release, msgwnd, arg, true, &context); + } } if(os_code < keyboard::os_arrow_left || keyboard::os_arrow_down < os_code) @@ -1218,6 +1290,7 @@ namespace detail context.event_window = pre_event_window; root_runtime->condition.pressed = pressed_wd; root_runtime->condition.hovered = hovered_wd; + root_runtime->condition.pressed_by_space = pressed_wd_space; } else { @@ -1400,4 +1473,4 @@ namespace detail } }//end namespace detail }//end namespace nana -#endif //NANA_POSIX && NANA_X11 \ No newline at end of file +#endif //NANA_POSIX && NANA_X11 diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index eb48b9e9..2915ec1c 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -1,7 +1,7 @@ /* * A Bedrock 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 @@ -141,7 +141,7 @@ namespace detail struct platform_detail_tag { - nana::char_t keychar; + wchar_t keychar; }platform; struct cursor_tag @@ -215,7 +215,7 @@ namespace detail WNDCLASSEX wincl; wincl.hInstance = ::GetModuleHandle(0); - wincl.lpszClassName = STR("NanaWindowInternal"); + wincl.lpszClassName = L"NanaWindowInternal"; wincl.lpfnWndProc = &Bedrock_WIN32_WindowProc; wincl.style = CS_DBLCLKS | CS_OWNDC; wincl.cbSize = sizeof(wincl); @@ -441,9 +441,9 @@ namespace detail } catch(std::exception& e) { - (msgbox(modal_window, STR("An uncaptured std::exception during message pumping: ")).icon(msgbox::icon_information) - <condition.pressed; + auto pressed_wd_space = root_runtime->condition.pressed_by_space; auto hovered_wd = root_runtime->condition.hovered; parameter_decoder pmdec; @@ -913,6 +914,10 @@ namespace detail def_window_proc = true; break; case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: + //Ignore mouse events when a window has been pressed by pressing spacebar + if (pressed_wd_space) + break; + pressed_wd = nullptr; msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); if(msgwnd && msgwnd->flags.enabled) @@ -938,8 +943,13 @@ namespace detail def_window_proc = true; break; case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: + //Ignore mouse events when a window has been pressed by pressing spacebar + if (pressed_wd_space) + break; + msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); - if(nullptr == msgwnd) break; + if ((nullptr == msgwnd) || (pressed_wd && (msgwnd != pressed_wd))) + break; //if event on the menubar, just remove the menu if it is not associating with the menubar if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true)) @@ -994,7 +1004,11 @@ namespace detail case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: - msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); + //Ignore mouse events when a window has been pressed by pressing spacebar + if (pressed_wd_space) + break; + + msgwnd = brock.wd_manager().find_window(native_window, pmdec.mouse.x, pmdec.mouse.y); if(nullptr == msgwnd) break; @@ -1015,7 +1029,7 @@ namespace detail if (msgwnd->dimension.is_hit(arg.pos)) { msgwnd->flags.action = mouse_action::over; - if (::nana::mouse::left_button == arg.button) + if ((::nana::mouse::left_button == arg.button) && (pressed_wd == msgwnd)) { click_arg.window_handle = reinterpret_cast(msgwnd); emit_drawer(&drawer::click, msgwnd, click_arg, &context); @@ -1045,6 +1059,10 @@ namespace detail pressed_wd = nullptr; break; case WM_MOUSEMOVE: + //Ignore mouse events when a window has been pressed by pressing spacebar + 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)) { @@ -1176,7 +1194,7 @@ namespace detail { arg_dropfiles dropfiles; - std::unique_ptr varbuf; + std::unique_ptr varbuf; std::size_t bufsize = 0; unsigned size = ::DragQueryFile(drop, 0xFFFFFFFF, 0, 0); @@ -1185,12 +1203,13 @@ namespace detail unsigned reqlen = ::DragQueryFile(drop, i, 0, 0) + 1; if(bufsize < reqlen) { - varbuf.reset(new nana::char_t[reqlen]); + varbuf.reset(new wchar_t[reqlen]); bufsize = reqlen; } ::DragQueryFile(drop, i, varbuf.get(), reqlen); - dropfiles.files.emplace_back(varbuf.get()); + + dropfiles.files.emplace_back(to_utf8(varbuf.get())); } while(msgwnd && (msgwnd->flags.dropable == false)) @@ -1344,7 +1363,7 @@ namespace detail arg.evt_code = event_code::key_press; arg.window_handle = reinterpret_cast(msgwnd); arg.ignore = false; - arg.key = static_cast(wParam); + arg.key = static_cast(wParam); brock.get_key_state(arg); brock.emit(event_code::key_press, msgwnd, arg, true, &context); @@ -1372,7 +1391,7 @@ namespace detail arg.evt_code = event_code::key_release; arg.window_handle = reinterpret_cast(msgwnd); arg.ignore = false; - arg.key = static_cast(wParam); + arg.key = static_cast(wParam); brock.get_key_state(arg); brock.emit(event_code::key_release, msgwnd, arg, true, &context); @@ -1396,16 +1415,42 @@ namespace detail if(msgwnd) { - if((wParam == 9) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab + auto & wd_manager = brock.wd_manager(); + if((VK_TAB == wParam) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab { bool is_forward = (::GetKeyState(VK_SHIFT) >= 0); - auto tstop_wd = brock.wd_manager().tabstop(msgwnd, is_forward); + auto tstop_wd = wd_manager.tabstop(msgwnd, is_forward); if (tstop_wd) { - brock.wd_manager().set_focus(tstop_wd, false); - brock.wd_manager().do_lazy_refresh(msgwnd, false); - brock.wd_manager().do_lazy_refresh(tstop_wd, true); + wd_manager.set_focus(tstop_wd, false); + wd_manager.do_lazy_refresh(msgwnd, false); + wd_manager.do_lazy_refresh(tstop_wd, true); + } + } + else if ((VK_SPACE == wParam) && msgwnd->flags.space_click_enabled) + { + //Clicked by spacebar + if (nullptr == pressed_wd && nullptr == pressed_wd_space) + { + arg_mouse arg; + arg.alt = false; + arg.button = ::nana::mouse::left_button; + arg.ctrl = false; + arg.evt_code = event_code::mouse_down; + arg.left_button = true; + arg.mid_button = false; + arg.pos.x = 0; + arg.pos.y = 0; + arg.window_handle = reinterpret_cast(msgwnd); + + msgwnd->flags.action = mouse_action::pressed; + + pressed_wd_space = msgwnd; + auto retain = msgwnd->together.events_ptr; + + emit_drawer(&drawer::mouse_down, msgwnd, arg, &context); + wd_manager.do_lazy_refresh(msgwnd, false); } } else @@ -1414,7 +1459,7 @@ namespace detail arg.evt_code = event_code::key_press; arg.window_handle = reinterpret_cast(msgwnd); arg.ignore = false; - arg.key = static_cast(wParam); + arg.key = static_cast(wParam); brock.get_key_state(arg); brock.emit(event_code::key_press, msgwnd, arg, true, &context); @@ -1425,7 +1470,7 @@ namespace detail //If no menu popuped by the menubar, it should enable delay restore to //restore the focus for taken window. - int cmd = (menu_wd && (keyboard::escape == static_cast(wParam)) ? 1 : 0); + int cmd = (menu_wd && (keyboard::escape == static_cast(wParam)) ? 1 : 0); brock.delay_restore(cmd); } } @@ -1442,7 +1487,7 @@ namespace detail arg_keyboard arg; arg.evt_code = event_code::key_char; arg.window_handle = reinterpret_cast(msgwnd); - arg.key = static_cast(wParam); + arg.key = static_cast(wParam); brock.get_key_state(arg); arg.ignore = false; @@ -1455,18 +1500,48 @@ namespace detail } return 0; case WM_KEYUP: - if(wParam != 18) //MUST NOT BE AN ALT + if(wParam != VK_MENU) //MUST NOT BE AN ALT { msgwnd = brock.focus(); if(msgwnd) { - arg_keyboard arg; - arg.evt_code = event_code::key_release; - arg.window_handle = reinterpret_cast(msgwnd); - arg.key = static_cast(wParam); - brock.get_key_state(arg); - arg.ignore = false; - brock.emit(event_code::key_release, msgwnd, arg, true, &context); + if (msgwnd == pressed_wd_space) + { + msgwnd->flags.action = mouse_action::normal; + + arg_click click_arg; + click_arg.mouse_args = nullptr; + click_arg.window_handle = reinterpret_cast(msgwnd); + + auto retain = msgwnd->together.events_ptr; + if (brock.emit(event_code::click, msgwnd, click_arg, true, &context)) + { + arg_mouse arg; + arg.alt = false; + arg.button = ::nana::mouse::left_button; + arg.ctrl = false; + arg.evt_code = event_code::mouse_up; + arg.left_button = true; + arg.mid_button = false; + arg.pos.x = 0; + arg.pos.y = 0; + arg.window_handle = reinterpret_cast(msgwnd); + + emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); + brock.wd_manager().do_lazy_refresh(msgwnd, false); + } + pressed_wd_space = nullptr; + } + else + { + arg_keyboard arg; + arg.evt_code = event_code::key_release; + arg.window_handle = reinterpret_cast(msgwnd); + arg.key = static_cast(wParam); + brock.get_key_state(arg); + arg.ignore = false; + brock.emit(event_code::key_release, msgwnd, arg, true, &context); + } } } else @@ -1520,6 +1595,7 @@ namespace detail { root_runtime->condition.pressed = pressed_wd; root_runtime->condition.hovered = hovered_wd; + root_runtime->condition.pressed_by_space = pressed_wd_space; } if (!def_window_proc) @@ -1728,9 +1804,9 @@ namespace detail return true; } - const nana::char_t* translate(cursor id) + const wchar_t* translate(cursor id) { - const nana::char_t* name = IDC_ARROW; + const wchar_t* name = IDC_ARROW; switch(id) { diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 202a76d3..ea84c1d3 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -158,7 +158,7 @@ namespace nana{ { #if defined(NANA_WINDOWS) typedef HMONITOR (__stdcall * MonitorFromPointT)(POINT,DWORD); - + MonitorFromPointT mfp = reinterpret_cast(::GetProcAddress(::GetModuleHandleA("User32.DLL"), "MonitorFromPoint")); if(mfp) { @@ -202,7 +202,7 @@ namespace nana{ if(owner && (nested == false)) ::ClientToScreen(reinterpret_cast(owner), &pt); - HWND native_wd = ::CreateWindowEx(style_ex, STR("NanaWindowInternal"), STR("Nana Window"), + HWND native_wd = ::CreateWindowEx(style_ex, L"NanaWindowInternal", L"Nana Window", style, pt.x, pt.y, 100, 100, reinterpret_cast(owner), 0, ::GetModuleHandle(0), 0); @@ -281,7 +281,8 @@ namespace nana{ attr_mask, &win_attr); if(handle) { - if(owner) + //make owner if it is a popup window + if((!nested) && owner) restrict::spec.make_owner(owner, reinterpret_cast(handle)); XTextProperty name; @@ -377,8 +378,8 @@ namespace nana{ if(nullptr == parent) return nullptr; #if defined(NANA_WINDOWS) HWND handle = ::CreateWindowEx(WS_EX_CONTROLPARENT, // Extended possibilites for variation - STR("NanaWindowInternal"), - STR("Nana Child Window"), // Title Text + L"NanaWindowInternal", + L"Nana Child Window", // Title Text WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, r.x, r.y, r.width, r.height, reinterpret_cast(parent), // The window is a child-window to desktop @@ -417,8 +418,6 @@ namespace nana{ if(handle) { - restrict::spec.make_owner(parent, reinterpret_cast(handle)); - XTextProperty name; char text[] = "Nana Child Window"; char * str = text; @@ -474,13 +473,13 @@ namespace nana{ auto & atombase = restrict::spec.atombase(); ::XSetTransientForHint(disp, reinterpret_cast(wd), owner); ::XChangeProperty(disp, reinterpret_cast(wd), - atombase.net_wm_state, XA_ATOM, sizeof(int) * 8, + atombase.net_wm_state, XA_ATOM, sizeof(int) * 8, PropModeReplace, reinterpret_cast(&atombase.net_wm_state_modal), 1); } } #endif - + void native_interface::enable_dropfiles(native_window_type wd, bool enb) { #if defined(NANA_WINDOWS) @@ -506,7 +505,7 @@ namespace nana{ } ::XSelectInput(restrict::spec.open_display(), reinterpret_cast(wd), mask); -#endif +#endif } bool native_interface::window_icon(native_window_type wd, const nana::paint::image& sml_icon, const ::nana::paint::image& big_icon) @@ -786,21 +785,30 @@ namespace nana{ #if defined(NANA_WINDOWS) ::RECT r; ::GetWindowRect(reinterpret_cast(wd), & r); - HWND owner = ::GetWindow(reinterpret_cast(wd), GW_OWNER); - if(owner) + HWND coord_wd = ::GetWindow(reinterpret_cast(wd), GW_OWNER); + + if (!coord_wd) + coord_wd = ::GetParent(reinterpret_cast(wd)); + + if (coord_wd) { ::POINT pos = {r.left, r.top}; - ::ScreenToClient(owner, &pos); + ::ScreenToClient(coord_wd, &pos); return nana::point(pos.x, pos.y); } return nana::point(r.left, r.top); #elif defined(NANA_X11) int x, y; nana::detail::platform_scope_guard psg; - Window root = reinterpret_cast(restrict::spec.get_owner(wd)); - if(root == 0) root = restrict::spec.root_window(); + Window coord_wd = reinterpret_cast(restrict::spec.get_owner(wd)); + if(!coord_wd) + { + coord_wd = reinterpret_cast(parent_window(wd)); + if(!coord_wd) + coord_wd = restrict::spec.root_window(); + } Window child; - if(True == ::XTranslateCoordinates(restrict::spec.open_display(), reinterpret_cast(wd), root, 0, 0, &x, &y, &child)) + if(True == ::XTranslateCoordinates(restrict::spec.open_display(), reinterpret_cast(wd), coord_wd, 0, 0, &x, &y, &child)) return nana::point(x, y); return nana::point(0, 0); #endif @@ -1076,59 +1084,47 @@ namespace nana{ #endif } - void native_interface::window_caption(native_window_type wd, const nana::string& title) + void native_interface::window_caption(native_window_type wd, const native_string_type& title) { #if defined(NANA_WINDOWS) if(::GetCurrentThreadId() != ::GetWindowThreadProcessId(reinterpret_cast(wd), 0)) { - wchar_t * wstr; -#if defined(NANA_UNICODE) - wstr = new wchar_t[title.length() + 1]; - wcscpy(wstr, title.c_str()); -#else - std::wstring str = nana::charset(title); - wstr = new wchar_t[str.length() + 1]; - wcscpy(wstr, str.c_str()); -#endif + wchar_t * wstr = new wchar_t[title.length() + 1]; + std::wcscpy(wstr, title.c_str()); ::PostMessage(reinterpret_cast(wd), nana::detail::messages::remote_thread_set_window_text, reinterpret_cast(wstr), 0); } else ::SetWindowText(reinterpret_cast(wd), title.c_str()); #elif defined(NANA_X11) ::XTextProperty name; - #if defined(NANA_UNICODE) - std::string mbstr = nana::charset(title); - char* text = const_cast(mbstr.c_str()); - #else - char* text = const_cast(title.c_str()); - #endif + char * text = const_cast(title.c_str()); + nana::detail::platform_scope_guard psg; ::XStringListToTextProperty(&text, 1, &name); ::XSetWMName(restrict::spec.open_display(), reinterpret_cast(wd), &name); ::XChangeProperty(restrict::spec.open_display(), reinterpret_cast(wd), restrict::spec.atombase().net_wm_name, restrict::spec.atombase().utf8_string, 8, - PropModeReplace, reinterpret_cast(text), mbstr.size()); + PropModeReplace, reinterpret_cast(text), title.size()); #endif } - nana::string native_interface::window_caption(native_window_type wd) + auto native_interface::window_caption(native_window_type wd) -> native_string_type { #if defined(NANA_WINDOWS) int length = ::GetWindowTextLength(reinterpret_cast(wd)); if(length > 0) { - nana::string str; + native_string_type str; //One for NULL terminator which GetWindowText will write. str.resize(length+1); - + ::GetWindowText(reinterpret_cast(wd), &(str[0]), static_cast(str.size())); - + //Remove the null terminator writtien by GetWindowText str.resize(length); return str; } - return nana::string(); #elif defined(NANA_X11) nana::detail::platform_scope_guard psg; ::XTextProperty txtpro; @@ -1140,14 +1136,14 @@ namespace nana{ { if(size > 1) { - nana::string str = nana::charset(*strlist); + std::string text = *strlist; ::XFreeStringList(strlist); - return str; + return text; } } } - return nana::string(); #endif + return native_string_type(); } void native_interface::capture_window(native_window_type wd, bool cap) @@ -1202,6 +1198,54 @@ namespace nana{ #endif } + native_window_type native_interface::parent_window(native_window_type wd) + { +#ifdef NANA_WINDOWS + return reinterpret_cast(::GetParent(reinterpret_cast(wd))); +#elif defined(NANA_X11) + Window root; + Window parent; + Window * children; + unsigned size; + + platform_scope_guard lock; + + if(0 != ::XQueryTree(restrict::spec.open_display(), reinterpret_cast(wd), + &root, &parent, &children, &size)) + { + ::XFree(children); + return reinterpret_cast(parent); + } + return nullptr; +#endif + } + + native_window_type native_interface::parent_window(native_window_type child, native_window_type new_parent, bool returns_previous) + { +#ifdef NANA_WINDOWS + auto prev = ::SetParent(reinterpret_cast(child), reinterpret_cast(new_parent)); + + if (prev) + ::PostMessage(prev, /*WM_CHANGEUISTATE*/0x0127, /*UIS_INITIALIZE*/ 3, 0); + + ::SetWindowPos(reinterpret_cast(child), NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + + return reinterpret_cast(returns_previous ? prev : nullptr); +#elif defined(NANA_X11) + native_window_type prev = nullptr; + + platform_scope_guard lock; + + if(returns_previous) + prev = parent_window(child); + + ::XReparentWindow(restrict::spec.open_display(), + reinterpret_cast(child), reinterpret_cast(new_parent), + 0, 0); + return prev; +#endif + } + void native_interface::caret_create(native_window_type wd, const ::nana::size& caret_sz) { #if defined(NANA_WINDOWS) diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 9f0e779e..f44be0a6 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -140,7 +140,7 @@ namespace nana for (++i; i < end; ++i) { core_window_t* cover = *i; - if (cover->visible && (nullptr == cover->effect.bground)) + if ((category::flags::root != cover->other.category) && cover->visible && (nullptr == cover->effect.bground)) { if (overlap(vis_rect, rectangle{ cover->pos_root, cover->dimension }, block.r)) { @@ -271,9 +271,15 @@ namespace nana for (auto child : wd->children) { //it will not past children if no drawer and visible is false. - if ((false == child->visible) || ((child->other.category != category::lite_widget_tag::value) && child->drawer.graphics.empty())) + if ((false == child->visible) || ((category::flags::lite_widget != child->other.category) && child->drawer.graphics.empty())) continue; + if (category::flags::root == child->other.category) + { + paint(child, is_child_refreshed, is_child_refreshed); + continue; + } + if (nullptr == child->effect.bground) { if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect)) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 909cf193..4aa19757 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -291,6 +291,14 @@ namespace detail if (result.native_handle) { core_window_t* wd = new core_window_t(owner, widget_notifier_interface::get_notifier(wdg), (category::root_tag**)nullptr); + if (nested) + { + wd->owner = nullptr; + wd->parent = owner; + wd->index = static_cast(owner->children.size()); + owner->children.push_back(wd); + } + wd->flags.take_active = !app.no_activate; wd->title = native_interface::window_caption(result.native_handle); @@ -542,10 +550,10 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd)) { - if(wd->other.category != category::root_tag::value) + if (category::flags::root != wd->other.category) { //Move child widgets - if(x != wd->pos_owner.x || y != wd->pos_owner.y) + if (x != wd->pos_owner.x || y != wd->pos_owner.y) { point delta{ x - wd->pos_owner.x, y - wd->pos_owner.y }; @@ -562,8 +570,20 @@ namespace detail return true; } } - else if(false == passive) + else if (!passive) + { + //Check if this root is a nested + if (wd->parent && (category::flags::root != wd->parent->other.category)) + { + //The parent of the window is not a root, the position should + //be transformed to a position based on its parent. + + x += wd->parent->pos_root.x; + y += wd->parent->pos_root.y; + } + native_interface::move_window(wd->root, x, y); + } } return false; @@ -602,22 +622,36 @@ namespace detail } else { + ::nana::rectangle root_r = r; + //Move event should not get called here, + //because the window is a root, the event will get called by system event handler. + + //Check if this root is a nested + if (wd->parent && (category::flags::root != wd->parent->other.category)) + { + //The parent of the window is not a root, the position should + //be transformed to a position based on its parent. + + root_r.x += wd->parent->pos_root.x; + root_r.y += wd->parent->pos_root.y; + } + if(size_changed) { - wd->dimension.width = r.width; - wd->dimension.height = r.height; + wd->dimension.width = root_r.width; + wd->dimension.height = root_r.height; wd->drawer.graphics.make(wd->dimension); wd->root_graph->make(wd->dimension); - native_interface::move_window(wd->root, r); + native_interface::move_window(wd->root, root_r); arg_resized arg; arg.window_handle = reinterpret_cast(wd); - arg.width = r.width; - arg.height = r.height; + arg.width = root_r.width; + arg.height = root_r.height; brock.emit(event_code::resized, wd, arg, true, brock.get_thread_context()); } else - native_interface::move_window(wd->root, r.x, r.y); + native_interface::move_window(wd->root, root_r.x, root_r.y); } return (moved || size_changed); @@ -919,34 +953,37 @@ namespace detail arg.receiver = wd->root; brock.emit(event_code::focus, prev_focus, arg, true, brock.get_thread_context()); } + + //Check the prev_focus again, because it may be closed in focus event + if (!impl_->wd_register.available(prev_focus)) + prev_focus = nullptr; } else if(wd->root == native_interface::get_focus_window()) - wd = nullptr; //no new focus_window + return prev_focus; //no new focus_window - if(wd) - { - if(wd->together.caret) - wd->together.caret->set_active(true); - arg.window_handle = reinterpret_cast(wd); - arg.getting = true; - arg.receiver = wd->root; - brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context()); + if(wd->together.caret) + wd->together.caret->set_active(true); - if (!root_has_been_focused) - native_interface::set_focus(root_wd->root); + arg.window_handle = reinterpret_cast(wd); + arg.getting = true; + arg.receiver = wd->root; + brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context()); - //A fix by Katsuhisa Yuasa - //The menubar token window will be redirected to the prev focus window when the new - //focus window is a menubar. - //The focus window will be restore to the prev focus which losts the focus becuase of - //memberbar. - if (wd == wd->root_widget->other.attribute.root->menubar) - wd = prev_focus; + if (!root_has_been_focused) + native_interface::set_focus(root_wd->root); + + //A fix by Katsuhisa Yuasa + //The menubar token window will be redirected to the prev focus window when the new + //focus window is a menubar. + //The focus window will be restore to the prev focus which losts the focus becuase of + //memberbar. + if (prev_focus && (wd == wd->root_widget->other.attribute.root->menubar)) + wd = prev_focus; + + if (wd != wd->root_widget->other.attribute.root->menubar) + brock.set_menubar_taken(wd); - if (wd != wd->root_widget->other.attribute.root->menubar) - brock.set_menubar_taken(wd); - } return prev_focus; } @@ -1301,7 +1338,9 @@ namespace detail void window_manager::_m_disengage(core_window_t* wd, core_window_t* for_new) { auto * const wdpa = wd->parent; - bool established = (for_new && wdpa != for_new); + + + bool established = (for_new && (wdpa != for_new)); decltype(for_new->root_widget->other.attribute.root) pa_root_attr = nullptr; if (established) @@ -1443,14 +1482,26 @@ namespace detail std::function set_pos_root; set_pos_root = [&set_pos_root](core_window_t* wd, const nana::point& delta_pos) { - wd->pos_root -= delta_pos; for (auto child : wd->children) { - child->root = wd->root; - child->root_graph = wd->root_graph; - child->root_widget = wd->root_widget; - set_pos_root(child, delta_pos); + if (category::flags::root == child->other.category) + { + auto pos = native_interface::window_position(child->root); + native_interface::parent_window(child->root, wd->root, false); + + pos -= delta_pos; + native_interface::move_window(child->root, pos.x, pos.y); + } + else + { + child->root = wd->root; + child->root_graph = wd->root_graph; + child->root_widget = wd->root_widget; + set_pos_root(child, delta_pos); + } } + + wd->pos_root -= delta_pos; }; set_pos_root(wd, delta_pos); @@ -1481,8 +1532,30 @@ namespace detail brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context()); //Delete the children widgets. - for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end; ++i) - _m_destroy(*i); + for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end;) + { + auto child = *i; + + if (category::flags::root == child->other.category) + { + //closing a child root window erases itself from wd->children, + //to make sure the iterator is valid, it must be reloaded. + + auto offset = std::distance(wd->children.rbegin(), i); + + //!!! + //a potential issue is that if the calling thread is not same with child's thread, + //the child root window may not be erased from wd->children now. + native_interface::close_window(child->root); + + i = wd->children.rbegin(); + std::advance(i, offset); + end = wd->children.rend(); + continue; + } + _m_destroy(child); + ++i; + } wd->children.clear(); @@ -1508,7 +1581,7 @@ namespace detail void window_manager::_m_move_core(core_window_t* wd, const point& delta) { - if(wd->other.category != category::root_tag::value) //A root widget always starts at (0, 0) and its childs are not to be changed + if(category::flags::root != wd->other.category) //A root widget always starts at (0, 0) and its childs are not to be changed { wd->pos_root += delta; if (category::flags::frame != wd->other.category) @@ -1525,6 +1598,11 @@ namespace detail for (auto child : wd->children) _m_move_core(child, delta); } + else + { + auto pos = native_interface::window_position(wd->root) + delta; + native_interface::move_window(wd->root, pos.x, pos.y); + } } //_m_find diff --git a/source/gui/dragger.cpp b/source/gui/dragger.cpp index 8b865891..43a56ba2 100644 --- a/source/gui/dragger.cpp +++ b/source/gui/dragger.cpp @@ -1,5 +1,17 @@ +/* +* A Dragger Implementation +* 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/gui/dragger.cpp +*/ #include +#include namespace nana { @@ -180,6 +192,23 @@ namespace nana delete impl_; } + dragger::dragger(dragger&& other) + : impl_(other.impl_) + { + other.impl_ = nullptr; + } + + dragger& dragger::operator=(dragger&& other) + { + if (this != &other) + { + delete impl_; + impl_ = other.impl_; + other.impl_ = nullptr; + } + return *this; + } + void dragger::target(window wd) { impl_->drag_target(wd, rectangle(), nana::arrange::horizontal_vertical); diff --git a/source/gui/element.cpp b/source/gui/element.cpp index 4271a4d2..b2fdbb7f 100644 --- a/source/gui/element.cpp +++ b/source/gui/element.cpp @@ -173,11 +173,8 @@ namespace nana const int x = r.x + 1; const int y = r.y + 1; - graph.set_color(bld_bgcolor); - graph.rectangle(rectangle{ x + 1, y + 1, 11, 11 }, true); - - graph.set_color(bld_fgcolor); - graph.rectangle(rectangle{ x, y, 13, 13 }, false); + graph.rectangle(rectangle{ x + 1, y + 1, 11, 11 }, true, bld_bgcolor); + graph.rectangle(rectangle{ x, y, 13, 13 }, false, bld_fgcolor); switch(crook_data.check_state) { @@ -252,11 +249,11 @@ namespace nana int x = r.x + (static_cast(r.width) - 16) / 2; int y = r.y + (static_cast(r.height) - 16) / 2; - graph.set_color(fgcolor); + graph.palette(false, fgcolor); graph.line(point{ x + 3, y + 7 }, point{ x + 6, y + 10 }); graph.line(point{ x + 7, y + 9 }, point{ x + 12, y + 4 }); - graph.set_color(fgcolor.blend(colors::white, 0.5)); + graph.palette(false, fgcolor.blend(colors::white, 0.5)); graph.line(point{ x + 3, y + 8 }, point{ x + 6, y + 11 }); graph.line(point{ x + 7, y + 10 }, point{ x + 12, y + 5 }); graph.line(point{ x + 4, y + 7 }, point{ x + 6, y + 9 }); @@ -515,16 +512,16 @@ namespace nana ::nana::point left_mid{ r.x + 1, r.y + 1 + static_cast(part_px) }, right_mid{ right_top.x, left_mid.y }; ::nana::point left_bottom{ r.x + 1, r.bottom() - 2 }, right_bottom{ r.right() - 2, r.bottom() - 2 }; - graph.set_color(bgcolor.blend(colors::white, 0.9)); + graph.palette(false, bgcolor.blend(colors::white, 0.9)); graph.line(left_top, left_mid); graph.line(right_top, right_mid); - graph.set_color(bgcolor.blend(colors::white, 0.5)); + graph.palette(false, bgcolor.blend(colors::white, 0.5)); graph.line(left_top, right_top); left_mid.y++; right_mid.y++; - graph.set_color(bgcolor.blend(colors::black, 0.8)); + graph.palette(false, bgcolor.blend(colors::black, 0.8)); graph.line(left_mid, left_bottom); graph.line(right_mid, right_bottom); @@ -557,7 +554,7 @@ namespace nana break; } - graph.set_color(clr); + graph.palette(false, clr); const int x = r.x + 4; const int y = r.y + 4; @@ -959,13 +956,13 @@ namespace nana ps[11].x = r.x + gap; ps[11].y = r.y + gap; - graph.set_color(fgcolor.blend(colors::black, true)); + graph.palette(false, fgcolor.blend(colors::black, true)); for (int i = 0; i < 11; ++i) graph.line(ps[i], ps[i + 1]); graph.line(ps[11], ps[0]); - graph.set_color(fgcolor); + graph.palette(false, fgcolor); unsigned thk_minus_2 = thickness_ - 2; graph.rectangle(rectangle{ ps[10].x + 1, ps[10].y + 1, (gap << 1) + thk_minus_2, thk_minus_2 }, true); @@ -1010,7 +1007,7 @@ namespace nana //Implement element_interface bool facade::draw(graph_reference graph, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle& r, element_state estate) { - graph.set_color(fgcolor); + graph.palette(false, fgcolor); return (*cite_)->draw(graph, bgcolor, fgcolor, r, estate, dir_); } //end class facade diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index ef5a4d52..b9772d23 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -1,7 +1,7 @@ /* * Filebox * 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 @@ -12,11 +12,11 @@ #include #include -#include +#include #if defined(NANA_WINDOWS) #include -#elif defined(NANA_LINUX) || defined(NANA_MACOS) +#elif defined(NANA_POSIX) #include #include #include @@ -24,7 +24,7 @@ #include #include #include - #include + #include #include #include #include @@ -32,22 +32,22 @@ namespace nana { -#if defined(NANA_LINUX) || defined(NANA_MACOS) +#if defined(NANA_POSIX) class filebox_implement : public form { struct item_fs { - nana::string name; + std::string name; ::tm modified_time; bool directory; nana::long_long_t bytes; friend listbox::iresolver& operator>>(listbox::iresolver& ires, item_fs& m) { - nana::string type; + std::wstring type; ires>>m.name>>type>>type; - m.directory = (type == STR("Directory")); + m.directory = (type == L"Directory"); return ires; } @@ -65,16 +65,16 @@ namespace nana ores<= 1024) { double cap = bytes / 1024.0; std::size_t uid = 0; - while((cap >= 1024.0) && (uid < (sizeof(ustr) / sizeof(nana::char_t*)))) + while((cap >= 1024.0) && (uid < (sizeof(ustr) / sizeof(char*)))) { cap /= 1024.0; ++uid; @@ -108,10 +108,11 @@ namespace nana if(pos + 2 < s.size()) s.erase(pos + 2); } - return static_cast(nana::charset(s)) + ustr[uid]; + + return s + ustr[uid]; } ss<&) { auto path = path_.caption(); - auto root = path.substr(0, path.find(STR('/'))); - if(root == STR("HOME")) - path.replace(0, 4, nana::filesystem::path_user()); - else if(root == STR("FILESYSTEM")) + auto root = path.substr(0, path.find('/')); + if(root == "HOME") + path.replace(0, 4, nana::filesystem::path_user().native()); + else if(root == "FILESYSTEM") path.erase(0, 10); else throw std::runtime_error("Nana.GUI.Filebox: Wrong categorize path"); - if(path.size() == 0) path = STR("/"); + if(path.size() == 0) path = "/"; _m_load_cat_path(path); }); filter_.create(*this); filter_.multi_lines(false); - filter_.tip_string(STR("Filter")); + filter_.tip_string("Filter"); filter_.events().key_release.connect_unignorable([this](const arg_keyboard&) { @@ -161,23 +162,23 @@ namespace nana }); btn_folder_.create(*this); - btn_folder_.caption(STR("&New Folder")); + btn_folder_.caption("&New Folder"); btn_folder_.events().click.connect_unignorable([this](const arg_click&) { form fm(this->handle(), API::make_center(*this, 300, 35)); - fm.caption(STR("Name the new folder")); + fm.caption("Name the new folder"); textbox folder(fm, nana::rectangle(5, 5, 160, 25)); folder.multi_lines(false); button btn(fm, nana::rectangle(170, 5, 60, 25)); - btn.caption(STR("Create")); + btn.caption("Create"); btn.events().click.connect_unignorable(folder_creator(*this, fm, folder)); button btn_cancel(fm, nana::rectangle(235, 5, 60, 25)); - btn_cancel.caption(STR("Cancel")); + btn_cancel.caption("Cancel"); btn_cancel.events().click.connect_unignorable([&fm](const arg_click&) { @@ -189,20 +190,20 @@ namespace nana tree_.create(*this); ls_file_.create(*this); - ls_file_.append_header(STR("Name"), 190); - ls_file_.append_header(STR("Modified"), 145); - ls_file_.append_header(STR("Type"), 80); - ls_file_.append_header(STR("Size"), 70); + ls_file_.append_header("Name", 190); + ls_file_.append_header("Modified", 145); + ls_file_.append_header("Type", 80); + ls_file_.append_header("Size", 70); auto fn_sel_file = [this](const arg_mouse& arg){ _m_sel_file(arg); }; ls_file_.events().dbl_click.connect_unignorable(fn_sel_file); ls_file_.events().mouse_down.connect_unignorable(fn_sel_file); - ls_file_.set_sort_compare(0, [](const nana::string& a, nana::any* fs_a, const nana::string& b, nana::any* fs_b, bool reverse) -> bool + ls_file_.set_sort_compare(0, [](const std::string& a, nana::any* fs_a, const std::string& b, nana::any* fs_b, bool reverse) -> bool { - int dira = fs_a->get()->directory ? 1 : 0; - int dirb = fs_b->get()->directory ? 1 : 0; + int dira = any_cast(fs_a)->directory ? 1 : 0; + int dirb = any_cast(fs_b)->directory ? 1 : 0; if(dira != dirb) return (reverse ? dira < dirb : dira > dirb); @@ -211,8 +212,8 @@ namespace nana while(true) { - std::size_t pos_a = a.find_first_of(STR("0123456789"), seek_a); - std::size_t pos_b = b.find_first_of(STR("0123456789"), seek_b); + std::size_t pos_a = a.find_first_of("0123456789", seek_a); + std::size_t pos_b = b.find_first_of("0123456789", seek_b); if((pos_a != a.npos) && (pos_a == pos_b)) { @@ -222,11 +223,11 @@ namespace nana if(text_a != text_b) return (reverse ? text_a > text_b : text_a < text_b); - std::size_t end_a = a.find_first_not_of(STR("0123456789"), pos_a + 1); - std::size_t end_b = b.find_first_not_of(STR("0123456789"), pos_b + 1); + std::size_t end_a = a.find_first_not_of("0123456789", pos_a + 1); + std::size_t end_b = b.find_first_not_of("0123456789", pos_b + 1); - nana::string num_a = a.substr(pos_a, end_a != a.npos ? end_a - pos_a : a.npos); - nana::string num_b = b.substr(pos_b, end_b != b.npos ? end_b - pos_b : b.npos); + auto num_a = a.substr(pos_a, end_a != a.npos ? end_a - pos_a : a.npos); + auto num_b = b.substr(pos_b, end_b != b.npos ? end_b - pos_b : b.npos); if(num_a != num_b) { @@ -253,24 +254,24 @@ namespace nana return (reverse ? cia > cib : cia < cib); return (reverse ? cia.substr(seek_a) > cib.substr(seek_b) : cia.substr(seek_a) < cib.substr(seek_b)); }); - ls_file_.set_sort_compare(2, [](const nana::string& a, nana::any* anyptr_a, const nana::string& b, nana::any* anyptr_b, bool reverse) -> bool + ls_file_.set_sort_compare(2, [](const std::string& a, nana::any* anyptr_a, const std::string& b, nana::any* anyptr_b, bool reverse) -> bool { - int dir1 = anyptr_a->get()->directory ? 1 : 0; - int dir2 = anyptr_b->get()->directory ? 1 : 0; + int dir1 = any_cast(anyptr_a)->directory ? 1 : 0; + int dir2 = any_cast(anyptr_b)->directory ? 1 : 0; if(dir1 != dir2) return (reverse ? dir1 < dir2 : dir1 > dir2); return (reverse ? a > b : a < b); }); - ls_file_.set_sort_compare(3, [this](const nana::string&, nana::any* anyptr_a, const nana::string&, nana::any* anyptr_b, bool reverse) -> bool + ls_file_.set_sort_compare(3, [this](const std::string&, nana::any* anyptr_a, const std::string&, nana::any* anyptr_b, bool reverse) -> bool { - item_fs * fsa = anyptr_a->get(); - item_fs * fsb = anyptr_b->get(); + item_fs * fsa = any_cast(anyptr_a); + item_fs * fsb = any_cast(anyptr_b); return (reverse ? fsa->bytes > fsb->bytes : fsa->bytes < fsb->bytes); }); lb_file_.create(*this); - lb_file_.caption(STR("File:")); + lb_file_.caption("File:"); tb_file_.create(*this); tb_file_.multi_lines(false); @@ -286,14 +287,14 @@ namespace nana cb_types_.events().selected.connect_unignorable([this](const arg_combox&){ _m_list_fs(); }); btn_ok_.create(*this); - btn_ok_.caption(STR("&OK")); + btn_ok_.caption("&OK"); btn_ok_.events().click.connect_unignorable([this](const arg_click&) { _m_ok(); }); btn_cancel_.create(*this); - btn_cancel_.caption(STR("&Cancel")); + btn_cancel_.caption("&Cancel"); btn_cancel_.events().click.connect_unignorable([this](const arg_click&) { @@ -305,25 +306,25 @@ namespace nana _m_init_tree(); if(0 == title.size()) - caption(io_read ? STR("Open") : STR("Save As")); + caption(io_read ? "Open" : "Save As"); else caption(title); } - void def_extension(const nana::string& ext) + void def_extension(const std::string& ext) { def_ext_ = ext; } - void load_fs(const nana::string& init_path, const nana::string& init_file) + void load_fs(const std::string& init_path, const std::string& init_file) { //Simulate the behavior like Windows7's lpstrInitialDir(http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx) //Phase 1 - nana::string dir; + std::string dir; - auto pos = init_file.find_last_of(STR("\\/")); - nana::string file_with_path_removed = (pos != init_file.npos ? init_file.substr(pos + 1) : init_file); + auto pos = init_file.find_last_of("\\/"); + auto file_with_path_removed = (pos != init_file.npos ? init_file.substr(pos + 1) : init_file); if(saved_init_path != init_path) { @@ -343,29 +344,29 @@ namespace nana else dir = saved_selected_path; - _m_load_cat_path(dir.size() ? dir : nana::filesystem::path_user()); + _m_load_cat_path(dir.size() ? dir : nana::filesystem::path_user().native()); - tb_file_.caption(file_with_path_removed); + tb_file_.caption(file_with_path_removed); } - void add_filter(const nana::string& desc, const nana::string& type) + void add_filter(const std::string& desc, const std::string& type) { std::size_t i = cb_types_.the_number_of_options(); cb_types_.push_back(desc); if(0 == i) cb_types_.option(0); - std::vector v; + std::vector v; std::size_t beg = 0; while(true) { - auto pos = type.find(STR(';'), beg); + auto pos = type.find(';', beg); auto ext = type.substr(beg, pos == type.npos ? type.npos : pos - beg); - auto dot = ext.find(STR('.')); + auto dot = ext.find('.'); if((dot != ext.npos) && (dot + 1 < ext.size())) { ext.erase(0, dot + 1); - if(ext == STR("*")) + if(ext == "*") { v.clear(); break; @@ -381,12 +382,12 @@ namespace nana cb_types_.anyobj(i, v); } - bool file(nana::string& fs) const + bool file(std::string& fs) const { if(selection_.type == kind::none) return false; - auto pos = selection_.target.find_last_of(STR("\\/")); + auto pos = selection_.target.find_last_of("\\/"); if(pos != selection_.target.npos) saved_selected_path = selection_.target.substr(0, pos); else @@ -419,37 +420,34 @@ namespace nana void _m_init_tree() { - using namespace nana::filesystem; - //The path in linux is starting with the character '/', the name of root key should be //"FS.HOME", "FS.ROOT". Because a key of the tree widget should not be '/' - nodes_.home = tree_.insert(STR("FS.HOME"), STR("Home")); + nodes_.home = tree_.insert("FS.HOME", "Home"); nodes_.home.value(kind::filesystem); - nodes_.filesystem = tree_.insert(STR("FS.ROOT"), STR("Filesystem")); + nodes_.filesystem = tree_.insert("FS.ROOT", "Filesystem"); nodes_.filesystem.value(kind::filesystem); - file_iterator end; - for(file_iterator i(path_user()); i != end; ++i) + namespace fs = ::nana::experimental::filesystem; + + std::vector paths; + paths.emplace_back(fs::path_user().native()); + paths.emplace_back("/"); + + fs::directory_iterator end; + for (auto & p : paths) { - if((false == i->directory) || (i->name.size() && i->name[0] == '.')) continue; - - item_proxy node = tree_.insert(nodes_.home, i->name, i->name); - if(false == node.empty()) + for (fs::directory_iterator i(p); i != end; ++i) { - node.value(kind::filesystem); - break; - } - } + auto name = i->path().filename().native(); + if (!is_directory(i->status()) || (name.size() && name[0] == '.')) + continue; - for(file_iterator i(STR("/")); i != end; ++i) - { - if((false == i->directory) || (i->name.size() && i->name[0] == '.')) continue; - - item_proxy node = tree_.insert(nodes_.filesystem, i->name, i->name); - if(false == node.empty()) - { - node.value(kind::filesystem); - break; + item_proxy node = tree_.insert(nodes_.filesystem, name, name); + if (false == node.empty()) + { + node.value(kind::filesystem); + break; + } } } @@ -462,56 +460,61 @@ namespace nana { if(arg.operated && (arg.item.value() == kind::filesystem)) { - auto path = tree_.make_key_path(arg.item, STR("/")) + STR("/"); + auto path = tree_.make_key_path(arg.item, "/") + "/"; _m_resolute_path(path); _m_load_cat_path(path); } }); } - nana::string _m_resolute_path(nana::string& path) + std::string _m_resolute_path(std::string& path) { - auto pos = path.find(STR('/')); + auto pos = path.find('/'); if(pos != path.npos) { auto begstr = path.substr(0, pos); - if(begstr == STR("FS.HOME")) - path.replace(0, 7, nana::filesystem::path_user()); + if(begstr == "FS.HOME") + path.replace(0, 7, nana::filesystem::path_user().native()); else path.erase(0, pos); return begstr; } - return nana::string(); + return std::string(); } - void _m_load_path(const nana::string& path) + void _m_load_path(const std::string& path) { addr_.filesystem = path; - if(addr_.filesystem.size() && addr_.filesystem[addr_.filesystem.size() - 1] != STR('/')) - addr_.filesystem += STR('/'); + if(addr_.filesystem.size() && addr_.filesystem[addr_.filesystem.size() - 1] != '/') + addr_.filesystem += '/'; file_container_.clear(); - using namespace nana::filesystem; - attribute fattr; - file_iterator end; - for(file_iterator i(path); i != end; ++i) + namespace fs = ::nana::experimental::filesystem; + + fs::directory_iterator end; + for(fs::directory_iterator i(path); i != end; ++i) { - if((i->name.size() == 0) || (i->name[0] == STR('.'))) + auto name = i->path().filename().native(); + if(name.empty() || (name.front() == '.')) continue; + item_fs m; - m.name = i->name; - if(file_attrib(path + m.name, fattr)) + m.name = name; + + auto fattr = fs::status(path + m.name); + + if(fattr.type() != fs::file_type::not_found && fattr.type() != fs::file_type::unknown) { - m.bytes = fattr.bytes; - m.directory = fattr.is_directory; - m.modified_time = fattr.modified; + m.bytes = fs::file_size(path + m.name); + m.directory = fs::is_directory(fattr); + ::nana::filesystem::modified_file_time(path + m.name, m.modified_time); } else { m.bytes = 0; - m.directory = i->directory; - modified_file_time(path + i->name, m.modified_time); + m.directory = fs::is_directory(*i); + ::nana::filesystem::modified_file_time(path + i->path().filename().native(), m.modified_time); } file_container_.push_back(m); @@ -522,57 +525,59 @@ namespace nana std::sort(file_container_.begin(), file_container_.end(), pred_sort_fs()); } - void _m_load_cat_path(nana::string path) + void _m_load_cat_path(std::string path) { - if((path.size() == 0) || (path[path.size() - 1] != STR('/'))) - path += STR('/'); + if((path.size() == 0) || (path[path.size() - 1] != '/')) + path += '/'; auto beg_node = tree_.selected(); while(!beg_node.empty() && (beg_node != nodes_.home) && (beg_node != nodes_.filesystem)) beg_node = beg_node.owner(); - auto head = nana::filesystem::path_user(); + auto head = nana::filesystem::path_user().native(); if(path.size() >= head.size() && (path.substr(0, head.size()) == head)) {//This is HOME - path_.caption(STR("HOME")); + path_.caption("HOME"); if(beg_node != nodes_.home) nodes_.home->select(true); } else { //Redirect to '/' - path_.caption(STR("FILESYSTEM")); + path_.caption("FILESYSTEM"); if(beg_node != nodes_.filesystem) nodes_.filesystem->select(true); head.clear(); } - if(head.size() == 0 || head[head.size() - 1] != STR('/')) - head += STR('/'); + if(head.size() == 0 || head[head.size() - 1] != '/') + head += '/'; - nana::filesystem::file_iterator end; - for(nana::filesystem::file_iterator i(head); i != end; ++i) + namespace fs = ::nana::experimental::filesystem; + + fs::directory_iterator end; + for(fs::directory_iterator i(head); i != end; ++i) { - if(i->directory) - path_.childset(i->name, 0); + if(is_directory(*i)) + path_.childset(i->path().filename().native(), 0); } auto cat_path = path_.caption(); - if(cat_path.size() && cat_path[cat_path.size() - 1] != STR('/')) - cat_path += STR('/'); + if(cat_path.size() && cat_path[cat_path.size() - 1] != '/') + cat_path += '/'; auto beg = head.size(); while(true) { - auto pos = path.find(STR('/'), beg); + auto pos = path.find('/', beg); auto folder = path.substr(beg, pos != path.npos ? pos - beg: path.npos); if(folder.size() == 0) break; - (cat_path += folder) += STR('/'); - (head += folder) += STR('/'); + (cat_path += folder) += '/'; + (head += folder) += '/'; path_.caption(cat_path); - for(nana::filesystem::file_iterator i(head); i != end; ++i) + for(fs::directory_iterator i(head); i != end; ++i) { - if(i->directory) - path_.childset(i->name, 0); + if (is_directory(*i)) + path_.childset(i->path().filename().native(), 0); } if(pos == path.npos) @@ -583,7 +588,7 @@ namespace nana _m_list_fs(); } - bool _m_filter_allowed(const nana::string& name, bool is_dir, const nana::string& filter, const std::vector* extension) const + bool _m_filter_allowed(const std::string& name, bool is_dir, const std::string& filter, const std::vector* extension) const { if(filter.size() && (name.find(filter) == filter.npos)) return false; @@ -601,12 +606,12 @@ namespace nana void _m_list_fs() { - nana::string filter = filter_.caption(); + auto filter = filter_.caption(); ls_file_.auto_draw(false); ls_file_.clear(); - std::vector* ext_types = cb_types_.anyobj >(cb_types_.option()); + auto ext_types = cb_types_.anyobj >(cb_types_.option()); auto cat = ls_file_.at(0); for(auto & fs: file_container_) { @@ -618,7 +623,7 @@ namespace nana ls_file_.auto_draw(true); } - void _m_finish(kind::t type, const nana::string& tar) + void _m_finish(kind::t type, const std::string& tar) { selection_.target = tar; selection_.type = type; @@ -635,25 +640,35 @@ namespace nana { auto path = tx_path_.caption(); - msgbox mb(fm_, STR("Create Folder")); + msgbox mb(fm_, "Create Folder"); mb.icon(msgbox::icon_warning); - if(0 == path.size() || path[0] == STR('.') || path[0] == STR('/')) + if(0 == path.size() || path[0] == '.' || path[0] == '/') { - mb< * exts = cb_types_.anyobj >(cb_types_.option()); + auto exts = cb_types_.anyobj >(cb_types_.option()); if(0 == exts || exts->size() == 0) return false; auto & ext = exts->at(0); - if(def_ext_[0] != STR('.')) - tar += STR('.'); + if(def_ext_[0] != '.') + tar += '.'; tar += ext; return true; } @@ -703,7 +718,7 @@ namespace nana if(event_code::dbl_click == arg.evt_code) { if(m.directory) - _m_load_cat_path(addr_.filesystem + m.name + STR("/")); + _m_load_cat_path(addr_.filesystem + m.name + "/"); else _m_finish(kind::filesystem, addr_.filesystem + m.name); } @@ -724,34 +739,34 @@ namespace nana auto file = tb_file_.caption(); if(file.size()) { - if(file[0] == STR('.')) + if(file[0] == L'.') { msgbox mb(*this, caption()); mb.icon(msgbox::icon_warning); - mb<()) { - nana::string path = tree_.make_key_path(node, STR("/")) + STR("/"); + auto path = tree_.make_key_path(node, "/") + "/"; _m_resolute_path(path); - nana::filesystem::file_iterator end; - for(nana::filesystem::file_iterator i(path); i != end; ++i) + namespace fs = ::nana::experimental::filesystem; + + fs::directory_iterator end; + for (fs::directory_iterator i{path}; i != end; ++i) { - if((false == i->directory) || (i->name.size() && i->name[0] == '.')) continue; - auto child = node.append(i->name, i->name, kind::filesystem); + auto name = i->path().filename().native(); + if((!is_directory(*i)) || (name.size() && name[0] == '.')) + continue; + + auto child = node.append(name, name, kind::filesystem); if(!child.empty()) { - for(nana::filesystem::file_iterator u(path + i->name); u != end; ++u) + for(fs::directory_iterator u(i->path()); u != end; ++u) { - if(false == u->directory || (u->name.size() && u->name[0] == '.')) continue; + auto uname = i->path().filename().native(); + if ((!is_directory(*i)) || (uname.size() && uname[0] == '.')) + continue; - child.append(u->name, u->name, kind::filesystem); + child.append(uname, uname, kind::filesystem); break; } } @@ -814,7 +836,7 @@ namespace nana } private: bool io_read_; - nana::string def_ext_; + std::string def_ext_; place place_; categorize path_; @@ -835,22 +857,22 @@ namespace nana }nodes_; std::vector file_container_; - struct path_tag + struct path_rep { - nana::string filesystem; + std::string filesystem; }addr_; - struct selection_tag + struct selection_rep { kind::t type; - nana::string target; + std::string target; }selection_; - static nana::string saved_init_path; - static nana::string saved_selected_path; + static std::string saved_init_path; + static std::string saved_selected_path; };//end class filebox_implement - nana::string filebox_implement::saved_init_path; - nana::string filebox_implement::saved_selected_path; + std::string filebox_implement::saved_init_path; + std::string filebox_implement::saved_selected_path; #endif //class filebox @@ -858,16 +880,16 @@ namespace nana { struct filter { - nana::string des; - nana::string type; + std::string des; + std::string type; }; window owner; bool open_or_save; - nana::string file; - nana::string title; - nana::string path; + std::string file; + std::string title; + std::string path; std::vector filters; }; @@ -885,9 +907,12 @@ namespace nana auto len = ::GetCurrentDirectory(0, nullptr); if(len) { - impl_->path.resize(len + 1); - ::GetCurrentDirectory(len, &(impl_->path[0])); - impl_->path.resize(len); + std::wstring path; + path.resize(len + 1); + ::GetCurrentDirectory(len, &(path[0])); + path.resize(len); + + impl_->path = to_utf8(path); } #endif } @@ -913,13 +938,13 @@ namespace nana impl_->owner = wd; } - nana::string filebox::title(nana::string s) + std::string filebox::title(std::string s) { impl_->title.swap(s); return s; } - filebox& filebox::init_path(const nana::string& ipstr) + filebox& filebox::init_path(const std::string& ipstr) { if(ipstr.empty()) { @@ -927,33 +952,32 @@ namespace nana } else { - nana::filesystem::attribute attr; - if (nana::filesystem::file_attrib(ipstr, attr)) - if (attr.is_directory) + namespace fs = ::nana::experimental::filesystem; + if (fs::is_directory(ipstr)) impl_->path = ipstr; } return *this; } - filebox& filebox::init_file(const nana::string& ifstr) + filebox& filebox::init_file(const std::string& ifstr) { impl_->file = ifstr; return *this; } - filebox& filebox::add_filter(const nana::string& description, const nana::string& filetype) + filebox& filebox::add_filter(const std::string& description, const std::string& filetype) { implement::filter flt = {description, filetype}; impl_->filters.push_back(flt); return *this; } - nana::string filebox::path() const + std::string filebox::path() const { return impl_->path; } - nana::string filebox::file() const + std::string filebox::file() const { return impl_->file; } @@ -961,36 +985,36 @@ namespace nana bool filebox::show() const { #if defined(NANA_WINDOWS) - if(impl_->file.size() < 520) - impl_->file.resize(520); + std::wstring wfile; + wfile.resize(520); OPENFILENAME ofn; memset(&ofn, 0, sizeof ofn); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = reinterpret_cast(API::root(impl_->owner)); - ofn.lpstrFile = &(impl_->file[0]); - ofn.nMaxFile = static_cast(impl_->file.size() - 1); + ofn.lpstrFile = &(wfile[0]); + ofn.nMaxFile = static_cast(wfile.size() - 1); - const nana::char_t * filter; - nana::string filter_holder; - nana::string default_extension; + const wchar_t * filter; + std::wstring filter_holder; + std::wstring default_extension; if(impl_->filters.size()) { for(auto & f : impl_->filters) { - filter_holder += f.des; - filter_holder += static_cast('\0'); - nana::string fs = f.type; + filter_holder += to_wstring(f.des); + filter_holder += static_cast('\0'); + std::wstring fs = to_wstring(f.type); std::size_t pos = 0; while(true) { - pos = fs.find(STR(" "), pos); + pos = fs.find(L" ", pos); if(pos == fs.npos) break; fs.erase(pos); } filter_holder += fs; - filter_holder += static_cast('\0'); + filter_holder += static_cast('\0'); //Get the default file extentsion if (default_extension.empty()) @@ -1010,14 +1034,16 @@ namespace nana filter = filter_holder.data(); } else - filter = STR("All Files\0*.*\0"); + filter = L"All Files\0*.*\0"; + auto wtitle = to_wstring(impl_->title); + auto wpath = to_wstring(impl_->path); ofn.lpstrFilter = filter; - ofn.lpstrTitle = (impl_->title.size() ? impl_->title.c_str() : nullptr); + ofn.lpstrTitle = (wtitle.empty() ? nullptr : wtitle.c_str()); ofn.nFilterIndex = 0; ofn.lpstrFileTitle = nullptr; ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = (impl_->path.size() ? impl_->path.c_str() : nullptr); + ofn.lpstrInitialDir = (wpath.empty() ? nullptr : wpath.c_str()); if (!impl_->open_or_save) ofn.Flags = OFN_OVERWRITEPROMPT; //Overwrite prompt if it is save mode @@ -1026,19 +1052,20 @@ namespace nana if(FALSE == (impl_->open_or_save ? ::GetOpenFileName(&ofn) : ::GetSaveFileName(&ofn))) return false; - impl_->file.resize(nana::strlen(impl_->file.data())); -#elif defined(NANA_LINUX) || defined(NANA_MACOS) + wfile.resize(std::wcslen(wfile.data())); + impl_->file = to_utf8(wfile); +#elif defined(NANA_POSIX) filebox_implement fb(impl_->owner, impl_->open_or_save, impl_->title); if(impl_->filters.size()) { for(auto & f: impl_->filters) { - nana::string fs = f.type; + std::string fs = f.type; std::size_t pos = 0; while(true) { - pos = fs.find(STR(" "), pos); + pos = fs.find(" ", pos); if(pos == fs.npos) break; fs.erase(pos); @@ -1047,7 +1074,7 @@ namespace nana } } else - fb.add_filter(STR("All Files"), STR("*.*")); + fb.add_filter("All Files", "*.*"); fb.load_fs(impl_->path, impl_->file); @@ -1055,7 +1082,7 @@ namespace nana if(false == fb.file(impl_->file)) return false; #endif - auto tpos = impl_->file.find_last_of(STR("\\/")); + auto tpos = impl_->file.find_last_of("\\/"); if(tpos != impl_->file.npos) impl_->path = impl_->file.substr(0, tpos); else diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index a34fdbe2..dd20cf6e 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -38,7 +38,7 @@ namespace nana : public form { public: - msgbox_window(window wd, const ::nana::string& title, msgbox::button_t btn, msgbox::icon_t ico) + msgbox_window(window wd, const std::string& title, msgbox::button_t btn, msgbox::icon_t ico) : form(wd, rectangle(1, 1, 1, 1), appear::decorate<>()), owner_(wd), pick_(msgbox::pick_yes) { @@ -61,14 +61,14 @@ namespace nana { _m_click(arg); }); - yes_.caption(STR("OK")); + yes_.caption("OK"); width_pixel += 77; if(msgbox::yes_no == btn || msgbox::yes_no_cancel == btn) { - yes_.caption(STR("Yes")); + yes_.caption("Yes"); no_.create(*this); - no_.caption(STR("No")); + no_.caption("No"); no_.events().click.connect_unignorable([this](const arg_click& arg) { _m_click(arg); @@ -79,7 +79,7 @@ namespace nana if(msgbox::yes_no_cancel == btn) { cancel_.create(*this); - cancel_.caption(STR("Cancel")); + cancel_.caption("Cancel"); cancel_.events().click.connect_unignorable([this](const arg_click& arg) { _m_click(arg); @@ -108,7 +108,7 @@ namespace nana _m_icon(ico); } - void prompt(const nana::string& text) + void prompt(const std::string& text) { if(text.size()) { @@ -352,13 +352,17 @@ namespace nana return *this; } - msgbox::msgbox(const nana::string& title) + msgbox::msgbox(const std::string& title) : wd_(nullptr), title_(title), button_(ok), icon_(icon_none) - {} + { + throw_not_utf8(title_); + } - msgbox::msgbox(window wd, const nana::string& title, button_t b) + msgbox::msgbox(window wd, const std::string& title, button_t b) : wd_(wd), title_(title), button_(b), icon_(icon_none) - {} + { + throw_not_utf8(title_); + } msgbox& msgbox::icon(icon_t ic) { @@ -372,23 +376,15 @@ namespace nana sstream_.clear(); } - msgbox & msgbox::operator<<(const nana::string& str) + msgbox & msgbox::operator<<(const std::wstring& str) { -#if defined(NANA_UNICODE) - sstream_<(nana::charset(str)); -#else - sstream_<(nana::charset(str));; -#else - sstream_<(API::root(wd_)), static_cast(nana::charset(sstream_.str())).c_str(), title_.c_str(), type); - #else - int bt = ::MessageBoxA(reinterpret_cast(API::root(wd_), sstream_.str().c_str(), title_.c_str(), type); - #endif + auto bt = ::MessageBoxW(reinterpret_cast(API::root(wd_)), to_wstring(sstream_.str()).c_str(), to_wstring(title_).c_str(), type); + switch(bt) { case IDOK: @@ -473,9 +466,12 @@ namespace nana : public ::nana::form { public: - inputbox_window(window owner, paint::image (&imgs)[4], ::nana::rectangle (&valid_areas)[4], const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) + inputbox_window(window owner, paint::image (&imgs)[4], ::nana::rectangle (&valid_areas)[4], const ::std::string & desc, const ::std::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector& each_height) : form(owner, API::make_center(owner, 500, 300), appear::decorate<>()) { + throw_not_utf8(desc); + throw_not_utf8(title); + desc_.create(*this); desc_.format(true).caption(desc); auto desc_extent = desc_.measure(470); @@ -652,13 +648,13 @@ namespace nana int last; int step; - ::nana::string label_text; + ::std::string label_text; ::nana::panel dock; ::nana::label label; ::nana::spinbox spinbox; }; - inputbox::integer::integer(::nana::string label, int init_value, int begin, int last, int step) + inputbox::integer::integer(::std::string label, int init_value, int begin, int last, int step) : impl_(new implement) { auto impl = impl_.get(); @@ -681,7 +677,7 @@ namespace nana } //Implementation of abstract_content - const ::nana::string& inputbox::integer::label() const + const ::std::string& inputbox::integer::label() const { return impl_->label_text; } @@ -704,7 +700,7 @@ namespace nana impl->spinbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, value_px, 0 }); impl->spinbox.range(impl->begin, impl->last, impl->step); - impl->spinbox.value(std::to_wstring(impl->value)); + impl->spinbox.value(std::to_string(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -730,13 +726,13 @@ namespace nana double last; double step; - ::nana::string label_text; + ::std::string label_text; ::nana::panel dock; ::nana::label label; ::nana::spinbox spinbox; }; - inputbox::real::real(::nana::string label, double init_value, double begin, double last, double step) + inputbox::real::real(::std::string label, double init_value, double begin, double last, double step) : impl_(new implement) { auto impl = impl_.get(); @@ -759,7 +755,7 @@ namespace nana } //Implementation of abstract_content - const ::nana::string& inputbox::real::label() const + const ::std::string& inputbox::real::label() const { return impl_->label_text; } @@ -782,7 +778,7 @@ namespace nana impl->spinbox.create(impl->dock, rectangle{ static_cast(label_px + 10), 0, value_px, 0 }); impl->spinbox.range(impl->begin, impl->last, impl->step); - impl->spinbox.value(std::to_wstring(impl->value)); + impl->spinbox.value(std::to_string(impl->value)); impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg) { @@ -803,29 +799,33 @@ namespace nana //class text struct inputbox::text::implement { - ::nana::string value; - ::nana::string tip; + ::std::string value; + ::std::string tip; wchar_t mask_character{0}; - std::vector< ::nana::string> options; + std::vector< ::std::string> options; - ::nana::string label_text; - ::nana::string init_text; + ::std::string label_text; + ::std::string init_text; ::nana::panel dock; ::nana::label label; ::nana::combox combox; ::nana::textbox textbox; }; - inputbox::text::text(::nana::string label, ::nana::string init_text) + inputbox::text::text(::std::string label, ::std::string init_text) : impl_(new implement) { impl_->label_text.swap(label); impl_->init_text.swap(init_text); } - inputbox::text::text(::nana::string label, std::vector<::nana::string> options) + inputbox::text::text(::std::string label, std::vector<::std::string> options) : impl_(new implement) { + throw_not_utf8(label); + for (auto & text : options) + throw_not_utf8(text); + impl_->options.swap(options); impl_->label_text.swap(label); } @@ -835,12 +835,12 @@ namespace nana void inputbox::text::tip_string(std::wstring tip) { - impl_->tip.swap(tip); + impl_->tip = to_utf8(tip); } void inputbox::text::tip_string(std::string tip_utf8) { - impl_->tip = ::nana::charset(tip_utf8, ::nana::unicode::utf8); + impl_->tip.swap(tip_utf8); } void inputbox::text::mask_character(wchar_t ch) @@ -848,7 +848,7 @@ namespace nana impl_->mask_character = ch; } - ::nana::string inputbox::text::value() const + ::std::string inputbox::text::value() const { if (!impl_->textbox.empty()) return impl_->textbox.caption(); @@ -859,7 +859,7 @@ namespace nana } //Implementation of abstract_content - const ::nana::string& inputbox::text::label() const + const ::std::string& inputbox::text::label() const { return impl_->label_text; } @@ -929,7 +929,7 @@ namespace nana int month; int day; - ::nana::string label_text; + ::std::string label_text; ::nana::panel dock; ::nana::label label; ::nana::combox wdg_month; @@ -937,18 +937,18 @@ namespace nana ::nana::spinbox wdg_year; }; - inputbox::date::date(::nana::string label) + inputbox::date::date(::std::string label) : impl_(new implement) { - impl_->label_text = std::move(label); + impl_->label_text.swap(label); } //Instance for impl_ because implmenet is incomplete type at the point of declaration inputbox::date::~date(){} - ::nana::string inputbox::date::value() const + ::std::string inputbox::date::value() const { - return std::to_wstring(impl_->month) + L'-' + std::to_wstring(impl_->day) + L", " + std::to_wstring(impl_->year); + return std::to_string(impl_->month) + '-' + std::to_string(impl_->day) + ", " + std::to_string(impl_->year); } int inputbox::date::year() const @@ -974,7 +974,7 @@ namespace nana } //Implementation of abstract_content - const ::nana::string& inputbox::date::label() const + const ::std::string& inputbox::date::label() const { return impl_->label_text; } @@ -1009,8 +1009,8 @@ namespace nana impl->wdg_month.option(today.month - 1); - impl->wdg_day.value(std::to_wstring(today.day)); - impl->wdg_year.value(std::to_wstring(today.year)); + impl->wdg_day.value(std::to_string(today.day)); + impl->wdg_year.value(std::to_string(today.year)); impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg) { @@ -1051,7 +1051,7 @@ namespace nana if (day > days) day = days; - impl->wdg_day.value(std::to_wstring(day)); + impl->wdg_day.value(std::to_string(day)); }; impl->wdg_year.events().text_changed.connect_unignorable(make_days); @@ -1071,19 +1071,21 @@ namespace nana { filebox fbox; - ::nana::string value; - ::nana::string label_text; + ::std::string value; + ::std::string label_text; ::nana::panel dock; ::nana::label label; ::nana::textbox path_edit; ::nana::button browse; - implement(const filebox& fb, ::nana::string&& labelstr) + implement(const filebox& fb, ::std::string&& labelstr) : fbox(fb), label_text(std::move(labelstr)) - {} + { + throw_not_utf8(label_text); + } }; - inputbox::path::path(::nana::string label, const filebox& fb) + inputbox::path::path(::std::string label, const filebox& fb) : impl_(new implement(fb, std::move(label))) { } @@ -1091,7 +1093,7 @@ namespace nana //Instance for impl_ because implmenet is incomplete type at the point of declaration inputbox::path::~path(){} - ::nana::string inputbox::path::value() const + ::std::string inputbox::path::value() const { if (!impl_->path_edit.empty()) return impl_->path_edit.caption(); @@ -1100,7 +1102,7 @@ namespace nana } //Implementation of abstract_content - const ::nana::string& inputbox::path::label() const + const ::std::string& inputbox::path::label() const { return impl_->label_text; } @@ -1148,7 +1150,7 @@ namespace nana //end class path - inputbox::inputbox(window owner, ::nana::string desc, ::nana::string title) + inputbox::inputbox(window owner, ::std::string desc, ::std::string title) : owner_{ owner }, description_(std::move(desc)), title_(std::move(title)) diff --git a/source/gui/notifier.cpp b/source/gui/notifier.cpp index 242b0334..4e98e037 100644 --- a/source/gui/notifier.cpp +++ b/source/gui/notifier.cpp @@ -299,10 +299,10 @@ namespace nana impl_->native_handle = nullptr; } - void notifier::text(const nana::string& str) + void notifier::text(const std::string& str) { #if defined(NANA_WINDOWS) - NOTIFYICONDATA icon_data; + NOTIFYICONDATAW icon_data; memset(&icon_data, 0, sizeof icon_data); icon_data.cbSize = sizeof icon_data; icon_data.hWnd = reinterpret_cast(impl_->native_handle); @@ -310,18 +310,18 @@ namespace nana icon_data.uFlags = NIF_MESSAGE | NIF_TIP; icon_data.uCallbackMessage = nana::detail::messages::tray; - strcpy(icon_data.szTip, str.data()); + std::wcscpy(icon_data.szTip, to_wstring(str).c_str()); ::Shell_NotifyIcon(impl_->icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); impl_->icon_added = true; #endif } - void notifier::icon(const nana::string& icon_file) + void notifier::icon(const std::string& icon_file) { #if defined(NANA_WINDOWS) auto pre_icon = impl_->icon_handle; - auto ico = (HICON)::LoadImage(0, icon_file.data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + auto ico = (HICON)::LoadImageW(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); if (ico) { impl_->icon_handle = ico; @@ -333,10 +333,10 @@ namespace nana #endif } - void notifier::insert_icon(const nana::string& icon_file) + void notifier::insert_icon(const std::string& icon_file) { #if defined(NANA_WINDOWS) - auto icon = (HICON)::LoadImage(0, icon_file.data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); impl_->icons.push_back(icon); #endif } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index 88ea8dd7..d6adb5d0 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -1,7 +1,7 @@ /* * An Implementation of Place for Layout * 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 @@ -534,12 +534,12 @@ namespace nana }); } - field_interface& operator<<(const nana::char_t* label_text) override + field_interface& operator<<(const char* label_text) override { - return static_cast(this)->operator<<(agent