Merge branch 'develop'

This commit is contained in:
Jinhao 2018-05-06 00:03:04 +08:00
commit db4fa8b32c
54 changed files with 2057 additions and 1178 deletions

3
.gitignore vendored
View File

@ -7,6 +7,8 @@ bii/cmake/*
bii/deps/* bii/deps/*
build/vc2013-bkl/* build/vc2013-bkl/*
build/makefile-bkl/* build/makefile-bkl/*
build/compile_commands.json
build/install_manifest.txt
*.obj *.obj
*.exe *.exe
*.pdb *.pdb
@ -46,3 +48,4 @@ cmake_install.cmake
*.db *.db
*.opendb *.opendb
.vscode

View File

@ -59,7 +59,7 @@ matrix:
- llvm-toolchain-precise - llvm-toolchain-precise
before_install: before_install:
- git clone --depth=1 --branch=hotfix-1.5 https://github.com/qPCR4vir/nana-demo.git ../nana-demo - git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git ../nana-demo
- export PATH="$HOME/bin:$PATH" - export PATH="$HOME/bin:$PATH"
#- mkdir ~/bin #it seemd that a bin already exists from 20170901 #- mkdir ~/bin #it seemd that a bin already exists from 20170901
- wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true
@ -87,7 +87,7 @@ script:
# we are in "... nana/../nana_lib/bin/" we need "../../nana" to get the CMakeList.txt of nana. # we are in "... nana/../nana_lib/bin/" we need "../../nana" to get the CMakeList.txt of nana.
# Thus, make install will put the nana.lib in "... nana/../nana_lib/lib/" # Thus, make install will put the nana.lib in "... nana/../nana_lib/lib/"
# and the includes in "... nana/../nana_lib/include/" # and the includes in "... nana/../nana_lib/include/"
- cmake -G"Unix Makefiles" ../../nana -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON - cmake -G"Unix Makefiles" ../../nana -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_ENABLE_PNG=OFF -DNANA_CMAKE_BUILD_DEMOS=ON -DNANA_CMAKE_ENABLE_AUDIO=OFF -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_BOOST_FILESYSTEM_FORCE=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON
- make install - make install
- ls - ls
- cd .. - cd ..

View File

@ -1,4 +1,4 @@
# CMake configuration for Nana # CMake configuration for Nana
# Author: Andrew Kornilov(https://github.com/ierofant) # Author: Andrew Kornilov(https://github.com/ierofant)
# Contributors: # Contributors:
# Jinhao # Jinhao
@ -59,20 +59,14 @@ option(NANA_CMAKE_BOOST_FILESYSTEM_FORCE "Force use of Boost filesystem if avail
########### Compatibility with CMake 3.1 ########### Compatibility with CMake 3.1
if(POLICY CMP0054) if(POLICY CMP0054)
# http://www.cmake.org/cmake/help/v3.1/policy/CMP0054.html # http://www.cmake.org/cmake/help/v3.1/policy/CMP0054.html
cmake_policy(SET CMP0054 OLD) cmake_policy(SET CMP0054 NEW)
endif() endif()
if(POLICY CMP0004) # ignore leading space
# http://www.cmake.org/cmake/help/v3.0/policy/CMP0004.html
cmake_policy(SET CMP0004 OLD)
endif()
set(CMAKE_DEBUG_POSTFIX "_d")
########### OS ########### OS
if(WIN32) if(WIN32)
add_definitions(-DWIN32) add_definitions(-DWIN32)
#Global MSVC definitions. You may prefer the hand-tuned sln and projects from the nana repository. # Global MSVC definitions. You may prefer the hand-tuned sln and projects from the nana repository.
if(MSVC) if(MSVC)
option(MSVC_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON) option(MSVC_USE_MP "Set to ON to build nana with the /MP option (Visual Studio 2005 and above)." ON)
option(MSVC_USE_STATIC_RUNTIME "Set to ON to build nana with the /MT(d) option." ON) option(MSVC_USE_STATIC_RUNTIME "Set to ON to build nana with the /MT(d) option." ON)
@ -80,7 +74,7 @@ if(WIN32)
# Change the MSVC Compiler flags # Change the MSVC Compiler flags
if(MSVC_USE_MP) if(MSVC_USE_MP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
endif(MSVC_USE_MP) endif()
if(MSVC_USE_STATIC_RUNTIME) if(MSVC_USE_STATIC_RUNTIME)
foreach(flag foreach(flag
@ -92,32 +86,26 @@ if(WIN32)
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}") string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
endif() endif()
endforeach() endforeach()
endif(MSVC_USE_STATIC_RUNTIME) endif()
endif(MSVC) endif()
if(MINGW) if(MINGW)
if(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) if(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
add_definitions(-DSTD_THREAD_NOT_SUPPORTED) add_definitions(-DSTD_THREAD_NOT_SUPPORTED)
add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) add_definitions(-DNANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)
endif(NANA_CMAKE_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ) endif()
endif(MINGW) endif()
if (MSVC) if(MSVC)
set (DLLTOOL OFF) set(DLLTOOL OFF)
else () else()
# mingw: If dlltool is found the def and lib file will be created # mingw: If dlltool is found the def and lib file will be created
message (STATUS "Detecting dlltool")
find_program (DLLTOOL dlltool) find_program (DLLTOOL dlltool)
if (DLLTOOL) if(NOT DLLTOOL)
message (STATUS "Found dlltool: ${DLLTOOL}") message(WARNING "dlltool not found. Skipping import library generation.")
else () endif()
message (WARNING "dlltool not found. Skipping import library generation.") endif()
endif (DLLTOOL) endif()
endif (MSVC)
endif(WIN32)
if(APPLE) if(APPLE)
add_definitions(-DAPPLE) add_definitions(-DAPPLE)
@ -126,17 +114,16 @@ if(APPLE)
set(ENABLE_AUDIO OFF) set(ENABLE_AUDIO OFF)
elseif(UNIX) elseif(UNIX)
add_definitions(-Dlinux) add_definitions(-Dlinux)
message("added -D linux") endif()
endif(APPLE)
if(UNIX) if(UNIX)
list(APPEND NANA_LINKS -lX11) list(APPEND NANA_LINKS -lX11)
find_package(Freetype) include(FindFreetype)
if (FREETYPE_FOUND) if(FREETYPE_FOUND)
include_directories( ${FREETYPE_INCLUDE_DIRS}) include_directories( ${FREETYPE_INCLUDE_DIRS})
list(APPEND NANA_LINKS -lXft) list(APPEND NANA_LINKS -lXft -lfontconfig)
endif(FREETYPE_FOUND) endif()
endif(UNIX) endif()
########### Compilers ########### Compilers
@ -152,44 +139,31 @@ endif(UNIX)
# #
# #
# see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html # see at end of: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang || GNU #
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall -g") # Clang set(CMAKE_CXX_FLAGS "-std=gnu++14 -Wall")
else()
else ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "-std=c++14 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -g") # GNU endif()
endif()
endif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# enable static linkage # GNU || CLang not MinGW
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AND NOT MINGW
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if(NANA_CMAKE_SHARED_LIB) if(NANA_CMAKE_SHARED_LIB)
list(APPEND NANA_LINKS -lgcc -lstdc++ -pthread) list(APPEND NANA_LINKS -lgcc -lstdc++ -pthread)
else() else()
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread") set(CMAKE_EXE_LINKER_FLAGS "-static -pthread")
# message("Setting NANA_LINKS to -static-libgcc -static-libstdc++ -pthread or ${NANA_LINKS}") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s")
endif(NANA_CMAKE_SHARED_LIB) endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3)
# IS_GNUCXX < 5.3
else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3)
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++fs") # IS_GNUCXX 5.3 or more
list(APPEND NANA_LINKS -lstdc++fs) list(APPEND NANA_LINKS -lstdc++fs)
endif()
endif()
endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
list(APPEND NANA_LINKS -stdlib=libstdc++)
endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AND NOT MINGW endif()
if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++")
list(APPEND NANA_LINKS -stdlib=libstdc++)
endif ()
############# Optional libraries ############# Optional libraries
@ -198,69 +172,67 @@ endif ()
if(NANA_CMAKE_ENABLE_PNG) if(NANA_CMAKE_ENABLE_PNG)
if(NANA_CMAKE_LIBPNG_FROM_OS) if(NANA_CMAKE_LIBPNG_FROM_OS)
find_package(PNG) find_package(PNG)
if (PNG_FOUND) if(PNG_FOUND)
include_directories( ${PNG_INCLUDE_DIRS}) include_directories(${PNG_INCLUDE_DIRS})
list(APPEND NANA_LINKS ${PNG_LIBRARIES}) list(APPEND NANA_LINKS ${PNG_LIBRARIES})
add_definitions("-DNANA_ENABLE_PNG" add_definitions(-DNANA_ENABLE_PNG -DUSE_LIBPNG_FROM_OS)
"-DUSE_LIBPNG_FROM_OS") endif()
endif(PNG_FOUND)
else() else()
add_definitions(-DNANA_ENABLE_PNG) add_definitions(-DNANA_ENABLE_PNG)
endif(NANA_CMAKE_LIBPNG_FROM_OS) endif()
endif(NANA_CMAKE_ENABLE_PNG) endif()
# Find JPEG # Find JPEG
if(NANA_CMAKE_ENABLE_JPEG) if(NANA_CMAKE_ENABLE_JPEG)
add_definitions(-DNANA_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG)
if(NANA_CMAKE_LIBJPEG_FROM_OS) if(NANA_CMAKE_LIBJPEG_FROM_OS)
find_package(JPEG) find_package(JPEG)
if (JPEG_FOUND) if(JPEG_FOUND)
include_directories( ${JPEG_INCLUDE_DIR}) include_directories( ${JPEG_INCLUDE_DIR})
list(APPEND NANA_LINKS ${JPEG_LIBRARY}) list(APPEND NANA_LINKS ${JPEG_LIBRARY})
add_definitions("-DNANA_ENABLE_JPEG" add_definitions(-DNANA_ENABLE_JPEG -DUSE_LIBJPEG_FROM_OS)
"-DUSE_LIBJPEG_FROM_OS") endif()
endif(JPEG_FOUND)
else() else()
add_definitions(-DNANA_ENABLE_JPEG) add_definitions(-DNANA_ENABLE_JPEG)
endif(NANA_CMAKE_LIBJPEG_FROM_OS) endif()
endif(NANA_CMAKE_ENABLE_JPEG) endif()
# Find ASOUND # Find ASOUND
if(NANA_CMAKE_ENABLE_AUDIO) if(NANA_CMAKE_ENABLE_AUDIO)
add_definitions(-DNANA_ENABLE_AUDIO) add_definitions(-DNANA_ENABLE_AUDIO)
if(UNIX) if(UNIX)
find_package(ASOUND) find_package(ASOUND)
if (ASOUND_FOUND) if(ASOUND_FOUND)
include_directories( ${ASOUND_INCLUDE_DIRS}) include_directories(${ASOUND_INCLUDE_DIRS})
list(APPEND NANA_LINKS -lasound) list(APPEND NANA_LINKS -lasound)
else(ASOUND_FOUND) else()
message(FATAL_ERROR "libasound is not found") message(FATAL_ERROR "libasound is not found")
endif(ASOUND_FOUND) endif()
endif(UNIX) endif()
endif(NANA_CMAKE_ENABLE_AUDIO) endif()
# Find/Select filesystem # Find/Select filesystem
if (NANA_CMAKE_NANA_FILESYSTEM_FORCE) if(NANA_CMAKE_NANA_FILESYSTEM_FORCE)
add_definitions(-DNANA_FILESYSTEM_FORCE) add_definitions(-DNANA_FILESYSTEM_FORCE)
elseif (NANA_CMAKE_STD_FILESYSTEM_FORCE) elseif(NANA_CMAKE_STD_FILESYSTEM_FORCE)
add_definitions(-DSTD_FILESYSTEM_FORCE) add_definitions(-DSTD_FILESYSTEM_FORCE)
elseif (NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE) elseif(NANA_CMAKE_FIND_BOOST_FILESYSTEM OR NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
if (NANA_CMAKE_BOOST_FILESYSTEM_FORCE) if(NANA_CMAKE_BOOST_FILESYSTEM_FORCE)
add_definitions(-DBOOST_FILESYSTEM_FORCE) add_definitions(-DBOOST_FILESYSTEM_FORCE)
endif(NANA_CMAKE_BOOST_FILESYSTEM_FORCE) endif()
# https://cmake.org/cmake/help/git-master/module/FindBoost.html # https://cmake.org/cmake/help/git-master/module/FindBoost.html
# Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, # Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied,
# even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries. # even if system is not specified when using find_package and if Boost::system is not added to target_link_libraries.
# If using Boost::thread, then Thread::Thread will also be added automatically. # If using Boost::thread, then Thread::Thread will also be added automatically.
find_package(Boost COMPONENTS filesystem) find_package(Boost COMPONENTS filesystem)
if (Boost_FOUND) if(Boost_FOUND)
add_definitions(-DBOOST_FILESYSTEM_AVAILABLE) add_definitions(-DBOOST_FILESYSTEM_AVAILABLE)
include_directories(SYSTEM "${Boost_INCLUDE_DIR}") include_directories(SYSTEM "${Boost_INCLUDE_DIR}")
list(APPEND NANA_LINKS ${Boost_LIBRARIES}) ###### FIRST !!!!!!!!!!!!!!!!! add is not first list(APPEND NANA_LINKS ${Boost_LIBRARIES})
endif (Boost_FOUND) endif()
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON) # ?? set(Boost_USE_STATIC_RUNTIME ON)
endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE) endif()
######## Nana options ######## Nana options
@ -268,11 +240,11 @@ endif (NANA_CMAKE_NANA_FILESYSTEM_FORCE)
add_definitions(-DNANA_IGNORE_CONF) add_definitions(-DNANA_IGNORE_CONF)
if(NANA_CMAKE_VERBOSE_PREPROCESSOR) if(NANA_CMAKE_VERBOSE_PREPROCESSOR)
add_definitions(-DVERBOSE_PREPROCESSOR) add_definitions(-DVERBOSE_PREPROCESSOR)
endif(NANA_CMAKE_VERBOSE_PREPROCESSOR) endif()
if(NANA_CMAKE_AUTOMATIC_GUI_TESTING) if(NANA_CMAKE_AUTOMATIC_GUI_TESTING)
add_definitions(-DNANA_AUTOMATIC_GUI_TESTING) add_definitions(-DNANA_AUTOMATIC_GUI_TESTING)
enable_testing () enable_testing()
endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING) endif()
####################### Main setting of Nana sources, targets and install ####################### Main setting of Nana sources, targets and install
@ -280,39 +252,41 @@ endif(NANA_CMAKE_AUTOMATIC_GUI_TESTING)
set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source) set(NANA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source)
set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) set(NANA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
# collect all source sub-directories in a list to avoid duplication here # collect all source sub-directories in a list to avoid duplication here
set(NANA_SOURCE_SUBDIRS /. set(NANA_SOURCE_SUBDIRS /.
/detail /detail
/filesystem /filesystem
/gui /gui
/gui/detail /gui/detail
/gui/widgets /gui/widgets
/gui/widgets/skeletons /gui/widgets/skeletons
/paint /paint
/paint/detail /paint/detail
/system /system
/threads ) /threads
)
if(NANA_CMAKE_ENABLE_AUDIO) if(NANA_CMAKE_ENABLE_AUDIO)
list(APPEND NANA_SOURCE_SUBDIRS list(APPEND NANA_SOURCE_SUBDIRS /audio
/audio /audio/detail
/audio/detail ) )
endif(NANA_CMAKE_ENABLE_AUDIO) endif()
# collect all source files in the source-sub-dir # collect all source files in the source-sub-dir
# To show .h files in Visual Studio, add them to the list of sources in add_executable / add_library # 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 # and Use SOURCE_GROUP if all your sources are in the same directory
foreach(subdir ${NANA_SOURCE_SUBDIRS}) foreach(subdir ${NANA_SOURCE_SUBDIRS})
aux_source_directory(${NANA_SOURCE_DIR}${subdir} sources) aux_source_directory(${NANA_SOURCE_DIR}${subdir} SOURCES)
# message("Subir: ${subdir}") # message("Files: ${sources}") endforeach()
endforeach(subdir ${NANA_SOURCE_SUBDIRS})
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
add_definitions(-fmax-errors=3) add_definitions(-fmax-errors=3)
endif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") endif()
set(CMAKE_DEBUG_POSTFIX "_d")
if(NANA_CMAKE_SHARED_LIB) if(NANA_CMAKE_SHARED_LIB)
add_library(${PROJECT_NAME} SHARED ${sources} ) add_library(${PROJECT_NAME} SHARED ${SOURCES})
else() else()
add_library(${PROJECT_NAME} STATIC ${sources} ) add_library(${PROJECT_NAME} STATIC ${SOURCES})
endif(NANA_CMAKE_SHARED_LIB) endif()
target_include_directories(${PROJECT_NAME} PUBLIC ${NANA_INCLUDE_DIR}) target_include_directories(${PROJECT_NAME} PUBLIC ${NANA_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${NANA_LINKS}) target_link_libraries(${PROJECT_NAME} ${NANA_LINKS})
@ -324,27 +298,22 @@ target_link_libraries(${PROJECT_NAME} ${NANA_LINKS})
# and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/ # and the includes files "include/nana/" in DESTDIR/CMAKE_INSTALL_PREFIX/include/nana/
# unfortunatelly install() is still ignored by CLion: # unfortunatelly install() is still ignored by CLion:
# https://intellij-support.jetbrains.com/hc/en-us/community/posts/205822949-CMake-install-isn-t-supported- # https://intellij-support.jetbrains.com/hc/en-us/community/posts/205822949-CMake-install-isn-t-supported-
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
RUNTIME DESTINATION bin) RUNTIME DESTINATION bin)
# http://stackoverflow.com/questions/33788729/how-do-i-get-clion-to-run-an-install-target # http://stackoverflow.com/questions/33788729/how-do-i-get-clion-to-run-an-install-target
if(NANA_CLION) # the Clion IDE don't reconize the install target if(NANA_CLION) # the Clion IDE don't reconize the install target
add_custom_target(install_${PROJECT_NAME} add_custom_target(install_${PROJECT_NAME}
$(MAKE) install $(MAKE) install
DEPENDS ${PROJECT_NAME} DEPENDS ${PROJECT_NAME}
COMMENT "Installing ${PROJECT_NAME}") COMMENT "Installing ${PROJECT_NAME}")
endif() endif()
set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 ) if(NANA_CMAKE_SHARED_LIB)
if(WIN32)
if (NANA_CMAKE_SHARED_LIB) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (WIN32) if(DLLTOOL)
set (CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (DLLTOOL)
#message(STATUS "CMAKE_CURRENT_BINARY_DIR = ${CMAKE_CURRENT_BINARY_DIR}")
#generate the lib and def files needed by msvc #generate the lib and def files needed by msvc
set_target_properties (${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}" set_target_properties (${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}"
ARCHIVE_OUTPUT_NAME "${PROJECT_NAME}" ARCHIVE_OUTPUT_NAME "${PROJECT_NAME}"
@ -359,42 +328,40 @@ if (NANA_CMAKE_SHARED_LIB)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.def" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.def"
"${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.lib" DESTINATION lib) "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.lib" DESTINATION lib)
endif () endif()
endif()
endif (WIN32) endif()
endif (NANA_CMAKE_SHARED_LIB)
message ("")
message("")
message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib") message("The compiled Nana library will be installed in ${CMAKE_INSTALL_PREFIX}/lib")
# Install the include directories too. # Install the include directories too.
if(NANA_CMAKE_INSTALL_INCLUDES) if(NANA_CMAKE_INSTALL_INCLUDES)
install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include ) install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include)
message("The Nana include files will be installed in ${CMAKE_INSTALL_PREFIX}/include") message("The Nana include files will be installed in ${CMAKE_INSTALL_PREFIX}/include")
endif(NANA_CMAKE_INSTALL_INCLUDES) endif()
# Just for information: # Just for information:
message ("") message("")
message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID}) message("CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID})
message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG}) message("COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG})
message ( "CMAKE_COMPILER_IS_GNUCXX = " ${CMAKE_COMPILER_IS_GNUCXX}) message("CMAKE_COMPILER_IS_GNUCXX = " ${CMAKE_COMPILER_IS_GNUCXX})
message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS}) message("CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS}) message("CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS})
message ( "CMAKE_STATIC_LINKER_FLAGS = " ${CMAKE_STATIC_LINKER_FLAGS}) message("CMAKE_STATIC_LINKER_FLAGS = " ${CMAKE_STATIC_LINKER_FLAGS})
message ( "NANA_LINKS = " ${NANA_LINKS}) message("NANA_LINKS = " ${NANA_LINKS})
message ( "DESTDIR = " ${DESTDIR}) message("DESTDIR = " ${DESTDIR})
message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX}) message("CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX})
message ( "NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR}) message("NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR})
message ( "CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR}) message("CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR})
message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO}) message("NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO})
message ( "NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB}) message("NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB})
message ( "NANA_CLION = " ${NANA_CLION}) message("NANA_CLION = " ${NANA_CLION})
message ( "CMAKE_MAKE_PROGRAM = " ${CMAKE_MAKE_PROGRAM}) message("CMAKE_MAKE_PROGRAM = " ${CMAKE_MAKE_PROGRAM})
message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) message("NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) message("NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT}) message("NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB}) message("NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB})
message ( "NANA_CMAKE_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_AUTOMATIC_GUI_TESTING}) message("NANA_CMAKE_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_AUTOMATIC_GUI_TESTING})
message ( "NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING}) message("NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING})

View File

@ -1,7 +1,7 @@
/** /**
* Predefined Symbols for C++ * Predefined Symbols for C++
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2016-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2016-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -171,9 +171,9 @@
#endif #endif
#endif #endif
//Assume the std::thread is not implement on MinGW //Assume the std::thread is not implemented on MinGW,
//unless it was compiled with POSIX threading support.
//But some toolchains may implement std::thread. //But some toolchains may implement std::thread.
// it seems that MinGW 6.3 and 7.1 have std::thread
#ifdef NANA_MINGW #ifdef NANA_MINGW
# ifndef STD_THREAD_NOT_SUPPORTED # ifndef STD_THREAD_NOT_SUPPORTED
# define STD_THREAD_NOT_SUPPORTED # define STD_THREAD_NOT_SUPPORTED
@ -222,7 +222,10 @@
# undef STD_FILESYSTEM_NOT_SUPPORTED # undef STD_FILESYSTEM_NOT_SUPPORTED
# endif # endif
# if __has_include(<mutex>) # if __has_include(<mutex>)
# undef STD_THREAD_NOT_SUPPORTED # if !(defined(NANA_MINGW) && !defined(_GLIBCXX_HAS_GTHREADS))
//See the comment above regarding MinGW's threading support
# undef STD_THREAD_NOT_SUPPORTED
# endif
# endif # endif
#endif #endif

View File

@ -1,7 +1,7 @@
/** /**
* A ISO C++ filesystem Implementation * A ISO C++ filesystem Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -55,6 +55,36 @@
#define NANA_USING_BOOST_FILESYSTEM 1 #define NANA_USING_BOOST_FILESYSTEM 1
# include <chrono> # include <chrono>
# include <boost/filesystem.hpp> # include <boost/filesystem.hpp>
// dont include generic_u8string
// http://www.boost.org/doc/libs/1_66_0/boost/filesystem/path.hpp
// enable directory_iterator C++11 range-base for
// http://www.boost.org/doc/libs/1_66_0/boost/filesystem/operations.hpp
// but travis come with an oooold version of boost
// NOT enable directory_iterator C++11 range-base for
// http://www.boost.org/doc/libs/1_54_0/boost/filesystem/operations.hpp
namespace boost
{
namespace filesystem
{
// enable directory_iterator C++11 range-base for statement use --------------------//
// begin() and end() are only used by a range-based for statement in the context of
// auto - thus the top-level const is stripped - so returning const is harmless and
// emphasizes begin() is just a pass through.
inline const directory_iterator& begin(const directory_iterator& iter) BOOST_NOEXCEPT
{
return iter;
}
inline directory_iterator end(const directory_iterator&) BOOST_NOEXCEPT
{
return directory_iterator();
}
} // namespace filesystem
}
// add boost::filesystem into std::experimental::filesystem // add boost::filesystem into std::experimental::filesystem
namespace std { namespace std {
@ -75,6 +105,16 @@ namespace std {
socket = boost::filesystem::file_type::socket_file, socket = boost::filesystem::file_type::socket_file,
unknown = boost::filesystem::file_type::type_unknown, unknown = boost::filesystem::file_type::type_unknown,
}; };
/// enable directory_iterator range-based for statements
//inline directory_iterator begin(directory_iterator iter) noexcept
//{
// return iter;
//}
//inline directory_iterator end(const directory_iterator&) noexcept
//{
// return {};
//}
} // filesystem } // filesystem
} // experimental } // experimental
} // std } // std

View File

@ -1,6 +1,6 @@
/** /**
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -16,6 +16,7 @@
#define NANA_FILESYSTEM_EXT_HPP #define NANA_FILESYSTEM_EXT_HPP
#include <nana/filesystem/filesystem.hpp> #include <nana/filesystem/filesystem.hpp>
#include <nana/deploy.hpp>
namespace nana namespace nana
{ {
@ -34,6 +35,16 @@ namespace filesystem_ext
std::experimental::filesystem::path path_user(); ///< extention ? std::experimental::filesystem::path path_user(); ///< extention ?
/// workaround Boost not having path.generic_u8string() - a good point for http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0251r0.pdf
inline std::string generic_u8string(const std::experimental::filesystem::path& p)
{
#if NANA_USING_BOOST_FILESYSTEM
return nana::to_utf8(p.generic_wstring());
#else
return p.generic_u8string();
#endif
}
inline bool is_directory(const std::experimental::filesystem::directory_entry& dir) noexcept inline bool is_directory(const std::experimental::filesystem::directory_entry& dir) noexcept
{ {
return is_directory(dir.status()); return is_directory(dir.status());

View File

@ -4,7 +4,7 @@
* *
* Basis Implementation * Basis Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -30,6 +30,15 @@ namespace nana
struct native_drawable_impl{}; struct native_drawable_impl{};
} }
struct accel_key
{
char key;
bool case_sensitive{ false };
bool alt{ false };
bool ctrl{ false };
bool shift{ false };
};
enum class checkstate enum class checkstate
{ {
unchecked, checked, partial unchecked, checked, partial
@ -288,6 +297,19 @@ that return a corresponding nana::appearance with predefined values.
virtual bool visible() const = 0; virtual bool visible() const = 0;
};//end class caret_interface };//end class caret_interface
/// Interface for scroll operations
/**
* This interface provides methods to operate the scrollbars that are contained
* in a specific widget, such as listbox and treebox
*/
class scroll_operation_interface
{
public:
virtual ~scroll_operation_interface() = default;
virtual bool visible(bool vert) const = 0;
};
namespace parameters namespace parameters
{ {
/// The system-wide parameters for mouse wheel /// The system-wide parameters for mouse wheel

View File

@ -1,7 +1,7 @@
/** /**
* A Bedrock Implementation * A Bedrock Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -27,6 +27,7 @@ namespace detail
struct basic_window; struct basic_window;
class window_manager; class window_manager;
struct window_platform_assoc;
/// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions. /// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions.
class bedrock class bedrock
@ -73,6 +74,11 @@ namespace detail
//Closes the windows which are associated with the specified thread. If the given thread_id is 0, it closes all windows //Closes the windows which are associated with the specified thread. If the given thread_id is 0, it closes all windows
void close_thread_window(unsigned thread_id); void close_thread_window(unsigned thread_id);
public:
//Platform-dependent functions
static void delete_platform_assoc(window_platform_assoc*);
void keyboard_accelerator(native_window_type, const accel_key&, const std::function<void()>&);
public: public:
void event_expose(core_window_t *, bool exposed); void event_expose(core_window_t *, bool exposed);
void event_move(core_window_t*, int x, int y); void event_move(core_window_t*, int x, int y);

View File

@ -1,3 +1,15 @@
/*
* Effects Renderer
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2018 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/effects_renderer.cpp
*/
#ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP #ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP #define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#include <nana/gui/effects.hpp> #include <nana/gui/effects.hpp>
@ -76,7 +88,7 @@ namespace nana{
nana::rectangle r; nana::rectangle r;
for(auto & action : nimbus) for(auto & action : nimbus)
{ {
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r)) if(_m_edge_nimbus(action.window, focused) && window_layer::read_visual_rectangle(action.window, r))
{ {
if (action.window == wd) if (action.window == wd)
{ {
@ -140,12 +152,17 @@ namespace nana{
} }
} }
private: private:
static bool _m_edge_nimbus(core_window_t * focused_wd, core_window_t * wd) /// Determines whether the effect will be rendered for the given window.
static bool _m_edge_nimbus(core_window_t * const wd, core_window_t * const focused_wd)
{ {
if((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active))) // Don't render the effect if the window is disabled.
return true; if (wd->flags.enabled)
else if((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered)) {
return true; if ((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active)))
return true;
else if ((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered))
return true;
}
return false; return false;
} }

View File

@ -1,7 +1,7 @@
/** /**
* Definition of General Events * Definition of General Events
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -460,8 +460,9 @@ namespace nana
::nana::window window_handle; ///< A handle to the event window ::nana::window window_handle; ///< A handle to the event window
mutable wchar_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 only available for key_char event, set 'true' to ignore the input. mutable bool ignore; ///< this member is only available for key_char event, set 'true' to ignore the input.
bool ctrl; ///< keyboard Ctrl is pressed? bool alt; ///< it is set to indicate the modifier key Alt just prior to the event.
bool shift; ///< keyboard Shift is pressed bool ctrl; ///< it is set to indicate the modifier key Ctrl just prior to the event.
bool shift; ///< it is set to indicate the modifier key Shift just prior to the event.
}; };
struct arg_move : public event_arg struct arg_move : public event_arg

View File

@ -301,6 +301,8 @@ namespace API
void window_size(window, const size&); void window_size(window, const size&);
size window_outline_size(window); size window_outline_size(window);
void window_outline_size(window, const size&); void window_outline_size(window, const size&);
nana::optional<rectangle> window_rectangle(window);
bool get_window_rectangle(window, rectangle&); bool get_window_rectangle(window, rectangle&);
bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window. bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window.
void window_enabled(window, bool); void window_enabled(window, bool);
@ -434,6 +436,8 @@ namespace API
* widget by the content extent. * widget by the content extent.
*/ */
optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width); optional<std::pair<::nana::size, ::nana::size>> content_extent(window wd, unsigned limited_px, bool limit_width);
unsigned screen_dpi(bool x_requested);
}//end namespace API }//end namespace API
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/** /**
* A CheckBox Implementation * A CheckBox Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -100,6 +100,7 @@ namespace drawerbase
event_handle eh_keyboard; event_handle eh_keyboard;
}; };
public: public:
constexpr static const std::size_t npos = static_cast<std::size_t>(-1);
~radio_group(); ~radio_group();
void add(checkbox&); void add(checkbox&);
std::size_t checked() const; ///< Retrieves the index of the checkbox which is checked. std::size_t checked() const; ///< Retrieves the index of the checkbox which is checked.

View File

@ -1,7 +1,7 @@
/** /**
* A Form Implementation * A Form Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -68,6 +68,8 @@ namespace nana
void modality() const; void modality() const;
void wait_for_this(); void wait_for_this();
void keyboard_accelerator(const accel_key&, const std::function<void()>& fn);
}; };
class nested_form class nested_form

View File

@ -1,7 +1,7 @@
/** /**
* A group widget implementation * A group widget implementation
* Nana C++ Library(http://www.nanaro.org) * Nana C++ Library(http://www.nanaro.org)
* Copyright(C) 2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2015-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -28,6 +28,7 @@ namespace nana{
struct implement; struct implement;
public: public:
using field_reference = place::field_reference; using field_reference = place::field_reference;
constexpr static const std::size_t npos = static_cast<std::size_t>(-1);
/// The default construction /// The default construction
group(); group();
@ -63,10 +64,14 @@ namespace nana{
group& enable_format_caption(bool format); group& enable_format_caption(bool format);
group& collocate() throw(); group& collocate() noexcept;
group& div(const char* div_str) throw(); group& div(const char* div_str) noexcept;
field_reference operator[](const char* field); field_reference operator[](const char* field);
void field_display(const char* field_name, bool display); ///<Displays/Discards an existing field.
bool field_display(const char* field_name) const; ///<Determines whether the specified field is displayed.
void erase(window handle); ///< Erases a window from field.
template<typename Widget, typename ...Args> template<typename Widget, typename ...Args>
Widget* create_child(const char* field, Args && ... args) Widget* create_child(const char* field, Args && ... args)
{ {

View File

@ -1,7 +1,7 @@
/** /**
* A List Box Implementation * A List Box Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -94,6 +94,12 @@ namespace nana
*/ */
virtual void fit_content(unsigned maximum = 0) noexcept = 0; virtual void fit_content(unsigned maximum = 0) noexcept = 0;
/// Sets an exclusive font for the column
virtual void typeface(const paint::font& column_font) = 0;
/// Returns a font
virtual paint::font typeface() const noexcept = 0;
/// Determines the visibility state of the column /// Determines the visibility state of the column
/** /**
* @return true if the column is visible, false otherwise * @return true if the column is visible, false otherwise
@ -987,9 +993,13 @@ namespace nana
cat_proxy(essence*, size_type pos) noexcept; cat_proxy(essence*, size_type pos) noexcept;
cat_proxy(essence*, category_t*) noexcept; cat_proxy(essence*, category_t*) noexcept;
/// Append an item at abs end of the category, set_value determines whether assign T object to the value of item. /// Append an item at the end of this category using the oresolver to generate the texts to be put in each column.
template<typename T> ///
item_proxy append(T&& t, bool set_value = false) /// First you have to make sure there is an overload of the operator<<() of the oresolver for the type of the object used here
/// If a listbox have a model set, try call append_model instead.
template<typename T>
item_proxy append( T&& t, ///< Value used by the resolver to generate the texts to be put in each column of the item
bool set_value = false) ///< determines whether to set the object as the value of this item.
{ {
oresolver ores(ess_); oresolver ores(ess_);
@ -1039,7 +1049,7 @@ namespace nana
model_guard model(); model_guard model();
/// Appends one item at the end of this category with the specifies text in the column fields /// Appends one item at the end of this category with the specifies texts in the column fields
void append(std::initializer_list<std::string> texts_utf8); void append(std::initializer_list<std::string> texts_utf8);
void append(std::initializer_list<std::wstring> texts); void append(std::initializer_list<std::wstring> texts);
@ -1194,17 +1204,25 @@ namespace nana
color_proxy selection_box{ static_cast<color_rgb>(0x3399FF) }; ///< Color of selection box border. color_proxy selection_box{ static_cast<color_rgb>(0x3399FF) }; ///< Color of selection box border.
std::shared_ptr<paint::font> column_font; ///< Renderer draws column texts with the font if it is not a nullptr.
/// The max column width which is generated by fit_content is allowed. It is ignored when it is 0, or a max value is passed to fit_content. /// The max column width which is generated by fit_content is allowed. It is ignored when it is 0, or a max value is passed to fit_content.
unsigned max_fit_content{ 0 }; unsigned max_fit_content{ 0 };
unsigned min_column_width{ 20 }; ///< def=20 . non counting suspension_width unsigned min_column_width{ 20 }; ///< def=20 . non counting suspension_width
unsigned suspension_width { 8 }; ///< def= . the trigger will set this to the width if ("...") unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...")
unsigned text_margin { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 unsigned text_margin{ 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1
unsigned header_height { 25 }; ///< def=25 . header height header_size
unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex //deprecated
//unsigned header_height { 25 }; ///< def=25 . header height header_size
unsigned item_height_ex{ 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex
unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO
unsigned header_splitter_area_after { 3 }; ///< def=3. But 4 is better... unsigned header_splitter_area_after{ 3 }; ///< def=3. But 4 is better...
unsigned header_padding_top{ 3 };
unsigned header_padding_bottom{ 3 };
::nana::parameters::mouse_wheel mouse_wheel{}; ///< The number of lines/characters to scroll when vertical/horizontal mouse wheel is moved. ::nana::parameters::mouse_wheel mouse_wheel{}; ///< The number of lines/characters to scroll when vertical/horizontal mouse wheel is moved.
}; };
@ -1411,6 +1429,8 @@ the nana::detail::basic_window member pointer scheme
size_type append_header(std::string text_utf8, unsigned width = 120); size_type append_header(std::string text_utf8, unsigned width = 120);
size_type append_header(std::wstring text, unsigned width = 120); size_type append_header(std::wstring text, unsigned width = 120);
void clear_headers(); ///< Removes all the columns.
cat_proxy append(std::string category); ///< Appends a new category to the end cat_proxy append(std::string category); ///< Appends a new category to the end
cat_proxy append(std::wstring category); ///< Appends a new category to the end cat_proxy append(std::wstring category); ///< Appends a new category to the end
void append(std::initializer_list<std::string> categories); ///< Appends categories to the end void append(std::initializer_list<std::string> categories); ///< Appends categories to the end
@ -1521,6 +1541,7 @@ the nana::detail::basic_window member pointer scheme
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override; nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override;
drawerbase::listbox::category_t* _m_assoc(std::shared_ptr<nana::detail::key_interface>, bool create_if_not_exists); drawerbase::listbox::category_t* _m_assoc(std::shared_ptr<nana::detail::key_interface>, bool create_if_not_exists);
void _m_erase_key(nana::detail::key_interface*) noexcept; void _m_erase_key(nana::detail::key_interface*) noexcept;
std::shared_ptr<scroll_operation_interface> _m_scroll_operation();
}; };
}//end namespace nana }//end namespace nana

View File

@ -95,6 +95,7 @@ namespace nana
menu& push_back(const std::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. menu& at(size_t index) const; ///< Gets the menu specified by index.
std::size_t length() const; ///< Number of menus. std::size_t length() const; ///< Number of menus.
void clear(); ///< Removes all the menus.
/// Deselects the menu /// Deselects the menu
/** /**

View File

@ -1,7 +1,7 @@
/** /**
* A Scroll Implementation * A Scroll Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -147,7 +147,7 @@ namespace nana
void step(size_type s) void step(size_type s)
{ {
metrics_.step = s; metrics_.step = (s ? s : 1);
} }
bool make_step(bool forward, unsigned multiple) bool make_step(bool forward, unsigned multiple)
@ -398,7 +398,7 @@ namespace nana
/// \brief The construct that creates a widget. /// \brief The construct that creates a widget.
/// @param wd A handle to the parent window of the widget being created. /// @param wd A handle to the parent window of the widget being created.
/// @param visible specify the visibility after creation. /// @param visible specify the visibility after creation.
scroll(window wd, bool visible) scroll(window wd, bool visible = true)
{ {
this->create(wd, rectangle(), visible); // add a widget scheme? and take some colors from these wd? this->create(wd, rectangle(), visible); // add a widget scheme? and take some colors from these wd?
} }
@ -501,7 +501,8 @@ namespace nana
/// @return true if the vlaue is changed. /// @return true if the vlaue is changed.
bool make_page_scroll(bool forward) bool make_page_scroll(bool forward)
{ {
return this->make_step(forward, static_cast<unsigned>(range() - 1)); auto const count = range() / step();
return this->make_step(forward, static_cast<unsigned>(count > 2 ? count - 1 : 1));
} }
};//end class scroll };//end class scroll
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/* /*
* A text editor implementation * A text editor implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -219,6 +219,8 @@ namespace nana{ namespace widgets
const skeletons::textbase<char_type>& textbase() const; const skeletons::textbase<char_type>& textbase() const;
bool try_refresh(); bool try_refresh();
std::shared_ptr<scroll_operation_interface> scroll_operation() const;
private: private:
nana::color _m_draw_colored_area(paint::graphics& graph, const std::pair<std::size_t,std::size_t>& row, bool whole_line); nana::color _m_draw_colored_area(paint::graphics& graph, const std::pair<std::size_t,std::size_t>& row, bool whole_line);
std::vector<upoint> _m_render_text(const ::nana::color& text_color); std::vector<upoint> _m_render_text(const ::nana::color& text_color);

View File

@ -1,7 +1,7 @@
/** /**
* A Tabbar implementation * A Tabbar implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -42,9 +42,8 @@ namespace nana
: arg_tabbar<T>({wdg, v}) : arg_tabbar<T>({wdg, v})
{} {}
bool remove = true; ///< determines whether to remove the item mutable bool remove = true; ///< determines whether to remove the item
bool close_attach_window = true; ///< determines whether to close the attached window. It is ignored if remove is false mutable bool close_attach_window = true; ///< determines whether to close the attached window. It is ignored if remove is false
}; };
namespace drawerbase namespace drawerbase
@ -293,7 +292,7 @@ namespace nana
if (pos > length()) if (pos > length())
throw std::out_of_range("tabbar::insert invalid position"); throw std::out_of_range("tabbar::insert invalid position");
this->get_drawer_trigger().insert(pos, to_nstring(text), std::move(value)); this->get_drawer_trigger().insert(pos, to_nstring(std::move(text)), std::move(value));
API::update_window(*this); API::update_window(*this);
} }

View File

@ -1,7 +1,7 @@
/** /**
* A Textbox Implementation * A Textbox Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -279,6 +279,7 @@ namespace nana
native_string_type _m_caption() const throw() override; native_string_type _m_caption() const throw() override;
void _m_caption(native_string_type&&) override; void _m_caption(native_string_type&&) override;
void _m_typeface(const paint::font&) override; void _m_typeface(const paint::font&) override;
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() const;
}; };
}//end namespace nana }//end namespace nana
#include <nana/pop_ignore_diagnostic> #include <nana/pop_ignore_diagnostic>

View File

@ -1,7 +1,7 @@
/** /**
* A Toolbar Implementation * A Toolbar Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -33,6 +33,14 @@ namespace nana
{ {
namespace toolbar namespace toolbar
{ {
struct item_proxy
{
nana::toolbar& widget;
std::size_t button;
void enable(bool enable_state);
};
struct toolbar_events struct toolbar_events
: public general_events : public general_events
{ {
@ -88,8 +96,10 @@ namespace nana
toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false); toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false);
void separate(); ///< Adds a separator. void separate(); ///< Adds a separator.
void append(const ::std::string& text, const nana::paint::image& img); ///< Adds a control button. drawerbase::toolbar::item_proxy append(const ::std::string& text, const nana::paint::image& img); ///< Adds a control button.
void append(const ::std::string& text); ///< Adds a control button. drawerbase::toolbar::item_proxy append(const ::std::string& text); ///< Adds a control button.
void clear(); ///< Removes all control buttons and separators.
bool enable(size_type index) const; bool enable(size_type index) const;
void enable(size_type index, bool enable_state); void enable(size_type index, bool enable_state);
void scale(unsigned s); ///< Sets the scale of control button. void scale(unsigned s); ///< Sets the scale of control button.

View File

@ -1,7 +1,7 @@
/** /**
* A Tree Box Implementation * A Tree Box Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at * (See accompanying file LICENSE or copy at
@ -445,6 +445,9 @@ namespace nana
item_proxy selected() const; ///< returns the selected node item_proxy selected() const; ///< returns the selected node
private:
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() const;
};//end class treebox };//end class treebox
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/** /**
* The fundamental widget class implementation * The fundamental widget class implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -83,6 +83,8 @@ namespace nana
void focus(); void focus();
bool focused() const; bool focused() const;
std::shared_ptr<scroll_operation_interface> scroll_operation();
void show(); ///< Sets the window visible. void show(); ///< Sets the window visible.
void hide(); ///< Sets the window invisible. void hide(); ///< Sets the window invisible.
bool visible() const; bool visible() const;
@ -137,6 +139,7 @@ namespace nana
virtual void _m_close(); virtual void _m_close();
virtual bool _m_enabled() const; virtual bool _m_enabled() const;
virtual void _m_enabled(bool); virtual void _m_enabled(bool);
virtual std::shared_ptr<scroll_operation_interface> _m_scroll_operation();
virtual bool _m_show(bool); virtual bool _m_show(bool);
virtual bool _m_visible() const; virtual bool _m_visible() const;
virtual void _m_size(const nana::size&); virtual void _m_size(const nana::size&);

View File

@ -38,14 +38,21 @@ namespace nana
font(const font&); font(const font&);
font(const ::std::string& name, double size_pt, const font_style& fs = {}); font(const ::std::string& name, double size_pt, const font_style& fs = {});
font(double size_pt, const path_type& truetype, const font_style& ft = {}); font(double size_pt, const path_type& truetype, const font_style& fs = {});
~font(); ~font();
bool empty() const; bool empty() const;
void set_default() const; void set_default() const;
::std::string name() const; ::std::string name() const;
double size() const;
/// Returns font size, in point.
/**
* @param fixed Indicates whether to return a fixed font size. If this parameter is false, the method may return zero for default system font size. If the parameter is true, the method returns a fixed size of default font size if the font size that assigned by constructor is zero.
* @return The font size, in point.
*/
double size(bool fixed = false) const;
bool bold() const; bool bold() const;
unsigned weight() const; unsigned weight() const;
bool italic() const; bool italic() const;

