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

7
.gitignore vendored
View File

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

View File

@ -59,7 +59,7 @@ matrix:
- llvm-toolchain-precise
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"
#- 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
@ -87,7 +87,7 @@ script:
# 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/"
# 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
- ls
- cd ..

View File

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

View File

@ -1,7 +1,7 @@
/**
* Predefined Symbols for C++
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -171,9 +171,9 @@
#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.
// it seems that MinGW 6.3 and 7.1 have std::thread
#ifdef NANA_MINGW
# ifndef STD_THREAD_NOT_SUPPORTED
# define STD_THREAD_NOT_SUPPORTED
@ -221,8 +221,11 @@
# if __has_include(<filesystem>)
# undef STD_FILESYSTEM_NOT_SUPPORTED
# endif
# if __has_include(<mutex>)
# undef STD_THREAD_NOT_SUPPORTED
# if __has_include(<mutex>)
# 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

View File

@ -1,7 +1,7 @@
/**
* A ISO C++ filesystem Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -55,6 +55,36 @@
#define NANA_USING_BOOST_FILESYSTEM 1
# include <chrono>
# 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
namespace std {
@ -75,6 +105,16 @@ namespace std {
socket = boost::filesystem::file_type::socket_file,
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
} // experimental
} // std

View File

@ -1,6 +1,6 @@
/**
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -16,6 +16,7 @@
#define NANA_FILESYSTEM_EXT_HPP
#include <nana/filesystem/filesystem.hpp>
#include <nana/deploy.hpp>
namespace nana
{
@ -34,6 +35,16 @@ namespace filesystem_ext
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
{
return is_directory(dir.status());

View File

@ -4,7 +4,7 @@
*
* Basis Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -30,6 +30,15 @@ namespace nana
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
{
unchecked, checked, partial
@ -288,6 +297,19 @@ that return a corresponding nana::appearance with predefined values.
virtual bool visible() const = 0;
};//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
{
/// The system-wide parameters for mouse wheel

View File

@ -1,7 +1,7 @@
/**
* A Bedrock Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -27,6 +27,7 @@ namespace detail
struct basic_window;
class window_manager;
struct window_platform_assoc;
/// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions.
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
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:
void event_expose(core_window_t *, bool exposed);
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
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
#include <nana/gui/effects.hpp>
@ -76,7 +88,7 @@ namespace nana{
nana::rectangle r;
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)
{
@ -140,12 +152,17 @@ namespace nana{
}
}
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)))
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;
// Don't render the effect if the window is disabled.
if (wd->flags.enabled)
{
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;
}

View File

@ -1,7 +1,7 @@
/**
* Definition of General Events
* 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.
* (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
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.
bool ctrl; ///< keyboard Ctrl is pressed?
bool shift; ///< keyboard Shift is pressed
bool alt; ///< it is set to indicate the modifier key Alt just prior to the event.
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

View File

@ -301,6 +301,8 @@ namespace API
void window_size(window, const size&);
size window_outline_size(window);
void window_outline_size(window, const size&);
nana::optional<rectangle> window_rectangle(window);
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.
void window_enabled(window, bool);
@ -434,6 +436,8 @@ namespace API
* widget by the content extent.
*/
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 nana

View File