View File

@ -1,7 +1,7 @@
/** /**
* Standard Library for C++11/14/17 * Standard Library for C++11/14/17
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2017-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at

View File

@ -255,6 +255,35 @@ namespace nana
data::storage = nullptr; data::storage = nullptr;
} }
double platform_abstraction::font_default_pt()
{
#ifdef NANA_WINDOWS
//Create default font object.
NONCLIENTMETRICS metrics = {};
metrics.cbSize = sizeof metrics;
#if(WINVER >= 0x0600)
#if defined(NANA_MINGW)
OSVERSIONINFO osvi = {};
osvi.dwOSVersionInfoSize = sizeof(osvi);
::GetVersionEx(&osvi);
if (osvi.dwMajorVersion < 6)
metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth);
#else
if (!IsWindowsVistaOrGreater())
metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth);
#endif
#endif
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0);
auto desktop = ::GetDC(nullptr);
auto pt = std::abs(metrics.lfMessageFont.lfHeight) * 72.0 / ::GetDeviceCaps(desktop, LOGPIXELSY);
::ReleaseDC(nullptr, desktop);
return pt;
#else
return 10;
#endif
}
::std::shared_ptr<platform_abstraction::font> platform_abstraction::default_font(const ::std::shared_ptr<font>& new_font) ::std::shared_ptr<platform_abstraction::font> platform_abstraction::default_font(const ::std::shared_ptr<font>& new_font)
{ {
auto & r = platform_storage(); auto & r = platform_storage();
@ -337,7 +366,7 @@ namespace nana
if(font_family.empty()) if(font_family.empty())
font_family = '*'; font_family = '*';
std::string pat_str = font_family + '-' + std::to_string(size_pt ? size_pt : 10); std::string pat_str = font_family + '-' + std::to_string(size_pt ? size_pt : platform_abstraction::font_default_pt());
auto pat = ::XftNameParse(pat_str.c_str()); auto pat = ::XftNameParse(pat_str.c_str());
XftResult res; XftResult res;
auto match_pat = ::XftFontMatch(disp, ::XDefaultScreen(disp), pat, &res); auto match_pat = ::XftFontMatch(disp, ::XDefaultScreen(disp), pat, &res);
@ -407,6 +436,31 @@ namespace nana
::FcConfigAppFontClear(nullptr); ::FcConfigAppFontClear(nullptr);
} }
} }
#endif
}
unsigned platform_abstraction::screen_dpi(bool x_requested)
{
#ifdef NANA_WINDOWS
auto hdc = ::GetDC(nullptr);
auto dots = static_cast<unsigned>(::GetDeviceCaps(hdc, (x_requested ? LOGPIXELSX : LOGPIXELSY)));
::ReleaseDC(nullptr, hdc);
return dots;
#else
auto & spec = ::nana::detail::platform_spec::instance();
auto disp = spec.open_display();
auto screen = ::XDefaultScreen(disp);
double dots;
if (x_requested)
dots += ((((double)DisplayWidth(disp, screen)) * 25.4) /
((double)DisplayWidthMM(disp, screen)));
else
dots += ((((double)DisplayHeight(disp, screen)) * 25.4) /
((double)DisplayHeightMM(disp, screen)));
return static_cast<unsigned>(dots + 0.5);
#endif #endif
} }
} }

View File

@ -33,10 +33,13 @@ namespace nana
static void initialize(); static void initialize();
/// Shutdown before destruction of platform_spec /// Shutdown before destruction of platform_spec
static void shutdown(); static void shutdown();
static double font_default_pt();
static ::std::shared_ptr<font> default_font(const ::std::shared_ptr<font>&); static ::std::shared_ptr<font> default_font(const ::std::shared_ptr<font>&);
static ::std::shared_ptr<font> make_font(const ::std::string& font_family, double size_pt, const font::font_style& fs); static ::std::shared_ptr<font> make_font(const ::std::string& font_family, double size_pt, const font::font_style& fs);
static ::std::shared_ptr<font> make_font_from_ttf(const path_type& ttf, double size_pt, const font::font_style& fs); static ::std::shared_ptr<font> make_font_from_ttf(const path_type& ttf, double size_pt, const font::font_style& fs);
static void font_resource(bool try_add, const path_type& ttf); static void font_resource(bool try_add, const path_type& ttf);
static unsigned screen_dpi(bool x_requested);
}; };
} }

View File

@ -1,7 +1,7 @@
/* /*
* A Bedrock Implementation * A Bedrock Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -15,10 +15,10 @@
#include <nana/gui/detail/bedrock_pi_data.hpp> #include <nana/gui/detail/bedrock_pi_data.hpp>
#include <nana/gui/detail/event_code.hpp> #include <nana/gui/detail/event_code.hpp>
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <nana/gui/detail/inner_fwd_implement.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/element_store.hpp> #include <nana/gui/detail/element_store.hpp>
#include "inner_fwd_implement.hpp"
#include <errno.h> #include <errno.h>
#include <algorithm> #include <algorithm>
@ -104,6 +104,42 @@ namespace detail
void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&); void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&);
void window_proc_for_xevent(Display*, XEvent&); void window_proc_for_xevent(Display*, XEvent&);
class accel_key_comparer
{
public:
bool operator()(const accel_key& a, const accel_key& b) const
{
auto va = a.case_sensitive ? a.key : std::tolower(a.key);
auto vb = b.case_sensitive ? b.key : std::tolower(b.key);
if(va < vb)
return true;
else if(va > vb)
return false;
if (a.case_sensitive != b.case_sensitive)
return b.case_sensitive;
if (a.alt != b.alt)
return b.alt;
if (a.ctrl != b.ctrl)
return b.ctrl;
return ((a.shift != b.shift) && b.shift);
}
};
struct accel_key_value
{
std::function<void()> command;
};
struct window_platform_assoc
{
std::map<accel_key, accel_key_value, accel_key_comparer> accel_commands;
};
//class bedrock defines a static object itself to implement a static singleton //class bedrock defines a static object itself to implement a static singleton
//here is the definition of this object //here is the definition of this object
bedrock bedrock::bedrock_object; bedrock bedrock::bedrock_object;
@ -218,10 +254,28 @@ namespace detail
{ {
XKeyEvent xkey; XKeyEvent xkey;
nana::detail::platform_spec::instance().read_keystate(xkey); nana::detail::platform_spec::instance().read_keystate(xkey);
arg.alt = (xkey.state & Mod1Mask);
arg.ctrl = (xkey.state & ControlMask); arg.ctrl = (xkey.state & ControlMask);
arg.shift = (xkey.state & ShiftMask); arg.shift = (xkey.state & ShiftMask);
} }
void bedrock::delete_platform_assoc(window_platform_assoc* passoc)
{
delete passoc;
}
void bedrock::keyboard_accelerator(native_window_type wd, const accel_key& ackey, const std::function<void()>& fn)
{
auto misc = wd_manager().root_runtime(wd);
if (nullptr == misc)
return;
if (!misc->wpassoc)
misc->wpassoc = new window_platform_assoc;
misc->wpassoc->accel_commands[ackey].command = fn;
}
element_store& bedrock::get_element_store() const element_store& bedrock::get_element_store() const
{ {
return impl_->estore; return impl_->estore;
@ -490,6 +544,34 @@ namespace detail
return wchar_t(keysym); return wchar_t(keysym);
} }
bool translate_keyboard_accelerator(root_misc* misc, char os_code, const arg_keyboard& modifiers)
{
if(!misc->wpassoc)
return false;
auto lower_oc = std::tolower(os_code);
std::function<void()> command;
for(auto & accel : misc->wpassoc->accel_commands)
{
if(accel.first.key != (accel.first.case_sensitive ? os_code : lower_oc))
continue;
if(accel.first.alt == modifiers.alt && accel.first.ctrl == modifiers.ctrl && accel.first.shift == modifiers.shift)
{
command = accel.second.command;
break;
}
}
if(!command)
return false;
command();
return true;
}
void window_proc_for_xevent(Display* /*display*/, XEvent& xevent) void window_proc_for_xevent(Display* /*display*/, XEvent& xevent)
{ {
typedef detail::bedrock::core_window_t core_window_t; typedef detail::bedrock::core_window_t core_window_t;
@ -849,6 +931,9 @@ namespace detail
if(msgwnd) if(msgwnd)
{ {
arg_keyboard modifiers_status;
brock.get_key_state(modifiers_status);
KeySym keysym; KeySym keysym;
Status status; Status status;
char fixbuf[33]; char fixbuf[33];
@ -883,16 +968,20 @@ namespace detail
keybuf[len] = 0; keybuf[len] = 0;
wchar_t os_code = 0; wchar_t os_code = 0;
bool accel_translated = false;
switch(status) switch(status)
{ {
case XLookupKeySym: case XLookupKeySym:
case XLookupBoth: case XLookupBoth:
os_code = os_code_from_keysym(keysym); os_code = os_code_from_keysym(keysym);
accel_translated = translate_keyboard_accelerator(root_runtime, os_code, modifiers_status);
if(accel_translated)
break;
if(os_code == keyboard::tab && (false == (msgwnd->flags.tab & detail::tab_type::eating))) //Tab if(os_code == keyboard::tab && (false == (msgwnd->flags.tab & detail::tab_type::eating))) //Tab
{ {
arg_keyboard argkey; auto tstop_wd = wd_manager.tabstop(msgwnd, !modifiers_status.shift);
brock.get_key_state(argkey);
auto tstop_wd = wd_manager.tabstop(msgwnd, !argkey.shift);
if (tstop_wd) if (tstop_wd)
{ {
root_runtime->condition.ignore_tab = true; root_runtime->condition.ignore_tab = true;
@ -907,9 +996,9 @@ namespace detail
if((nullptr == pressed_wd) && (nullptr == pressed_wd_space)) if((nullptr == pressed_wd) && (nullptr == pressed_wd_space))
{ {
arg_mouse arg; arg_mouse arg;
arg.alt = false; arg.alt = modifiers_status.alt;
arg.button = ::nana::mouse::left_button; arg.button = ::nana::mouse::left_button;
arg.ctrl = false; arg.ctrl = modifiers_status.ctrl;
arg.evt_code = event_code::mouse_down; arg.evt_code = event_code::mouse_down;
arg.left_button = true; arg.left_button = true;
arg.mid_button = false; arg.mid_button = false;
@ -955,11 +1044,10 @@ namespace detail
if(keyboard::os_ctrl == os_code) if(keyboard::os_ctrl == os_code)
context.is_ctrl_pressed = true; context.is_ctrl_pressed = true;
arg_keyboard arg; arg_keyboard arg = modifiers_status;
arg.ignore = false; arg.ignore = false;
arg.key = os_code; arg.key = os_code;
arg.evt_code = event_code::key_press; arg.evt_code = event_code::key_press;
brock.get_key_state(arg);
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = reinterpret_cast<window>(msgwnd);
brock.emit(event_code::key_press, msgwnd, arg, true, &context); brock.emit(event_code::key_press, msgwnd, arg, true, &context);
@ -988,7 +1076,7 @@ namespace detail
for(int i = 0; i < len; ++i) for(int i = 0; i < len; ++i)
{ {
arg_keyboard arg; arg_keyboard arg = modifiers_status;
arg.ignore = false; arg.ignore = false;
arg.key = charbuf[i]; arg.key = charbuf[i];
@ -1011,7 +1099,6 @@ namespace detail
} }
arg.evt_code = event_code::key_char; arg.evt_code = event_code::key_char;
arg.window_handle = reinterpret_cast<window>(msgwnd); arg.window_handle = reinterpret_cast<window>(msgwnd);
brock.get_key_state(arg);
msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd)); msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd));
if(arg.ignore == false && wd_manager.available(msgwnd)) if(arg.ignore == false && wd_manager.available(msgwnd))
draw_invoker(&drawer::key_char, msgwnd, arg, &context); draw_invoker(&drawer::key_char, msgwnd, arg, &context);

View File

@ -1,7 +1,7 @@
/** /**
* A Bedrock Implementation * A Bedrock Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -20,11 +20,11 @@
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <nana/system/timepiece.hpp> #include <nana/system/timepiece.hpp>
#include <nana/gui.hpp> #include <nana/gui.hpp>
#include <nana/gui/detail/inner_fwd_implement.hpp>
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/element_store.hpp> #include <nana/gui/detail/element_store.hpp>
#include <nana/gui/detail/color_schemes.hpp> #include <nana/gui/detail/color_schemes.hpp>
#include "inner_fwd_implement.hpp"
#include <iostream> //use std::cerr #include <iostream> //use std::cerr
@ -182,6 +182,12 @@ namespace detail
}cache; }cache;
}; };
struct window_platform_assoc
{
HACCEL accel{ nullptr }; ///< A handle to a Windows keyboard accelerator object.
std::map<int, std::function<void()>> accel_commands;
};
//class bedrock defines a static object itself to implement a static singleton //class bedrock defines a static object itself to implement a static singleton
//here is the definition of this object //here is the definition of this object
bedrock bedrock::bedrock_object; bedrock bedrock::bedrock_object;
@ -345,6 +351,25 @@ namespace detail
} }
} }
void process_msg(bedrock* brock, MSG& msg)
{
if (WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST)
{
auto misc = brock->wd_manager().root_runtime(reinterpret_cast<native_window_type>(msg.hwnd));
if (misc && misc->wpassoc && misc->wpassoc->accel)
{
if (::TranslateAccelerator(msg.hwnd, misc->wpassoc->accel, &msg))
return;
}
}
auto menu_wd = brock->get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
void bedrock::pump_event(window condition_wd, bool is_modal) void bedrock::pump_event(window condition_wd, bool is_modal)
{ {
const unsigned tid = ::GetCurrentThreadId(); const unsigned tid = ::GetCurrentThreadId();
@ -383,11 +408,15 @@ namespace detail
if (msg.message == WM_QUIT) break; if (msg.message == WM_QUIT) break;
if ((WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) || !::IsDialogMessage(native_handle, &msg)) if ((WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) || !::IsDialogMessage(native_handle, &msg))
{ {
#if 0
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true); auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
if (menu_wd) interior_helper_for_menu(msg, menu_wd); if (menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg); ::TranslateMessage(&msg); //deprecated
::DispatchMessage(&msg); ::DispatchMessage(&msg);
#else
process_msg(this, msg);
#endif
wd_manager().remove_trash_handle(tid); wd_manager().remove_trash_handle(tid);
} }
@ -400,11 +429,15 @@ namespace detail
{ {
if (-1 != ::GetMessage(&msg, 0, 0, 0)) if (-1 != ::GetMessage(&msg, 0, 0, 0))
{ {
#if 0
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true); auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
if (menu_wd) interior_helper_for_menu(msg, menu_wd); if (menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
#else
process_msg(this, msg);
#endif
} }
wd_manager().call_safe_place(tid); wd_manager().call_safe_place(tid);
@ -420,11 +453,15 @@ namespace detail
{ {
if(-1 != ::GetMessage(&msg, 0, 0, 0)) if(-1 != ::GetMessage(&msg, 0, 0, 0))
{ {
#if 0
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true); auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
if(menu_wd) interior_helper_for_menu(msg, menu_wd); if(menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
#else
process_msg(this, msg);
#endif
} }
wd_manager().call_safe_place(tid); wd_manager().call_safe_place(tid);
@ -635,6 +672,7 @@ namespace detail
switch(msg) switch(msg)
{ {
case WM_COMMAND:
case WM_DESTROY: case WM_DESTROY:
case WM_SHOWWINDOW: case WM_SHOWWINDOW:
case WM_SIZING: case WM_SIZING:
@ -786,6 +824,17 @@ namespace detail
switch (message) switch (message)
{ {
case WM_COMMAND:
if ((1 == HIWORD(wParam)) && root_runtime->wpassoc)
{
auto i = root_runtime->wpassoc->accel_commands.find(LOWORD(wParam));
if (i != root_runtime->wpassoc->accel_commands.end())
{
auto fn = i->second;
fn();
}
}
break;
case WM_IME_STARTCOMPOSITION: case WM_IME_STARTCOMPOSITION:
if (msgwnd->other.attribute.root->ime_enabled) if (msgwnd->other.attribute.root->ime_enabled)
{ {
@ -1578,10 +1627,58 @@ namespace detail
void bedrock::get_key_state(arg_keyboard& kb) void bedrock::get_key_state(arg_keyboard& kb)
{ {
kb.alt = (0 != (::GetKeyState(VK_MENU) & 0x80));
kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 0x80)); kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 0x80));
kb.shift = (0 != (::GetKeyState(VK_SHIFT) & 0x80)); kb.shift = (0 != (::GetKeyState(VK_SHIFT) & 0x80));
} }
void bedrock::delete_platform_assoc(window_platform_assoc* passoc)
{
delete passoc;
}
//Generates an identitifer for an accel key.
std::pair<int, WORD> id_accel_key(const accel_key& key)
{
std::pair<int, WORD> ret;
//Use virt-key for non-case sensitive
if (!key.case_sensitive)
ret.second = static_cast<WORD>(std::tolower(key.key) - 'a' + 0x41);
ret.first = ret.second | int(key.case_sensitive ? (1 << 8) : 0) | int(key.alt ? (1 << 9) : 0) | int(key.ctrl ? (1 << 10) : 0) | int(key.shift ? (1 << 11) : 0);
return ret;
}
void bedrock::keyboard_accelerator(native_window_type wd, const accel_key& key, const std::function<void()>& fn)
{
auto misc = wd_manager().root_runtime(wd);
if (nullptr == misc)
return;
if (!misc->wpassoc)
misc->wpassoc = new window_platform_assoc;
auto idkey = id_accel_key(key);
misc->wpassoc->accel_commands[idkey.first] = fn;
auto accel_size = ::CopyAcceleratorTable(misc->wpassoc->accel, nullptr, 0);
std::unique_ptr<ACCEL[]> accels(new ACCEL[accel_size + 1]);
if (accel_size)
::CopyAcceleratorTable(misc->wpassoc->accel, accels.get(), accel_size);
auto p = accels.get() + accel_size;
p->cmd = idkey.first;
p->fVirt = (key.case_sensitive ? 0 : FVIRTKEY) | (key.alt ? FALT : 0) | (key.ctrl ? FCONTROL : 0) | (key.shift ? FSHIFT : 0);
p->key = idkey.second;
::DestroyAcceleratorTable(misc->wpassoc->accel);
misc->wpassoc->accel = ::CreateAcceleratorTable(accels.get(), accel_size + 1);
}
element_store& bedrock::get_element_store() const element_store& bedrock::get_element_store() const
{ {
return impl_->estore; return impl_->estore;

View File

@ -1,7 +1,7 @@
/* /*
* Implementations of Inner Forward Declaration * Implementations of Inner Forward Declaration
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -15,9 +15,9 @@
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP #define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
#include <nana/push_ignore_diagnostic> #include <nana/push_ignore_diagnostic>
#include "inner_fwd.hpp" #include <nana/gui/detail/inner_fwd.hpp>
#include "basic_window.hpp" #include <nana/gui/detail/basic_window.hpp>
#include "../../paint/graphics.hpp" #include <nana/paint/graphics.hpp>
#include <map> #include <map>
@ -54,10 +54,13 @@ namespace nana{
implementation * impl_; implementation * impl_;
}; };
struct window_platform_assoc;
struct root_misc struct root_misc
{ {
basic_window * window; basic_window * window;
window_platform_assoc * wpassoc{ nullptr };
nana::paint::graphics root_graph; nana::paint::graphics root_graph;
shortkey_container shortkeys; shortkey_container shortkeys;
@ -71,6 +74,10 @@ namespace nana{
root_misc(root_misc&&); root_misc(root_misc&&);
root_misc(basic_window * wd, unsigned width, unsigned height); root_misc(basic_window * wd, unsigned width, unsigned height);
~root_misc();
private:
root_misc(const root_misc&) = delete;
root_misc& operator=(const root_misc&) = delete;
};//end struct root_misc };//end struct root_misc

View File

@ -549,7 +549,7 @@ namespace nana{
{ {
nana::detail::platform_spec::instance().keep_window_icon(wd, sml_icon, big_icon); nana::detail::platform_spec::instance().keep_window_icon(wd, sml_icon, big_icon);
if (sml_handle) if (sml_handle)
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_SMALL, reinterpret_cast<WPARAM>(sml_handle)); ::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(sml_handle));
if (big_handle) if (big_handle)
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(big_handle)); ::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(big_handle));

View File

@ -1,7 +1,7 @@
/* /*
* Window Layout Implementation * Window Layout Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -106,43 +106,46 @@ namespace nana
visual = rectangle{ wd->pos_root, wd->dimension }; visual = rectangle{ wd->pos_root, wd->dimension };
if (wd->root_widget != wd) if (category::flags::root != wd->other.category)
{ {
//Test if the root widget is overlapped the specified widget //Test if the root widget is overlapped the specified widget
//the pos of root widget is (0, 0) //the pos of root widget is (0, 0)
if (overlapped(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false) if (overlapped(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false)
return false; return false;
}
for (auto parent = wd->parent; parent; parent = parent->parent) for (auto parent = wd->parent; parent; parent = parent->parent)
{
if (category::flags::root == parent->other.category)
{ {
//visual rectangle of wd's parent if (category::flags::root == parent->other.category)
rectangle vrt_parent{parent->pos_root, parent->dimension};
point pos_root;
while (parent->parent)
{ {
pos_root -= native_interface::window_position(parent->root); wd = parent;
break;
if (!overlap(rectangle{ pos_root, parent->parent->root_widget->dimension }, vrt_parent, vrt_parent))
return false;
parent = parent->parent->root_widget;
} }
if (!overlap(vrt_parent, visual, visual)) if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
return false; return false;
return true;
} }
if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
return false;
} }
return true; //Now, wd actually is the root widget of original parameter wd
if (nullptr == wd->parent)
return true;
auto parent_rw = wd->parent->root_widget;
//visual rectangle of wd's parent
rectangle vrt_parent{ parent_rw->pos_root, parent_rw->dimension };
point pos_root;
while (parent_rw->parent)
{
pos_root -= native_interface::window_position(parent_rw->root);
if (!overlap(rectangle{ pos_root, parent_rw->parent->root_widget->dimension }, vrt_parent, vrt_parent))
return false;
parent_rw = parent_rw->parent->root_widget;
}
return overlap(vrt_parent, visual, visual);
} }
//read_overlaps //read_overlaps
@ -386,6 +389,13 @@ namespace nana
nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension); nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension);
for (auto wd : data_sect.effects_bground_windows) for (auto wd : data_sect.effects_bground_windows)
{ {
//Don't notify the window if both native root windows are not same(e.g. wd and sigwd have
//a some parent). Otherwise, _m_paint_glass_window() recursively paints sigwd to make stack overflow.
//On the other hand, a nested root window is always floating on its parent's child widgets, it's unnecessary to
//notify the wd if they haven't a same native root window.
if (sigwd->root != wd->root)
continue;
if (wd == sigwd || !wd->displayed() || if (wd == sigwd || !wd->displayed() ||
(false == overlapped(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd))) (false == overlapped(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd)))
continue; continue;

View File

@ -1,7 +1,7 @@
/* /*
* Window Manager Implementation * Window Manager Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -16,11 +16,11 @@
#include <nana/gui/detail/events_operation.hpp> #include <nana/gui/detail/events_operation.hpp>
#include <nana/gui/detail/window_manager.hpp> #include <nana/gui/detail/window_manager.hpp>
#include <nana/gui/detail/window_layout.hpp> #include <nana/gui/detail/window_layout.hpp>
#include "window_register.hpp"
#include <nana/gui/detail/native_window_interface.hpp> #include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/detail/inner_fwd_implement.hpp>
#include <nana/gui/layout_utility.hpp> #include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/effects_renderer.hpp> #include <nana/gui/detail/effects_renderer.hpp>
#include "window_register.hpp"
#include "inner_fwd_implement.hpp"
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
@ -140,10 +140,12 @@ namespace nana
//struct root_misc //struct root_misc
root_misc::root_misc(root_misc&& other): root_misc::root_misc(root_misc&& other):
window(other.window), window(other.window),
wpassoc(other.wpassoc),
root_graph(std::move(other.root_graph)), root_graph(std::move(other.root_graph)),
shortkeys(std::move(other.shortkeys)), shortkeys(std::move(other.shortkeys)),
condition(std::move(other.condition)) condition(std::move(other.condition))
{ {
other.wpassoc = nullptr; //moved-from
} }
root_misc::root_misc(basic_window * wd, unsigned width, unsigned height) root_misc::root_misc(basic_window * wd, unsigned width, unsigned height)
@ -155,6 +157,11 @@ namespace nana
condition.pressed_by_space = nullptr; condition.pressed_by_space = nullptr;
condition.hovered = nullptr; condition.hovered = nullptr;
} }
root_misc::~root_misc()
{
bedrock::delete_platform_assoc(wpassoc);
}
//end struct root_misc //end struct root_misc
//class root_register //class root_register

View File

@ -1041,7 +1041,8 @@ namespace nana
bool filebox::show() const bool filebox::show() const
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
std::wstring wfile; auto winitfile = to_wstring(impl_->file);
std::wstring wfile(winitfile);
wfile.resize(520); wfile.resize(520);
OPENFILENAME ofn; OPENFILENAME ofn;

View File

@ -1,7 +1,7 @@
/* /*
* An Implementation of Place for Layout * An Implementation of Place for Layout
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -58,7 +58,7 @@ namespace nana
{ {
div_start, div_end, splitter, div_start, div_end, splitter,
identifier, dock, fit, hfit, vfit, vert, grid, number, array, reparray, identifier, dock, fit, hfit, vfit, vert, grid, number, array, reparray,
weight, width, height, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible, weight, width, height, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible, switchable,
collapse, parameters, collapse, parameters,
equal, equal,
eof, error eof, error
@ -252,14 +252,6 @@ namespace nana
case 'd': return token::width; case 'd': return token::width;
} }
} }
else if ("dock" == idstr_)
return token::dock;
else if ("fit" == idstr_)
return token::fit;
else if ("vertical" == idstr_ || "vert" == idstr_)
return token::vert;
else if ("variable" == idstr_ || "repeated" == idstr_)
return ('v' == idstr_[0] ? token::variable : token::repeated);
else if ("arrange" == idstr_ || "hfit" == idstr_ || "vfit" == idstr_ || "gap" == idstr_) else if ("arrange" == idstr_ || "hfit" == idstr_ || "vfit" == idstr_ || "gap" == idstr_)
{ {
auto ch = idstr_[0]; auto ch = idstr_[0];
@ -287,16 +279,54 @@ namespace nana
_m_throw_error("a parameter list is required after 'collapse'"); _m_throw_error("a parameter list is required after 'collapse'");
return token::collapse; return token::collapse;
} }
else if ("left" == idstr_ || "right" == idstr_ || "top" == idstr_ || "bottom" == idstr_ || "undisplayed" == idstr_ || "invisible" == idstr_) else if (!idstr_.empty())
{ {
switch (idstr_.front()) switch (idstr_.front())
{ {
case 'l': return token::left; case 'b':
case 'r': return token::right; if ("bottom" == idstr_)
case 't': return token::top; return token::bottom;
case 'b': return token::bottom; break;
case 'u': return token::undisplayed; case 'd':
case 'i': return token::invisible; if ("dock" == idstr_)
return token::dock;
break;
case 'f':
if ("fit" == idstr_)
return token::fit;
break;
case 'i':
if ("invisible" == idstr_)
return token::invisible;
break;
case 'l':
if ("left" == idstr_)
return token::left;
break;
case 'r':
if ("repeated" == idstr_)
return token::repeated;
else if ("right" == idstr_)
return token::right;
break;
case 's':
if ("switchable" == idstr_)
return token::switchable;
break;
case 't':
if ("top" == idstr_)
return token::top;
break;
case 'u':
if ("undisplayed" == idstr_)
return token::undisplayed;
break;
case 'v':
if ("vertical" == idstr_ || "vert" == idstr_)
return token::vert;
else if ("variable" == idstr_)
return token::variable;
break;
} }
} }
@ -579,6 +609,7 @@ namespace nana
class div_splitter; class div_splitter;
class div_dock; class div_dock;
class div_dockpane; class div_dockpane;
class div_switchable;
window window_handle{nullptr}; window window_handle{nullptr};
event_handle event_size_handle{nullptr}; event_handle event_size_handle{nullptr};
@ -747,7 +778,7 @@ namespace nana
class place::implement::division class place::implement::division
{ {
public: public:
enum class kind{ arrange, vertical_arrange, grid, splitter, dock, dockpane}; enum class kind{ arrange, vertical_arrange, grid, splitter, dock, dockpane, switchable};
using token = place_parts::tokenizer::token; using token = place_parts::tokenizer::token;
division(kind k, std::string&& n) noexcept division(kind k, std::string&& n) noexcept
@ -981,6 +1012,19 @@ namespace nana
div_next->set_display(true); div_next->set_display(true);
} }
} }
if (display)
{
//If the field is a child of switchable field, hides other child fields.
if (this->div_owner && (kind::switchable == this->div_owner->kind_of_division))
{
for (auto & child : this->div_owner->children)
{
if (child.get() != this)
child->set_display(false);
}
}
}
} }
bool is_back(const division* div) const noexcept bool is_back(const division* div) const noexcept
@ -2539,6 +2583,43 @@ namespace nana
implement * const impl_; implement * const impl_;
}; };
class place::implement::div_switchable
: public division
{
public:
div_switchable(std::string && name, implement* impl) noexcept
: division(kind::switchable, std::move(name)), impl_(impl)
{}
private:
void collocate(window wd) override
{
division * div = nullptr;
for (auto & child : children)
{
if (child->display)
{
div = child.get();
div->field_area = this->margin_area();
div->collocate(wd);
break;
}
}
//Hide other child fields.
rectangle empty_r{ this->margin_area().position() , size{ 0, 0 } };
for (auto & child : children)
{
if (child.get() != div)
{
child->field_area = empty_r;
child->collocate(wd);
}
}
}
private:
implement * const impl_;
};
place::implement::~implement() place::implement::~implement()
{ {
API::umake_event(event_size_handle); API::umake_event(event_size_handle);
@ -2680,6 +2761,9 @@ namespace nana
children.emplace_back(std::move(div)); children.emplace_back(std::move(div));
} }
break; break;
case token::switchable:
div_type = token::switchable;
break;
case token::vert: case token::vert:
div_type = tk; div_type = tk;
break; break;
@ -2850,6 +2934,9 @@ namespace nana
case token::dock: case token::dock:
div.reset(new div_dock(std::move(name), this)); div.reset(new div_dock(std::move(name), this));
break; break;
case token::switchable:
div.reset(new div_switchable(std::move(name), this));
break;
default: default:
throw std::invalid_argument("nana.place: invalid division type."); throw std::invalid_argument("nana.place: invalid division type.");
} }
@ -3184,6 +3271,22 @@ namespace nana
modified_ptr->div_owner = div_owner; modified_ptr->div_owner = div_owner;
modified_ptr->div_next = div_next; modified_ptr->div_next = div_next;
if (div_owner)
{
implement::division * pv_div = nullptr;
//Updates the div_next of the div at front of modified one.
for (auto & div : div_owner->children)
{
if (div.get() == modified_ptr)
{
if (pv_div)
pv_div->div_next = modified_ptr;
break;
}
pv_div = div.get();
}
}
} }
catch (...) catch (...)
{ {

View File

@ -1,7 +1,7 @@
/* /*
* Nana GUI Programming Interface Implementation * Nana GUI Programming Interface Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -20,6 +20,8 @@
#include <nana/gui/widgets/widget.hpp> #include <nana/gui/widgets/widget.hpp>
#include <nana/gui/detail/events_operation.hpp> #include <nana/gui/detail/events_operation.hpp>
#include "../../source/detail/platform_abstraction.hpp"
namespace nana namespace nana
{ {
//restrict //restrict
@ -821,6 +823,15 @@ namespace API
} }
} }
nana::optional<rectangle> window_rectangle(window wd)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard lock;
if (restrict::wd_manager().available(iwd))
return rectangle(iwd->pos_owner, iwd->dimension);
return{};
}
bool get_window_rectangle(window wd, rectangle& r) bool get_window_rectangle(window wd, rectangle& r)
{ {
auto iwd = reinterpret_cast<basic_window*>(wd); auto iwd = reinterpret_cast<basic_window*>(wd);
@ -1473,5 +1484,10 @@ namespace API
return{}; return{};
} }
unsigned screen_dpi(bool x_requested)
{
return ::nana::platform_abstraction::screen_dpi(x_requested);
}
}//end namespace API }//end namespace API
}//end namespace nana }//end namespace nana

View File

@ -379,7 +379,7 @@ namespace nana{ namespace drawerbase
}//end namespace drawerbase }//end namespace drawerbase
//button //button
//@brief: Defaine a button widget and it provides the interfaces to be operational //@brief: Define a button widget and it provides the interfaces to be operational
button::button(){} button::button(){}
button::button(window wd, bool visible) button::button(window wd, bool visible)

View File

@ -1,7 +1,7 @@
/* /*
* A CheckBox Implementation * A CheckBox Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -296,7 +296,7 @@ namespace nana{ namespace drawerbase
return static_cast<std::size_t>(i - ui_container_.cbegin()); return static_cast<std::size_t>(i - ui_container_.cbegin());
} }
return ui_container_.size(); return npos;
} }
std::size_t radio_group::size() const std::size_t radio_group::size() const

View File

@ -1,6 +1,6 @@
/* /*
* A Form Implementation * A Form Implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -10,6 +10,7 @@
*/ */
#include <nana/gui/widgets/form.hpp> #include <nana/gui/widgets/form.hpp>
#include <nana/gui/detail/bedrock.hpp>
namespace nana namespace nana
{ {
@ -94,6 +95,11 @@ namespace nana
{ {
API::wait_for(handle()); API::wait_for(handle());
} }
void form::keyboard_accelerator(const accel_key& key, const std::function<void()>& fn)
{
nana::detail::bedrock::instance().keyboard_accelerator(this->native_handle(), key, fn);
}
//end class form //end class form
//class nested_form //class nested_form

View File

@ -1,7 +1,7 @@
/** /**
* A group widget implementation * A group widget implementation
* Nana C++ Library(http://www.nanaro.org) * Nana C++ Library(http://www.nanaro.org)
* Copyright(C) 2015-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2015-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -172,13 +172,13 @@ namespace nana{
return *this; return *this;
} }
group& group::collocate() throw () group& group::collocate() noexcept
{ {
impl_->place_content.collocate(); impl_->place_content.collocate();
return *this; return *this;
} }
group& group::div(const char* div_str) throw () group& group::div(const char* div_str) noexcept
{ {
if (div_str) if (div_str)
impl_->usr_div_str = div_str; impl_->usr_div_str = div_str;
@ -194,6 +194,21 @@ namespace nana{
return impl_->place_content.field(field); return impl_->place_content.field(field);
} }
void group::field_display(const char* field_name, bool display)
{
impl_->place_content.field_display(field_name, display);
}
bool group::field_display(const char* field_name) const
{
return impl_->place_content.field_display(field_name);
}
void group::erase(window handle)
{
impl_->place_content.erase(handle);
}
void group::_m_add_child(const char* field, widget* wdg) void group::_m_add_child(const char* field, widget* wdg)
{ {
impl_->place_content[field] << wdg->handle(); impl_->place_content[field] << wdg->handle();
@ -208,8 +223,8 @@ namespace nana{
outter[field_title] << impl_->caption; outter[field_title] << impl_->caption;
outter.collocate(); outter.collocate();
impl_->caption.transparent(true);
color pbg = API::bgcolor(this->parent()); color pbg = API::bgcolor(this->parent());
impl_->caption.bgcolor(pbg.blend(colors::black, 0.025)); impl_->caption.bgcolor(pbg.blend(colors::black, 0.025));
this->bgcolor(pbg.blend(colors::black, 0.05)); this->bgcolor(pbg.blend(colors::black, 0.05));
@ -222,10 +237,27 @@ namespace nana{
auto gap_px = impl_->gap - 1; auto gap_px = impl_->gap - 1;
graph.rectangle(true, API::bgcolor(this->parent())); graph.rectangle(true, API::bgcolor(this->parent()));
graph.round_rectangle(rectangle(point(gap_px, impl_->caption_dimension.height / 2),
nana::size(graph.width() - 2 * gap_px, graph.height() - impl_->caption_dimension.height / 2 - gap_px) auto const top_round_line = static_cast<int>(impl_->caption_dimension.height) / 2;
graph.round_rectangle(rectangle(point(gap_px, top_round_line),
nana::size(graph.width() - 2 * gap_px, graph.height() - top_round_line - gap_px)
), ),
3, 3, colors::gray_border, true, this->bgcolor()); 3, 3, colors::gray_border, true, this->bgcolor());
auto opt_r = API::window_rectangle(impl_->caption);
if (opt_r)
{
rectangle grad_r{ opt_r->position(), nana::size{ opt_r->width, static_cast<unsigned>(top_round_line - opt_r->y) } };
grad_r.y += top_round_line*2 / 3;
grad_r.x -= 2;
grad_r.width += 4;
graph.gradual_rectangle(grad_r,
API::bgcolor(this->parent()), this->bgcolor(), true
);
}
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@ -626,6 +626,13 @@ namespace nana
return get_drawer_trigger().ess().items.size(); return get_drawer_trigger().ess().items.size();
} }
void menubar::clear()
{
internal_scope_guard lock;
get_drawer_trigger().ess().items.clear();
API::refresh_window(handle());
}
bool menubar::cancel() bool menubar::cancel()
{ {
return get_drawer_trigger().ess().cancel(); return get_drawer_trigger().ess().cancel();

View File

@ -1,6 +1,6 @@
/* /*
* A Progress Indicator Implementation * A Progress Indicator Implementation
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -96,7 +96,11 @@ namespace nana
{ {
if (widget_) if (widget_)
{ {
auto value_px = (widget_->size().width - border_px * 2) * value_ / max_; auto value_px = (widget_->size().width - border_px * 2);
//avoid overflow
if (value_ < max_)
value_px = static_cast<unsigned>(value_px * (double(value_) / double(max_)));
if (value_px != value_px_) if (value_px != value_px_)
{ {

View File

@ -1,7 +1,7 @@
/* /*
* A Scroll Implementation * A Scroll Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -20,9 +20,15 @@ namespace nana
namespace scroll namespace scroll
{ {
//struct metrics_type //struct metrics_type
metrics_type::metrics_type() metrics_type::metrics_type():
:peak(1), range(1), step(1), value(0), peak(1),
what(buttons::none), pressed(false), scroll_length(0), scroll_pos(0) range(1),
step(1),
value(0),
what(buttons::none),
pressed(false),
scroll_length(0),
scroll_pos(0)
{} {}
//end struct metrics_type //end struct metrics_type

View File

@ -1,7 +1,7 @@
/* /*
* A Content View Implementation * A Content View Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2017-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -19,6 +19,39 @@ namespace nana {
namespace widgets { namespace widgets {
namespace skeletons namespace skeletons
{ {
struct cv_scroll_rep
{
content_view::scrolls enabled_scrolls{ content_view::scrolls::both };
nana::scroll<false> horz;
nana::scroll<true> vert;
scroll_interface* scroll(arg_wheel::wheel whl)
{
if (arg_wheel::wheel::horizontal == whl)
return &horz;
else if (arg_wheel::wheel::vertical == whl)
return &vert;
return nullptr;
}
};
class scroll_operation
: public scroll_operation_interface
{
public:
scroll_operation(std::shared_ptr<cv_scroll_rep>& impl)
: cv_scroll_(impl)
{
}
private:
bool visible(bool vert) const override
{
return !(vert ? cv_scroll_->vert.empty() : cv_scroll_->horz.empty());
}
private:
std::shared_ptr<cv_scroll_rep> const cv_scroll_;
};
struct content_view::implementation struct content_view::implementation
{ {
content_view& view; content_view& view;
@ -35,9 +68,13 @@ namespace nana {
bool drag_started{ false }; bool drag_started{ false };
point origin; point origin;
scrolls enabled_scrolls{scrolls::both}; /*
scrolls enabled_scrolls{scrolls::both}; //deprecated
nana::scroll<false> horz; nana::scroll<false> horz;
nana::scroll<true> vert; nana::scroll<true> vert;
*/
std::shared_ptr<cv_scroll_rep> cv_scroll;
timer tmr; timer tmr;
@ -50,9 +87,11 @@ namespace nana {
implementation(content_view& v, window handle) : implementation(content_view& v, window handle) :
view(v), view(v),
window_handle(handle) window_handle(handle),
cv_scroll(std::make_shared<cv_scroll_rep>())
{ {
API::events(handle).mouse_wheel.connect_unignorable([this](const arg_wheel& arg) { API::events(handle).mouse_wheel.connect_unignorable([this](const arg_wheel& arg) {
#if 0
scroll_interface * scroll = nullptr; scroll_interface * scroll = nullptr;
switch (arg.which) switch (arg.which)
{ {
@ -66,6 +105,11 @@ namespace nana {
//Other button is not unsupported. //Other button is not unsupported.
return; return;
} }
#else
auto const scroll = cv_scroll->scroll(arg.which);
if (nullptr == scroll)
return;
#endif
if (!API::empty_window(arg.window_handle)) if (!API::empty_window(arg.window_handle))
{ {
@ -159,11 +203,11 @@ namespace nana {
auto speed_horz = 0; auto speed_horz = 0;
if (skew.x) if (skew.x)
speed_horz = skew.x / (std::max)(1, static_cast<int>(horz.step())) + (skew.x < 0 ? -1 : 1); speed_horz = skew.x / (std::max)(1, static_cast<int>(cv_scroll->horz.step())) + (skew.x < 0 ? -1 : 1);
auto speed_vert = 0; auto speed_vert = 0;
if (skew.y) if (skew.y)
speed_vert = skew.y / (std::max)(1, static_cast<int>(vert.step())) + (skew.y < 0 ? -1 : 1); speed_vert = skew.y / (std::max)(1, static_cast<int>(cv_scroll->vert.step())) + (skew.y < 0 ? -1 : 1);
speed_horz = (std::min)(5, (std::max)(speed_horz, -5)); speed_horz = (std::min)(5, (std::max)(speed_horz, -5));
speed_vert = (std::min)(5, (std::max)(speed_vert, -5)); speed_vert = (std::min)(5, (std::max)(speed_vert, -5));
@ -180,10 +224,10 @@ namespace nana {
//event hander for scrollbars //event hander for scrollbars
auto event_fn = [this](const arg_scroll& arg) auto event_fn = [this](const arg_scroll& arg)
{ {
if (arg.window_handle == this->vert.handle()) if (arg.window_handle == cv_scroll->vert.handle())
origin.y = static_cast<int>(this->vert.value()); origin.y = static_cast<int>(cv_scroll->vert.value());
else else
origin.x = static_cast<int>(this->horz.value()); origin.x = static_cast<int>(cv_scroll->horz.value());
if (this->events.scrolled) if (this->events.scrolled)
this->events.scrolled(); this->events.scrolled();
@ -194,33 +238,33 @@ namespace nana {
this->passive = passive; this->passive = passive;
bool const vert_allowed = (enabled_scrolls == scrolls::vert || enabled_scrolls == scrolls::both); bool const vert_allowed = (cv_scroll->enabled_scrolls == scrolls::vert || cv_scroll->enabled_scrolls == scrolls::both);
bool const horz_allowed = (enabled_scrolls == scrolls::horz || enabled_scrolls == scrolls::both); bool const horz_allowed = (cv_scroll->enabled_scrolls == scrolls::horz || cv_scroll->enabled_scrolls == scrolls::both);
if ((imd_area.width != disp_area.width) && vert_allowed) if ((imd_area.width != disp_area.width) && vert_allowed)
{ {
if (vert.empty()) if (cv_scroll->vert.empty())
{ {
vert.create(window_handle); cv_scroll->vert.create(window_handle);
vert.events().value_changed.connect_unignorable(event_fn); cv_scroll->vert.events().value_changed.connect_unignorable(event_fn);
API::take_active(vert, false, window_handle); API::take_active(cv_scroll->vert, false, window_handle);
this->passive = false; this->passive = false;
} }
vert.move({ cv_scroll->vert.move({
disp_area.x + static_cast<int>(imd_area.width) + skew_vert.x, disp_area.x + static_cast<int>(imd_area.width) + skew_vert.x,
disp_area.y + skew_vert.y, disp_area.y + skew_vert.y,
space(), space(),
imd_area.height + extra_px.height imd_area.height + extra_px.height
}); });
vert.amount(content_size.height); cv_scroll->vert.amount(content_size.height);
vert.range(imd_area.height); cv_scroll->vert.range(imd_area.height);
vert.value(origin.y); cv_scroll->vert.value(origin.y);
} }
else else
{ {
vert.close(); cv_scroll->vert.close();
//If vert is allowed, it indicates the vertical origin is not moved //If vert is allowed, it indicates the vertical origin is not moved
//Make sure the v origin is zero //Make sure the v origin is zero
@ -230,28 +274,28 @@ namespace nana {
if ((imd_area.height != disp_area.height) && horz_allowed) if ((imd_area.height != disp_area.height) && horz_allowed)
{ {
if (horz.empty()) if (cv_scroll->horz.empty())
{ {
horz.create(window_handle); cv_scroll->horz.create(window_handle);
horz.events().value_changed.connect_unignorable(event_fn); cv_scroll->horz.events().value_changed.connect_unignorable(event_fn);
API::take_active(horz, false, window_handle); API::take_active(cv_scroll->horz, false, window_handle);
this->passive = false; this->passive = false;
} }
horz.move({ cv_scroll->horz.move({
disp_area.x + skew_horz.x, disp_area.x + skew_horz.x,
disp_area.y + static_cast<int>(imd_area.height) + skew_horz.y, disp_area.y + static_cast<int>(imd_area.height) + skew_horz.y,
imd_area.width + extra_px.width, imd_area.width + extra_px.width,
space() space()
}); });
horz.amount(content_size.width); cv_scroll->horz.amount(content_size.width);
horz.range(imd_area.width); cv_scroll->horz.range(imd_area.width);
horz.value(origin.x); cv_scroll->horz.value(origin.x);
} }
else else
{ {
horz.close(); cv_scroll->horz.close();
//If horz is allowed, it indicates the horzontal origin is not moved //If horz is allowed, it indicates the horzontal origin is not moved
//Make sure the x origin is zero //Make sure the x origin is zero
if (horz_allowed) if (horz_allowed)
@ -279,20 +323,25 @@ namespace nana {
bool content_view::enable_scrolls(scrolls which) bool content_view::enable_scrolls(scrolls which)
{ {
if (impl_->enabled_scrolls == which) if (impl_->cv_scroll->enabled_scrolls == which)
return false; return false;
impl_->enabled_scrolls = which; impl_->cv_scroll->enabled_scrolls = which;
impl_->size_changed(false); impl_->size_changed(false);
return true; return true;
} }
std::shared_ptr<scroll_operation_interface> content_view::scroll_operation() const
{
return std::make_shared<skeletons::scroll_operation>(impl_->cv_scroll);
}
void content_view::step(unsigned step_value, bool horz) void content_view::step(unsigned step_value, bool horz)
{ {
if (horz) if (horz)
impl_->horz.step(step_value); impl_->cv_scroll->horz.step(step_value);
else else
impl_->vert.step(step_value); impl_->cv_scroll->vert.step(step_value);
} }
bool content_view::scroll(bool forwards, bool horz) bool content_view::scroll(bool forwards, bool horz)
@ -306,17 +355,17 @@ namespace nana {
} }
if (horz) if (horz)
return impl_->horz.make_step(forwards, speed); return impl_->cv_scroll->horz.make_step(forwards, speed);
return impl_->vert.make_step(forwards, speed); return impl_->cv_scroll->vert.make_step(forwards, speed);
} }
bool content_view::turn_page(bool forwards, bool horz) bool content_view::turn_page(bool forwards, bool horz)
{ {
if (horz) if (horz)
return impl_->horz.make_page_scroll(forwards); return impl_->cv_scroll->horz.make_page_scroll(forwards);
else else
return impl_->vert.make_page_scroll(forwards); return impl_->cv_scroll->vert.make_page_scroll(forwards);
} }
void content_view::disp_area(const rectangle& da, const point& skew_horz, const point& skew_vert, const size& extra_px, bool try_update) void content_view::disp_area(const rectangle& da, const point& skew_horz, const point& skew_vert, const size& extra_px, bool try_update)
@ -404,7 +453,7 @@ namespace nana {
void content_view::draw_corner(graph_reference graph) void content_view::draw_corner(graph_reference graph)
{ {
auto r = corner(); auto r = corner();
if ((!r.empty()) && (scrolls::both == impl_->enabled_scrolls)) if ((!r.empty()) && (scrolls::both == impl_->cv_scroll->enabled_scrolls))
graph.rectangle(r, true, colors::button_face); graph.rectangle(r, true, colors::button_face);
} }
@ -415,8 +464,8 @@ namespace nana {
rectangle content_view::view_area(const size& alt_content_size) const rectangle content_view::view_area(const size& alt_content_size) const
{ {
bool const vert_allowed = (impl_->enabled_scrolls == scrolls::vert || impl_->enabled_scrolls == scrolls::both); bool const vert_allowed = (impl_->cv_scroll->enabled_scrolls == scrolls::vert || impl_->cv_scroll->enabled_scrolls == scrolls::both);
bool const horz_allowed = (impl_->enabled_scrolls == scrolls::horz || impl_->enabled_scrolls == scrolls::both); bool const horz_allowed = (impl_->cv_scroll->enabled_scrolls == scrolls::horz || impl_->cv_scroll->enabled_scrolls == scrolls::both);
unsigned extra_horz = (horz_allowed && (impl_->disp_area.width < alt_content_size.width) ? space() : 0); unsigned extra_horz = (horz_allowed && (impl_->disp_area.width < alt_content_size.width) ? space() : 0);
unsigned extra_vert = (vert_allowed && (impl_->disp_area.height < alt_content_size.height + extra_horz) ? space() : 0); unsigned extra_vert = (vert_allowed && (impl_->disp_area.height < alt_content_size.height + extra_horz) ? space() : 0);
@ -435,13 +484,13 @@ namespace nana {
unsigned content_view::extra_space(bool horz) const unsigned content_view::extra_space(bool horz) const
{ {
return ((horz ? impl_->horz.empty() : impl_->vert.empty()) ? 0 : space()); return ((horz ? impl_->cv_scroll->horz.empty() : impl_->cv_scroll->vert.empty()) ? 0 : space());
} }
void content_view::change_position(int pos, bool aligned, bool horz) void content_view::change_position(int pos, bool aligned, bool horz)
{ {
if (aligned) if (aligned)
pos -= (pos % static_cast<int>(horz ? impl_->horz.step() : impl_->vert.step())); pos -= (pos % static_cast<int>(horz ? impl_->cv_scroll->horz.step() : impl_->cv_scroll->vert.step()));
auto imd_size = this->view_area(); auto imd_size = this->view_area();
@ -490,8 +539,8 @@ namespace nana {
void content_view::sync(bool passive) void content_view::sync(bool passive)
{ {
impl_->passive = passive; impl_->passive = passive;
impl_->horz.value(impl_->origin.x); impl_->cv_scroll->horz.value(impl_->origin.x);
impl_->vert.value(impl_->origin.y); impl_->cv_scroll->vert.value(impl_->origin.y);
impl_->passive = true; impl_->passive = true;
} }
@ -520,15 +569,15 @@ namespace nana {
impl_->origin.y = 0; impl_->origin.y = 0;
bool changed = false; bool changed = false;
if (!impl_->horz.empty() && (static_cast<long long>(impl_->horz.value()) != impl_->origin.x)) if (!impl_->cv_scroll->horz.empty() && (static_cast<long long>(impl_->cv_scroll->horz.value()) != impl_->origin.x))
{ {
impl_->horz.value(impl_->origin.x); impl_->cv_scroll->horz.value(impl_->origin.x);
changed = true; changed = true;
} }
if ((!impl_->vert.empty()) && (static_cast<long long>(impl_->vert.value()) != impl_->origin.y)) if ((!impl_->cv_scroll->vert.empty()) && (static_cast<long long>(impl_->cv_scroll->vert.value()) != impl_->origin.y))
{ {
impl_->vert.value(impl_->origin.y); impl_->cv_scroll->vert.value(impl_->origin.y);
changed = true; changed = true;
} }

View File

@ -1,7 +1,7 @@
/* /*
* A Content View Implementation * A Content View Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2017-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -16,6 +16,7 @@
#include <nana/gui/basis.hpp> #include <nana/gui/basis.hpp>
#include <functional> #include <functional>
#include <memory>
namespace nana namespace nana
{ {
@ -58,6 +59,8 @@ namespace skeletons
bool enable_scrolls(scrolls which); bool enable_scrolls(scrolls which);
std::shared_ptr<scroll_operation_interface> scroll_operation() const;
void step(unsigned step_value, bool horz); void step(unsigned step_value, bool horz);
bool scroll(bool forwards, bool horz); bool scroll(bool forwards, bool horz);
bool turn_page(bool forwards, bool horz); bool turn_page(bool forwards, bool horz);
@ -92,7 +95,7 @@ namespace skeletons
return 16; return 16;
} }
private: private:
implementation * const impl_; implementation* const impl_;
}; };
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* A text editor implementation * A text editor implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -1954,6 +1954,11 @@ namespace nana{ namespace widgets
return impl_->capacities.behavior->take_lines(); return impl_->capacities.behavior->take_lines();
} }
std::shared_ptr<scroll_operation_interface> text_editor::scroll_operation() const
{
return impl_->cview->scroll_operation();
}
void text_editor::draw_corner() void text_editor::draw_corner()
{ {
impl_->cview->draw_corner(graph_); impl_->cview->draw_corner(graph_);

View File

@ -1,7 +1,7 @@
/* /*
* A Textbox Implementation * A Textbox Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -816,6 +816,16 @@ namespace drawerbase {
if(editor) if(editor)
editor->reset_caret_pixels(); editor->reset_caret_pixels();
} }
std::shared_ptr<scroll_operation_interface> textbox::_m_scroll_operation() const
{
internal_scope_guard lock;
auto editor = get_drawer_trigger().editor();
if (editor)
return editor->scroll_operation();
return {};
}
//end class textbox //end class textbox
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/* /*
* A Toolbar Implementation * A Toolbar Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -47,8 +47,6 @@ namespace nana
{} {}
}; };
class item_container class item_container
{ {
public: public:
@ -57,8 +55,7 @@ namespace nana
~item_container() ~item_container()
{ {
for(auto ptr : cont_) clear();
delete ptr;
} }
void insert(size_type pos, std::string text, const nana::paint::image& img, item_type::kind type) void insert(size_type pos, std::string text, const nana::paint::image& img, item_type::kind type)
@ -120,6 +117,15 @@ namespace nana
{ {
return cont_.at(pos); return cont_.at(pos);
} }
void clear()
{
for(auto ptr : cont_)
delete ptr;
cont_.clear();
}
private: private:
container_type cont_; container_type cont_;
size_t right_{ npos }; size_t right_{ npos };
@ -421,6 +427,12 @@ namespace nana
} }
} }
//class drawer //class drawer
// Item Proxy
void item_proxy::enable(bool enable_state)
{
widget.enable(button, enable_state);
}
}//end namespace toolbar }//end namespace toolbar
}//end namespace drawerbase }//end namespace drawerbase
@ -449,16 +461,24 @@ namespace nana
API::refresh_window(handle()); API::refresh_window(handle());
} }
void toolbar::append(const std::string& text, const nana::paint::image& img) drawerbase::toolbar::item_proxy toolbar::append(const std::string& text, const nana::paint::image& img)
{ {
get_drawer_trigger().items().push_back(text, img); get_drawer_trigger().items().push_back(text, img);
API::refresh_window(handle()); API::refresh_window(handle());
return {*this, get_drawer_trigger().items().size() - 1u};
} }
void toolbar::append(const std::string& text) drawerbase::toolbar::item_proxy toolbar::append(const std::string& text)
{ {
get_drawer_trigger().items().push_back(text, {}); get_drawer_trigger().items().push_back(text, {});
API::refresh_window(this->handle()); API::refresh_window(this->handle());
return {*this, get_drawer_trigger().items().size() - 1u};
}
void toolbar::clear()
{
get_drawer_trigger().items().clear();
API::refresh_window(this->handle());
} }
bool toolbar::enable(size_type pos) const bool toolbar::enable(size_type pos) const

View File

@ -1,7 +1,7 @@
/* /*
* A Treebox Implementation * A Treebox Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -29,6 +29,25 @@ namespace nana
{ {
using node_type = trigger::node_type; using node_type = trigger::node_type;
class exclusive_scroll_operation
: public scroll_operation_interface
{
public:
exclusive_scroll_operation(std::shared_ptr<nana::scroll<true>>& scroll_wdg)
:scroll_(scroll_wdg)
{}
bool visible(bool vert) const override
{
if (vert)
return !scroll_->empty();
return false;
}
private:
std::shared_ptr<nana::scroll<true>> scroll_;
};
bool no_sensitive_compare(const std::string& text, const char *pattern, std::size_t len) bool no_sensitive_compare(const std::string& text, const char *pattern, std::size_t len)
{ {
if(len <= text.length()) if(len <= text.length())
@ -214,7 +233,7 @@ namespace nana
struct shape_tag struct shape_tag
{ {
nana::upoint border; nana::upoint border;
nana::scroll<true> scroll; std::shared_ptr<nana::scroll<true>> scroll;
mutable std::map<std::string, node_image_tag> image_table; mutable std::map<std::string, node_image_tag> image_table;
@ -261,6 +280,7 @@ namespace nana
shape.first = nullptr; shape.first = nullptr;
shape.indent_pixels = 10; shape.indent_pixels = 10;
shape.offset_x = 0; shape.offset_x = 0;
shape.scroll = std::make_shared<nana::scroll<true>>();
attr.auto_draw = true; attr.auto_draw = true;
@ -598,7 +618,7 @@ namespace nana
std::size_t max_allow = max_allowed(); std::size_t max_allow = max_allowed();
std::size_t visual_items = visual_item_size(); std::size_t visual_items = visual_item_size();
auto & scroll = shape.scroll; auto & scroll = *shape.scroll;
if(visual_items <= max_allow) if(visual_items <= max_allow)
{ {
if(!scroll.empty()) if(!scroll.empty())
@ -618,7 +638,7 @@ namespace nana
adjust.scroll_timestamp = nana::system::timestamp(); adjust.scroll_timestamp = nana::system::timestamp();
adjust.timer.start(); adjust.timer.start();
shape.first = attr.tree_cont.advance_if(nullptr, shape.scroll.value(), pred_allow_child{}); shape.first = attr.tree_cont.advance_if(nullptr, shape.scroll->value(), pred_allow_child{});
draw(false, false, true); draw(false, false, true);
}); });
} }
@ -641,7 +661,7 @@ namespace nana
if(!data.graph) if(!data.graph)
return 0; return 0;
return static_cast<int>(data.graph->width() - (shape.scroll.empty() ? 0 : shape.scroll.size().width)); return static_cast<int>(data.graph->width() - (shape.scroll->empty() ? 0 : shape.scroll->size().width));
} }
unsigned node_w_pixels(const node_type *node) const unsigned node_w_pixels(const node_type *node) const
@ -958,10 +978,14 @@ namespace nana
return *this; return *this;
} }
std::size_t item_proxy::size() const std::size_t item_proxy::size() const
{ {
std::size_t n = 0; std::size_t n = 0;
for(auto child = node_->child; child; child = child->child)
//Fixed by ErrorFlynn
//this method incorrectly returned the number of levels beneath the nodes using child = child->child
for(auto child = node_->child; child; child = child->next)
++n; ++n;
return n; return n;
@ -1897,7 +1921,7 @@ namespace nana
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg) void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
{ {
auto & scroll = impl_->shape.scroll; auto & scroll = *impl_->shape.scroll;
if (scroll.empty()) if (scroll.empty())
return; return;
@ -1931,10 +1955,10 @@ namespace nana
impl_->draw(false); impl_->draw(false);
API::dev::lazy_refresh(); API::dev::lazy_refresh();
impl_->show_scroll(); impl_->show_scroll();
if(!impl_->shape.scroll.empty()) if(!impl_->shape.scroll->empty())
{ {
nana::size s = impl_->data.graph->size(); nana::size s = impl_->data.graph->size();
impl_->shape.scroll.move(rectangle{ static_cast<int>(s.width) - 16, 0, 16, s.height }); impl_->shape.scroll->move(rectangle{ static_cast<int>(s.width) - 16, 0, 16, s.height });
} }
} }
@ -2209,5 +2233,11 @@ namespace nana
{ {
return item_proxy(const_cast<drawer_trigger_t*>(&get_drawer_trigger()), get_drawer_trigger().selected()); return item_proxy(const_cast<drawer_trigger_t*>(&get_drawer_trigger()), get_drawer_trigger().selected());
} }
std::shared_ptr<scroll_operation_interface> treebox::_m_scroll_operation() const
{
internal_scope_guard lock;
return std::make_shared<drawerbase::treebox::exclusive_scroll_operation>(get_drawer_trigger().impl()->shape.scroll);
}
//end class treebox //end class treebox
}//end namespace nana }//end namespace nana

View File

@ -1,6 +1,6 @@
/* /*
* The fundamental widget class implementation * The fundamental widget class implementation
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -158,6 +158,11 @@ namespace nana
return (API::focus_window() == handle()); return (API::focus_window() == handle());
} }
std::shared_ptr<scroll_operation_interface> widget::scroll_operation()
{
return _m_scroll_operation();
}
void widget::show() void widget::show()
{ {
_m_show(true); _m_show(true);
@ -317,6 +322,11 @@ namespace nana
API::window_enabled(handle(), value); API::window_enabled(handle(), value);
} }
std::shared_ptr<scroll_operation_interface> widget::_m_scroll_operation()
{
return {};
}
bool widget::_m_show(bool visible) bool widget::_m_show(bool visible)
{ {
API::show_window(handle(), visible); API::show_window(handle(), visible);

View File

@ -91,7 +91,7 @@ namespace nana
{ {
::jpeg_create_decompress(&jdstru); ::jpeg_create_decompress(&jdstru);
::jpeg_mem_src(&jdstru, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(data)), bytes); ::jpeg_mem_src(&jdstru, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(data)), static_cast<unsigned long>(bytes));
_m_read_jpg(jdstru); _m_read_jpg(jdstru);
jpeg_finish_decompress(&jdstru); jpeg_finish_decompress(&jdstru);

View File

@ -1,7 +1,7 @@
/* /*
* Paint Graphics Implementation * Paint Graphics Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -127,11 +127,14 @@ namespace paint
return impl_->real_font->family(); return impl_->real_font->family();
} }
double font::size() const double font::size(bool fixed) const
{ {
if(empty()) return 0; double size_pt = (empty() ? 0.0 : impl_->real_font->size());
return impl_->real_font->size(); if (fixed && (0.0 == size_pt))
return platform_abstraction::font_default_pt();
return size_pt;
} }
bool font::bold() const bool font::bold() const

View File

@ -208,7 +208,7 @@ namespace nana{ namespace system{
memcpy(addr, buf, size); memcpy(addr, buf, size);
::GlobalUnlock(g); ::GlobalUnlock(g);
unsigned data_format; unsigned data_format = CF_MAX;
switch(fmt) switch(fmt)
{ {
case format::text: data_format = CF_UNICODETEXT; break; case format::text: data_format = CF_UNICODETEXT; break;
@ -244,7 +244,7 @@ namespace nana{ namespace system{
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
if(::OpenClipboard(::GetFocus())) if(::OpenClipboard(::GetFocus()))
{ {
unsigned data_format; unsigned data_format = CF_MAX;
switch(fmt) switch(fmt)
{ {
case format::text: data_format = CF_UNICODETEXT; break; case format::text: data_format = CF_UNICODETEXT; break;