@ -1,7 +1,7 @@
/**
* A CheckBox Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -100,6 +100,7 @@ namespace drawerbase
event_handle eh_keyboard;
};
public:
constexpr static const std::size_t npos = static_cast<std::size_t>(-1);
~radio_group();
void add(checkbox&);
std::size_t checked() const; ///< Retrieves the index of the checkbox which is checked.

View File

@ -1,7 +1,7 @@
/**
* A Form Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -68,6 +68,8 @@ namespace nana
void modality() const;
void wait_for_this();
void keyboard_accelerator(const accel_key&, const std::function<void()>& fn);
};
class nested_form

View File

@ -1,7 +1,7 @@
/**
* A group widget implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -28,6 +28,7 @@ namespace nana{
struct implement;
public:
using field_reference = place::field_reference;
constexpr static const std::size_t npos = static_cast<std::size_t>(-1);
/// The default construction
group();
@ -63,9 +64,13 @@ namespace nana{
group& enable_format_caption(bool format);
group& collocate() throw();
group& div(const char* div_str) throw();
group& collocate() noexcept;
group& div(const char* div_str) noexcept;
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>
Widget* create_child(const char* field, Args && ... args)

View File

@ -1,7 +1,7 @@
/**
* A List Box Implementation
* 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.
* (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;
/// 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
/**
* @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*, category_t*) noexcept;
/// Append an item at abs end of the category, set_value determines whether assign T object to the value of item.
template<typename T>
item_proxy append(T&& t, bool set_value = false)
/// Append an item at the end of this category using the oresolver to generate the texts to be put in each column.
///
/// 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_);
@ -1039,7 +1049,7 @@ namespace nana
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::wstring> texts);
@ -1194,17 +1204,25 @@ namespace nana
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.
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 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
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
//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_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.
};
@ -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::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::wstring category); ///< Appends a new category 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;
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;
std::shared_ptr<scroll_operation_interface> _m_scroll_operation();
};
}//end namespace nana

View File

@ -95,6 +95,7 @@ namespace nana
menu& push_back(const std::string&); ///< Appends a new (empty) menu.
menu& at(size_t index) const; ///< Gets the menu specified by index.
std::size_t length() const; ///< Number of menus.
void clear(); ///< Removes all the menus.
/// Deselects the menu
/**

View File

@ -1,7 +1,7 @@
/**
* A Scroll Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -147,7 +147,7 @@ namespace nana
void step(size_type s)
{
metrics_.step = s;
metrics_.step = (s ? s : 1);
}
bool make_step(bool forward, unsigned multiple)
@ -398,7 +398,7 @@ namespace nana
/// \brief The construct that creates a widget.
/// @param wd A handle to the parent window of the widget being created.
/// @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?
}
@ -501,7 +501,8 @@ namespace nana
/// @return true if the vlaue is changed.
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 namespace nana

View File

@ -1,7 +1,7 @@
/*
* A text editor implementation
* 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.
* (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;
bool try_refresh();
std::shared_ptr<scroll_operation_interface> scroll_operation() const;
private:
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);

View File

@ -1,7 +1,7 @@
/**
* A Tabbar implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -42,9 +42,8 @@ namespace nana
: arg_tabbar<T>({wdg, v})
{}
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 remove = true; ///< determines whether to remove the item
mutable bool close_attach_window = true; ///< determines whether to close the attached window. It is ignored if remove is false
};
namespace drawerbase
@ -293,7 +292,7 @@ namespace nana
if (pos > length())
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);
}

View File

@ -1,7 +1,7 @@
/**
* A Textbox Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -279,6 +279,7 @@ namespace nana
native_string_type _m_caption() const throw() override;
void _m_caption(native_string_type&&) override;
void _m_typeface(const paint::font&) override;
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() const;
};
}//end namespace nana
#include <nana/pop_ignore_diagnostic>

View File

@ -1,108 +1,118 @@
/**
* A Toolbar Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/toolbar.hpp
*/
#ifndef NANA_GUI_WIDGET_TOOLBAR_HPP
#define NANA_GUI_WIDGET_TOOLBAR_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp"
namespace nana
{
class toolbar;
struct arg_toolbar
: public event_arg
{
toolbar& widget;
std::size_t button;
arg_toolbar(toolbar&, std::size_t);
};
namespace drawerbase
{
namespace toolbar
{
struct toolbar_events
: public general_events
{
basic_event<arg_toolbar> selected; ///< A mouse click on a control button.
basic_event<arg_toolbar> enter; ///< The mouse enters a control button.
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
};
struct item_type;
class item_container;
class drawer
: public drawer_trigger
{
struct drawer_impl_type;
public:
using size_type = std::size_t;
drawer();
~drawer();
item_container& items() const;
void scale(unsigned);
private:
void refresh(graph_reference) override;
void attached(widget_reference, graph_reference) override;
void detached() override;
void mouse_move(graph_reference, const arg_mouse&) override;
void mouse_leave(graph_reference, const arg_mouse&) override;
void mouse_down(graph_reference, const arg_mouse&) override;
void mouse_up(graph_reference, const arg_mouse&) override;
private:
size_type _m_which(point, bool want_if_disabled) const;
void _m_calc_pixels(item_type*, bool force);
private:
::nana::toolbar* widget_;
drawer_impl_type* impl_;
};
}//end namespace toolbar
}//end namespace drawerbase
/// Control bar that contains buttons for controlling
class toolbar
: public widget_object<category::widget_tag, drawerbase::toolbar::drawer, drawerbase::toolbar::toolbar_events>
{
public:
using size_type = std::size_t; ///< A type to count the number of elements.
toolbar() = default;
toolbar(window, bool visible, bool detached=false);
toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false);
void separate(); ///< Adds a separator.
void append(const ::std::string& text, const nana::paint::image& img); ///< Adds a control button.
void append(const ::std::string& text); ///< Adds a control button.
bool enable(size_type index) const;
void enable(size_type index, bool enable_state);
void scale(unsigned s); ///< Sets the scale of control button.
/// Enable to place buttons at right part. After calling it, every new button is right aligned.
void go_right();
bool detached() { return detached_; };
private:
bool detached_;
};
}//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif
/**
* A Toolbar Implementation
* 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/widgets/toolbar.hpp
*/
#ifndef NANA_GUI_WIDGET_TOOLBAR_HPP
#define NANA_GUI_WIDGET_TOOLBAR_HPP
#include <nana/push_ignore_diagnostic>
#include "widget.hpp"
namespace nana
{
class toolbar;
struct arg_toolbar
: public event_arg
{
toolbar& widget;
std::size_t button;
arg_toolbar(toolbar&, std::size_t);
};
namespace drawerbase
{
namespace toolbar
{
struct item_proxy
{
nana::toolbar& widget;
std::size_t button;
void enable(bool enable_state);
};
struct toolbar_events
: public general_events
{
basic_event<arg_toolbar> selected; ///< A mouse click on a control button.
basic_event<arg_toolbar> enter; ///< The mouse enters a control button.
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
};
struct item_type;
class item_container;
class drawer
: public drawer_trigger
{
struct drawer_impl_type;
public:
using size_type = std::size_t;
drawer();
~drawer();
item_container& items() const;
void scale(unsigned);
private:
void refresh(graph_reference) override;
void attached(widget_reference, graph_reference) override;
void detached() override;
void mouse_move(graph_reference, const arg_mouse&) override;
void mouse_leave(graph_reference, const arg_mouse&) override;
void mouse_down(graph_reference, const arg_mouse&) override;
void mouse_up(graph_reference, const arg_mouse&) override;
private:
size_type _m_which(point, bool want_if_disabled) const;
void _m_calc_pixels(item_type*, bool force);
private:
::nana::toolbar* widget_;
drawer_impl_type* impl_;
};
}//end namespace toolbar
}//end namespace drawerbase
/// Control bar that contains buttons for controlling
class toolbar
: public widget_object<category::widget_tag, drawerbase::toolbar::drawer, drawerbase::toolbar::toolbar_events>
{
public:
using size_type = std::size_t; ///< A type to count the number of elements.
toolbar() = default;
toolbar(window, bool visible, bool detached=false);
toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false);
void separate(); ///< Adds a separator.
drawerbase::toolbar::item_proxy append(const ::std::string& text, const nana::paint::image& img); ///< 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;
void enable(size_type index, bool enable_state);
void scale(unsigned s); ///< Sets the scale of control button.
/// Enable to place buttons at right part. After calling it, every new button is right aligned.
void go_right();
bool detached() { return detached_; };
private:
bool detached_;
};
}//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif

View File

@ -1,7 +1,7 @@
/**
* A Tree Box Implementation
* 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.
* (See accompanying file LICENSE or copy at
@ -445,6 +445,9 @@ namespace nana
item_proxy selected() const; ///< returns the selected node
private:
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() const;
};//end class treebox
}//end namespace nana

View File

@ -1,7 +1,7 @@
/**
* The fundamental widget class implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -83,6 +83,8 @@ namespace nana
void focus();
bool focused() const;
std::shared_ptr<scroll_operation_interface> scroll_operation();
void show(); ///< Sets the window visible.
void hide(); ///< Sets the window invisible.
bool visible() const;
@ -137,6 +139,7 @@ namespace nana
virtual void _m_close();
virtual bool _m_enabled() const;
virtual void _m_enabled(bool);
virtual std::shared_ptr<scroll_operation_interface> _m_scroll_operation();
virtual bool _m_show(bool);
virtual bool _m_visible() const;
virtual void _m_size(const nana::size&);

View File

@ -38,14 +38,21 @@ namespace nana
font(const font&);
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();
bool empty() const;
void set_default() 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;
unsigned weight() const;
bool italic() const;

View File

@ -1,7 +1,7 @@
/**
* Standard Library for C++11/14/17
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at

View File

@ -255,6 +255,35 @@ namespace nana
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)
{
auto & r = platform_storage();
@ -337,7 +366,7 @@ namespace nana
if(font_family.empty())
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());
XftResult res;
auto match_pat = ::XftFontMatch(disp, ::XDefaultScreen(disp), pat, &res);
@ -407,6 +436,31 @@ namespace nana
::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
}
}

View File

@ -33,10 +33,13 @@ namespace nana
static void initialize();
/// Shutdown before destruction of platform_spec
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> 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 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
* 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.
* (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/event_code.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/layout_utility.hpp>
#include <nana/gui/detail/element_store.hpp>
#include "inner_fwd_implement.hpp"
#include <errno.h>
#include <algorithm>
@ -104,6 +104,42 @@ namespace detail
void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&);
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
//here is the definition of this object
bedrock bedrock::bedrock_object;
@ -218,10 +254,28 @@ namespace detail
{
XKeyEvent xkey;
nana::detail::platform_spec::instance().read_keystate(xkey);
arg.alt = (xkey.state & Mod1Mask);
arg.ctrl = (xkey.state & ControlMask);
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
{
return impl_->estore;
@ -490,6 +544,34 @@ namespace detail
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)
{
typedef detail::bedrock::core_window_t core_window_t;
@ -849,6 +931,9 @@ namespace detail
if(msgwnd)
{
arg_keyboard modifiers_status;
brock.get_key_state(modifiers_status);
KeySym keysym;
Status status;
char fixbuf[33];
@ -883,16 +968,20 @@ namespace detail
keybuf[len] = 0;
wchar_t os_code = 0;
bool accel_translated = false;
switch(status)
{
case XLookupKeySym:
case XLookupBoth:
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
{
arg_keyboard argkey;
brock.get_key_state(argkey);
auto tstop_wd = wd_manager.tabstop(msgwnd, !argkey.shift);
auto tstop_wd = wd_manager.tabstop(msgwnd, !modifiers_status.shift);
if (tstop_wd)
{
root_runtime->condition.ignore_tab = true;
@ -907,9 +996,9 @@ namespace detail
if((nullptr == pressed_wd) && (nullptr == pressed_wd_space))
{
arg_mouse arg;
arg.alt = false;
arg.alt = modifiers_status.alt;
arg.button = ::nana::mouse::left_button;
arg.ctrl = false;
arg.ctrl = modifiers_status.ctrl;
arg.evt_code = event_code::mouse_down;
arg.left_button = true;
arg.mid_button = false;
@ -955,11 +1044,10 @@ namespace detail
if(keyboard::os_ctrl == os_code)
context.is_ctrl_pressed = true;
arg_keyboard arg;
arg_keyboard arg = modifiers_status;
arg.ignore = false;
arg.key = os_code;
arg.evt_code = event_code::key_press;
brock.get_key_state(arg);
arg.window_handle = reinterpret_cast<window>(msgwnd);
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
@ -988,7 +1076,7 @@ namespace detail
for(int i = 0; i < len; ++i)
{
arg_keyboard arg;
arg_keyboard arg = modifiers_status;
arg.ignore = false;
arg.key = charbuf[i];
@ -1011,7 +1099,6 @@ namespace detail
}
arg.evt_code = event_code::key_char;
arg.window_handle = reinterpret_cast<window>(msgwnd);
brock.get_key_state(arg);
msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd));
if(arg.ignore == false && wd_manager.available(msgwnd))
draw_invoker(&drawer::key_char, msgwnd, arg, &context);

View File

@ -1,7 +1,7 @@
/**
* A Bedrock Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -20,11 +20,11 @@
#include <nana/system/platform.hpp>
#include <nana/system/timepiece.hpp>
#include <nana/gui.hpp>
#include <nana/gui/detail/inner_fwd_implement.hpp>
#include <nana/gui/detail/native_window_interface.hpp>
#include <nana/gui/layout_utility.hpp>
#include <nana/gui/detail/element_store.hpp>
#include <nana/gui/detail/color_schemes.hpp>
#include "inner_fwd_implement.hpp"
#include <iostream> //use std::cerr
@ -182,6 +182,12 @@ namespace detail
}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
//here is the definition of this 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)
{
const unsigned tid = ::GetCurrentThreadId();
@ -383,11 +408,15 @@ namespace detail
if (msg.message == WM_QUIT) break;
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);
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg);
::TranslateMessage(&msg); //deprecated
::DispatchMessage(&msg);
#else
process_msg(this, msg);
#endif
wd_manager().remove_trash_handle(tid);
}
@ -400,11 +429,15 @@ namespace detail
{
if (-1 != ::GetMessage(&msg, 0, 0, 0))
{
#if 0
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
#else
process_msg(this, msg);
#endif
}
wd_manager().call_safe_place(tid);
@ -420,11 +453,15 @@ namespace detail
{
if(-1 != ::GetMessage(&msg, 0, 0, 0))
{
#if 0
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
if(menu_wd) interior_helper_for_menu(msg, menu_wd);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
#else
process_msg(this, msg);
#endif
}
wd_manager().call_safe_place(tid);
@ -635,6 +672,7 @@ namespace detail
switch(msg)
{
case WM_COMMAND:
case WM_DESTROY:
case WM_SHOWWINDOW:
case WM_SIZING:
@ -786,6 +824,17 @@ namespace detail
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:
if (msgwnd->other.attribute.root->ime_enabled)
{
@ -1578,10 +1627,58 @@ namespace detail
void bedrock::get_key_state(arg_keyboard& kb)
{
kb.alt = (0 != (::GetKeyState(VK_MENU) & 0x80));
kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 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
{
return impl_->estore;

View File

@ -1,7 +1,7 @@
/*
* Implementations of Inner Forward Declaration
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -15,9 +15,9 @@
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
#include <nana/push_ignore_diagnostic>
#include "inner_fwd.hpp"
#include "basic_window.hpp"
#include "../../paint/graphics.hpp"
#include <nana/gui/detail/inner_fwd.hpp>
#include <nana/gui/detail/basic_window.hpp>
#include <nana/paint/graphics.hpp>
#include <map>
@ -54,10 +54,13 @@ namespace nana{
implementation * impl_;
};
struct window_platform_assoc;
struct root_misc
{
basic_window * window;
window_platform_assoc * wpassoc{ nullptr };
nana::paint::graphics root_graph;
shortkey_container shortkeys;
@ -71,6 +74,10 @@ namespace nana{
root_misc(root_misc&&);
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

View File

@ -549,7 +549,7 @@ namespace nana{
{
nana::detail::platform_spec::instance().keep_window_icon(wd, sml_icon, big_icon);
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)
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(big_handle));

View File

@ -1,7 +1,7 @@
/*
* Window Layout Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -106,43 +106,46 @@ namespace nana
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
//the pos of root widget is (0, 0)
if (overlapped(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false)
return false;
}
for (auto parent = wd->parent; parent; parent = parent->parent)
{
if (category::flags::root == parent->other.category)
for (auto parent = wd->parent; parent; parent = parent->parent)
{
//visual rectangle of wd's parent
rectangle vrt_parent{parent->pos_root, parent->dimension};
point pos_root;
while (parent->parent)
if (category::flags::root == parent->other.category)
{
pos_root -= native_interface::window_position(parent->root);
if (!overlap(rectangle{ pos_root, parent->parent->root_widget->dimension }, vrt_parent, vrt_parent))
return false;
parent = parent->parent->root_widget;
wd = parent;
break;
}
if (!overlap(vrt_parent, visual, visual))
if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
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
@ -386,6 +389,13 @@ namespace nana
nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension);
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() ||
(false == overlapped(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd)))
continue;

View File

@ -1,7 +1,7 @@
/*
* Window Manager Implementation
* 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.
* (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/window_manager.hpp>
#include <nana/gui/detail/window_layout.hpp>
#include "window_register.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/detail/effects_renderer.hpp>
#include "window_register.hpp"
#include "inner_fwd_implement.hpp"
#include <stdexcept>
#include <algorithm>
@ -140,10 +140,12 @@ namespace nana
//struct root_misc
root_misc::root_misc(root_misc&& other):
window(other.window),
wpassoc(other.wpassoc),
root_graph(std::move(other.root_graph)),
shortkeys(std::move(other.shortkeys)),
condition(std::move(other.condition))
{
other.wpassoc = nullptr; //moved-from
}
root_misc::root_misc(basic_window * wd, unsigned width, unsigned height)
@ -155,6 +157,11 @@ namespace nana
condition.pressed_by_space = nullptr;
condition.hovered = nullptr;
}
root_misc::~root_misc()
{
bedrock::delete_platform_assoc(wpassoc);
}
//end struct root_misc
//class root_register

View File

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

View File

@ -1,7 +1,7 @@
/*
* An Implementation of Place for Layout
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -58,7 +58,7 @@ namespace nana
{
div_start, div_end, splitter,
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,
equal,
eof, error
@ -252,14 +252,6 @@ namespace nana
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_)
{
auto ch = idstr_[0];
@ -287,16 +279,54 @@ namespace nana
_m_throw_error("a parameter list is required after '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())
{
case 'l': return token::left;
case 'r': return token::right;
case 't': return token::top;
case 'b': return token::bottom;
case 'u': return token::undisplayed;
case 'i': return token::invisible;
case 'b':
if ("bottom" == idstr_)
return token::bottom;
break;
case 'd':
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_dock;
class div_dockpane;
class div_switchable;
window window_handle{nullptr};
event_handle event_size_handle{nullptr};
@ -747,7 +778,7 @@ namespace nana
class place::implement::division
{
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;
division(kind k, std::string&& n) noexcept
@ -981,6 +1012,19 @@ namespace nana
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
@ -2539,6 +2583,43 @@ namespace nana
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()
{
API::umake_event(event_size_handle);
@ -2680,6 +2761,9 @@ namespace nana
children.emplace_back(std::move(div));
}
break;
case token::switchable:
div_type = token::switchable;
break;
case token::vert:
div_type = tk;
break;
@ -2850,6 +2934,9 @@ namespace nana
case token::dock:
div.reset(new div_dock(std::move(name), this));
break;
case token::switchable:
div.reset(new div_switchable(std::move(name), this));
break;
default:
throw std::invalid_argument("nana.place: invalid division type.");
}
@ -3184,6 +3271,22 @@ namespace nana
modified_ptr->div_owner = div_owner;
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 (...)
{

View File

@ -1,7 +1,7 @@
/*
* Nana GUI Programming Interface Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -20,6 +20,8 @@
#include <nana/gui/widgets/widget.hpp>
#include <nana/gui/detail/events_operation.hpp>
#include "../../source/detail/platform_abstraction.hpp"
namespace nana
{
//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)
{
auto iwd = reinterpret_cast<basic_window*>(wd);
@ -1473,5 +1484,10 @@ namespace API
return{};
}
unsigned screen_dpi(bool x_requested)
{
return ::nana::platform_abstraction::screen_dpi(x_requested);
}
}//end namespace API
}//end namespace nana

View File

@ -379,7 +379,7 @@ namespace nana{ namespace drawerbase
}//end namespace drawerbase
//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(window wd, bool visible)

View File

@ -1,7 +1,7 @@
/*
* A CheckBox Implementation
* 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.
* (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 ui_container_.size();
return npos;
}
std::size_t radio_group::size() const

View File

@ -1,6 +1,6 @@
/*
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -10,6 +10,7 @@
*/
#include <nana/gui/widgets/form.hpp>
#include <nana/gui/detail/bedrock.hpp>
namespace nana
{
@ -94,6 +95,11 @@ namespace nana
{
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
//class nested_form

View File

@ -1,7 +1,7 @@
/**
* A group widget implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -172,13 +172,13 @@ namespace nana{
return *this;
}
group& group::collocate() throw ()
group& group::collocate() noexcept
{
impl_->place_content.collocate();
return *this;
}
group& group::div(const char* div_str) throw ()
group& group::div(const char* div_str) noexcept
{
if (div_str)
impl_->usr_div_str = div_str;
@ -194,6 +194,21 @@ namespace nana{
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)
{
impl_->place_content[field] << wdg->handle();
@ -208,8 +223,8 @@ namespace nana{
outter[field_title] << impl_->caption;
outter.collocate();
impl_->caption.transparent(true);
color pbg = API::bgcolor(this->parent());
impl_->caption.bgcolor(pbg.blend(colors::black, 0.025));
this->bgcolor(pbg.blend(colors::black, 0.05));
@ -222,10 +237,27 @@ namespace nana{
auto gap_px = impl_->gap - 1;
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());
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

@ -625,6 +625,13 @@ namespace nana
{
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()
{

View File

@ -1,6 +1,6 @@
/*
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -96,7 +96,11 @@ namespace nana
{
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_)
{

View File

@ -1,7 +1,7 @@
/*
* A Scroll Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -20,9 +20,15 @@ namespace nana
namespace scroll
{
//struct metrics_type
metrics_type::metrics_type()
:peak(1), range(1), step(1), value(0),
what(buttons::none), pressed(false), scroll_length(0), scroll_pos(0)
metrics_type::metrics_type():
peak(1),
range(1),
step(1),
value(0),
what(buttons::none),
pressed(false),
scroll_length(0),
scroll_pos(0)
{}
//end struct metrics_type

View File

@ -1,7 +1,7 @@
/*
* A Content View Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -19,6 +19,39 @@ namespace nana {
namespace widgets {
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
{
content_view& view;
@ -35,9 +68,13 @@ namespace nana {
bool drag_started{ false };
point origin;
scrolls enabled_scrolls{scrolls::both};
/*
scrolls enabled_scrolls{scrolls::both}; //deprecated
nana::scroll<false> horz;
nana::scroll<true> vert;
*/
std::shared_ptr<cv_scroll_rep> cv_scroll;
timer tmr;
@ -50,9 +87,11 @@ namespace nana {
implementation(content_view& v, window handle) :
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) {
#if 0
scroll_interface * scroll = nullptr;
switch (arg.which)
{
@ -66,6 +105,11 @@ namespace nana {
//Other button is not unsupported.
return;
}
#else
auto const scroll = cv_scroll->scroll(arg.which);
if (nullptr == scroll)
return;
#endif
if (!API::empty_window(arg.window_handle))
{
@ -159,11 +203,11 @@ namespace nana {
auto speed_horz = 0;
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;
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_vert = (std::min)(5, (std::max)(speed_vert, -5));
@ -180,10 +224,10 @@ namespace nana {
//event hander for scrollbars
auto event_fn = [this](const arg_scroll& arg)
{
if (arg.window_handle == this->vert.handle())
origin.y = static_cast<int>(this->vert.value());
if (arg.window_handle == cv_scroll->vert.handle())
origin.y = static_cast<int>(cv_scroll->vert.value());
else
origin.x = static_cast<int>(this->horz.value());
origin.x = static_cast<int>(cv_scroll->horz.value());
if (this->events.scrolled)
this->events.scrolled();
@ -194,33 +238,33 @@ namespace nana {
this->passive = passive;
bool const vert_allowed = (enabled_scrolls == scrolls::vert || enabled_scrolls == scrolls::both);
bool const horz_allowed = (enabled_scrolls == scrolls::horz || enabled_scrolls == scrolls::both);
bool const vert_allowed = (cv_scroll->enabled_scrolls == scrolls::vert || cv_scroll->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 (vert.empty())
if (cv_scroll->vert.empty())
{
vert.create(window_handle);
vert.events().value_changed.connect_unignorable(event_fn);
API::take_active(vert, false, window_handle);
cv_scroll->vert.create(window_handle);
cv_scroll->vert.events().value_changed.connect_unignorable(event_fn);
API::take_active(cv_scroll->vert, false, window_handle);
this->passive = false;
}
vert.move({
cv_scroll->vert.move({
disp_area.x + static_cast<int>(imd_area.width) + skew_vert.x,
disp_area.y + skew_vert.y,
space(),
imd_area.height + extra_px.height
});
vert.amount(content_size.height);
vert.range(imd_area.height);
vert.value(origin.y);
cv_scroll->vert.amount(content_size.height);
cv_scroll->vert.range(imd_area.height);
cv_scroll->vert.value(origin.y);
}
else
{
vert.close();
cv_scroll->vert.close();
//If vert is allowed, it indicates the vertical origin is not moved
//Make sure the v origin is zero
@ -230,28 +274,28 @@ namespace nana {
if ((imd_area.height != disp_area.height) && horz_allowed)
{
if (horz.empty())
if (cv_scroll->horz.empty())
{
horz.create(window_handle);
horz.events().value_changed.connect_unignorable(event_fn);
API::take_active(horz, false, window_handle);
cv_scroll->horz.create(window_handle);
cv_scroll->horz.events().value_changed.connect_unignorable(event_fn);
API::take_active(cv_scroll->horz, false, window_handle);
this->passive = false;
}
horz.move({
cv_scroll->horz.move({
disp_area.x + skew_horz.x,
disp_area.y + static_cast<int>(imd_area.height) + skew_horz.y,
imd_area.width + extra_px.width,
space()
});
horz.amount(content_size.width);
horz.range(imd_area.width);
horz.value(origin.x);
cv_scroll->horz.amount(content_size.width);
cv_scroll->horz.range(imd_area.width);
cv_scroll->horz.value(origin.x);
}
else
{
horz.close();
cv_scroll->horz.close();
//If horz is allowed, it indicates the horzontal origin is not moved
//Make sure the x origin is zero
if (horz_allowed)
@ -279,20 +323,25 @@ namespace nana {
bool content_view::enable_scrolls(scrolls which)
{
if (impl_->enabled_scrolls == which)
if (impl_->cv_scroll->enabled_scrolls == which)
return false;
impl_->enabled_scrolls = which;
impl_->cv_scroll->enabled_scrolls = which;
impl_->size_changed(false);
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)
{
if (horz)
impl_->horz.step(step_value);
impl_->cv_scroll->horz.step(step_value);
else
impl_->vert.step(step_value);
impl_->cv_scroll->vert.step(step_value);
}
bool content_view::scroll(bool forwards, bool horz)
@ -306,17 +355,17 @@ namespace nana {
}
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)
{
if (horz)
return impl_->horz.make_page_scroll(forwards);
return impl_->cv_scroll->horz.make_page_scroll(forwards);
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)
@ -404,7 +453,7 @@ namespace nana {
void content_view::draw_corner(graph_reference graph)
{
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);
}
@ -415,8 +464,8 @@ namespace nana {
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 horz_allowed = (impl_->enabled_scrolls == scrolls::horz || 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_->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_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
{
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)
{
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();
@ -490,8 +539,8 @@ namespace nana {
void content_view::sync(bool passive)
{
impl_->passive = passive;
impl_->horz.value(impl_->origin.x);
impl_->vert.value(impl_->origin.y);
impl_->cv_scroll->horz.value(impl_->origin.x);
impl_->cv_scroll->vert.value(impl_->origin.y);
impl_->passive = true;
}
@ -520,15 +569,15 @@ namespace nana {
impl_->origin.y = 0;
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;
}
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;
}

View File

@ -1,7 +1,7 @@
/*
* A Content View Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -16,6 +16,7 @@
#include <nana/gui/basis.hpp>
#include <functional>
#include <memory>
namespace nana
{
@ -58,6 +59,8 @@ namespace skeletons
bool enable_scrolls(scrolls which);
std::shared_ptr<scroll_operation_interface> scroll_operation() const;
void step(unsigned step_value, bool horz);
bool scroll(bool forwards, bool horz);
bool turn_page(bool forwards, bool horz);
@ -92,7 +95,7 @@ namespace skeletons
return 16;
}
private:
implementation * const impl_;
implementation* const impl_;
};
}
}

View File

@ -1,7 +1,7 @@
/*
* A text editor implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -1954,6 +1954,11 @@ namespace nana{ namespace widgets
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()
{
impl_->cview->draw_corner(graph_);

View File

@ -1,7 +1,7 @@
/*
* A Textbox Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -816,6 +816,16 @@ namespace drawerbase {
if(editor)
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 namespace nana

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
* A Treebox Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -29,6 +29,25 @@ namespace nana
{
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)
{
if(len <= text.length())
@ -214,7 +233,7 @@ namespace nana
struct shape_tag
{
nana::upoint border;
nana::scroll<true> scroll;
std::shared_ptr<nana::scroll<true>> scroll;
mutable std::map<std::string, node_image_tag> image_table;
@ -261,6 +280,7 @@ namespace nana
shape.first = nullptr;
shape.indent_pixels = 10;
shape.offset_x = 0;
shape.scroll = std::make_shared<nana::scroll<true>>();
attr.auto_draw = true;
@ -598,7 +618,7 @@ namespace nana
std::size_t max_allow = max_allowed();
std::size_t visual_items = visual_item_size();
auto & scroll = shape.scroll;
auto & scroll = *shape.scroll;
if(visual_items <= max_allow)
{
if(!scroll.empty())
@ -618,7 +638,7 @@ namespace nana
adjust.scroll_timestamp = nana::system::timestamp();
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);
});
}
@ -641,7 +661,7 @@ namespace nana
if(!data.graph)
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
@ -958,10 +978,14 @@ namespace nana
return *this;
}
std::size_t item_proxy::size() const
{
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;
return n;
@ -1897,7 +1921,7 @@ namespace nana
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
{
auto & scroll = impl_->shape.scroll;
auto & scroll = *impl_->shape.scroll;
if (scroll.empty())
return;
@ -1931,10 +1955,10 @@ namespace nana
impl_->draw(false);
API::dev::lazy_refresh();
impl_->show_scroll();
if(!impl_->shape.scroll.empty())
if(!impl_->shape.scroll->empty())
{
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());
}
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 namespace nana

View File

@ -1,6 +1,6 @@
/*
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -158,6 +158,11 @@ namespace nana
return (API::focus_window() == handle());
}
std::shared_ptr<scroll_operation_interface> widget::scroll_operation()
{
return _m_scroll_operation();
}
void widget::show()
{
_m_show(true);
@ -317,6 +322,11 @@ namespace nana
API::window_enabled(handle(), value);
}
std::shared_ptr<scroll_operation_interface> widget::_m_scroll_operation()
{
return {};
}
bool widget::_m_show(bool visible)
{
API::show_window(handle(), visible);

View File

@ -91,7 +91,7 @@ namespace nana
{
::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);
jpeg_finish_decompress(&jdstru);

View File

@ -1,7 +1,7 @@
/*
* Paint Graphics Implementation
* 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.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -127,11 +127,14 @@ namespace paint
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

View File

@ -208,20 +208,20 @@ namespace nana{ namespace system{
memcpy(addr, buf, size);
::GlobalUnlock(g);
unsigned data_format;
unsigned data_format = CF_MAX;
switch(fmt)
{
case format::text: data_format = CF_UNICODETEXT; break;
case format::pixmap: data_format = CF_BITMAP; break;
}
res = (nullptr != ::SetClipboardData(data_format, g));
}
::CloseClipboard();
}
#elif defined(NANA_X11)
auto & spec = ::nana::detail::platform_spec::instance();
Atom atom_type;
switch(fmt)
{
@ -232,7 +232,7 @@ namespace nana{ namespace system{
spec.write_selection(owner, atom_type, buf, size);
return true;
#endif
return res;
}
@ -244,7 +244,7 @@ namespace nana{ namespace system{
#if defined(NANA_WINDOWS)
if(::OpenClipboard(::GetFocus()))
{
unsigned data_format;
unsigned data_format = CF_MAX;
switch(fmt)
{
case format::text: data_format = CF_UNICODETEXT; break;