Merge remote-tracking branch 'origin/master' into ys_imperial_unit
This commit is contained in:
commit
bf09d8f93a
103 changed files with 19303 additions and 1133 deletions
|
@ -160,6 +160,9 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||
# Boost on Raspberry-Pi does not link to pthreads.
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(DBus REQUIRED)
|
||||
include_directories(${DBUS_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX)
|
||||
|
@ -369,9 +372,9 @@ include_directories(BEFORE SYSTEM ${EIGEN3_INCLUDE_DIR})
|
|||
|
||||
# Find expat or use bundled version
|
||||
# Always use the system libexpat on Linux.
|
||||
if (NOT SLIC3R_STATIC OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(EXPAT)
|
||||
endif ()
|
||||
|
||||
find_package(EXPAT)
|
||||
|
||||
if (NOT EXPAT_FOUND)
|
||||
add_library(expat STATIC
|
||||
${LIBDIR}/expat/xmlparse.c
|
||||
|
@ -382,7 +385,8 @@ if (NOT EXPAT_FOUND)
|
|||
set(EXPAT_INCLUDE_DIRS ${LIBDIR}/expat/)
|
||||
set(EXPAT_LIBRARIES expat)
|
||||
endif ()
|
||||
include_directories(${EXPAT_INCLUDE_DIRS})
|
||||
|
||||
find_package(PNG)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
|
|
59
cmake/modules/FindDBus.cmake
Normal file
59
cmake/modules/FindDBus.cmake
Normal file
|
@ -0,0 +1,59 @@
|
|||
# - Try to find DBus
|
||||
# Once done, this will define
|
||||
#
|
||||
# DBUS_FOUND - system has DBus
|
||||
# DBUS_INCLUDE_DIRS - the DBus include directories
|
||||
# DBUS_LIBRARIES - link these to use DBus
|
||||
#
|
||||
# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
|
||||
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PC_DBUS QUIET dbus-1)
|
||||
|
||||
FIND_LIBRARY(DBUS_LIBRARIES
|
||||
NAMES dbus-1
|
||||
HINTS ${PC_DBUS_LIBDIR}
|
||||
${PC_DBUS_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
FIND_PATH(DBUS_INCLUDE_DIR
|
||||
NAMES dbus/dbus.h
|
||||
HINTS ${PC_DBUS_INCLUDEDIR}
|
||||
${PC_DBUS_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
GET_FILENAME_COMPONENT(_DBUS_LIBRARY_DIR ${DBUS_LIBRARIES} PATH)
|
||||
FIND_PATH(DBUS_ARCH_INCLUDE_DIR
|
||||
NAMES dbus/dbus-arch-deps.h
|
||||
HINTS ${PC_DBUS_INCLUDEDIR}
|
||||
${PC_DBUS_INCLUDE_DIRS}
|
||||
${_DBUS_LIBRARY_DIR}
|
||||
${DBUS_INCLUDE_DIR}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
SET(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DBUS REQUIRED_VARS DBUS_INCLUDE_DIRS DBUS_LIBRARIES)
|
35
deps/CMakeLists.txt
vendored
35
deps/CMakeLists.txt
vendored
|
@ -34,8 +34,10 @@ endif ()
|
|||
set(DESTDIR "${CMAKE_CURRENT_BINARY_DIR}/destdir" CACHE PATH "Destination directory")
|
||||
|
||||
option(DEP_DEBUG "Build debug variants (only applicable on Windows)" ON)
|
||||
option(DEP_WX_STABLE "Build against wxWidgets stable 3.0 as opposed to default 3.1 (Linux only)" OFF)
|
||||
option(DEP_WX_GTK3 "Build wxWidgets against GTK3" OFF)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
option(DEP_WX_GTK3 "Build wxWidgets against GTK3" OFF)
|
||||
endif()
|
||||
|
||||
# On developer machines, it can be enabled to speed up compilation and suppress warnings coming from IGL.
|
||||
# FIXME:
|
||||
|
@ -127,12 +129,28 @@ else()
|
|||
include("deps-linux.cmake")
|
||||
endif()
|
||||
|
||||
set(ZLIB_PKG "")
|
||||
if (NOT ZLIB_FOUND)
|
||||
include(ZLIB/ZLIB.cmake)
|
||||
set(ZLIB_PKG dep_ZLIB)
|
||||
endif ()
|
||||
set(PNG_PKG "")
|
||||
if (NOT PNG_FOUND)
|
||||
include(PNG/PNG.cmake)
|
||||
set(PNG_PKG dep_PNG)
|
||||
endif ()
|
||||
set(EXPAT_PKG "")
|
||||
if (NOT EXPAT_FOUND)
|
||||
include(EXPAT/EXPAT.cmake)
|
||||
set(EXPAT_PKG dep_EXPAT)
|
||||
endif ()
|
||||
|
||||
include(GLEW/GLEW.cmake)
|
||||
include(OpenCSG/OpenCSG.cmake)
|
||||
|
||||
include(GMP/GMP.cmake)
|
||||
include(MPFR/MPFR.cmake)
|
||||
include(CGAL/CGAL.cmake)
|
||||
include(wxWidgets/wxWidgets.cmake)
|
||||
|
||||
if (MSVC)
|
||||
|
||||
|
@ -141,15 +159,17 @@ if (MSVC)
|
|||
dep_boost
|
||||
dep_tbb
|
||||
dep_libcurl
|
||||
dep_wxwidgets
|
||||
dep_wxWidgets
|
||||
dep_gtest
|
||||
dep_cereal
|
||||
dep_nlopt
|
||||
# dep_qhull # Experimental
|
||||
dep_ZLIB # on Windows we still need zlib
|
||||
dep_openvdb
|
||||
dep_OpenCSG
|
||||
dep_CGAL
|
||||
${PNG_PKG}
|
||||
${ZLIB_PKG}
|
||||
${EXPAT_PKG}
|
||||
)
|
||||
|
||||
else()
|
||||
|
@ -159,7 +179,7 @@ else()
|
|||
dep_boost
|
||||
dep_tbb
|
||||
dep_libcurl
|
||||
dep_wxwidgets
|
||||
dep_wxWidgets
|
||||
dep_gtest
|
||||
dep_cereal
|
||||
dep_nlopt
|
||||
|
@ -167,6 +187,9 @@ else()
|
|||
dep_openvdb
|
||||
dep_OpenCSG
|
||||
dep_CGAL
|
||||
${PNG_PKG}
|
||||
${ZLIB_PKG}
|
||||
${EXPAT_PKG}
|
||||
# dep_libigl # Not working, static build has different Eigen
|
||||
)
|
||||
|
||||
|
|
9
deps/EXPAT/EXPAT.cmake
vendored
Normal file
9
deps/EXPAT/EXPAT.cmake
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
prusaslicer_add_cmake_project(EXPAT
|
||||
# GIT_REPOSITORY https://github.com/nigels-com/glew.git
|
||||
# GIT_TAG 3a8eff7 # 2.1.0
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/expat
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_debug_dep(dep_EXPAT)
|
||||
endif ()
|
71
deps/EXPAT/expat/CMakeLists.txt
vendored
Normal file
71
deps/EXPAT/expat/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(EXPAT)
|
||||
|
||||
if (BUILD_SHARED_LIBS AND MSVC)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
endif()
|
||||
|
||||
add_library(expat
|
||||
xmlparse.c
|
||||
xmlrole.c
|
||||
xmltok.c
|
||||
)
|
||||
|
||||
target_include_directories(expat PRIVATE ${PROJECT_SOURCE_DIR})
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${PROJECT_SOURCE_DIR}/expat.h
|
||||
${PROJECT_SOURCE_DIR}/expat_config.h
|
||||
${PROJECT_SOURCE_DIR}/expat_external.h
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
add_library(EXPAT INTERFACE)
|
||||
target_link_libraries(EXPAT INTERFACE expat)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
VERSION 1.95
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
install(TARGETS expat EXPAT
|
||||
EXPORT ${PROJECT_NAME}Targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
export(EXPORT ${PROJECT_NAME}Targets
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake"
|
||||
NAMESPACE ${PROJECT_NAME}:: )
|
||||
|
||||
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
|
||||
install(EXPORT ${PROJECT_NAME}Targets
|
||||
FILE
|
||||
"${PROJECT_NAME}Targets.cmake"
|
||||
NAMESPACE
|
||||
${PROJECT_NAME}::
|
||||
DESTINATION
|
||||
${ConfigPackageLocation}
|
||||
)
|
||||
|
||||
configure_file(config.cmake.in ${PROJECT_NAME}Config.cmake @ONLY)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
DESTINATION
|
||||
${ConfigPackageLocation}
|
||||
)
|
||||
|
21
deps/EXPAT/expat/COPYING
vendored
Normal file
21
deps/EXPAT/expat/COPYING
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
|
||||
Copyright (c) 2001-2016 Expat maintainers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
146
deps/EXPAT/expat/README
vendored
Normal file
146
deps/EXPAT/expat/README
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
Expat, Release 2.2.0, stripped and modified for inclusion into Slic3r.
|
||||
Only the library sources needed for static linking were left.
|
||||
|
||||
The original README follows:
|
||||
---------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
Expat, Release 2.2.0
|
||||
|
||||
This is Expat, a C library for parsing XML, written by James Clark.
|
||||
Expat is a stream-oriented XML parser. This means that you register
|
||||
handlers with the parser before starting the parse. These handlers
|
||||
are called when the parser discovers the associated structures in the
|
||||
document being parsed. A start tag is an example of the kind of
|
||||
structures for which you may register handlers.
|
||||
|
||||
Windows users should use the expat_win32bin package, which includes
|
||||
both precompiled libraries and executables, and source code for
|
||||
developers.
|
||||
|
||||
Expat is free software. You may copy, distribute, and modify it under
|
||||
the terms of the License contained in the file COPYING distributed
|
||||
with this package. This license is the same as the MIT/X Consortium
|
||||
license.
|
||||
|
||||
Versions of Expat that have an odd minor version (the middle number in
|
||||
the release above), are development releases and should be considered
|
||||
as beta software. Releases with even minor version numbers are
|
||||
intended to be production grade software.
|
||||
|
||||
If you are building Expat from a check-out from the CVS repository,
|
||||
you need to run a script that generates the configure script using the
|
||||
GNU autoconf and libtool tools. To do this, you need to have
|
||||
autoconf 2.58 or newer. Run the script like this:
|
||||
|
||||
./buildconf.sh
|
||||
|
||||
Once this has been done, follow the same instructions as for building
|
||||
from a source distribution.
|
||||
|
||||
To build Expat from a source distribution, you first run the
|
||||
configuration shell script in the top level distribution directory:
|
||||
|
||||
./configure
|
||||
|
||||
There are many options which you may provide to configure (which you
|
||||
can discover by running configure with the --help option). But the
|
||||
one of most interest is the one that sets the installation directory.
|
||||
By default, the configure script will set things up to install
|
||||
libexpat into /usr/local/lib, expat.h into /usr/local/include, and
|
||||
xmlwf into /usr/local/bin. If, for example, you'd prefer to install
|
||||
into /home/me/mystuff/lib, /home/me/mystuff/include, and
|
||||
/home/me/mystuff/bin, you can tell configure about that with:
|
||||
|
||||
./configure --prefix=/home/me/mystuff
|
||||
|
||||
Another interesting option is to enable 64-bit integer support for
|
||||
line and column numbers and the over-all byte index:
|
||||
|
||||
./configure CPPFLAGS=-DXML_LARGE_SIZE
|
||||
|
||||
However, such a modification would be a breaking change to the ABI
|
||||
and is therefore not recommended for general use - e.g. as part of
|
||||
a Linux distribution - but rather for builds with special requirements.
|
||||
|
||||
After running the configure script, the "make" command will build
|
||||
things and "make install" will install things into their proper
|
||||
location. Have a look at the "Makefile" to learn about additional
|
||||
"make" options. Note that you need to have write permission into
|
||||
the directories into which things will be installed.
|
||||
|
||||
If you are interested in building Expat to provide document
|
||||
information in UTF-16 encoding rather than the default UTF-8, follow
|
||||
these instructions (after having run "make distclean"):
|
||||
|
||||
1. For UTF-16 output as unsigned short (and version/error
|
||||
strings as char), run:
|
||||
|
||||
./configure CPPFLAGS=-DXML_UNICODE
|
||||
|
||||
For UTF-16 output as wchar_t (incl. version/error strings),
|
||||
run:
|
||||
|
||||
./configure CFLAGS="-g -O2 -fshort-wchar" \
|
||||
CPPFLAGS=-DXML_UNICODE_WCHAR_T
|
||||
|
||||
2. Edit the MakeFile, changing:
|
||||
|
||||
LIBRARY = libexpat.la
|
||||
|
||||
to:
|
||||
|
||||
LIBRARY = libexpatw.la
|
||||
|
||||
(Note the additional "w" in the library name.)
|
||||
|
||||
3. Run "make buildlib" (which builds the library only).
|
||||
Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".
|
||||
|
||||
4. Run "make installlib" (which installs the library only).
|
||||
Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".
|
||||
|
||||
Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default
|
||||
value for DESTDIR, and the rest of the make file using only DESTDIR.
|
||||
It works as follows:
|
||||
$ make install DESTDIR=/path/to/image
|
||||
overrides the in-makefile set DESTDIR, while both
|
||||
$ INSTALL_ROOT=/path/to/image make install
|
||||
$ make install INSTALL_ROOT=/path/to/image
|
||||
use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the
|
||||
environment, because variable-setting priority is
|
||||
1) commandline
|
||||
2) in-makefile
|
||||
3) environment
|
||||
|
||||
Note: This only applies to the Expat library itself, building UTF-16 versions
|
||||
of xmlwf and the tests is currently not supported.
|
||||
|
||||
Note for Solaris users: The "ar" command is usually located in
|
||||
"/usr/ccs/bin", which is not in the default PATH. You will need to
|
||||
add this to your path for the "make" command, and probably also switch
|
||||
to GNU make (the "make" found in /usr/ccs/bin does not seem to work
|
||||
properly -- apparently it does not understand .PHONY directives). If
|
||||
you're using ksh or bash, use this command to build:
|
||||
|
||||
PATH=/usr/ccs/bin:$PATH make
|
||||
|
||||
When using Expat with a project using autoconf for configuration, you
|
||||
can use the probing macro in conftools/expat.m4 to determine how to
|
||||
include Expat. See the comments at the top of that file for more
|
||||
information.
|
||||
|
||||
A reference manual is available in the file doc/reference.html in this
|
||||
distribution.
|
||||
|
||||
The homepage for this project is http://www.libexpat.org/. There
|
||||
are links there to connect you to the bug reports page. If you need
|
||||
to report a bug when you don't have access to a browser, you may also
|
||||
send a bug report by email to expat-bugs@mail.libexpat.org.
|
||||
|
||||
Discussion related to the direction of future expat development takes
|
||||
place on expat-discuss@mail.libexpat.org. Archives of this list and
|
||||
other Expat-related lists may be found at:
|
||||
|
||||
http://mail.libexpat.org/mailman/listinfo/
|
92
deps/EXPAT/expat/ascii.h
vendored
Normal file
92
deps/EXPAT/expat/ascii.h
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#define ASCII_A 0x41
|
||||
#define ASCII_B 0x42
|
||||
#define ASCII_C 0x43
|
||||
#define ASCII_D 0x44
|
||||
#define ASCII_E 0x45
|
||||
#define ASCII_F 0x46
|
||||
#define ASCII_G 0x47
|
||||
#define ASCII_H 0x48
|
||||
#define ASCII_I 0x49
|
||||
#define ASCII_J 0x4A
|
||||
#define ASCII_K 0x4B
|
||||
#define ASCII_L 0x4C
|
||||
#define ASCII_M 0x4D
|
||||
#define ASCII_N 0x4E
|
||||
#define ASCII_O 0x4F
|
||||
#define ASCII_P 0x50
|
||||
#define ASCII_Q 0x51
|
||||
#define ASCII_R 0x52
|
||||
#define ASCII_S 0x53
|
||||
#define ASCII_T 0x54
|
||||
#define ASCII_U 0x55
|
||||
#define ASCII_V 0x56
|
||||
#define ASCII_W 0x57
|
||||
#define ASCII_X 0x58
|
||||
#define ASCII_Y 0x59
|
||||
#define ASCII_Z 0x5A
|
||||
|
||||
#define ASCII_a 0x61
|
||||
#define ASCII_b 0x62
|
||||
#define ASCII_c 0x63
|
||||
#define ASCII_d 0x64
|
||||
#define ASCII_e 0x65
|
||||
#define ASCII_f 0x66
|
||||
#define ASCII_g 0x67
|
||||
#define ASCII_h 0x68
|
||||
#define ASCII_i 0x69
|
||||
#define ASCII_j 0x6A
|
||||
#define ASCII_k 0x6B
|
||||
#define ASCII_l 0x6C
|
||||
#define ASCII_m 0x6D
|
||||
#define ASCII_n 0x6E
|
||||
#define ASCII_o 0x6F
|
||||
#define ASCII_p 0x70
|
||||
#define ASCII_q 0x71
|
||||
#define ASCII_r 0x72
|
||||
#define ASCII_s 0x73
|
||||
#define ASCII_t 0x74
|
||||
#define ASCII_u 0x75
|
||||
#define ASCII_v 0x76
|
||||
#define ASCII_w 0x77
|
||||
#define ASCII_x 0x78
|
||||
#define ASCII_y 0x79
|
||||
#define ASCII_z 0x7A
|
||||
|
||||
#define ASCII_0 0x30
|
||||
#define ASCII_1 0x31
|
||||
#define ASCII_2 0x32
|
||||
#define ASCII_3 0x33
|
||||
#define ASCII_4 0x34
|
||||
#define ASCII_5 0x35
|
||||
#define ASCII_6 0x36
|
||||
#define ASCII_7 0x37
|
||||
#define ASCII_8 0x38
|
||||
#define ASCII_9 0x39
|
||||
|
||||
#define ASCII_TAB 0x09
|
||||
#define ASCII_SPACE 0x20
|
||||
#define ASCII_EXCL 0x21
|
||||
#define ASCII_QUOT 0x22
|
||||
#define ASCII_AMP 0x26
|
||||
#define ASCII_APOS 0x27
|
||||
#define ASCII_MINUS 0x2D
|
||||
#define ASCII_PERIOD 0x2E
|
||||
#define ASCII_COLON 0x3A
|
||||
#define ASCII_SEMI 0x3B
|
||||
#define ASCII_LT 0x3C
|
||||
#define ASCII_EQUALS 0x3D
|
||||
#define ASCII_GT 0x3E
|
||||
#define ASCII_LSQB 0x5B
|
||||
#define ASCII_RSQB 0x5D
|
||||
#define ASCII_UNDERSCORE 0x5F
|
||||
#define ASCII_LPAREN 0x28
|
||||
#define ASCII_RPAREN 0x29
|
||||
#define ASCII_FF 0x0C
|
||||
#define ASCII_SLASH 0x2F
|
||||
#define ASCII_HASH 0x23
|
||||
#define ASCII_PIPE 0x7C
|
||||
#define ASCII_COMMA 0x2C
|
36
deps/EXPAT/expat/asciitab.h
vendored
Normal file
36
deps/EXPAT/expat/asciitab.h
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
4
deps/EXPAT/expat/config.cmake.in
vendored
Normal file
4
deps/EXPAT/expat/config.cmake.in
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
include(${CMAKE_CURRENT_LIST_DIR}/EXPATTargets.cmake)
|
||||
set(EXPAT_LIBRARIES EXPAT::expat)
|
||||
set(EXPAT_INCLUDE_DIRS ${_IMPORT_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
1048
deps/EXPAT/expat/expat.h
vendored
Normal file
1048
deps/EXPAT/expat/expat.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
33
deps/EXPAT/expat/expat_config.h
vendored
Normal file
33
deps/EXPAT/expat/expat_config.h
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*================================================================
|
||||
** Copyright 2000, Clark Cooper
|
||||
** All rights reserved.
|
||||
**
|
||||
** This is free software. You are permitted to copy, distribute, or modify
|
||||
** it under the terms of the MIT/X license (contained in the COPYING file
|
||||
** with this distribution.)
|
||||
*/
|
||||
|
||||
#ifndef EXPATCONFIG_H
|
||||
#define EXPATCONFIG_H
|
||||
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#define XML_NS 1
|
||||
#define XML_DTD 1
|
||||
#define XML_CONTEXT_BYTES 1024
|
||||
|
||||
/* we will assume all Windows platforms are little endian */
|
||||
#define BYTEORDER 1234
|
||||
|
||||
/* Windows has memmove() available. */
|
||||
#define HAVE_MEMMOVE
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#else
|
||||
#endif
|
||||
|
||||
#endif /* ifndef EXPATCONFIG_H */
|
129
deps/EXPAT/expat/expat_external.h
vendored
Normal file
129
deps/EXPAT/expat/expat_external.h
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef Expat_External_INCLUDED
|
||||
#define Expat_External_INCLUDED 1
|
||||
|
||||
/* External API definitions */
|
||||
|
||||
#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
|
||||
#define XML_USE_MSC_EXTENSIONS 1
|
||||
#endif
|
||||
|
||||
/* Expat tries very hard to make the API boundary very specifically
|
||||
defined. There are two macros defined to control this boundary;
|
||||
each of these can be defined before including this header to
|
||||
achieve some different behavior, but doing so it not recommended or
|
||||
tested frequently.
|
||||
|
||||
XMLCALL - The calling convention to use for all calls across the
|
||||
"library boundary." This will default to cdecl, and
|
||||
try really hard to tell the compiler that's what we
|
||||
want.
|
||||
|
||||
XMLIMPORT - Whatever magic is needed to note that a function is
|
||||
to be imported from a dynamically loaded library
|
||||
(.dll, .so, or .sl, depending on your platform).
|
||||
|
||||
The XMLCALL macro was added in Expat 1.95.7. The only one which is
|
||||
expected to be directly useful in client code is XMLCALL.
|
||||
|
||||
Note that on at least some Unix versions, the Expat library must be
|
||||
compiled with the cdecl calling convention as the default since
|
||||
system headers may assume the cdecl convention.
|
||||
*/
|
||||
#ifndef XMLCALL
|
||||
#if defined(_MSC_VER)
|
||||
#define XMLCALL __cdecl
|
||||
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
|
||||
#define XMLCALL __attribute__((cdecl))
|
||||
#else
|
||||
/* For any platform which uses this definition and supports more than
|
||||
one calling convention, we need to extend this definition to
|
||||
declare the convention used on that platform, if it's possible to
|
||||
do so.
|
||||
|
||||
If this is the case for your platform, please file a bug report
|
||||
with information on how to identify your platform via the C
|
||||
pre-processor and how to specify the same calling convention as the
|
||||
platform's malloc() implementation.
|
||||
*/
|
||||
#define XMLCALL
|
||||
#endif
|
||||
#endif /* not defined XMLCALL */
|
||||
|
||||
|
||||
#if !defined(XML_STATIC) && !defined(XMLIMPORT)
|
||||
#ifndef XML_BUILDING_EXPAT
|
||||
/* using Expat from an application */
|
||||
|
||||
#ifdef XML_USE_MSC_EXTENSIONS
|
||||
// #define XMLIMPORT __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* not defined XML_STATIC */
|
||||
|
||||
#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#define XMLIMPORT __attribute__ ((visibility ("default")))
|
||||
#endif
|
||||
|
||||
/* If we didn't define it above, define it away: */
|
||||
#ifndef XMLIMPORT
|
||||
#define XMLIMPORT
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
|
||||
#define XML_ATTR_MALLOC __attribute__((__malloc__))
|
||||
#else
|
||||
#define XML_ATTR_MALLOC
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
|
||||
#else
|
||||
#define XML_ATTR_ALLOC_SIZE(x)
|
||||
#endif
|
||||
|
||||
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
#define XML_UNICODE
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
typedef wchar_t XML_Char;
|
||||
typedef wchar_t XML_LChar;
|
||||
#else
|
||||
typedef unsigned short XML_Char;
|
||||
typedef char XML_LChar;
|
||||
#endif /* XML_UNICODE_WCHAR_T */
|
||||
#else /* Information is UTF-8 encoded. */
|
||||
typedef char XML_Char;
|
||||
typedef char XML_LChar;
|
||||
#endif /* XML_UNICODE */
|
||||
|
||||
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
|
||||
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
|
||||
typedef __int64 XML_Index;
|
||||
typedef unsigned __int64 XML_Size;
|
||||
#else
|
||||
typedef long long XML_Index;
|
||||
typedef unsigned long long XML_Size;
|
||||
#endif
|
||||
#else
|
||||
typedef long XML_Index;
|
||||
typedef unsigned long XML_Size;
|
||||
#endif /* XML_LARGE_SIZE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not Expat_External_INCLUDED */
|
37
deps/EXPAT/expat/iasciitab.h
vendored
Normal file
37
deps/EXPAT/expat/iasciitab.h
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
|
||||
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
95
deps/EXPAT/expat/internal.h
vendored
Normal file
95
deps/EXPAT/expat/internal.h
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* internal.h
|
||||
|
||||
Internal definitions used by Expat. This is not needed to compile
|
||||
client code.
|
||||
|
||||
The following calling convention macros are defined for frequently
|
||||
called functions:
|
||||
|
||||
FASTCALL - Used for those internal functions that have a simple
|
||||
body and a low number of arguments and local variables.
|
||||
|
||||
PTRCALL - Used for functions called though function pointers.
|
||||
|
||||
PTRFASTCALL - Like PTRCALL, but for low number of arguments.
|
||||
|
||||
inline - Used for selected internal functions for which inlining
|
||||
may improve performance on some platforms.
|
||||
|
||||
Note: Use of these macros is based on judgement, not hard rules,
|
||||
and therefore subject to change.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
|
||||
/* We'll use this version by default only where we know it helps.
|
||||
|
||||
regparm() generates warnings on Solaris boxes. See SF bug #692878.
|
||||
|
||||
Instability reported with egcs on a RedHat Linux 7.3.
|
||||
Let's comment out:
|
||||
#define FASTCALL __attribute__((stdcall, regparm(3)))
|
||||
and let's try this:
|
||||
*/
|
||||
#define FASTCALL __attribute__((regparm(3)))
|
||||
#define PTRFASTCALL __attribute__((regparm(3)))
|
||||
#endif
|
||||
|
||||
/* Using __fastcall seems to have an unexpected negative effect under
|
||||
MS VC++, especially for function pointers, so we won't use it for
|
||||
now on that platform. It may be reconsidered for a future release
|
||||
if it can be made more effective.
|
||||
Likely reason: __fastcall on Windows is like stdcall, therefore
|
||||
the compiler cannot perform stack optimizations for call clusters.
|
||||
*/
|
||||
|
||||
/* Make sure all of these are defined if they aren't already. */
|
||||
|
||||
#ifndef FASTCALL
|
||||
#define FASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef PTRCALL
|
||||
#define PTRCALL
|
||||
#endif
|
||||
|
||||
#ifndef PTRFASTCALL
|
||||
#define PTRFASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef XML_MIN_SIZE
|
||||
#if !defined(__cplusplus) && !defined(inline)
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
#endif /* XML_MIN_SIZE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define inline inline
|
||||
#else
|
||||
#ifndef inline
|
||||
#define inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UNUSED_P
|
||||
# ifdef __GNUC__
|
||||
# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
|
||||
# else
|
||||
# define UNUSED_P(p) UNUSED_ ## p
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
36
deps/EXPAT/expat/latin1tab.h
vendored
Normal file
36
deps/EXPAT/expat/latin1tab.h
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
|
||||
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
150
deps/EXPAT/expat/nametab.h
vendored
Normal file
150
deps/EXPAT/expat/nametab.h
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
static const unsigned namingBitmap[] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
|
||||
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
|
||||
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
|
||||
0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
|
||||
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
|
||||
0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
|
||||
0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
|
||||
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
|
||||
0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
|
||||
0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
|
||||
0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
|
||||
0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
|
||||
0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
|
||||
0x40000000, 0xF580C900, 0x00000007, 0x02010800,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
|
||||
0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
|
||||
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
|
||||
0x00000000, 0x00004C40, 0x00000000, 0x00000000,
|
||||
0x00000007, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
|
||||
0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
|
||||
0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
|
||||
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
|
||||
0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
|
||||
0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
|
||||
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
|
||||
0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
|
||||
0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
|
||||
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
|
||||
0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
|
||||
0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
|
||||
0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
|
||||
0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
|
||||
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
|
||||
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
|
||||
};
|
||||
static const unsigned char nmstrtPages[] = {
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
|
||||
0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const unsigned char namePages[] = {
|
||||
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
|
||||
0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
|
||||
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
|
||||
0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
37
deps/EXPAT/expat/utf8tab.h
vendored
Normal file
37
deps/EXPAT/expat/utf8tab.h
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
|
||||
/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
|
||||
/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
|
6458
deps/EXPAT/expat/xmlparse.c
vendored
Normal file
6458
deps/EXPAT/expat/xmlparse.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
1322
deps/EXPAT/expat/xmlrole.c
vendored
Normal file
1322
deps/EXPAT/expat/xmlrole.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
114
deps/EXPAT/expat/xmlrole.h
vendored
Normal file
114
deps/EXPAT/expat/xmlrole.h
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef XmlRole_INCLUDED
|
||||
#define XmlRole_INCLUDED 1
|
||||
|
||||
#ifdef __VMS
|
||||
/* 0 1 2 3 0 1 2 3
|
||||
1234567890123456789012345678901 1234567890123456789012345678901 */
|
||||
#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
|
||||
#endif
|
||||
|
||||
#include "xmltok.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
XML_ROLE_ERROR = -1,
|
||||
XML_ROLE_NONE = 0,
|
||||
XML_ROLE_XML_DECL,
|
||||
XML_ROLE_INSTANCE_START,
|
||||
XML_ROLE_DOCTYPE_NONE,
|
||||
XML_ROLE_DOCTYPE_NAME,
|
||||
XML_ROLE_DOCTYPE_SYSTEM_ID,
|
||||
XML_ROLE_DOCTYPE_PUBLIC_ID,
|
||||
XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
|
||||
XML_ROLE_DOCTYPE_CLOSE,
|
||||
XML_ROLE_GENERAL_ENTITY_NAME,
|
||||
XML_ROLE_PARAM_ENTITY_NAME,
|
||||
XML_ROLE_ENTITY_NONE,
|
||||
XML_ROLE_ENTITY_VALUE,
|
||||
XML_ROLE_ENTITY_SYSTEM_ID,
|
||||
XML_ROLE_ENTITY_PUBLIC_ID,
|
||||
XML_ROLE_ENTITY_COMPLETE,
|
||||
XML_ROLE_ENTITY_NOTATION_NAME,
|
||||
XML_ROLE_NOTATION_NONE,
|
||||
XML_ROLE_NOTATION_NAME,
|
||||
XML_ROLE_NOTATION_SYSTEM_ID,
|
||||
XML_ROLE_NOTATION_NO_SYSTEM_ID,
|
||||
XML_ROLE_NOTATION_PUBLIC_ID,
|
||||
XML_ROLE_ATTRIBUTE_NAME,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_CDATA,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_ID,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_IDREF,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
|
||||
XML_ROLE_ATTRIBUTE_ENUM_VALUE,
|
||||
XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
|
||||
XML_ROLE_ATTLIST_NONE,
|
||||
XML_ROLE_ATTLIST_ELEMENT_NAME,
|
||||
XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_FIXED_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_ELEMENT_NONE,
|
||||
XML_ROLE_ELEMENT_NAME,
|
||||
XML_ROLE_CONTENT_ANY,
|
||||
XML_ROLE_CONTENT_EMPTY,
|
||||
XML_ROLE_CONTENT_PCDATA,
|
||||
XML_ROLE_GROUP_OPEN,
|
||||
XML_ROLE_GROUP_CLOSE,
|
||||
XML_ROLE_GROUP_CLOSE_REP,
|
||||
XML_ROLE_GROUP_CLOSE_OPT,
|
||||
XML_ROLE_GROUP_CLOSE_PLUS,
|
||||
XML_ROLE_GROUP_CHOICE,
|
||||
XML_ROLE_GROUP_SEQUENCE,
|
||||
XML_ROLE_CONTENT_ELEMENT,
|
||||
XML_ROLE_CONTENT_ELEMENT_REP,
|
||||
XML_ROLE_CONTENT_ELEMENT_OPT,
|
||||
XML_ROLE_CONTENT_ELEMENT_PLUS,
|
||||
XML_ROLE_PI,
|
||||
XML_ROLE_COMMENT,
|
||||
#ifdef XML_DTD
|
||||
XML_ROLE_TEXT_DECL,
|
||||
XML_ROLE_IGNORE_SECT,
|
||||
XML_ROLE_INNER_PARAM_ENTITY_REF,
|
||||
#endif /* XML_DTD */
|
||||
XML_ROLE_PARAM_ENTITY_REF
|
||||
};
|
||||
|
||||
typedef struct prolog_state {
|
||||
int (PTRCALL *handler) (struct prolog_state *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc);
|
||||
unsigned level;
|
||||
int role_none;
|
||||
#ifdef XML_DTD
|
||||
unsigned includeLevel;
|
||||
int documentEntity;
|
||||
int inEntityValue;
|
||||
#endif /* XML_DTD */
|
||||
} PROLOG_STATE;
|
||||
|
||||
void XmlPrologStateInit(PROLOG_STATE *);
|
||||
#ifdef XML_DTD
|
||||
void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#define XmlTokenRole(state, tok, ptr, end, enc) \
|
||||
(((state)->handler)(state, tok, ptr, end, enc))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not XmlRole_INCLUDED */
|
1737
deps/EXPAT/expat/xmltok.c
vendored
Normal file
1737
deps/EXPAT/expat/xmltok.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
322
deps/EXPAT/expat/xmltok.h
vendored
Normal file
322
deps/EXPAT/expat/xmltok.h
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef XmlTok_INCLUDED
|
||||
#define XmlTok_INCLUDED 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The following token may be returned by XmlContentTok */
|
||||
#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
|
||||
start of illegal ]]> sequence */
|
||||
/* The following tokens may be returned by both XmlPrologTok and
|
||||
XmlContentTok.
|
||||
*/
|
||||
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
|
||||
#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
|
||||
might be part of CRLF sequence */
|
||||
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
|
||||
#define XML_TOK_PARTIAL -1 /* only part of a token */
|
||||
#define XML_TOK_INVALID 0
|
||||
|
||||
/* The following tokens are returned by XmlContentTok; some are also
|
||||
returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
|
||||
*/
|
||||
#define XML_TOK_START_TAG_WITH_ATTS 1
|
||||
#define XML_TOK_START_TAG_NO_ATTS 2
|
||||
#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
|
||||
#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
|
||||
#define XML_TOK_END_TAG 5
|
||||
#define XML_TOK_DATA_CHARS 6
|
||||
#define XML_TOK_DATA_NEWLINE 7
|
||||
#define XML_TOK_CDATA_SECT_OPEN 8
|
||||
#define XML_TOK_ENTITY_REF 9
|
||||
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
|
||||
|
||||
/* The following tokens may be returned by both XmlPrologTok and
|
||||
XmlContentTok.
|
||||
*/
|
||||
#define XML_TOK_PI 11 /* processing instruction */
|
||||
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
|
||||
#define XML_TOK_COMMENT 13
|
||||
#define XML_TOK_BOM 14 /* Byte order mark */
|
||||
|
||||
/* The following tokens are returned only by XmlPrologTok */
|
||||
#define XML_TOK_PROLOG_S 15
|
||||
#define XML_TOK_DECL_OPEN 16 /* <!foo */
|
||||
#define XML_TOK_DECL_CLOSE 17 /* > */
|
||||
#define XML_TOK_NAME 18
|
||||
#define XML_TOK_NMTOKEN 19
|
||||
#define XML_TOK_POUND_NAME 20 /* #name */
|
||||
#define XML_TOK_OR 21 /* | */
|
||||
#define XML_TOK_PERCENT 22
|
||||
#define XML_TOK_OPEN_PAREN 23
|
||||
#define XML_TOK_CLOSE_PAREN 24
|
||||
#define XML_TOK_OPEN_BRACKET 25
|
||||
#define XML_TOK_CLOSE_BRACKET 26
|
||||
#define XML_TOK_LITERAL 27
|
||||
#define XML_TOK_PARAM_ENTITY_REF 28
|
||||
#define XML_TOK_INSTANCE_START 29
|
||||
|
||||
/* The following occur only in element type declarations */
|
||||
#define XML_TOK_NAME_QUESTION 30 /* name? */
|
||||
#define XML_TOK_NAME_ASTERISK 31 /* name* */
|
||||
#define XML_TOK_NAME_PLUS 32 /* name+ */
|
||||
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
|
||||
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
|
||||
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
|
||||
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
|
||||
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
|
||||
#define XML_TOK_COMMA 38
|
||||
|
||||
/* The following token is returned only by XmlAttributeValueTok */
|
||||
#define XML_TOK_ATTRIBUTE_VALUE_S 39
|
||||
|
||||
/* The following token is returned only by XmlCdataSectionTok */
|
||||
#define XML_TOK_CDATA_SECT_CLOSE 40
|
||||
|
||||
/* With namespace processing this is returned by XmlPrologTok for a
|
||||
name with a colon.
|
||||
*/
|
||||
#define XML_TOK_PREFIXED_NAME 41
|
||||
|
||||
#ifdef XML_DTD
|
||||
#define XML_TOK_IGNORE_SECT 42
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#ifdef XML_DTD
|
||||
#define XML_N_STATES 4
|
||||
#else /* not XML_DTD */
|
||||
#define XML_N_STATES 3
|
||||
#endif /* not XML_DTD */
|
||||
|
||||
#define XML_PROLOG_STATE 0
|
||||
#define XML_CONTENT_STATE 1
|
||||
#define XML_CDATA_SECTION_STATE 2
|
||||
#ifdef XML_DTD
|
||||
#define XML_IGNORE_SECTION_STATE 3
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#define XML_N_LITERAL_TYPES 2
|
||||
#define XML_ATTRIBUTE_VALUE_LITERAL 0
|
||||
#define XML_ENTITY_VALUE_LITERAL 1
|
||||
|
||||
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
|
||||
#define XML_UTF8_ENCODE_MAX 4
|
||||
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
|
||||
#define XML_UTF16_ENCODE_MAX 2
|
||||
|
||||
typedef struct position {
|
||||
/* first line and first column are 0 not 1 */
|
||||
XML_Size lineNumber;
|
||||
XML_Size columnNumber;
|
||||
} POSITION;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *valuePtr;
|
||||
const char *valueEnd;
|
||||
char normalized;
|
||||
} ATTRIBUTE;
|
||||
|
||||
struct encoding;
|
||||
typedef struct encoding ENCODING;
|
||||
|
||||
typedef int (PTRCALL *SCANNER)(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char **);
|
||||
|
||||
enum XML_Convert_Result {
|
||||
XML_CONVERT_COMPLETED = 0,
|
||||
XML_CONVERT_INPUT_INCOMPLETE = 1,
|
||||
XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */
|
||||
};
|
||||
|
||||
struct encoding {
|
||||
SCANNER scanners[XML_N_STATES];
|
||||
SCANNER literalScanners[XML_N_LITERAL_TYPES];
|
||||
int (PTRCALL *sameName)(const ENCODING *,
|
||||
const char *,
|
||||
const char *);
|
||||
int (PTRCALL *nameMatchesAscii)(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char *);
|
||||
int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
|
||||
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
|
||||
int (PTRCALL *getAtts)(const ENCODING *enc,
|
||||
const char *ptr,
|
||||
int attsMax,
|
||||
ATTRIBUTE *atts);
|
||||
int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
|
||||
int (PTRCALL *predefinedEntityName)(const ENCODING *,
|
||||
const char *,
|
||||
const char *);
|
||||
void (PTRCALL *updatePosition)(const ENCODING *,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
POSITION *);
|
||||
int (PTRCALL *isPublicId)(const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr);
|
||||
enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
char **toP,
|
||||
const char *toLim);
|
||||
enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
unsigned short **toP,
|
||||
const unsigned short *toLim);
|
||||
int minBytesPerChar;
|
||||
char isUtf8;
|
||||
char isUtf16;
|
||||
};
|
||||
|
||||
/* Scan the string starting at ptr until the end of the next complete
|
||||
token, but do not scan past eptr. Return an integer giving the
|
||||
type of token.
|
||||
|
||||
Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
|
||||
|
||||
Return XML_TOK_PARTIAL when the string does not contain a complete
|
||||
token; nextTokPtr will not be set.
|
||||
|
||||
Return XML_TOK_INVALID when the string does not start a valid
|
||||
token; nextTokPtr will be set to point to the character which made
|
||||
the token invalid.
|
||||
|
||||
Otherwise the string starts with a valid token; nextTokPtr will be
|
||||
set to point to the character following the end of that token.
|
||||
|
||||
Each data character counts as a single token, but adjacent data
|
||||
characters may be returned together. Similarly for characters in
|
||||
the prolog outside literals, comments and processing instructions.
|
||||
*/
|
||||
|
||||
|
||||
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
|
||||
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
|
||||
|
||||
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#endif /* XML_DTD */
|
||||
|
||||
/* This is used for performing a 2nd-level tokenization on the content
|
||||
of a literal that has already been returned by XmlTok.
|
||||
*/
|
||||
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
|
||||
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
|
||||
|
||||
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
|
||||
|
||||
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
|
||||
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
|
||||
|
||||
#define XmlNameLength(enc, ptr) \
|
||||
(((enc)->nameLength)(enc, ptr))
|
||||
|
||||
#define XmlSkipS(enc, ptr) \
|
||||
(((enc)->skipS)(enc, ptr))
|
||||
|
||||
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
|
||||
(((enc)->getAtts)(enc, ptr, attsMax, atts))
|
||||
|
||||
#define XmlCharRefNumber(enc, ptr) \
|
||||
(((enc)->charRefNumber)(enc, ptr))
|
||||
|
||||
#define XmlPredefinedEntityName(enc, ptr, end) \
|
||||
(((enc)->predefinedEntityName)(enc, ptr, end))
|
||||
|
||||
#define XmlUpdatePosition(enc, ptr, end, pos) \
|
||||
(((enc)->updatePosition)(enc, ptr, end, pos))
|
||||
|
||||
#define XmlIsPublicId(enc, ptr, end, badPtr) \
|
||||
(((enc)->isPublicId)(enc, ptr, end, badPtr))
|
||||
|
||||
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
|
||||
|
||||
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
|
||||
|
||||
typedef struct {
|
||||
ENCODING initEnc;
|
||||
const ENCODING **encPtr;
|
||||
} INIT_ENCODING;
|
||||
|
||||
int XmlParseXmlDecl(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingNamePtr,
|
||||
const ENCODING **namedEncodingPtr,
|
||||
int *standalonePtr);
|
||||
|
||||
int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
|
||||
const ENCODING *XmlGetUtf8InternalEncoding(void);
|
||||
const ENCODING *XmlGetUtf16InternalEncoding(void);
|
||||
int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
|
||||
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
|
||||
int XmlSizeOfUnknownEncoding(void);
|
||||
|
||||
|
||||
typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
|
||||
|
||||
ENCODING *
|
||||
XmlInitUnknownEncoding(void *mem,
|
||||
int *table,
|
||||
CONVERTER convert,
|
||||
void *userData);
|
||||
|
||||
int XmlParseXmlDeclNS(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingNamePtr,
|
||||
const ENCODING **namedEncodingPtr,
|
||||
int *standalonePtr);
|
||||
|
||||
int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
|
||||
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
|
||||
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
|
||||
ENCODING *
|
||||
XmlInitUnknownEncodingNS(void *mem,
|
||||
int *table,
|
||||
CONVERTER convert,
|
||||
void *userData);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not XmlTok_INCLUDED */
|
46
deps/EXPAT/expat/xmltok_impl.h
vendored
Normal file
46
deps/EXPAT/expat/xmltok_impl.h
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
enum {
|
||||
BT_NONXML,
|
||||
BT_MALFORM,
|
||||
BT_LT,
|
||||
BT_AMP,
|
||||
BT_RSQB,
|
||||
BT_LEAD2,
|
||||
BT_LEAD3,
|
||||
BT_LEAD4,
|
||||
BT_TRAIL,
|
||||
BT_CR,
|
||||
BT_LF,
|
||||
BT_GT,
|
||||
BT_QUOT,
|
||||
BT_APOS,
|
||||
BT_EQUALS,
|
||||
BT_QUEST,
|
||||
BT_EXCL,
|
||||
BT_SOL,
|
||||
BT_SEMI,
|
||||
BT_NUM,
|
||||
BT_LSQB,
|
||||
BT_S,
|
||||
BT_NMSTRT,
|
||||
BT_COLON,
|
||||
BT_HEX,
|
||||
BT_DIGIT,
|
||||
BT_NAME,
|
||||
BT_MINUS,
|
||||
BT_OTHER, /* known not to be a name or name start character */
|
||||
BT_NONASCII, /* might be a name or name start character */
|
||||
BT_PERCNT,
|
||||
BT_LPAR,
|
||||
BT_RPAR,
|
||||
BT_AST,
|
||||
BT_PLUS,
|
||||
BT_COMMA,
|
||||
BT_VERBAR
|
||||
};
|
||||
|
||||
#include <stddef.h>
|
1779
deps/EXPAT/expat/xmltok_impl.inc
vendored
Normal file
1779
deps/EXPAT/expat/xmltok_impl.inc
vendored
Normal file
File diff suppressed because it is too large
Load diff
115
deps/EXPAT/expat/xmltok_ns.inc
vendored
Normal file
115
deps/EXPAT/expat/xmltok_ns.inc
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* This file is included! */
|
||||
#ifdef XML_TOK_NS_C
|
||||
|
||||
const ENCODING *
|
||||
NS(XmlGetUtf8InternalEncoding)(void)
|
||||
{
|
||||
return &ns(internal_utf8_encoding).enc;
|
||||
}
|
||||
|
||||
const ENCODING *
|
||||
NS(XmlGetUtf16InternalEncoding)(void)
|
||||
{
|
||||
#if BYTEORDER == 1234
|
||||
return &ns(internal_little2_encoding).enc;
|
||||
#elif BYTEORDER == 4321
|
||||
return &ns(internal_big2_encoding).enc;
|
||||
#else
|
||||
const short n = 1;
|
||||
return (*(const char *)&n
|
||||
? &ns(internal_little2_encoding).enc
|
||||
: &ns(internal_big2_encoding).enc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const ENCODING * const NS(encodings)[] = {
|
||||
&ns(latin1_encoding).enc,
|
||||
&ns(ascii_encoding).enc,
|
||||
&ns(utf8_encoding).enc,
|
||||
&ns(big2_encoding).enc,
|
||||
&ns(big2_encoding).enc,
|
||||
&ns(little2_encoding).enc,
|
||||
&ns(utf8_encoding).enc /* NO_ENC */
|
||||
};
|
||||
|
||||
static int PTRCALL
|
||||
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **nextTokPtr)
|
||||
{
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
|
||||
XML_PROLOG_STATE, ptr, end, nextTokPtr);
|
||||
}
|
||||
|
||||
static int PTRCALL
|
||||
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **nextTokPtr)
|
||||
{
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
|
||||
XML_CONTENT_STATE, ptr, end, nextTokPtr);
|
||||
}
|
||||
|
||||
int
|
||||
NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
|
||||
const char *name)
|
||||
{
|
||||
int i = getEncodingIndex(name);
|
||||
if (i == UNKNOWN_ENC)
|
||||
return 0;
|
||||
SET_INIT_ENC_INDEX(p, i);
|
||||
p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
|
||||
p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
|
||||
p->initEnc.updatePosition = initUpdatePosition;
|
||||
p->encPtr = encPtr;
|
||||
*encPtr = &(p->initEnc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const ENCODING *
|
||||
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
|
||||
{
|
||||
#define ENCODING_MAX 128
|
||||
char buf[ENCODING_MAX];
|
||||
char *p = buf;
|
||||
int i;
|
||||
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
|
||||
if (ptr != end)
|
||||
return 0;
|
||||
*p = 0;
|
||||
if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
|
||||
return enc;
|
||||
i = getEncodingIndex(buf);
|
||||
if (i == UNKNOWN_ENC)
|
||||
return 0;
|
||||
return NS(encodings)[i];
|
||||
}
|
||||
|
||||
int
|
||||
NS(XmlParseXmlDecl)(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingName,
|
||||
const ENCODING **encoding,
|
||||
int *standalone)
|
||||
{
|
||||
return doParseXmlDecl(NS(findEncoding),
|
||||
isGeneralTextEntity,
|
||||
enc,
|
||||
ptr,
|
||||
end,
|
||||
badPtr,
|
||||
versionPtr,
|
||||
versionEndPtr,
|
||||
encodingName,
|
||||
encoding,
|
||||
standalone);
|
||||
}
|
||||
|
||||
#endif /* XML_TOK_NS_C */
|
1
deps/GLEW/GLEW.cmake
vendored
1
deps/GLEW/GLEW.cmake
vendored
|
@ -1,4 +1,5 @@
|
|||
# We have to check for OpenGL to compile GLEW
|
||||
set(OpenGL_GL_PREFERENCE "LEGACY") # to prevent a nasty warning by cmake
|
||||
find_package(OpenGL QUIET REQUIRED)
|
||||
|
||||
prusaslicer_add_cmake_project(
|
||||
|
|
4
deps/OpenCSG/OpenCSG.cmake
vendored
4
deps/OpenCSG/OpenCSG.cmake
vendored
|
@ -6,8 +6,8 @@ prusaslicer_add_cmake_project(OpenCSG
|
|||
DEPENDS dep_GLEW
|
||||
)
|
||||
|
||||
if (TARGET dep_ZLIB)
|
||||
add_dependencies(dep_OpenCSG dep_ZLIB)
|
||||
if (TARGET ${ZLIB_PKG})
|
||||
add_dependencies(dep_OpenCSG ${ZLIB_PKG})
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
|
|
13
deps/PNG/PNG.cmake
vendored
Normal file
13
deps/PNG/PNG.cmake
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
prusaslicer_add_cmake_project(PNG
|
||||
GIT_REPOSITORY https://github.com/glennrp/libpng.git
|
||||
GIT_TAG v1.6.35
|
||||
DEPENDS ${ZLIB_PKG}
|
||||
CMAKE_ARGS
|
||||
-DPNG_SHARED=OFF
|
||||
-DPNG_STATIC=ON
|
||||
-DPNG_TESTS=OFF
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_debug_dep(dep_PNG)
|
||||
endif ()
|
48
deps/deps-linux.cmake
vendored
48
deps/deps-linux.cmake
vendored
|
@ -3,6 +3,13 @@ set(DEP_CMAKE_OPTS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON")
|
|||
|
||||
include("deps-unix-common.cmake")
|
||||
|
||||
find_package(PNG QUIET)
|
||||
if (NOT PNG_FOUND)
|
||||
message(WARNING "No PNG dev package found in system, building static library. You should install the system package.")
|
||||
endif ()
|
||||
|
||||
#TODO UDEV
|
||||
|
||||
ExternalProject_Add(dep_boost
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz"
|
||||
|
@ -93,45 +100,4 @@ ExternalProject_Add(dep_libcurl
|
|||
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
||||
)
|
||||
|
||||
if (DEP_WX_STABLE)
|
||||
set(DEP_WX_TAG "v3.0.4")
|
||||
else ()
|
||||
set(DEP_WX_TAG "v3.1.1-patched")
|
||||
endif()
|
||||
|
||||
if (DEP_WX_GTK3)
|
||||
set(WX_GTK_VERSION "3")
|
||||
else ()
|
||||
set(WX_GTK_VERSION "2")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(dep_wxwidgets
|
||||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
GIT_TAG "${DEP_WX_TAG}"
|
||||
BUILD_IN_SOURCE 1
|
||||
# PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/wxwidgets-pngprefix.h" src/png/pngprefix.h
|
||||
CONFIGURE_COMMAND ./configure
|
||||
"--prefix=${DESTDIR}/usr/local"
|
||||
--disable-shared
|
||||
--with-gtk=${WX_GTK_VERSION}
|
||||
--with-opengl
|
||||
--enable-unicode
|
||||
--enable-graphics_ctx
|
||||
--with-regex=builtin
|
||||
--with-libpng=builtin
|
||||
--with-libxpm=builtin
|
||||
--with-libjpeg=builtin
|
||||
--with-libtiff=builtin
|
||||
--with-zlib
|
||||
--with-expat=builtin
|
||||
--disable-precomp-headers
|
||||
--enable-debug_info
|
||||
--enable-debug_gdb
|
||||
--disable-debug
|
||||
--disable-debug_flag
|
||||
BUILD_COMMAND make "-j${NPROC}" && make -C locale allmo
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
||||
add_dependencies(dep_openvdb dep_boost)
|
||||
|
|
26
deps/deps-macos.cmake
vendored
26
deps/deps-macos.cmake
vendored
|
@ -86,30 +86,4 @@ ExternalProject_Add(dep_libcurl
|
|||
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_wxwidgets
|
||||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
GIT_TAG v3.1.3-patched
|
||||
BUILD_IN_SOURCE 1
|
||||
# PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/wxwidgets-pngprefix.h" src/png/pngprefix.h
|
||||
CONFIGURE_COMMAND env "CXXFLAGS=${DEP_WERRORS_SDK}" "CFLAGS=${DEP_WERRORS_SDK}" ./configure
|
||||
"--prefix=${DESTDIR}/usr/local"
|
||||
--disable-shared
|
||||
--with-osx_cocoa
|
||||
--with-macosx-sdk=${CMAKE_OSX_SYSROOT}
|
||||
"--with-macosx-version-min=${DEP_OSX_TARGET}"
|
||||
--with-opengl
|
||||
--with-regex=builtin
|
||||
--with-libpng=builtin
|
||||
--with-libxpm=builtin
|
||||
--with-libjpeg=builtin
|
||||
--with-libtiff=builtin
|
||||
--with-zlib
|
||||
--with-expat=builtin
|
||||
--disable-debug
|
||||
--disable-debug_flag
|
||||
BUILD_COMMAND make "-j${NPROC}" && PATH=/usr/local/opt/gettext/bin/:$ENV{PATH} make -C locale allmo
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
||||
add_dependencies(dep_openvdb dep_boost)
|
16
deps/deps-mingw.cmake
vendored
16
deps/deps-mingw.cmake
vendored
|
@ -57,20 +57,4 @@ ExternalProject_Add(dep_libcurl
|
|||
-DCURL_DISABLE_GOPHER=ON
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_wxwidgets
|
||||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
GIT_TAG v3.1.1-patched
|
||||
# URL "https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.1/wxWidgets-3.1.1.tar.bz2"
|
||||
# URL_HASH SHA256=c925dfe17e8f8b09eb7ea9bfdcfcc13696a3e14e92750effd839f5e10726159e
|
||||
# PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}\\wxwidgets-pngprefix.h" src\\png\\pngprefix.h
|
||||
CMAKE_ARGS
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DwxUSE_LIBPNG=builtin
|
||||
-DwxUSE_ZLIB=builtin
|
||||
-DwxUSE_OPENGL=ON
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
8
deps/deps-unix-common.cmake
vendored
8
deps/deps-unix-common.cmake
vendored
|
@ -9,9 +9,15 @@ endif ()
|
|||
|
||||
find_package(ZLIB QUIET)
|
||||
if (NOT ZLIB_FOUND)
|
||||
include(ZLIB/ZLIB.cmake)
|
||||
message(WARNING "No ZLIB dev package found in system, building static library. You should install the system package.")
|
||||
endif ()
|
||||
|
||||
# TODO Evaluate expat modifications in the bundled version and test with system versions in various distros and OSX SDKs
|
||||
# find_package(EXPAT QUIET)
|
||||
# if (NOT EXPAT_FOUND)
|
||||
# message(WARNING "No EXPAT dev package found in system, building static library. Consider installing the system package.")
|
||||
# endif ()
|
||||
|
||||
ExternalProject_Add(dep_tbb
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
|
||||
|
|
61
deps/deps-windows.cmake
vendored
61
deps/deps-windows.cmake
vendored
|
@ -149,38 +149,6 @@ ExternalProject_Add(dep_nlopt
|
|||
|
||||
add_debug_dep(dep_nlopt)
|
||||
|
||||
include(ZLIB/ZLIB.cmake)
|
||||
# ExternalProject_Add(dep_zlib
|
||||
# EXCLUDE_FROM_ALL 1
|
||||
# URL "https://zlib.net/zlib-1.2.11.tar.xz"
|
||||
# URL_HASH SHA256=4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066
|
||||
# CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
# CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
# CMAKE_ARGS
|
||||
# -DSKIP_INSTALL_FILES=ON # Prevent installation of man pages et al.
|
||||
# "-DINSTALL_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}\\fallout" # I found no better way of preventing zlib from creating & installing DLLs :-/
|
||||
# -DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
# "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
|
||||
# BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
|
||||
# INSTALL_COMMAND ""
|
||||
# )
|
||||
|
||||
add_debug_dep(dep_ZLIB)
|
||||
|
||||
# The following steps are unfortunately needed to remove the _static suffix on libraries
|
||||
# ExternalProject_Add_Step(dep_zlib fix_static
|
||||
# DEPENDEES install
|
||||
# COMMAND "${CMAKE_COMMAND}" -E rename zlibstatic.lib zlib.lib
|
||||
# WORKING_DIRECTORY "${DESTDIR}\\usr\\local\\lib\\"
|
||||
# )
|
||||
# if (${DEP_DEBUG})
|
||||
# ExternalProject_Add_Step(dep_zlib fix_static_debug
|
||||
# DEPENDEES install
|
||||
# COMMAND "${CMAKE_COMMAND}" -E rename zlibstaticd.lib zlibd.lib
|
||||
# WORKING_DIRECTORY "${DESTDIR}\\usr\\local\\lib\\"
|
||||
# )
|
||||
# endif ()
|
||||
|
||||
if (${DEPS_BITS} EQUAL 32)
|
||||
set(DEP_LIBCURL_TARGET "x86")
|
||||
else ()
|
||||
|
@ -243,36 +211,13 @@ endif ()
|
|||
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
ExternalProject_Add(dep_wxwidgets
|
||||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
GIT_TAG v3.1.1-patched
|
||||
# URL "https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.1/wxWidgets-3.1.1.tar.bz2"
|
||||
# URL_HASH SHA256=c925dfe17e8f8b09eb7ea9bfdcfcc13696a3e14e92750effd839f5e10726159e
|
||||
BUILD_IN_SOURCE 1
|
||||
# PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}\\wxwidgets-pngprefix.h" src\\png\\pngprefix.h
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND cd build\\msw && nmake /f makefile.vc BUILD=release SHARED=0 UNICODE=1 USE_GUI=1 "${DEP_WXWIDGETS_TARGET}"
|
||||
INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_directory include "${DESTDIR}\\usr\\local\\include"
|
||||
&& "${CMAKE_COMMAND}" -E copy_directory "lib\\${DEP_WXWIDGETS_LIBDIR}" "${DESTDIR}\\usr\\local\\lib\\${DEP_WXWIDGETS_LIBDIR}"
|
||||
)
|
||||
if (${DEP_DEBUG})
|
||||
ExternalProject_Get_Property(dep_wxwidgets SOURCE_DIR)
|
||||
ExternalProject_Add_Step(dep_wxwidgets build_debug
|
||||
DEPENDEES build
|
||||
DEPENDERS install
|
||||
COMMAND cd build\\msw && nmake /f makefile.vc BUILD=debug SHARED=0 UNICODE=1 USE_GUI=1 "${DEP_WXWIDGETS_TARGET}"
|
||||
WORKING_DIRECTORY "${SOURCE_DIR}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(dep_blosc
|
||||
EXCLUDE_FROM_ALL 1
|
||||
#URL https://github.com/Blosc/c-blosc/archive/v1.17.0.zip
|
||||
#URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9
|
||||
GIT_REPOSITORY https://github.com/Blosc/c-blosc.git
|
||||
GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0
|
||||
DEPENDS dep_ZLIB
|
||||
DEPENDS ${ZLIB_PKG}
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
|
@ -299,7 +244,7 @@ ExternalProject_Add(dep_openexr
|
|||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY https://github.com/openexr/openexr.git
|
||||
GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0
|
||||
DEPENDS dep_ZLIB
|
||||
DEPENDS ${ZLIB_PKG}
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
|
@ -352,4 +297,4 @@ if (${DEP_DEBUG})
|
|||
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
|
||||
WORKING_DIRECTORY "${BINARY_DIR}"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
36
deps/wxWidgets/wxWidgets.cmake
vendored
Normal file
36
deps/wxWidgets/wxWidgets.cmake
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
set(_wx_git_tag v3.1.3-patched)
|
||||
|
||||
# set(_patch_command "")
|
||||
set(_wx_toolkit "")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(_gtk_ver 2)
|
||||
if (DEP_WX_GTK3)
|
||||
set(_gtk_ver 3)
|
||||
endif ()
|
||||
set(_wx_toolkit "-DwxBUILD_TOOLKIT=gtk${_gtk_ver}")
|
||||
endif()
|
||||
|
||||
prusaslicer_add_cmake_project(wxWidgets
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
GIT_TAG ${_wx_git_tag}
|
||||
# PATCH_COMMAND "${_patch_command}"
|
||||
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG}
|
||||
CMAKE_ARGS
|
||||
-DwxBUILD_PRECOMP=ON
|
||||
${_wx_toolkit}
|
||||
"-DCMAKE_DEBUG_POSTFIX:STRING="
|
||||
-DwxUSE_DETECT_SM=OFF
|
||||
-DwxUSE_UNICODE=ON
|
||||
-DwxUSE_OPENGL=ON
|
||||
-DwxUSE_LIBPNG=sys
|
||||
-DwxUSE_ZLIB=sys
|
||||
-DwxUSE_REGEX=builtin
|
||||
-DwxUSE_LIBXPM=builtin
|
||||
-DwxUSE_LIBJPEG=builtin
|
||||
-DwxUSE_LIBTIFF=builtin
|
||||
-DwxUSE_EXPAT=sys
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_debug_dep(dep_wxWidgets)
|
||||
endif ()
|
12
resources/icons/attention.svg
Normal file
12
resources/icons/attention.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="attention">
|
||||
<path fill="#ED0000" d="M8,1.85l5.29,3.53V7v3.62L8,14.15l-5.29-3.53V7V5.38L8,1.85 M8,1L2,5v2v4l6,4l6-4V7V5L8,1L8,1z"/>
|
||||
|
||||
<path fill="none" stroke="#ED0000" stroke-linecap="round" stroke-width="3" d="M8 4 L8 8" />
|
||||
|
||||
<circle fill="#ED0000" cx="8" cy="12" r="1.5"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 641 B |
16
resources/icons/collapse.svg
Normal file
16
resources/icons/collapse.svg
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="cross">
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="12" y1="1" x2="15" y2="4"/></g>
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="12" y1="7" x2="15" y2="4"/></g>
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="1" x2="11" y2="4"/></g>
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="7" x2="11" y2="4"/></g>
|
||||
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="4" y1="9" x2="1" y2="12"/></g>
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="4" y1="15" x2="1" y2="12"/></g>
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="9" x2="5" y2="12"/></g>
|
||||
<g><line fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="15" x2="5" y2="12"/></g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
4
resources/icons/search.svg
Normal file
4
resources/icons/search.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px" height="24px">
|
||||
<path fill="#808080" d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||
<path fill="#ED6B21" d="M 13.261719 14.867188 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
4
resources/icons/search_.svg
Normal file
4
resources/icons/search_.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px" height="24px">
|
||||
<path fill="#FFFFFF" d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||
<path fill="#ED6B21" d="M 13.261719 14.867188 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
4
resources/icons/search_gray.svg
Normal file
4
resources/icons/search_gray.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px" height="24px">
|
||||
<path fill="#808080" d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||
<path fill="#808080" d="M 13.261719 14.867188 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -59,6 +59,29 @@ if (SLIC3R_GUI)
|
|||
|
||||
include(${wxWidgets_USE_FILE})
|
||||
|
||||
string(REGEX MATCH "wxpng" WX_PNG_BUILTIN ${wxWidgets_LIBRARIES})
|
||||
if (PNG_FOUND AND NOT WX_PNG_BUILTIN)
|
||||
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX png)
|
||||
list(APPEND wxWidgets_LIBRARIES ${PNG_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
string(REGEX MATCH "wxexpat" WX_EXPAT_BUILTIN ${wxWidgets_LIBRARIES})
|
||||
if (EXPAT_FOUND AND NOT WX_EXPAT_BUILTIN)
|
||||
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX expat)
|
||||
list(APPEND wxWidgets_LIBRARIES ${EXPAT_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
# This is an issue in the new wxWidgets cmake build, doesn't deal with librt
|
||||
find_library(LIBRT rt)
|
||||
if(LIBRT)
|
||||
list(APPEND wxWidgets_LIBRARIES ${LIBRT})
|
||||
endif()
|
||||
|
||||
# This fixes a OpenGL linking issue on OSX. wxWidgets cmake build includes
|
||||
# wrong libs for opengl in the link line and it does not link to it by himself.
|
||||
# libslic3r_gui will link to opengl anyway, so lets override wx
|
||||
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX OpenGL)
|
||||
|
||||
# list(REMOVE_ITEM wxWidgets_LIBRARIES oleacc)
|
||||
message(STATUS "wx libs: ${wxWidgets_LIBRARIES}")
|
||||
|
||||
|
@ -178,13 +201,13 @@ if (WIN32)
|
|||
elseif (XCODE)
|
||||
# Because of Debug/Release/etc. configurations (similar to MSVC) the slic3r binary is located in an extra level
|
||||
add_custom_command(TARGET PrusaSlicer POST_BUILD
|
||||
COMMAND ln -sf "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/resources"
|
||||
COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/resources"
|
||||
COMMENT "Symlinking the resources directory into the build tree"
|
||||
VERBATIM
|
||||
)
|
||||
else ()
|
||||
add_custom_command(TARGET PrusaSlicer POST_BUILD
|
||||
COMMAND ln -sf "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources"
|
||||
COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources"
|
||||
COMMENT "Symlinking the resources directory into the build tree"
|
||||
VERBATIM
|
||||
)
|
||||
|
|
|
@ -51,13 +51,14 @@
|
|||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/InstanceCheck.hpp"
|
||||
#include "slic3r/GUI/AppConfig.hpp"
|
||||
#endif /* SLIC3R_GUI */
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
int CLI::run(int argc, char **argv)
|
||||
{
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// On Linux, wxGTK has no support for Wayland, and the app crashes on
|
||||
// startup if gtk3 is used. This env var has to be set explicitly to
|
||||
|
@ -524,6 +525,16 @@ int CLI::run(int argc, char **argv)
|
|||
#ifdef SLIC3R_GUI
|
||||
// #ifdef USE_WX
|
||||
GUI::GUI_App *gui = new GUI::GUI_App();
|
||||
|
||||
bool gui_single_instance_setting = gui->app_config->get("single_instance") == "1";
|
||||
if (Slic3r::instance_check(argc, argv, gui_single_instance_setting)) {
|
||||
//TODO: do we have delete gui and other stuff?
|
||||
return -1;
|
||||
}
|
||||
|
||||
//gui->app_config = app_config;
|
||||
//app_config = nullptr;
|
||||
|
||||
// gui->autosave = m_config.opt_string("autosave");
|
||||
GUI::GUI_App::SetInstance(gui);
|
||||
gui->CallAfter([gui, this, &load_configs] {
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <shellapi.h>
|
||||
#include <wchar.h>
|
||||
|
||||
|
||||
|
||||
#ifdef SLIC3R_GUI
|
||||
extern "C"
|
||||
{
|
||||
|
@ -216,7 +218,6 @@ int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */,
|
|||
int wmain(int argc, wchar_t **argv)
|
||||
{
|
||||
#endif
|
||||
|
||||
std::vector<wchar_t*> argv_extended;
|
||||
argv_extended.emplace_back(argv[0]);
|
||||
|
||||
|
|
|
@ -97,9 +97,17 @@
|
|||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
// Special ASCII character is used here as markup symbols for tokens to be highlighted as a for hovered item
|
||||
const char ColorMarkerHovered = 0x1; // STX
|
||||
|
||||
// Special ASCII characters STX and ETX are used here as markup symbols for tokens to be highlighted.
|
||||
const char ColorMarkerStart = 0x2; // STX
|
||||
const char ColorMarkerEnd = 0x3; // ETX
|
||||
|
||||
// void MyFunction(const char* name, const MyMatrix44& v);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ Index of this file:
|
|||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#endif
|
||||
#include "imgui_internal.h"
|
||||
#include "imconfig.h"
|
||||
|
||||
#include <stdio.h> // vsnprintf, sscanf, printf
|
||||
#if !defined(alloca)
|
||||
|
@ -2991,6 +2992,15 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
|
||||
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
|
||||
|
||||
ImU32 defaultCol = col;
|
||||
ImU32 highlighCol = ImGui::GetColorU32(ImGuiCol_ButtonHovered);
|
||||
|
||||
// if text is started with ColorMarkerHovered symbol, we should use another color for a highlighting
|
||||
if (*s == ImGui::ColorMarkerHovered) {
|
||||
highlighCol = ImGui::GetColorU32(ImGuiCol_FrameBg);
|
||||
s += 1;
|
||||
}
|
||||
|
||||
while (s < text_end)
|
||||
{
|
||||
if (word_wrap_enabled)
|
||||
|
@ -3019,6 +3029,17 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||
}
|
||||
}
|
||||
|
||||
if (*s == ImGui::ColorMarkerStart) {
|
||||
col = highlighCol;
|
||||
s += 1;
|
||||
}
|
||||
else if (*s == ImGui::ColorMarkerEnd) {
|
||||
col = defaultCol;
|
||||
s += 1;
|
||||
if (s == text_end)
|
||||
break;
|
||||
}
|
||||
|
||||
// Decode and advance source
|
||||
unsigned int c = (unsigned int)*s;
|
||||
if (c < 0x80)
|
||||
|
|
|
@ -272,7 +272,8 @@ endif ()
|
|||
encoding_check(libslic3r)
|
||||
|
||||
target_compile_definitions(libslic3r PUBLIC -DUSE_TBB -DTBB_USE_CAPTURED_EXCEPTION=0)
|
||||
target_include_directories(libslic3r PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LIBNEST2D_INCLUDES} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_include_directories(libslic3r PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_include_directories(libslic3r PUBLIC ${EXPAT_INCLUDE_DIRS})
|
||||
target_link_libraries(libslic3r
|
||||
libnest2d
|
||||
admesh
|
||||
|
|
|
@ -312,6 +312,7 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
|||
case erOverhangPerimeter : return L("Overhang perimeter");
|
||||
case erInternalInfill : return L("Internal infill");
|
||||
case erSolidInfill : return L("Solid infill");
|
||||
case erIroning : return L("Ironing");
|
||||
case erTopSolidInfill : return L("Top solid infill");
|
||||
case erBridgeInfill : return L("Bridge infill");
|
||||
case erGapFill : return L("Gap fill");
|
||||
|
|
|
@ -22,6 +22,7 @@ enum ExtrusionRole : uint8_t {
|
|||
erInternalInfill,
|
||||
erSolidInfill,
|
||||
erTopSolidInfill,
|
||||
erIroning,
|
||||
erBridgeInfill,
|
||||
erGapFill,
|
||||
erSkirt,
|
||||
|
@ -54,14 +55,16 @@ inline bool is_infill(ExtrusionRole role)
|
|||
return role == erBridgeInfill
|
||||
|| role == erInternalInfill
|
||||
|| role == erSolidInfill
|
||||
|| role == erTopSolidInfill;
|
||||
|| role == erTopSolidInfill
|
||||
|| role == erIroning;
|
||||
}
|
||||
|
||||
inline bool is_solid_infill(ExtrusionRole role)
|
||||
{
|
||||
return role == erBridgeInfill
|
||||
|| role == erSolidInfill
|
||||
|| role == erTopSolidInfill;
|
||||
|| role == erTopSolidInfill
|
||||
|| role == erIroning;
|
||||
}
|
||||
|
||||
inline bool is_bridge(ExtrusionRole role) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../Surface.hpp"
|
||||
|
||||
#include "FillBase.hpp"
|
||||
#include "FillRectilinear2.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -372,7 +373,11 @@ void Layer::make_fills()
|
|||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||
f->spacing = surface_fill.params.spacing;
|
||||
surface_fill.surface.expolygon = std::move(expoly);
|
||||
Polylines polylines = f->fill_surface(&surface_fill.surface, params);
|
||||
Polylines polylines;
|
||||
try {
|
||||
polylines = f->fill_surface(&surface_fill.surface, params);
|
||||
} catch (InfillFailedException &) {
|
||||
}
|
||||
if (! polylines.empty()) {
|
||||
// calculate actual flow from spacing (which might have been adjusted by the infill
|
||||
// pattern generator)
|
||||
|
@ -388,8 +393,8 @@ void Layer::make_fills()
|
|||
flow_width = new_flow.width;
|
||||
}
|
||||
// Save into layer.
|
||||
auto *eec = new ExtrusionEntityCollection();
|
||||
m_regions[surface_fill.region_id]->fills.entities.push_back(eec);
|
||||
ExtrusionEntityCollection* eec = nullptr;
|
||||
m_regions[surface_fill.region_id]->fills.entities.push_back(eec = new ExtrusionEntityCollection());
|
||||
// Only concentric fills are not sorted.
|
||||
eec->no_sort = f->no_sort();
|
||||
extrusion_entities_append_paths(
|
||||
|
@ -418,4 +423,170 @@ void Layer::make_fills()
|
|||
#endif
|
||||
}
|
||||
|
||||
// Create ironing extrusions over top surfaces.
|
||||
void Layer::make_ironing()
|
||||
{
|
||||
// LayerRegion::slices contains surfaces marked with SurfaceType.
|
||||
// Here we want to collect top surfaces extruded with the same extruder.
|
||||
// A surface will be ironed with the same extruder to not contaminate the print with another material leaking from the nozzle.
|
||||
|
||||
// First classify regions based on the extruder used.
|
||||
struct IroningParams {
|
||||
int extruder = -1;
|
||||
bool just_infill = false;
|
||||
// Spacing of the ironing lines, also to calculate the extrusion flow from.
|
||||
double line_spacing;
|
||||
// Height of the extrusion, to calculate the extrusion flow from.
|
||||
double height;
|
||||
double speed;
|
||||
double angle;
|
||||
|
||||
bool operator<(const IroningParams &rhs) const {
|
||||
if (this->extruder < rhs.extruder)
|
||||
return true;
|
||||
if (this->extruder > rhs.extruder)
|
||||
return false;
|
||||
if (int(this->just_infill) < int(rhs.just_infill))
|
||||
return true;
|
||||
if (int(this->just_infill) > int(rhs.just_infill))
|
||||
return false;
|
||||
if (this->line_spacing < rhs.line_spacing)
|
||||
return true;
|
||||
if (this->line_spacing > rhs.line_spacing)
|
||||
return false;
|
||||
if (this->height < rhs.height)
|
||||
return true;
|
||||
if (this->height > rhs.height)
|
||||
return false;
|
||||
if (this->speed < rhs.speed)
|
||||
return true;
|
||||
if (this->speed > rhs.speed)
|
||||
return false;
|
||||
if (this->angle < rhs.angle)
|
||||
return true;
|
||||
if (this->angle > rhs.angle)
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const IroningParams &rhs) const {
|
||||
return this->extruder == rhs.extruder && this->just_infill == rhs.just_infill &&
|
||||
this->line_spacing == rhs.line_spacing && this->height == rhs.height && this->speed == rhs.speed &&
|
||||
this->angle == rhs.angle;
|
||||
}
|
||||
|
||||
LayerRegion *layerm = nullptr;
|
||||
|
||||
// IdeaMaker: ironing
|
||||
// ironing flowrate (5% percent)
|
||||
// ironing speed (10 mm/sec)
|
||||
|
||||
// Kisslicer:
|
||||
// iron off, Sweep, Group
|
||||
// ironing speed: 15 mm/sec
|
||||
|
||||
// Cura:
|
||||
// Pattern (zig-zag / concentric)
|
||||
// line spacing (0.1mm)
|
||||
// flow: from normal layer height. 10%
|
||||
// speed: 20 mm/sec
|
||||
};
|
||||
|
||||
std::vector<IroningParams> by_extruder;
|
||||
bool extruder_dont_care = this->object()->config().wipe_into_objects;
|
||||
double default_layer_height = this->object()->config().layer_height;
|
||||
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
if (! layerm->slices.empty()) {
|
||||
IroningParams ironing_params;
|
||||
const PrintRegionConfig &config = layerm->region()->config();
|
||||
if (config.ironing &&
|
||||
(config.ironing_type == IroningType::AllSolid ||
|
||||
(config.top_solid_layers > 0 &&
|
||||
(config.ironing_type == IroningType::TopSurfaces ||
|
||||
(config.ironing_type == IroningType::TopmostOnly && layerm->layer()->upper_layer == nullptr))))) {
|
||||
if (config.perimeter_extruder == config.solid_infill_extruder || config.perimeters == 0) {
|
||||
// Iron the whole face.
|
||||
ironing_params.extruder = config.solid_infill_extruder;
|
||||
} else {
|
||||
// Iron just the infill.
|
||||
ironing_params.extruder = config.solid_infill_extruder;
|
||||
}
|
||||
}
|
||||
if (ironing_params.extruder != -1) {
|
||||
ironing_params.just_infill = false;
|
||||
ironing_params.line_spacing = config.ironing_spacing;
|
||||
ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate;
|
||||
ironing_params.speed = config.ironing_speed;
|
||||
ironing_params.angle = config.fill_angle * M_PI / 180.;
|
||||
ironing_params.layerm = layerm;
|
||||
by_extruder.emplace_back(ironing_params);
|
||||
}
|
||||
}
|
||||
std::sort(by_extruder.begin(), by_extruder.end());
|
||||
|
||||
FillRectilinear2 fill;
|
||||
FillParams fill_params;
|
||||
fill.set_bounding_box(this->object()->bounding_box());
|
||||
fill.layer_id = this->id();
|
||||
fill.z = this->print_z;
|
||||
fill.overlap = 0;
|
||||
fill_params.density = 1.;
|
||||
// fill_params.dont_connect = true;
|
||||
fill_params.dont_connect = false;
|
||||
fill_params.monotonous = true;
|
||||
|
||||
for (size_t i = 0; i < by_extruder.size(); ++ i) {
|
||||
// Find span of regions equivalent to the ironing operation.
|
||||
IroningParams &ironing_params = by_extruder[i];
|
||||
size_t j = i;
|
||||
for (++ j; j < by_extruder.size() && ironing_params == by_extruder[j]; ++ j) ;
|
||||
|
||||
// Create the ironing extrusions for regions <i, j)
|
||||
ExPolygons ironing_areas;
|
||||
double nozzle_dmr = this->object()->print()->config().nozzle_diameter.values[ironing_params.extruder - 1];
|
||||
if (ironing_params.just_infill) {
|
||||
// Just infill.
|
||||
} else {
|
||||
// Infill and perimeter.
|
||||
// Merge top surfaces with the same ironing parameters.
|
||||
Polygons polys;
|
||||
for (size_t k = i; k < j; ++ k)
|
||||
for (const Surface &surface : by_extruder[k].layerm->slices.surfaces)
|
||||
if (surface.surface_type == stTop)
|
||||
polygons_append(polys, surface.expolygon);
|
||||
// Trim the top surfaces with half the nozzle diameter.
|
||||
ironing_areas = intersection_ex(polys, offset(this->lslices, - float(scale_(0.5 * nozzle_dmr))));
|
||||
}
|
||||
|
||||
// Create the filler object.
|
||||
fill.spacing = ironing_params.line_spacing;
|
||||
fill.angle = float(ironing_params.angle + 0.25 * M_PI);
|
||||
fill.link_max_length = (coord_t)scale_(3. * fill.spacing);
|
||||
double height = ironing_params.height * fill.spacing / nozzle_dmr;
|
||||
Flow flow = Flow::new_from_spacing(float(nozzle_dmr), 0., float(height), false);
|
||||
double flow_mm3_per_mm = flow.mm3_per_mm();
|
||||
Surface surface_fill(stTop, ExPolygon());
|
||||
for (ExPolygon &expoly : ironing_areas) {
|
||||
surface_fill.expolygon = std::move(expoly);
|
||||
Polylines polylines;
|
||||
try {
|
||||
polylines = fill.fill_surface(&surface_fill, fill_params);
|
||||
} catch (InfillFailedException &) {
|
||||
}
|
||||
if (! polylines.empty()) {
|
||||
// Save into layer.
|
||||
ExtrusionEntityCollection *eec = nullptr;
|
||||
ironing_params.layerm->fills.entities.push_back(eec = new ExtrusionEntityCollection());
|
||||
// Don't sort the ironing infill lines as they are monotonously ordered.
|
||||
eec->no_sort = true;
|
||||
extrusion_entities_append_paths(
|
||||
eec->entities, std::move(polylines),
|
||||
erIroning,
|
||||
flow_mm3_per_mm, float(flow.width), float(height));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -27,7 +27,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
|||
case ip3DHoneycomb: return new Fill3DHoneycomb();
|
||||
case ipGyroid: return new FillGyroid();
|
||||
case ipRectilinear: return new FillRectilinear2();
|
||||
// case ipRectilinear: return new FillRectilinear();
|
||||
case ipMonotonous: return new FillMonotonous();
|
||||
case ipLine: return new FillLine();
|
||||
case ipGrid: return new FillGrid2();
|
||||
case ipTriangles: return new FillTriangles();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <memory.h>
|
||||
#include <float.h>
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
@ -18,29 +19,31 @@ namespace Slic3r {
|
|||
class ExPolygon;
|
||||
class Surface;
|
||||
|
||||
class InfillFailedException : public std::runtime_error {
|
||||
public:
|
||||
InfillFailedException() : std::runtime_error("Infill failed") {}
|
||||
};
|
||||
|
||||
struct FillParams
|
||||
{
|
||||
FillParams() {
|
||||
memset(this, 0, sizeof(FillParams));
|
||||
// Adjustment does not work.
|
||||
dont_adjust = true;
|
||||
}
|
||||
|
||||
bool full_infill() const { return density > 0.9999f; }
|
||||
|
||||
// Fill density, fraction in <0, 1>
|
||||
float density;
|
||||
float density { 0.f };
|
||||
|
||||
// Don't connect the fill lines around the inner perimeter.
|
||||
bool dont_connect;
|
||||
bool dont_connect { false };
|
||||
|
||||
// Don't adjust spacing to fill the space evenly.
|
||||
bool dont_adjust;
|
||||
bool dont_adjust { true };
|
||||
|
||||
// Monotonous infill - strictly left to right for better surface quality of top infills.
|
||||
bool monotonous { false };
|
||||
|
||||
// For Honeycomb.
|
||||
// we were requested to complete each loop;
|
||||
// in this case we don't try to make more continuous paths
|
||||
bool complete;
|
||||
bool complete { false };
|
||||
};
|
||||
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,18 +13,27 @@ class FillRectilinear2 : public Fill
|
|||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillRectilinear2(*this); };
|
||||
virtual ~FillRectilinear2() {}
|
||||
virtual ~FillRectilinear2() = default;
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
|
||||
protected:
|
||||
bool fill_surface_by_lines(const Surface *surface, const FillParams ¶ms, float angleBase, float pattern_shift, Polylines &polylines_out);
|
||||
};
|
||||
|
||||
class FillMonotonous : public FillRectilinear2
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillMonotonous(*this); };
|
||||
virtual ~FillMonotonous() = default;
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
virtual bool no_sort() const { return true; }
|
||||
};
|
||||
|
||||
class FillGrid2 : public FillRectilinear2
|
||||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillGrid2(*this); };
|
||||
virtual ~FillGrid2() {}
|
||||
virtual ~FillGrid2() = default;
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
|
||||
protected:
|
||||
|
@ -36,7 +45,7 @@ class FillTriangles : public FillRectilinear2
|
|||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillTriangles(*this); };
|
||||
virtual ~FillTriangles() {}
|
||||
virtual ~FillTriangles() = default;
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
|
||||
protected:
|
||||
|
@ -48,7 +57,7 @@ class FillStars : public FillRectilinear2
|
|||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillStars(*this); };
|
||||
virtual ~FillStars() {}
|
||||
virtual ~FillStars() = default;
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
|
||||
protected:
|
||||
|
@ -60,7 +69,7 @@ class FillCubic : public FillRectilinear2
|
|||
{
|
||||
public:
|
||||
virtual Fill* clone() const { return new FillCubic(*this); };
|
||||
virtual ~FillCubic() {}
|
||||
virtual ~FillCubic() = default;
|
||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -2246,12 +2246,14 @@ void GCode::process_layer(
|
|||
const auto& by_region_specific = is_anything_overridden ? island.by_region_per_copy(by_region_per_copy_cache, static_cast<unsigned int>(instance_to_print.instance_id), extruder_id, print_wipe_extrusions != 0) : island.by_region;
|
||||
//FIXME the following code prints regions in the order they are defined, the path is not optimized in any way.
|
||||
if (print.config().infill_first) {
|
||||
gcode += this->extrude_infill(print, by_region_specific);
|
||||
gcode += this->extrude_infill(print, by_region_specific, false);
|
||||
gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]);
|
||||
} else {
|
||||
gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]);
|
||||
gcode += this->extrude_infill(print,by_region_specific);
|
||||
gcode += this->extrude_infill(print,by_region_specific, false);
|
||||
}
|
||||
// ironing
|
||||
gcode += this->extrude_infill(print,by_region_specific, true);
|
||||
}
|
||||
if (this->config().gcode_label_objects)
|
||||
gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name + " id:" + std::to_string(instance_to_print.layer_id) + " copy " + std::to_string(instance_to_print.instance_id) + "\n";
|
||||
|
@ -2873,22 +2875,30 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
|
|||
}
|
||||
|
||||
// Chain the paths hierarchically by a greedy algorithm to minimize a travel distance.
|
||||
std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region)
|
||||
std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool ironing)
|
||||
{
|
||||
std::string gcode;
|
||||
std::string gcode;
|
||||
ExtrusionEntitiesPtr extrusions;
|
||||
const char* extrusion_name = ironing ? "ironing" : "infill";
|
||||
for (const ObjectByExtruder::Island::Region ®ion : by_region)
|
||||
if (! region.infills.empty()) {
|
||||
m_config.apply(print.regions()[®ion - &by_region.front()]->config());
|
||||
ExtrusionEntitiesPtr extrusions { region.infills };
|
||||
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
|
||||
for (const ExtrusionEntity *fill : extrusions) {
|
||||
auto *eec = dynamic_cast<const ExtrusionEntityCollection*>(fill);
|
||||
if (eec) {
|
||||
for (ExtrusionEntity *ee : eec->chained_path_from(m_last_pos).entities)
|
||||
gcode += this->extrude_entity(*ee, "infill");
|
||||
} else
|
||||
gcode += this->extrude_entity(*fill, "infill");
|
||||
}
|
||||
extrusions.clear();
|
||||
extrusions.reserve(region.infills.size());
|
||||
for (ExtrusionEntity *ee : region.infills)
|
||||
if ((ee->role() == erIroning) == ironing)
|
||||
extrusions.emplace_back(ee);
|
||||
if (! extrusions.empty()) {
|
||||
m_config.apply(print.regions()[®ion - &by_region.front()]->config());
|
||||
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
|
||||
for (const ExtrusionEntity *fill : extrusions) {
|
||||
auto *eec = dynamic_cast<const ExtrusionEntityCollection*>(fill);
|
||||
if (eec) {
|
||||
for (ExtrusionEntity *ee : eec->chained_path_from(m_last_pos).entities)
|
||||
gcode += this->extrude_entity(*ee, extrusion_name);
|
||||
} else
|
||||
gcode += this->extrude_entity(*fill, extrusion_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return gcode;
|
||||
}
|
||||
|
@ -3027,6 +3037,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
speed = m_config.get_abs_value("solid_infill_speed");
|
||||
} else if (path.role() == erTopSolidInfill) {
|
||||
speed = m_config.get_abs_value("top_solid_infill_speed");
|
||||
} else if (path.role() == erIroning) {
|
||||
speed = m_config.get_abs_value("ironing_speed");
|
||||
} else if (path.role() == erGapFill) {
|
||||
speed = m_config.get_abs_value("gap_fill_speed");
|
||||
} else {
|
||||
|
@ -3427,10 +3439,13 @@ void GCode::ObjectByExtruder::Island::Region::append(const Type type, const Extr
|
|||
|
||||
// First we append the entities, there are eec->entities.size() of them:
|
||||
size_t old_size = perimeters_or_infills->size();
|
||||
size_t new_size = old_size + eec->entities.size();
|
||||
size_t new_size = old_size + (eec->can_reverse() ? eec->entities.size() : 1);
|
||||
perimeters_or_infills->reserve(new_size);
|
||||
for (auto* ee : eec->entities)
|
||||
perimeters_or_infills->emplace_back(ee);
|
||||
if (eec->can_reverse()) {
|
||||
for (auto* ee : eec->entities)
|
||||
perimeters_or_infills->emplace_back(ee);
|
||||
} else
|
||||
perimeters_or_infills->emplace_back(const_cast<ExtrusionEntityCollection*>(eec));
|
||||
|
||||
if (copies_extruder != nullptr) {
|
||||
// Don't reallocate overrides if not needed.
|
||||
|
|
|
@ -295,7 +295,7 @@ private:
|
|||
const size_t single_object_instance_idx);
|
||||
|
||||
std::string extrude_perimeters(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, std::unique_ptr<EdgeGrid::Grid> &lower_layer_edge_grid);
|
||||
std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region);
|
||||
std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, bool ironing);
|
||||
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
||||
|
||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||
|
|
|
@ -117,6 +117,7 @@ const Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[erCount]
|
|||
Color(1.0f, 1.0f, 0.0f, 1.0f), // erInternalInfill
|
||||
Color(1.0f, 0.0f, 1.0f, 1.0f), // erSolidInfill
|
||||
Color(0.0f, 1.0f, 1.0f, 1.0f), // erTopSolidInfill
|
||||
Color(0.0f, 1.0f, 1.0f, 1.0f), // erIroning
|
||||
Color(0.5f, 0.5f, 0.5f, 1.0f), // erBridgeInfill
|
||||
Color(1.0f, 1.0f, 1.0f, 1.0f), // erGapFill
|
||||
Color(0.5f, 0.0f, 0.0f, 1.0f), // erSkirt
|
||||
|
|
|
@ -36,11 +36,6 @@ public:
|
|||
// collection of surfaces for infill generation
|
||||
SurfaceCollection fill_surfaces;
|
||||
|
||||
// Collection of perimeter surfaces. This is a cached result of diff(slices, fill_surfaces).
|
||||
// While not necessary, the memory consumption is meager and it speeds up calculation.
|
||||
// The perimeter_surfaces keep the IDs of the slices (top/bottom/)
|
||||
SurfaceCollection perimeter_surfaces;
|
||||
|
||||
// collection of expolygons representing the bridged areas (thus not
|
||||
// needing support material)
|
||||
Polygons bridged;
|
||||
|
@ -140,6 +135,7 @@ public:
|
|||
}
|
||||
void make_perimeters();
|
||||
void make_fills();
|
||||
void make_ironing();
|
||||
|
||||
void export_region_slices_to_svg(const char *path) const;
|
||||
void export_region_fill_surfaces_to_svg(const char *path) const;
|
||||
|
|
|
@ -1586,6 +1586,8 @@ void Print::process()
|
|||
this->set_status(70, L("Infilling layers"));
|
||||
for (PrintObject *obj : m_objects)
|
||||
obj->infill();
|
||||
for (PrintObject *obj : m_objects)
|
||||
obj->ironing();
|
||||
for (PrintObject *obj : m_objects)
|
||||
obj->generate_support_material();
|
||||
if (this->set_started(psWipeTower)) {
|
||||
|
|
|
@ -41,7 +41,7 @@ enum PrintStep {
|
|||
|
||||
enum PrintObjectStep {
|
||||
posSlice, posPerimeters, posPrepareInfill,
|
||||
posInfill, posSupportMaterial, posCount,
|
||||
posInfill, posIroning, posSupportMaterial, posCount,
|
||||
};
|
||||
|
||||
// A PrintRegion object represents a group of volumes to print
|
||||
|
@ -223,6 +223,7 @@ private:
|
|||
void make_perimeters();
|
||||
void prepare_infill();
|
||||
void infill();
|
||||
void ironing();
|
||||
void generate_support_material();
|
||||
|
||||
void _slice(const std::vector<coordf_t> &layer_height_profile);
|
||||
|
|
|
@ -39,6 +39,11 @@ void PrintConfigDef::init_common_params()
|
|||
{
|
||||
ConfigOptionDef* def;
|
||||
|
||||
def = this->add("single_instance", coBool);
|
||||
def->label = L("Single Instance");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("printer_technology", coEnum);
|
||||
def->label = L("Printer technology");
|
||||
def->tooltip = L("Printer technology");
|
||||
|
@ -144,6 +149,7 @@ void PrintConfigDef::init_fff_params()
|
|||
def->label = L("Other layers");
|
||||
def->tooltip = L("Bed temperature for layers after the first one. "
|
||||
"Set this to zero to disable bed temperature control commands in the output.");
|
||||
def->sidetext = L("°C");
|
||||
def->full_label = L("Bed temperature");
|
||||
def->min = 0;
|
||||
def->max = 300;
|
||||
|
@ -418,18 +424,20 @@ void PrintConfigDef::init_fff_params()
|
|||
def->cli = "top-fill-pattern|external-fill-pattern|solid-fill-pattern";
|
||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
def->enum_values.push_back("rectilinear");
|
||||
def->enum_values.push_back("monotonous");
|
||||
def->enum_values.push_back("concentric");
|
||||
def->enum_values.push_back("hilbertcurve");
|
||||
def->enum_values.push_back("archimedeanchords");
|
||||
def->enum_values.push_back("octagramspiral");
|
||||
def->enum_labels.push_back(L("Rectilinear"));
|
||||
def->enum_labels.push_back(L("Monotonous"));
|
||||
def->enum_labels.push_back(L("Concentric"));
|
||||
def->enum_labels.push_back(L("Hilbert Curve"));
|
||||
def->enum_labels.push_back(L("Archimedean Chords"));
|
||||
def->enum_labels.push_back(L("Octagram Spiral"));
|
||||
// solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern.
|
||||
def->aliases = { "solid_fill_pattern", "external_fill_pattern" };
|
||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipRectilinear));
|
||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipMonotonous));
|
||||
|
||||
def = this->add("bottom_fill_pattern", coEnum);
|
||||
def->label = L("Bottom fill pattern");
|
||||
|
@ -866,8 +874,10 @@ void PrintConfigDef::init_fff_params()
|
|||
|
||||
def = this->add("first_layer_bed_temperature", coInts);
|
||||
def->label = L("First layer");
|
||||
def->full_label = L("First layer bed temperature");
|
||||
def->tooltip = L("Heated build plate temperature for the first layer. Set this to zero to disable "
|
||||
"bed temperature control commands in the output.");
|
||||
def->sidetext = L("°C");
|
||||
def->max = 0;
|
||||
def->max = 300;
|
||||
def->set_default_value(new ConfigOptionInts { 0 });
|
||||
|
@ -908,8 +918,10 @@ void PrintConfigDef::init_fff_params()
|
|||
|
||||
def = this->add("first_layer_temperature", coInts);
|
||||
def->label = L("First layer");
|
||||
def->full_label = L("First layer extruder temperature");
|
||||
def->tooltip = L("Extruder temperature for first layer. If you want to control temperature manually "
|
||||
"during print, set this to zero to disable temperature control commands in the output file.");
|
||||
def->sidetext = L("°C");
|
||||
def->min = 0;
|
||||
def->max = max_temp;
|
||||
def->set_default_value(new ConfigOptionInts { 200 });
|
||||
|
@ -1076,6 +1088,53 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("ironing", coBool);
|
||||
def->label = L("Enable ironing");
|
||||
def->tooltip = L("Enable ironing of the top layers with the hot print head for smooth surface");
|
||||
def->category = L("Ironing");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("ironing_type", coEnum);
|
||||
def->label = L("Ironingy Type");
|
||||
def->tooltip = L("Ironingy Type");
|
||||
def->enum_keys_map = &ConfigOptionEnum<IroningType>::get_enum_values();
|
||||
def->enum_values.push_back("top");
|
||||
def->enum_values.push_back("topmost");
|
||||
def->enum_values.push_back("solid");
|
||||
def->enum_labels.push_back("All top surfaces");
|
||||
def->enum_labels.push_back("Topmost surface only");
|
||||
def->enum_labels.push_back("All solid surfaces");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<IroningType>(IroningType::TopSurfaces));
|
||||
|
||||
def = this->add("ironing_flowrate", coPercent);
|
||||
def->label = L("Flow rate");
|
||||
def->category = L("Ironing");
|
||||
def->tooltip = L("Percent of a flow rate relative to object's normal layer height.");
|
||||
def->sidetext = L("%");
|
||||
def->ratio_over = "layer_height";
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionPercent(15));
|
||||
|
||||
def = this->add("ironing_spacing", coFloat);
|
||||
def->label = L("Spacing between ironing passes");
|
||||
def->tooltip = L("Distance between ironing lins");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0.1));
|
||||
|
||||
def = this->add("ironing_speed", coFloat);
|
||||
def->label = L("Ironing speed");
|
||||
def->category = L("Speed");
|
||||
def->tooltip = L("Ironing speed");
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(15));
|
||||
|
||||
def = this->add("layer_gcode", coString);
|
||||
def->label = L("After layer change G-code");
|
||||
def->tooltip = L("This custom code is inserted at every layer change, right after the Z move "
|
||||
|
@ -2071,7 +2130,8 @@ void PrintConfigDef::init_fff_params()
|
|||
def->label = L("Other layers");
|
||||
def->tooltip = L("Extruder temperature for layers after the first one. Set this to zero to disable "
|
||||
"temperature control commands in the output.");
|
||||
def->full_label = L("Temperature");
|
||||
def->sidetext = L("°C");
|
||||
def->full_label = L("Extruder temperature");
|
||||
def->min = 0;
|
||||
def->max = max_temp;
|
||||
def->set_default_value(new ConfigOptionInts { 200 });
|
||||
|
|
|
@ -34,10 +34,17 @@ enum PrintHostType {
|
|||
};
|
||||
|
||||
enum InfillPattern {
|
||||
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
|
||||
ipRectilinear, ipMonotonous, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
|
||||
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipCount,
|
||||
};
|
||||
|
||||
enum class IroningType {
|
||||
TopSurfaces,
|
||||
TopmostOnly,
|
||||
AllSolid,
|
||||
Count,
|
||||
};
|
||||
|
||||
enum SupportMaterialPattern {
|
||||
smpRectilinear, smpRectilinearGrid, smpHoneycomb,
|
||||
};
|
||||
|
@ -106,6 +113,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::g
|
|||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
keys_map["rectilinear"] = ipRectilinear;
|
||||
keys_map["monotonous"] = ipMonotonous;
|
||||
keys_map["grid"] = ipGrid;
|
||||
keys_map["triangles"] = ipTriangles;
|
||||
keys_map["stars"] = ipStars;
|
||||
|
@ -122,6 +130,16 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::g
|
|||
return keys_map;
|
||||
}
|
||||
|
||||
template<> inline const t_config_enum_values& ConfigOptionEnum<IroningType>::get_enum_values() {
|
||||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
keys_map["top"] = int(IroningType::TopSurfaces);
|
||||
keys_map["topmost"] = int(IroningType::TopmostOnly);
|
||||
keys_map["solid"] = int(IroningType::AllSolid);
|
||||
}
|
||||
return keys_map;
|
||||
}
|
||||
|
||||
template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() {
|
||||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
|
@ -488,6 +506,12 @@ public:
|
|||
ConfigOptionInt infill_every_layers;
|
||||
ConfigOptionFloatOrPercent infill_overlap;
|
||||
ConfigOptionFloat infill_speed;
|
||||
// Ironing options
|
||||
ConfigOptionBool ironing;
|
||||
ConfigOptionEnum<IroningType> ironing_type;
|
||||
ConfigOptionPercent ironing_flowrate;
|
||||
ConfigOptionFloat ironing_spacing;
|
||||
ConfigOptionFloat ironing_speed;
|
||||
// Detect bridging perimeters
|
||||
ConfigOptionBool overhangs;
|
||||
ConfigOptionInt perimeter_extruder;
|
||||
|
@ -533,6 +557,11 @@ protected:
|
|||
OPT_PTR(infill_every_layers);
|
||||
OPT_PTR(infill_overlap);
|
||||
OPT_PTR(infill_speed);
|
||||
OPT_PTR(ironing);
|
||||
OPT_PTR(ironing_type);
|
||||
OPT_PTR(ironing_flowrate);
|
||||
OPT_PTR(ironing_spacing);
|
||||
OPT_PTR(ironing_speed);
|
||||
OPT_PTR(overhangs);
|
||||
OPT_PTR(perimeter_extruder);
|
||||
OPT_PTR(perimeter_extrusion_width);
|
||||
|
|
|
@ -387,6 +387,25 @@ void PrintObject::infill()
|
|||
}
|
||||
}
|
||||
|
||||
void PrintObject::ironing()
|
||||
{
|
||||
if (this->set_started(posIroning)) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Ironing in parallel - start";
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(1, m_layers.size()),
|
||||
[this](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||
m_print->throw_if_canceled();
|
||||
m_layers[layer_idx]->make_ironing();
|
||||
}
|
||||
}
|
||||
);
|
||||
m_print->throw_if_canceled();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Ironing in parallel - end";
|
||||
this->set_done(posIroning);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintObject::generate_support_material()
|
||||
{
|
||||
if (this->set_started(posSupportMaterial)) {
|
||||
|
@ -2610,6 +2629,7 @@ void PrintObject::combine_infill()
|
|||
// Because fill areas for rectilinear and honeycomb are grown
|
||||
// later to overlap perimeters, we need to counteract that too.
|
||||
((region->config().fill_pattern == ipRectilinear ||
|
||||
region->config().fill_pattern == ipMonotonous ||
|
||||
region->config().fill_pattern == ipGrid ||
|
||||
region->config().fill_pattern == ipLine ||
|
||||
region->config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
|
||||
|
@ -2686,7 +2706,7 @@ void PrintObject::project_and_append_custom_supports(
|
|||
|
||||
// Iterate over all triangles.
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, custom_facets.size() - 1),
|
||||
tbb::blocked_range<size_t>(0, custom_facets.size()),
|
||||
[&](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t idx = range.begin(); idx < range.end(); ++ idx) {
|
||||
|
||||
|
@ -2799,10 +2819,9 @@ void PrintObject::project_and_append_custom_supports(
|
|||
// Now append the collected polygons to respective layers.
|
||||
for (auto& trg : projections_of_triangles) {
|
||||
int layer_id = trg.first_layer_id;
|
||||
if (layer_id == 0)
|
||||
continue;
|
||||
|
||||
for (const LightPolygon& poly : trg.polygons) {
|
||||
expolys[layer_id-1].emplace_back(std::move(poly.pts));
|
||||
expolys[layer_id].emplace_back(std::move(poly.pts));
|
||||
++layer_id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,11 +38,12 @@ std::vector<std::pair<size_t, bool>> chain_segments_closest_point(std::vector<En
|
|||
// Ignore the starting point as the starting point is considered to be occupied, no end point coud connect to it.
|
||||
size_t next_idx = find_closest_point(kdtree, this_point.pos,
|
||||
[this_idx, &end_points, &could_reverse_func](size_t idx) {
|
||||
return (idx ^ this_idx) > 1 && end_points[idx].chain_id == 0 && ((idx ^ 1) == 0 || could_reverse_func(idx >> 1));
|
||||
return (idx ^ this_idx) > 1 && end_points[idx].chain_id == 0 && ((idx & 1) == 0 || could_reverse_func(idx >> 1));
|
||||
});
|
||||
assert(next_idx < end_points.size());
|
||||
EndPointType &end_point = end_points[next_idx];
|
||||
end_point.chain_id = 1;
|
||||
assert((next_idx & 1) == 0 || could_reverse_func(next_idx >> 1));
|
||||
out.emplace_back(next_idx / 2, (next_idx & 1) != 0);
|
||||
this_idx = next_idx ^ 1;
|
||||
}
|
||||
|
@ -165,7 +166,9 @@ std::vector<std::pair<size_t, bool>> chain_segments_greedy_constrained_reversals
|
|||
EndPoint *first_point = nullptr;
|
||||
size_t first_point_idx = std::numeric_limits<size_t>::max();
|
||||
if (start_near != nullptr) {
|
||||
size_t idx = find_closest_point(kdtree, start_near->template cast<double>());
|
||||
size_t idx = find_closest_point(kdtree, start_near->template cast<double>(),
|
||||
// Don't start with a reverse segment, if flipping of the segment is not allowed.
|
||||
[&could_reverse_func](size_t idx) { return (idx & 1) == 0 || could_reverse_func(idx >> 1); });
|
||||
assert(idx < end_points.size());
|
||||
first_point = &end_points[idx];
|
||||
first_point->distance_out = 0.;
|
||||
|
|
|
@ -1101,10 +1101,10 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||
if (! enforcers.empty()) {
|
||||
// Apply the "support enforcers".
|
||||
//FIXME add the "enforcers" to the sparse support regions only.
|
||||
const ExPolygons &enforcer = enforcers[layer_id - 1];
|
||||
const ExPolygons &enforcer = enforcers[layer_id];
|
||||
if (! enforcer.empty()) {
|
||||
// Enforce supports (as if with 90 degrees of slope) for the regions covered by the enforcer meshes.
|
||||
Polygons new_contacts = diff(intersection(layerm_polygons, to_polygons(enforcer)),
|
||||
Polygons new_contacts = diff(intersection(layerm_polygons, to_polygons(std::move(enforcer))),
|
||||
offset(lower_layer_polygons, 0.05f * fw, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||
if (! new_contacts.empty()) {
|
||||
if (diff_polygons.empty())
|
||||
|
@ -1115,19 +1115,26 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||
}
|
||||
}
|
||||
}
|
||||
// Apply the "support blockers".
|
||||
if (! diff_polygons.empty() && ! blockers.empty() && ! blockers[layer_id].empty()) {
|
||||
// Enforce supports (as if with 90 degrees of slope) for the regions covered by the enforcer meshes.
|
||||
diff_polygons = diff(diff_polygons, to_polygons(blockers[layer_id]));
|
||||
}
|
||||
|
||||
if (diff_polygons.empty())
|
||||
continue;
|
||||
|
||||
// Apply the "support blockers".
|
||||
if (! blockers.empty() && ! blockers[layer_id].empty()) {
|
||||
// Expand the blocker a bit. Custom blockers produce strips
|
||||
// spanning just the projection between the two slices.
|
||||
// Subtracting them as they are may leave unwanted narrow
|
||||
// residues of diff_polygons that would then be supported.
|
||||
diff_polygons = diff(diff_polygons,
|
||||
offset(union_(to_polygons(std::move(blockers[layer_id]))),
|
||||
1000.*SCALED_EPSILON));
|
||||
}
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
{
|
||||
::Slic3r::SVG svg(debug_out_path("support-top-contacts-raw-run%d-layer%d-region%d.svg",
|
||||
iRun, layer_id,
|
||||
std::find_if(layer.regions.begin(), layer.regions.end(), [layerm](const LayerRegion* other){return other == layerm;}) - layer.regions.begin()),
|
||||
std::find_if(layer.regions.begin(), layer.regions.end(), [layerm](const LayerRegion* other){return other == layerm;}) - layer.regions.begin()),
|
||||
get_extents(diff_polygons));
|
||||
Slic3r::ExPolygons expolys = union_ex(diff_polygons, false);
|
||||
svg.draw(expolys);
|
||||
|
@ -2321,10 +2328,15 @@ static inline void fill_expolygons_generate_paths(
|
|||
fill_params.dont_adjust = true;
|
||||
for (const ExPolygon &expoly : expolygons) {
|
||||
Surface surface(stInternal, expoly);
|
||||
Polylines polylines;
|
||||
try {
|
||||
polylines = filler->fill_surface(&surface, fill_params);
|
||||
} catch (InfillFailedException &) {
|
||||
}
|
||||
extrusion_entities_append_paths(
|
||||
dst,
|
||||
filler->fill_surface(&surface, fill_params),
|
||||
role,
|
||||
std::move(polylines),
|
||||
role,
|
||||
flow.mm3_per_mm(), flow.width, flow.height);
|
||||
}
|
||||
}
|
||||
|
@ -2343,9 +2355,14 @@ static inline void fill_expolygons_generate_paths(
|
|||
fill_params.dont_adjust = true;
|
||||
for (ExPolygon &expoly : expolygons) {
|
||||
Surface surface(stInternal, std::move(expoly));
|
||||
Polylines polylines;
|
||||
try {
|
||||
polylines = filler->fill_surface(&surface, fill_params);
|
||||
} catch (InfillFailedException &) {
|
||||
}
|
||||
extrusion_entities_append_paths(
|
||||
dst,
|
||||
filler->fill_surface(&surface, fill_params),
|
||||
std::move(polylines),
|
||||
role,
|
||||
flow.mm3_per_mm(), flow.width, flow.height);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
// Saves around 32% RAM after slicing step, 6.7% after G-code export (tested on PrusaSlicer 2.2.0 final).
|
||||
typedef int32_t coord_t;
|
||||
#else
|
||||
//FIXME At least FillRectilinear2 requires coord_t to be 32bit.
|
||||
typedef int64_t coord_t;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -161,6 +161,10 @@ set(SLIC3R_GUI_SOURCES
|
|||
GUI/DoubleSlider.hpp
|
||||
GUI/ObjectDataViewModel.cpp
|
||||
GUI/ObjectDataViewModel.hpp
|
||||
GUI/InstanceCheck.cpp
|
||||
GUI/InstanceCheck.hpp
|
||||
GUI/Search.cpp
|
||||
GUI/Search.hpp
|
||||
Utils/Http.cpp
|
||||
Utils/Http.hpp
|
||||
Utils/FixModelByWin10.cpp
|
||||
|
@ -195,6 +199,8 @@ if (APPLE)
|
|||
GUI/RemovableDriveManagerMM.mm
|
||||
GUI/RemovableDriveManagerMM.h
|
||||
GUI/Mouse3DHandlerMac.mm
|
||||
GUI/InstanceCheckMac.mm
|
||||
GUI/InstanceCheckMac.h
|
||||
)
|
||||
FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration)
|
||||
|
||||
|
@ -206,6 +212,10 @@ encoding_check(libslic3r_gui)
|
|||
|
||||
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi libcurl ${wxWidgets_LIBRARIES})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(libslic3r_gui ${DBUS_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY})
|
||||
endif()
|
||||
|
|
|
@ -115,7 +115,9 @@ void CopyrightsDialog::fill_entries()
|
|||
{ "Icons for STL and GCODE files."
|
||||
, "Akira Yasuda" , "http://3dp0.com/icons-for-stl-and-gcode/" },
|
||||
{ "AppImage packaging for Linux using AppImageKit"
|
||||
, "2004-2019 Simon Peter and contributors" , "https://appimage.org/" }
|
||||
, "2004-2019 Simon Peter and contributors" , "https://appimage.org/" },
|
||||
{ "lib_fts"
|
||||
, "Forrest Smith" , "https://www.forrestthewoods.com/" }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ void AppConfig::set_defaults()
|
|||
set("use_retina_opengl", "1");
|
||||
#endif
|
||||
|
||||
if (get("single_instance").empty())
|
||||
set("single_instance", "0");
|
||||
|
||||
if (get("remember_output_path").empty())
|
||||
set("remember_output_path", "1");
|
||||
|
||||
|
|
|
@ -298,6 +298,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||
toggle_field("support_material_extruder", have_support_material || have_skirt);
|
||||
toggle_field("support_material_speed", have_support_material || have_brim || have_skirt);
|
||||
|
||||
bool has_ironing = config->opt_bool("ironing");
|
||||
for (auto el : { "ironing_type", "ironing_flowrate", "ironing_spacing", "ironing_speed" })
|
||||
toggle_field(el, has_ironing);
|
||||
|
||||
bool have_sequential_printing = config->opt_bool("complete_objects");
|
||||
for (auto el : { "extruder_clearance_radius", "extruder_clearance_height" })
|
||||
toggle_field(el, have_sequential_printing);
|
||||
|
|
|
@ -57,6 +57,8 @@ void Field::PostInitialize()
|
|||
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); }));
|
||||
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); }));
|
||||
|
||||
m_blinking_bmp = new BlinkingBitmap(m_parent);
|
||||
|
||||
switch (m_opt.type)
|
||||
{
|
||||
case coPercents:
|
||||
|
@ -943,7 +945,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
|||
}
|
||||
case coEnum: {
|
||||
int val = boost::any_cast<int>(value);
|
||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern")
|
||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern")
|
||||
{
|
||||
if (!m_opt.enum_values.empty()) {
|
||||
std::string key;
|
||||
|
@ -1013,7 +1015,7 @@ boost::any& Choice::get_value()
|
|||
if (m_opt.type == coEnum)
|
||||
{
|
||||
int ret_enum = field->GetSelection();
|
||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern")
|
||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern")
|
||||
{
|
||||
if (!m_opt.enum_values.empty()) {
|
||||
std::string key = m_opt.enum_values[ret_enum];
|
||||
|
@ -1025,8 +1027,8 @@ boost::any& Choice::get_value()
|
|||
else
|
||||
m_value = static_cast<InfillPattern>(0);
|
||||
}
|
||||
if (m_opt_id.compare("fill_pattern") == 0)
|
||||
m_value = static_cast<InfillPattern>(ret_enum);
|
||||
else if (m_opt_id.compare("ironing_type") == 0)
|
||||
m_value = static_cast<IroningType>(ret_enum);
|
||||
else if (m_opt_id.compare("gcode_flavor") == 0)
|
||||
m_value = static_cast<GCodeFlavor>(ret_enum);
|
||||
else if (m_opt_id.compare("support_material_pattern") == 0)
|
||||
|
|
|
@ -230,6 +230,8 @@ public:
|
|||
static int def_width_wider() ;
|
||||
static int def_width_thinner() ;
|
||||
|
||||
BlinkingBitmap* blinking_bitmap() const { return m_blinking_bmp;}
|
||||
|
||||
protected:
|
||||
RevertButton* m_Undo_btn = nullptr;
|
||||
// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
|
||||
|
@ -240,6 +242,8 @@ protected:
|
|||
const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
|
||||
const wxString* m_undo_to_sys_tooltip = nullptr;
|
||||
|
||||
BlinkingBitmap* m_blinking_bmp{ nullptr };
|
||||
|
||||
wxStaticText* m_Label = nullptr;
|
||||
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
|
||||
const wxColour* m_label_color = nullptr;
|
||||
|
@ -461,6 +465,7 @@ public:
|
|||
x_textctrl->Disable();
|
||||
y_textctrl->Disable(); }
|
||||
wxSizer* getSizer() override { return sizer; }
|
||||
wxWindow* getWindow() override { return dynamic_cast<wxWindow*>(x_textctrl); }
|
||||
};
|
||||
|
||||
class StaticText : public Field {
|
||||
|
|
|
@ -1531,6 +1531,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
|
|||
wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
||||
|
@ -1556,6 +1557,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar
|
|||
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
, m_main_toolbar(GLToolbar::Normal, "Top")
|
||||
, m_undoredo_toolbar(GLToolbar::Normal, "Top")
|
||||
, m_collapse_toolbar(GLToolbar::Normal, "Top")
|
||||
, m_gizmos(*this)
|
||||
, m_use_clipping_planes(false)
|
||||
, m_sidebar_field("")
|
||||
|
@ -1961,6 +1963,11 @@ void GLCanvas3D::enable_undoredo_toolbar(bool enable)
|
|||
m_undoredo_toolbar.set_enabled(enable);
|
||||
}
|
||||
|
||||
void GLCanvas3D::enable_collapse_toolbar(bool enable)
|
||||
{
|
||||
m_collapse_toolbar.set_enabled(enable);
|
||||
}
|
||||
|
||||
void GLCanvas3D::enable_dynamic_background(bool enable)
|
||||
{
|
||||
m_dynamic_background_enabled = enable;
|
||||
|
@ -2186,6 +2193,9 @@ void GLCanvas3D::render()
|
|||
tooltip = m_undoredo_toolbar.get_tooltip();
|
||||
|
||||
if (tooltip.empty())
|
||||
tooltip = m_collapse_toolbar.get_tooltip();
|
||||
|
||||
if (tooltip.empty())
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
tooltip = wxGetApp().plater()->get_view_toolbar().get_tooltip();
|
||||
#else
|
||||
|
@ -2224,6 +2234,9 @@ void GLCanvas3D::render()
|
|||
if (tooltip.empty())
|
||||
tooltip = m_undoredo_toolbar.get_tooltip();
|
||||
|
||||
if (tooltip.empty())
|
||||
tooltip = m_collapse_toolbar.get_tooltip();
|
||||
|
||||
if (tooltip.empty())
|
||||
tooltip = m_view_toolbar.get_tooltip();
|
||||
|
||||
|
@ -2950,6 +2963,7 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
|
|||
|
||||
m_dirty |= m_main_toolbar.update_items_state();
|
||||
m_dirty |= m_undoredo_toolbar.update_items_state();
|
||||
m_dirty |= m_collapse_toolbar.update_items_state();
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
m_dirty |= wxGetApp().plater()->get_view_toolbar().update_items_state();
|
||||
bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera());
|
||||
|
@ -2989,7 +3003,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((keyCode == WXK_ESCAPE) && _deactivate_undo_redo_toolbar_items())
|
||||
if ((keyCode == WXK_ESCAPE) && (_deactivate_undo_redo_toolbar_items() || _deactivate_search_toolbar_item()))
|
||||
return;
|
||||
|
||||
if (m_gizmos.on_char(evt))
|
||||
|
@ -3037,6 +3051,16 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
|||
break;
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
case 'f':
|
||||
case 'F':
|
||||
#else /* __APPLE__ */
|
||||
case WXK_CONTROL_F:
|
||||
#endif /* __APPLE__ */
|
||||
_activate_search_toolbar_item();
|
||||
break;
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
case 'y':
|
||||
case 'Y':
|
||||
|
@ -3436,6 +3460,15 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
// If the Search window or Undo/Redo list is opened,
|
||||
// update them according to the event
|
||||
if (m_main_toolbar.is_item_pressed("search") ||
|
||||
m_undoredo_toolbar.is_item_pressed("undo") ||
|
||||
m_undoredo_toolbar.is_item_pressed("redo")) {
|
||||
m_mouse_wheel = int((double)evt.GetWheelRotation() / (double)evt.GetWheelDelta());
|
||||
return;
|
||||
}
|
||||
|
||||
// Inform gizmos about the event so they have the opportunity to react.
|
||||
if (m_gizmos.on_mouse_wheel(evt))
|
||||
return;
|
||||
|
@ -3571,6 +3604,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_collapse_toolbar.on_mouse(evt, *this))
|
||||
{
|
||||
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
mouse_up_cleanup();
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
if (wxGetApp().plater()->get_view_toolbar().on_mouse(evt, *this))
|
||||
#else
|
||||
|
@ -3636,6 +3677,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
else if (evt.Leaving())
|
||||
{
|
||||
_deactivate_undo_redo_toolbar_items();
|
||||
_deactivate_search_toolbar_item();
|
||||
|
||||
// to remove hover on objects when the mouse goes out of this canvas
|
||||
m_mouse.position = Vec2d(-1.0, -1.0);
|
||||
|
@ -3643,7 +3685,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
else if (evt.LeftDown() || evt.RightDown() || evt.MiddleDown())
|
||||
{
|
||||
if (_deactivate_undo_redo_toolbar_items())
|
||||
if (_deactivate_undo_redo_toolbar_items() || _deactivate_search_toolbar_item())
|
||||
return;
|
||||
|
||||
// If user pressed left or right button we first check whether this happened
|
||||
|
@ -4434,7 +4476,7 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) const
|
|||
em *= m_retina_helper->get_scale_factor();
|
||||
#endif
|
||||
|
||||
if (imgui->undo_redo_list(ImVec2(18 * em, 26 * em), is_undo, &string_getter, hovered, selected))
|
||||
if (imgui->undo_redo_list(ImVec2(18 * em, 26 * em), is_undo, &string_getter, hovered, selected, m_mouse_wheel))
|
||||
m_imgui_undo_redo_hovered_pos = hovered;
|
||||
else
|
||||
m_imgui_undo_redo_hovered_pos = -1;
|
||||
|
@ -4452,6 +4494,64 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) const
|
|||
return action_taken;
|
||||
}
|
||||
|
||||
// Getter for the const char*[] for the search list
|
||||
static bool search_string_getter(int idx, const char** label, const char** tooltip)
|
||||
{
|
||||
return wxGetApp().plater()->search_string_getter(idx, label, tooltip);
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_render_search_list(float pos_x) const
|
||||
{
|
||||
bool action_taken = false;
|
||||
ImGuiWrapper* imgui = wxGetApp().imgui();
|
||||
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
|
||||
#else
|
||||
const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
|
||||
#endif
|
||||
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
|
||||
std::string title = L("Search");
|
||||
imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
int selected = -1;
|
||||
bool edited = false;
|
||||
bool check_changed = false;
|
||||
float em = static_cast<float>(wxGetApp().em_unit());
|
||||
#if ENABLE_RETINA_GL
|
||||
em *= m_retina_helper->get_scale_factor();
|
||||
#endif
|
||||
|
||||
Sidebar& sidebar = wxGetApp().sidebar();
|
||||
|
||||
std::string& search_line = sidebar.get_search_line();
|
||||
char *s = new char[255];
|
||||
strcpy(s, search_line.empty() ? _u8L("Type here to search").c_str() : search_line.c_str());
|
||||
|
||||
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
|
||||
sidebar.get_searcher().view_params,
|
||||
selected, edited, m_mouse_wheel);
|
||||
|
||||
search_line = s;
|
||||
delete [] s;
|
||||
if (search_line == _u8L("Type here to search"))
|
||||
search_line.clear();
|
||||
|
||||
if (edited)
|
||||
sidebar.search();
|
||||
|
||||
if (selected != size_t(-1)) {
|
||||
// selected == 9999 means that Esc kye was pressed
|
||||
if (selected != 9999)
|
||||
sidebar.jump_to_option(selected);
|
||||
action_taken = true;
|
||||
}
|
||||
|
||||
imgui->end();
|
||||
|
||||
return action_taken;
|
||||
}
|
||||
|
||||
#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
|
||||
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
||||
static void debug_output_thumbnail(const ThumbnailData& thumbnail_data)
|
||||
|
@ -4821,6 +4921,9 @@ bool GLCanvas3D::_init_toolbars()
|
|||
if (!_init_view_toolbar())
|
||||
return false;
|
||||
|
||||
if (!_init_collapse_toolbar())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4978,6 +5081,26 @@ bool GLCanvas3D::_init_main_toolbar()
|
|||
if (!m_main_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
if (!m_main_toolbar.add_separator())
|
||||
return false;
|
||||
|
||||
item.name = "search";
|
||||
item.icon_filename = "search_.svg";
|
||||
item.tooltip = _utf8(L("Search")) + " [" + GUI::shortkey_ctrl_prefix() + "F]";
|
||||
item.sprite_id = 11;
|
||||
item.left.render_callback = [this](float left, float right, float, float) {
|
||||
if (m_canvas != nullptr)
|
||||
{
|
||||
if (_render_search_list(0.5f * (left + right)))
|
||||
_deactivate_search_toolbar_item();
|
||||
}
|
||||
};
|
||||
item.left.action_callback = GLToolbarItem::Default_Action_Callback;
|
||||
item.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
|
||||
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
|
||||
if (!m_main_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5087,6 +5210,9 @@ bool GLCanvas3D::_init_undoredo_toolbar()
|
|||
if (!m_undoredo_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
if (!m_undoredo_toolbar.add_separator())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5095,6 +5221,106 @@ bool GLCanvas3D::_init_view_toolbar()
|
|||
return wxGetApp().plater()->init_view_toolbar();
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_init_collapse_toolbar()
|
||||
{
|
||||
if (!m_collapse_toolbar.is_enabled())
|
||||
return true;
|
||||
|
||||
BackgroundTexture::Metadata background_data;
|
||||
background_data.filename = "toolbar_background.png";
|
||||
background_data.left = 16;
|
||||
background_data.top = 16;
|
||||
background_data.right = 16;
|
||||
background_data.bottom = 16;
|
||||
|
||||
if (!m_collapse_toolbar.init(background_data))
|
||||
{
|
||||
// unable to init the toolbar texture, disable it
|
||||
m_collapse_toolbar.set_enabled(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_collapse_toolbar.set_layout_type(GLToolbar::Layout::Vertical);
|
||||
m_collapse_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Right);
|
||||
m_collapse_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Top);
|
||||
m_collapse_toolbar.set_border(5.0f);
|
||||
m_collapse_toolbar.set_separator_size(5);
|
||||
m_collapse_toolbar.set_gap_size(2);
|
||||
|
||||
GLToolbarItem::Data item;
|
||||
|
||||
item.name = "collapse_sidebar";
|
||||
item.icon_filename = "collapse.svg";
|
||||
item.tooltip = wxGetApp().plater()->is_sidebar_collapsed() ? _utf8(L("Expand right panel")) : _utf8(L("Collapse right panel"));
|
||||
item.sprite_id = 0;
|
||||
item.left.action_callback = [this, item]() {
|
||||
std::string new_tooltip = wxGetApp().plater()->is_sidebar_collapsed() ?
|
||||
_utf8(L("Collapse right panel")) : _utf8(L("Expand right panel"));
|
||||
|
||||
int id = m_collapse_toolbar.get_item_id("collapse_sidebar");
|
||||
m_collapse_toolbar.set_tooltip(id, new_tooltip);
|
||||
set_tooltip("");
|
||||
|
||||
wxGetApp().plater()->collapse_sidebar(!wxGetApp().plater()->is_sidebar_collapsed());
|
||||
};
|
||||
|
||||
if (!m_collapse_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
if (!m_collapse_toolbar.add_separator())
|
||||
return false;
|
||||
|
||||
item.name = "print";
|
||||
item.icon_filename = "cog.svg";
|
||||
item.tooltip = _utf8(L("Switch to Print Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "2]";
|
||||
item.sprite_id = 1;
|
||||
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*0*/1); };
|
||||
|
||||
if (!m_collapse_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "filament";
|
||||
item.icon_filename = "spool.svg";
|
||||
item.tooltip = _utf8(L("Switch to Filament Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
|
||||
item.sprite_id = 2;
|
||||
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*1*/2); };
|
||||
item.visibility_callback = [this]() { return wxGetApp().plater()->printer_technology() == ptFFF; };
|
||||
|
||||
if (!m_collapse_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "printer";
|
||||
item.icon_filename = "printer.svg";
|
||||
item.tooltip = _utf8(L("Switch to Printer Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "4]";
|
||||
item.sprite_id = 3;
|
||||
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*2*/3); };
|
||||
|
||||
if (!m_collapse_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "resin";
|
||||
item.icon_filename = "resin.svg";
|
||||
item.tooltip = _utf8(L("Switch to SLA Material Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
|
||||
item.sprite_id = 4;
|
||||
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*1*/2); };
|
||||
item.visibility_callback = [this]() { return m_process->current_printer_technology() == ptSLA; };
|
||||
|
||||
if (!m_collapse_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "sla_printer";
|
||||
item.icon_filename = "sla_printer.svg";
|
||||
item.tooltip = _utf8(L("Switch to Printer Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "4]";
|
||||
item.sprite_id = 5;
|
||||
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*2*/3); };
|
||||
|
||||
if (!m_collapse_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_set_current()
|
||||
{
|
||||
return m_context != nullptr && m_canvas->SetCurrent(*m_context);
|
||||
|
@ -5477,14 +5703,17 @@ void GLCanvas3D::_render_overlays() const
|
|||
const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(true);
|
||||
m_main_toolbar.set_scale(scale);
|
||||
m_undoredo_toolbar.set_scale(scale);
|
||||
m_collapse_toolbar.set_scale(scale);
|
||||
#else
|
||||
const float size = int(GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale(true));
|
||||
m_main_toolbar.set_icons_size(size);
|
||||
m_undoredo_toolbar.set_icons_size(size);
|
||||
m_collapse_toolbar.set_icons_size(size);
|
||||
#endif // ENABLE_RETINA_GL
|
||||
|
||||
_render_main_toolbar();
|
||||
_render_undoredo_toolbar();
|
||||
_render_collapse_toolbar();
|
||||
_render_view_toolbar();
|
||||
|
||||
if ((m_layers_editing.last_object_id >= 0) && (m_layers_editing.object_max_z() > 0.0f))
|
||||
|
@ -5615,6 +5844,27 @@ void GLCanvas3D::_render_undoredo_toolbar() const
|
|||
m_undoredo_toolbar.render(*this);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_collapse_toolbar() const
|
||||
{
|
||||
if (!m_collapse_toolbar.is_enabled())
|
||||
return;
|
||||
|
||||
Size cnv_size = get_canvas_size();
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
#else
|
||||
float inv_zoom = (float)m_camera.get_inv_zoom();
|
||||
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
|
||||
float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0;
|
||||
|
||||
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
|
||||
float left = (0.5f * (float)cnv_size.get_width() - (float)m_collapse_toolbar.get_width() - band) * inv_zoom;
|
||||
|
||||
m_collapse_toolbar.set_position(top, left);
|
||||
m_collapse_toolbar.render(*this);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_view_toolbar() const
|
||||
{
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
|
@ -7142,6 +7392,39 @@ bool GLCanvas3D::_deactivate_undo_redo_toolbar_items()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_deactivate_search_toolbar_item()
|
||||
{
|
||||
if (m_main_toolbar.is_item_pressed("search"))
|
||||
{
|
||||
m_main_toolbar.force_left_action(m_main_toolbar.get_item_id("search"), *this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_activate_search_toolbar_item()
|
||||
{
|
||||
if (!m_main_toolbar.is_item_pressed("search"))
|
||||
{
|
||||
m_main_toolbar.force_left_action(m_main_toolbar.get_item_id("search"), *this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_deactivate_collapse_toolbar_items()
|
||||
{
|
||||
if (m_collapse_toolbar.is_item_pressed("print"))
|
||||
{
|
||||
m_collapse_toolbar.force_left_action(m_collapse_toolbar.get_item_id("print"), *this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const Print* GLCanvas3D::fff_print() const
|
||||
{
|
||||
return (m_process == nullptr) ? nullptr : m_process->fff_print();
|
||||
|
|
|
@ -110,6 +110,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
|
|||
wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
||||
|
@ -159,8 +160,8 @@ private:
|
|||
Num_States
|
||||
};
|
||||
|
||||
private:
|
||||
static const float THICKNESS_BAR_WIDTH;
|
||||
private:
|
||||
|
||||
bool m_enabled;
|
||||
Shader m_shader;
|
||||
|
@ -455,6 +456,7 @@ private:
|
|||
mutable GLGizmosManager m_gizmos;
|
||||
mutable GLToolbar m_main_toolbar;
|
||||
mutable GLToolbar m_undoredo_toolbar;
|
||||
mutable GLToolbar m_collapse_toolbar;
|
||||
ClippingPlane m_clipping_planes[2];
|
||||
mutable ClippingPlane m_camera_clipping_plane;
|
||||
bool m_use_clipping_planes;
|
||||
|
@ -504,6 +506,7 @@ private:
|
|||
#endif // ENABLE_RENDER_STATISTICS
|
||||
|
||||
mutable int m_imgui_undo_redo_hovered_pos{ -1 };
|
||||
mutable int m_mouse_wheel {0};
|
||||
int m_selected_extruder;
|
||||
|
||||
Labels m_labels;
|
||||
|
@ -601,6 +604,7 @@ public:
|
|||
void enable_selection(bool enable);
|
||||
void enable_main_toolbar(bool enable);
|
||||
void enable_undoredo_toolbar(bool enable);
|
||||
void enable_collapse_toolbar(bool enable);
|
||||
void enable_dynamic_background(bool enable);
|
||||
void enable_labels(bool enable) { m_labels.enable(enable); }
|
||||
#if ENABLE_SLOPE_RENDERING
|
||||
|
@ -741,6 +745,7 @@ private:
|
|||
bool _init_main_toolbar();
|
||||
bool _init_undoredo_toolbar();
|
||||
bool _init_view_toolbar();
|
||||
bool _init_collapse_toolbar();
|
||||
|
||||
bool _set_current();
|
||||
void _resize(unsigned int w, unsigned int h);
|
||||
|
@ -769,6 +774,7 @@ private:
|
|||
void _render_gizmos_overlay() const;
|
||||
void _render_main_toolbar() const;
|
||||
void _render_undoredo_toolbar() const;
|
||||
void _render_collapse_toolbar() const;
|
||||
void _render_view_toolbar() const;
|
||||
#if ENABLE_SHOW_CAMERA_TARGET
|
||||
void _render_camera_target() const;
|
||||
|
@ -776,6 +782,7 @@ private:
|
|||
void _render_sla_slices() const;
|
||||
void _render_selection_sidebar_hints() const;
|
||||
bool _render_undo_redo_stack(const bool is_undo, float pos_x) const;
|
||||
bool _render_search_list(float pos_x) const;
|
||||
void _render_thumbnail_internal(ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
|
||||
// render thumbnail using an off-screen framebuffer
|
||||
void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
|
||||
|
@ -835,6 +842,9 @@ private:
|
|||
void _update_selection_from_hover();
|
||||
|
||||
bool _deactivate_undo_redo_toolbar_items();
|
||||
bool _deactivate_search_toolbar_item();
|
||||
bool _activate_search_toolbar_item();
|
||||
bool _deactivate_collapse_toolbar_items();
|
||||
|
||||
static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
|
||||
|
||||
|
|
|
@ -406,6 +406,12 @@ void GLToolbar::set_additional_tooltip(int item_id, const std::string& text)
|
|||
m_items[item_id]->set_additional_tooltip(text);
|
||||
}
|
||||
|
||||
void GLToolbar::set_tooltip(int item_id, const std::string& text)
|
||||
{
|
||||
if (0 <= item_id && item_id < (int)m_items.size())
|
||||
m_items[item_id]->set_tooltip(text);
|
||||
}
|
||||
|
||||
bool GLToolbar::update_items_state()
|
||||
{
|
||||
bool ret = false;
|
||||
|
|
|
@ -118,6 +118,7 @@ public:
|
|||
const std::string& get_tooltip() const { return m_data.tooltip; }
|
||||
const std::string& get_additional_tooltip() const { return m_data.additional_tooltip; }
|
||||
void set_additional_tooltip(const std::string& text) { m_data.additional_tooltip = text; }
|
||||
void set_tooltip(const std::string& text) { m_data.tooltip = text; }
|
||||
|
||||
void do_left_action() { m_last_action_type = Left; m_data.left.action_callback(); }
|
||||
void do_right_action() { m_last_action_type = Right; m_data.right.action_callback(); }
|
||||
|
@ -317,6 +318,7 @@ public:
|
|||
|
||||
void get_additional_tooltip(int item_id, std::string& text);
|
||||
void set_additional_tooltip(int item_id, const std::string& text);
|
||||
void set_tooltip(int item_id, const std::string& text);
|
||||
|
||||
// returns true if any item changed its state
|
||||
bool update_items_state();
|
||||
|
|
|
@ -188,6 +188,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
|||
opt_key == "bottom_fill_pattern" ||
|
||||
opt_key == "fill_pattern")
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
|
||||
else if (opt_key.compare("ironing_type") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<IroningType>(boost::any_cast<IroningType>(value)));
|
||||
else if (opt_key.compare("gcode_flavor") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));
|
||||
else if (opt_key.compare("support_material_pattern") == 0)
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "UpdateDialogs.hpp"
|
||||
#include "Mouse3DController.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include <dbt.h>
|
||||
|
@ -209,6 +210,17 @@ static void register_win32_device_notification_event()
|
|||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
wxWindow::MSWRegisterMessageHandler(WM_COPYDATA, [](wxWindow* win, WXUINT /* nMsg */, WXWPARAM wParam, WXLPARAM lParam) {
|
||||
|
||||
COPYDATASTRUCT* copy_data_structure = { 0 };
|
||||
copy_data_structure = (COPYDATASTRUCT*)lParam;
|
||||
if (copy_data_structure->dwData == 1) {
|
||||
LPCWSTR arguments = (LPCWSTR)copy_data_structure->lpData;
|
||||
Slic3r::GUI::wxGetApp().other_instance_message_handler()->handle_message(boost::nowide::narrow(arguments));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
|
@ -253,7 +265,11 @@ GUI_App::GUI_App()
|
|||
, m_imgui(new ImGuiWrapper())
|
||||
, m_wizard(nullptr)
|
||||
, m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
|
||||
{}
|
||||
, m_other_instance_message_handler(std::make_unique<OtherInstanceMessageHandler>())
|
||||
{
|
||||
//app config initializes early becasuse it is used in instance checking in PrusaSlicer.cpp
|
||||
this->init_app_config();
|
||||
}
|
||||
|
||||
GUI_App::~GUI_App()
|
||||
{
|
||||
|
@ -284,6 +300,30 @@ bool GUI_App::init_opengl()
|
|||
}
|
||||
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
|
||||
void GUI_App::init_app_config()
|
||||
{
|
||||
// Profiles for the alpha are stored into the PrusaSlicer-alpha directory to not mix with the current release.
|
||||
SetAppName(SLIC3R_APP_KEY);
|
||||
//SetAppName(SLIC3R_APP_KEY "-beta");
|
||||
SetAppDisplayName(SLIC3R_APP_NAME);
|
||||
|
||||
// Set the Slic3r data directory at the Slic3r XS module.
|
||||
// Unix: ~/ .Slic3r
|
||||
// Windows : "C:\Users\username\AppData\Roaming\Slic3r" or "C:\Documents and Settings\username\Application Data\Slic3r"
|
||||
// Mac : "~/Library/Application Support/Slic3r"
|
||||
|
||||
if (data_dir().empty())
|
||||
set_data_dir(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data());
|
||||
|
||||
if (!app_config)
|
||||
app_config = new AppConfig();
|
||||
|
||||
// load settings
|
||||
app_conf_exists = app_config->exists();
|
||||
if (app_conf_exists) {
|
||||
app_config->load();
|
||||
}
|
||||
}
|
||||
bool GUI_App::OnInit()
|
||||
{
|
||||
try {
|
||||
|
@ -301,46 +341,24 @@ bool GUI_App::on_init_inner()
|
|||
wxCHECK_MSG(wxDirExists(resources_dir), false,
|
||||
wxString::Format("Resources path does not exist or is not a directory: %s", resources_dir));
|
||||
|
||||
// Profiles for the alpha are stored into the PrusaSlicer-alpha directory to not mix with the current release.
|
||||
SetAppName(SLIC3R_APP_KEY);
|
||||
// SetAppName(SLIC3R_APP_KEY "-beta");
|
||||
SetAppDisplayName(SLIC3R_APP_NAME);
|
||||
|
||||
// Enable this to get the default Win32 COMCTRL32 behavior of static boxes.
|
||||
// Enable this to get the default Win32 COMCTRL32 behavior of static boxes.
|
||||
// wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0);
|
||||
// Enable this to disable Windows Vista themes for all wxNotebooks. The themes seem to lead to terrible
|
||||
// performance when working on high resolution multi-display setups.
|
||||
// Enable this to disable Windows Vista themes for all wxNotebooks. The themes seem to lead to terrible
|
||||
// performance when working on high resolution multi-display setups.
|
||||
// wxSystemOptions::SetOption("msw.notebook.themed-background", 0);
|
||||
|
||||
// Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION;
|
||||
|
||||
// Set the Slic3r data directory at the Slic3r XS module.
|
||||
// Unix: ~/ .Slic3r
|
||||
// Windows : "C:\Users\username\AppData\Roaming\Slic3r" or "C:\Documents and Settings\username\Application Data\Slic3r"
|
||||
// Mac : "~/Library/Application Support/Slic3r"
|
||||
if (data_dir().empty())
|
||||
set_data_dir(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data());
|
||||
|
||||
app_config = new AppConfig();
|
||||
|
||||
// load settings
|
||||
app_conf_exists = app_config->exists();
|
||||
if (app_conf_exists) {
|
||||
app_config->load();
|
||||
}
|
||||
|
||||
|
||||
std::string msg = Http::tls_global_init();
|
||||
wxRichMessageDialog
|
||||
dlg(nullptr,
|
||||
wxString::Format(_(L("%s\nDo you want to continue?")), _(msg)),
|
||||
"PrusaSlicer", wxICON_QUESTION | wxYES_NO);
|
||||
|
||||
bool ssl_accept = app_config->get("tls_cert_store_accepted") == "yes";
|
||||
std::string ssl_cert_store = app_config->get("tls_accepted_cert_store_location");
|
||||
ssl_accept = ssl_accept && ssl_cert_store == Http::tls_system_cert_store();
|
||||
bool ssl_accept = app_config->get("tls_cert_store_accepted") == "yes" && ssl_cert_store == Http::tls_system_cert_store();
|
||||
|
||||
dlg.ShowCheckBox(_(L("Remember my choice")));
|
||||
if (!msg.empty() && !ssl_accept) {
|
||||
wxRichMessageDialog
|
||||
dlg(nullptr,
|
||||
wxString::Format(_(L("%s\nDo you want to continue?")), msg),
|
||||
"PrusaSlicer", wxICON_QUESTION | wxYES_NO);
|
||||
dlg.ShowCheckBox(_(L("Remember my choice")));
|
||||
if (dlg.ShowModal() != wxID_YES) return false;
|
||||
|
||||
app_config->set("tls_cert_store_accepted",
|
||||
|
@ -395,6 +413,8 @@ bool GUI_App::on_init_inner()
|
|||
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
|
||||
wxImage::AddHandler(new wxPNGHandler());
|
||||
mainframe = new MainFrame();
|
||||
mainframe->switch_to(true); // hide settings tabs after first Layout
|
||||
|
||||
sidebar().obj_list()->init_objects(); // propagate model objects to object list
|
||||
// update_mode(); // !!! do that later
|
||||
SetTopWindow(mainframe);
|
||||
|
@ -407,6 +427,8 @@ bool GUI_App::on_init_inner()
|
|||
if (! plater_)
|
||||
return;
|
||||
|
||||
//m_other_instance_message_handler->report();
|
||||
|
||||
if (app_config->dirty() && app_config->get("autosave") == "1")
|
||||
app_config->save();
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ class PrintHostJobQueue;
|
|||
|
||||
namespace GUI{
|
||||
class RemovableDriveManager;
|
||||
class OtherInstanceMessageHandler;
|
||||
enum FileType
|
||||
{
|
||||
FT_STL,
|
||||
|
@ -108,7 +109,7 @@ class GUI_App : public wxApp
|
|||
std::unique_ptr<ImGuiWrapper> m_imgui;
|
||||
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
||||
ConfigWizard* m_wizard; // Managed by wxWindow tree
|
||||
|
||||
std::unique_ptr <OtherInstanceMessageHandler> m_other_instance_message_handler;
|
||||
public:
|
||||
bool OnInit() override;
|
||||
bool initialized() const { return m_initialized; }
|
||||
|
@ -196,6 +197,7 @@ public:
|
|||
std::vector<Tab *> tabs_list;
|
||||
|
||||
RemovableDriveManager* removable_drive_manager() { return m_removable_drive_manager.get(); }
|
||||
OtherInstanceMessageHandler* other_instance_message_handler() { return m_other_instance_message_handler.get(); }
|
||||
|
||||
ImGuiWrapper* imgui() { return m_imgui.get(); }
|
||||
|
||||
|
@ -211,6 +213,7 @@ public:
|
|||
|
||||
private:
|
||||
bool on_init_inner();
|
||||
void init_app_config();
|
||||
void window_pos_save(wxTopLevelWindow* window, const std::string &name);
|
||||
void window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false);
|
||||
void window_pos_sanitize(wxTopLevelWindow* window);
|
||||
|
|
|
@ -97,6 +97,7 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_
|
|||
m_canvas->enable_selection(true);
|
||||
m_canvas->enable_main_toolbar(true);
|
||||
m_canvas->enable_undoredo_toolbar(true);
|
||||
m_canvas->enable_collapse_toolbar(true);
|
||||
m_canvas->enable_labels(true);
|
||||
#if ENABLE_SLOPE_RENDERING
|
||||
m_canvas->enable_slope(true);
|
||||
|
@ -270,6 +271,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view
|
|||
m_canvas->set_process(m_process);
|
||||
m_canvas->enable_legend_texture(true);
|
||||
m_canvas->enable_dynamic_background(true);
|
||||
m_canvas->enable_collapse_toolbar(true);
|
||||
|
||||
m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
create_double_slider();
|
||||
|
|
|
@ -15,12 +15,17 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#endif
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "Search.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
@ -374,7 +379,40 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>&
|
|||
return res;
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool , int , const char**), int& hovered, int& selected)
|
||||
// Scroll up for one item
|
||||
static void scroll_up()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
float item_size_y = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y;
|
||||
float win_top = window->Scroll.y;
|
||||
|
||||
ImGui::SetScrollY(win_top - item_size_y);
|
||||
}
|
||||
|
||||
// Scroll down for one item
|
||||
static void scroll_down()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
float item_size_y = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y;
|
||||
float win_top = window->Scroll.y;
|
||||
|
||||
ImGui::SetScrollY(win_top + item_size_y);
|
||||
}
|
||||
|
||||
static void process_mouse_wheel(int& mouse_wheel)
|
||||
{
|
||||
if (mouse_wheel > 0)
|
||||
scroll_up();
|
||||
else if (mouse_wheel < 0)
|
||||
scroll_down();
|
||||
mouse_wheel = 0;
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool , int , const char**), int& hovered, int& selected, int& mouse_wheel)
|
||||
{
|
||||
bool is_hovered = false;
|
||||
ImGui::ListBoxHeader("", size);
|
||||
|
@ -396,10 +434,312 @@ bool ImGuiWrapper::undo_redo_list(const ImVec2& size, const bool is_undo, bool (
|
|||
i++;
|
||||
}
|
||||
|
||||
if (is_hovered)
|
||||
process_mouse_wheel(mouse_wheel);
|
||||
|
||||
ImGui::ListBoxFooter();
|
||||
return is_hovered;
|
||||
}
|
||||
|
||||
// It's a copy of IMGui::Selactable function.
|
||||
// But a little beat modified to change a label text.
|
||||
// If item is hovered we should use another color for highlighted letters.
|
||||
// To do that we push a ColorMarkerHovered symbol at the very beginning of the label
|
||||
// This symbol will be used to a color selection for the highlighted letters.
|
||||
// see imgui_draw.cpp, void ImFont::RenderText()
|
||||
static bool selectable(const char* label, bool selected, ImGuiSelectableFlags flags = 0, const ImVec2& size_arg = ImVec2(0, 0))
|
||||
{
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped.
|
||||
ImGui::PushColumnsBackground();
|
||||
|
||||
ImGuiID id = window->GetID(label);
|
||||
ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
||||
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
pos.y += window->DC.CurrLineTextBaseOffset;
|
||||
ImRect bb_inner(pos, pos + size);
|
||||
ImGui::ItemSize(size, 0.0f);
|
||||
|
||||
// Fill horizontal space.
|
||||
ImVec2 window_padding = window->WindowPadding;
|
||||
float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? ImGui::GetWindowContentRegionMax().x : ImGui::GetContentRegionMax().x;
|
||||
float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - pos.x);
|
||||
ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y);
|
||||
ImRect bb(pos, pos + size_draw);
|
||||
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth))
|
||||
bb.Max.x += window_padding.x;
|
||||
|
||||
// Selectables are tightly packed together so we extend the box to cover spacing between selectable.
|
||||
const float spacing_x = style.ItemSpacing.x;
|
||||
const float spacing_y = style.ItemSpacing.y;
|
||||
const float spacing_L = IM_FLOOR(spacing_x * 0.50f);
|
||||
const float spacing_U = IM_FLOOR(spacing_y * 0.50f);
|
||||
bb.Min.x -= spacing_L;
|
||||
bb.Min.y -= spacing_U;
|
||||
bb.Max.x += (spacing_x - spacing_L);
|
||||
bb.Max.y += (spacing_y - spacing_U);
|
||||
|
||||
bool item_add;
|
||||
if (flags & ImGuiSelectableFlags_Disabled)
|
||||
{
|
||||
ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
|
||||
window->DC.ItemFlags |= ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNavDefaultFocus;
|
||||
item_add = ImGui::ItemAdd(bb, id);
|
||||
window->DC.ItemFlags = backup_item_flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
item_add = ImGui::ItemAdd(bb, id);
|
||||
}
|
||||
if (!item_add)
|
||||
{
|
||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns)
|
||||
ImGui::PopColumnsBackground();
|
||||
return false;
|
||||
}
|
||||
|
||||
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
|
||||
ImGuiButtonFlags button_flags = 0;
|
||||
if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; }
|
||||
if (flags & ImGuiSelectableFlags_PressedOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; }
|
||||
if (flags & ImGuiSelectableFlags_PressedOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; }
|
||||
if (flags & ImGuiSelectableFlags_Disabled) { button_flags |= ImGuiButtonFlags_Disabled; }
|
||||
if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; }
|
||||
if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; }
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled)
|
||||
selected = false;
|
||||
|
||||
const bool was_selected = selected;
|
||||
bool hovered, held;
|
||||
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
|
||||
// Update NavId when clicking or when Hovering (this doesn't happen on most widgets), so navigation can be resumed with gamepad/keyboard
|
||||
if (pressed || (hovered && (flags & ImGuiSelectableFlags_SetNavIdOnHover)))
|
||||
{
|
||||
if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
|
||||
{
|
||||
g.NavDisableHighlight = true;
|
||||
ImGui::SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent);
|
||||
}
|
||||
}
|
||||
if (pressed)
|
||||
ImGui::MarkItemEdited(id);
|
||||
|
||||
if (flags & ImGuiSelectableFlags_AllowItemOverlap)
|
||||
ImGui::SetItemAllowOverlap();
|
||||
|
||||
// In this branch, Selectable() cannot toggle the selection so this will never trigger.
|
||||
if (selected != was_selected) //-V547
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
|
||||
// Render
|
||||
if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld))
|
||||
hovered = true;
|
||||
if (hovered || selected)
|
||||
{
|
||||
const ImU32 col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
ImGui::RenderFrame(bb.Min, bb.Max, col, false, 0.0f);
|
||||
ImGui::RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
||||
}
|
||||
|
||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns)
|
||||
{
|
||||
ImGui::PopColumnsBackground();
|
||||
bb.Max.x -= (ImGui::GetContentRegionMax().x - max_x);
|
||||
}
|
||||
|
||||
// mark a label with a ImGui::ColorMarkerHovered, if item is hovered
|
||||
char* marked_label = new char[255];
|
||||
if (hovered)
|
||||
sprintf(marked_label, "%c%s", ImGui::ColorMarkerHovered, label);
|
||||
else
|
||||
strcpy(marked_label, label);
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
ImGui::RenderTextClipped(bb_inner.Min, bb_inner.Max, marked_label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor();
|
||||
|
||||
delete[] marked_label;
|
||||
|
||||
// Automatically close popups
|
||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) ImGui::CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
// Scroll so that the hovered item is at the top of the window
|
||||
static void scroll_y(int hover_id)
|
||||
{
|
||||
if (hover_id < 0)
|
||||
return;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
float item_size_y = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y;
|
||||
float item_delta = 0.5 * item_size_y;
|
||||
|
||||
float item_top = item_size_y * hover_id;
|
||||
float item_bottom = item_top + item_size_y;
|
||||
|
||||
float win_top = window->Scroll.y;
|
||||
float win_bottom = window->Scroll.y + window->Size.y;
|
||||
|
||||
if (item_bottom + item_delta >= win_bottom)
|
||||
ImGui::SetScrollY(win_top + item_size_y);
|
||||
else if (item_top - item_delta <= win_top)
|
||||
ImGui::SetScrollY(win_top - item_size_y);
|
||||
}
|
||||
|
||||
// Use this function instead of ImGui::IsKeyPressed.
|
||||
// ImGui::IsKeyPressed is related for *GImGui.IO.KeysDownDuration[user_key_index]
|
||||
// And after first key pressing IsKeyPressed() return "true" always even if key wasn't pressed
|
||||
static void process_key_down(ImGuiKey imgui_key, std::function<void()> f)
|
||||
{
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(imgui_key)))
|
||||
{
|
||||
f();
|
||||
// set KeysDown to false to avoid redundant key down processing
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.IO.KeysDown[ImGui::GetKeyIndex(imgui_key)] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str,
|
||||
Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel)
|
||||
{
|
||||
// ImGui::ListBoxHeader("", size);
|
||||
{
|
||||
// rewrote part of function to add a TextInput instead of label Text
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return ;
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
||||
ImVec2 size = ImGui::CalcItemSize(size_, ImGui::CalcItemWidth(), ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
|
||||
ImRect frame_bb(window->DC.CursorPos, ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y + size.y));
|
||||
|
||||
ImRect bb(frame_bb.Min, frame_bb.Max);
|
||||
window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy.
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
if (!ImGui::IsRectVisible(bb.Min, bb.Max))
|
||||
{
|
||||
ImGui::ItemSize(bb.GetSize(), style.FramePadding.y);
|
||||
ImGui::ItemAdd(bb, 0, &frame_bb);
|
||||
return ;
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
const ImGuiID id = ImGui::GetID(search_str);
|
||||
ImVec2 search_size = ImVec2(size.x, ImGui::GetTextLineHeightWithSpacing() + style.ItemSpacing.y);
|
||||
|
||||
if (!ImGui::IsAnyItemFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))
|
||||
ImGui::SetKeyboardFocusHere(0);
|
||||
|
||||
// The press on Esc key invokes editing of InputText (removes last changes)
|
||||
// So we should save previous value...
|
||||
std::string str = search_str;
|
||||
ImGui::InputTextEx("", NULL, search_str, 20, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL);
|
||||
edited = ImGui::IsItemEdited();
|
||||
if (edited)
|
||||
view_params.hovered_id = -1;
|
||||
|
||||
process_key_down(ImGuiKey_Escape, [&selected, search_str, str]() {
|
||||
// use 9999 to mark selection as a Esc key
|
||||
selected = 9999;
|
||||
// ... and when Esc key was pressed, than revert search_str value
|
||||
strcpy(search_str, str.c_str());
|
||||
});
|
||||
|
||||
ImGui::BeginChildFrame(id, frame_bb.GetSize());
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
const char* item_text;
|
||||
const char* tooltip;
|
||||
int mouse_hovered = -1;
|
||||
int& hovered_id = view_params.hovered_id;
|
||||
|
||||
while (items_getter(i, &item_text, &tooltip))
|
||||
{
|
||||
selectable(item_text, i == hovered_id);
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", /*item_text*/tooltip);
|
||||
view_params.hovered_id = -1;
|
||||
mouse_hovered = i;
|
||||
}
|
||||
|
||||
if (ImGui::IsItemClicked())
|
||||
selected = i;
|
||||
i++;
|
||||
}
|
||||
|
||||
scroll_y(mouse_hovered);
|
||||
|
||||
// Process mouse wheel
|
||||
if (mouse_hovered > 0)
|
||||
process_mouse_wheel(mouse_wheel);
|
||||
|
||||
// process Up/DownArrows and Enter
|
||||
process_key_down(ImGuiKey_UpArrow, [&hovered_id, mouse_hovered]() {
|
||||
if (mouse_hovered > 0)
|
||||
scroll_up();
|
||||
else {
|
||||
if (hovered_id > 0 && hovered_id != size_t(-1))
|
||||
--hovered_id;
|
||||
scroll_y(hovered_id);
|
||||
}
|
||||
});
|
||||
|
||||
process_key_down(ImGuiKey_DownArrow, [&hovered_id, mouse_hovered, i]() {
|
||||
if (mouse_hovered > 0)
|
||||
scroll_down();
|
||||
else {
|
||||
if (hovered_id == size_t(-1))
|
||||
hovered_id = 0;
|
||||
else if (hovered_id < size_t(i - 1))
|
||||
++hovered_id;
|
||||
scroll_y(hovered_id);
|
||||
}
|
||||
});
|
||||
|
||||
process_key_down(ImGuiKey_Enter, [&selected, hovered_id]() {
|
||||
selected = hovered_id;
|
||||
});
|
||||
|
||||
ImGui::ListBoxFooter();
|
||||
|
||||
auto check_box = [&edited, this](const wxString& label, bool& check) {
|
||||
ImGui::SameLine();
|
||||
bool ch = check;
|
||||
checkbox(label, ch);
|
||||
if (ImGui::IsItemClicked()) {
|
||||
check = !check;
|
||||
edited = true;
|
||||
}
|
||||
};
|
||||
|
||||
// add checkboxes for show/hide Categories and Groups
|
||||
text(_L("Use for search")+":");
|
||||
check_box(_L("Type"), view_params.type);
|
||||
check_box(_L("Category"), view_params.category);
|
||||
check_box(_L("Group"), view_params.group);
|
||||
}
|
||||
|
||||
void ImGuiWrapper::disabled_begin(bool disabled)
|
||||
{
|
||||
wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call");
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
|
||||
#include "libslic3r/Point.hpp"
|
||||
|
||||
namespace Slic3r {namespace Search {
|
||||
struct OptionViewParameters;
|
||||
}}
|
||||
|
||||
class wxString;
|
||||
class wxMouseEvent;
|
||||
class wxKeyEvent;
|
||||
|
@ -73,7 +77,9 @@ public:
|
|||
bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||
bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||
bool combo(const wxString& label, const std::vector<std::string>& options, int& selection); // Use -1 to not mark any option as selected
|
||||
bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected);
|
||||
bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel);
|
||||
void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str,
|
||||
Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel);
|
||||
|
||||
void disabled_begin(bool disabled);
|
||||
void disabled_end();
|
||||
|
|
495
src/slic3r/GUI/InstanceCheck.cpp
Normal file
495
src/slic3r/GUI/InstanceCheck.cpp
Normal file
|
@ -0,0 +1,495 @@
|
|||
#include "GUI_App.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
|
||||
#include "boost/nowide/convert.hpp"
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if __linux__
|
||||
#include <dbus/dbus.h> /* Pull in all of D-Bus headers. */
|
||||
#endif //__linux__
|
||||
|
||||
namespace Slic3r {
|
||||
namespace instance_check_internal
|
||||
{
|
||||
struct CommandLineAnalysis
|
||||
{
|
||||
bool should_send;
|
||||
std::string cl_string;
|
||||
};
|
||||
static CommandLineAnalysis process_command_line(int argc, char** argv) //d:\3dmodels\Klapka\Klapka.3mf
|
||||
{
|
||||
CommandLineAnalysis ret { false };
|
||||
if (argc < 2)
|
||||
return ret;
|
||||
ret.cl_string = argv[0];
|
||||
for (size_t i = 1; i < argc; i++) {
|
||||
std::string token = argv[i];
|
||||
if (token == "--single-instance") {
|
||||
ret.should_send = true;
|
||||
} else {
|
||||
ret.cl_string += " ";
|
||||
ret.cl_string += token;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << "single instance: "<< ret.should_send << ". other params: " << ret.cl_string;
|
||||
return ret;
|
||||
}
|
||||
} //namespace instance_check_internal
|
||||
|
||||
#if _WIN32
|
||||
|
||||
namespace instance_check_internal
|
||||
{
|
||||
static HWND l_prusa_slicer_hwnd;
|
||||
static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM lParam)
|
||||
{
|
||||
//checks for other instances of prusaslicer, if found brings it to front and return false to stop enumeration and quit this instance
|
||||
//search is done by classname(wxWindowNR is wxwidgets thing, so probably not unique) and name in window upper panel
|
||||
//other option would be do a mutex and check for its existence
|
||||
TCHAR wndText[1000];
|
||||
TCHAR className[1000];
|
||||
GetClassName(hwnd, className, 1000);
|
||||
GetWindowText(hwnd, wndText, 1000);
|
||||
std::wstring classNameString(className);
|
||||
std::wstring wndTextString(wndText);
|
||||
if (wndTextString.find(L"PrusaSlicer") != std::wstring::npos && classNameString == L"wxWindowNR") {
|
||||
l_prusa_slicer_hwnd = hwnd;
|
||||
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
|
||||
SetForegroundWindow(hwnd);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static void send_message(const HWND hwnd)
|
||||
{
|
||||
LPWSTR command_line_args = GetCommandLine();
|
||||
//Create a COPYDATASTRUCT to send the information
|
||||
//cbData represents the size of the information we want to send.
|
||||
//lpData represents the information we want to send.
|
||||
//dwData is an ID defined by us(this is a type of ID different than WM_COPYDATA).
|
||||
COPYDATASTRUCT data_to_send = { 0 };
|
||||
data_to_send.dwData = 1;
|
||||
data_to_send.cbData = sizeof(TCHAR) * (wcslen(command_line_args) + 1);
|
||||
data_to_send.lpData = command_line_args;
|
||||
|
||||
SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&data_to_send);
|
||||
}
|
||||
} //namespace instance_check_internal
|
||||
|
||||
bool instance_check(int argc, char** argv, bool app_config_single_instance)
|
||||
{
|
||||
instance_check_internal::CommandLineAnalysis cla = instance_check_internal::process_command_line(argc, argv);
|
||||
if (cla.should_send || app_config_single_instance) {
|
||||
// Call EnumWidnows with own callback. cons: Based on text in the name of the window and class name which is generic.
|
||||
if (!EnumWindows(instance_check_internal::EnumWindowsProc, 0)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "instance check: Another instance found. This instance will terminate.";
|
||||
instance_check_internal::send_message(instance_check_internal::l_prusa_slicer_hwnd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "instance check: Another instance not found or single-instance not set.";
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
namespace instance_check_internal
|
||||
{
|
||||
static int get_lock()
|
||||
{
|
||||
struct flock fl;
|
||||
int fdlock;
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 1;
|
||||
|
||||
if ((fdlock = open("/tmp/prusaslicer.lock", O_WRONLY | O_CREAT, 0666)) == -1)
|
||||
return 0;
|
||||
|
||||
if (fcntl(fdlock, F_SETLK, &fl) == -1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
} //namespace instance_check_internal
|
||||
|
||||
bool instance_check(int argc, char** argv, bool app_config_single_instance)
|
||||
{
|
||||
instance_check_internal::CommandLineAnalysis cla = instance_check_internal::process_command_line(argc, argv);
|
||||
if (!instance_check_internal::get_lock() && (cla.should_send || app_config_single_instance)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "instance check: Another instance found. This instance will terminate.";
|
||||
send_message_mac(cla.cl_string);
|
||||
return true;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "instance check: Another instance not found or single-instance not set.";
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
namespace instance_check_internal
|
||||
{
|
||||
static int get_lock()
|
||||
{
|
||||
struct flock fl;
|
||||
int fdlock;
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 1;
|
||||
|
||||
if ((fdlock = open("/tmp/prusaslicer.lock", O_WRONLY | O_CREAT, 0666)) == -1)
|
||||
return 0;
|
||||
|
||||
if (fcntl(fdlock, F_SETLK, &fl) == -1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void send_message(std::string message_text)
|
||||
{
|
||||
DBusMessage* msg;
|
||||
DBusMessageIter args;
|
||||
DBusConnection* conn;
|
||||
DBusError err;
|
||||
dbus_uint32_t serial = 0;
|
||||
const char* sigval = message_text.c_str();
|
||||
std::string interface_name = "com.prusa3d.prusaslicer.InstanceCheck";
|
||||
std::string method_name = "AnotherInstace";
|
||||
std::string object_name = "/com/prusa3d/prusaslicer/InstanceCheck";
|
||||
|
||||
|
||||
// initialise the error value
|
||||
dbus_error_init(&err);
|
||||
|
||||
// connect to bus, and check for errors (use SESSION bus everywhere!)
|
||||
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Connection Error. Message to another instance wont be send.";
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Connection Error: "<< err.message;
|
||||
dbus_error_free(&err);
|
||||
return;
|
||||
}
|
||||
if (NULL == conn) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Connection is NULL. Message to another instance wont be send.";
|
||||
return;
|
||||
}
|
||||
|
||||
//some sources do request interface ownership before constructing msg but i think its wrong.
|
||||
|
||||
//create new method call message
|
||||
msg = dbus_message_new_method_call(interface_name.c_str(), object_name.c_str(), interface_name.c_str(), method_name.c_str());
|
||||
if (NULL == msg) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Message is NULL. Message to another instance wont be send.";
|
||||
dbus_connection_unref(conn);
|
||||
return;
|
||||
}
|
||||
//the AnotherInstace method is not sending reply.
|
||||
dbus_message_set_no_reply(msg, TRUE);
|
||||
|
||||
//append arguments to message
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &sigval, DBUS_TYPE_INVALID)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Ran out of memory while constructing args for DBus message. Message to another instance wont be send.";
|
||||
dbus_message_unref(msg);
|
||||
dbus_connection_unref(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
// send the message and flush the connection
|
||||
if (!dbus_connection_send(conn, msg, &serial)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Ran out of memory while sending DBus message.";
|
||||
dbus_message_unref(msg);
|
||||
dbus_connection_unref(conn);
|
||||
return;
|
||||
}
|
||||
dbus_connection_flush(conn);
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "DBus message sent.";
|
||||
|
||||
// free the message and close the connection
|
||||
dbus_message_unref(msg);
|
||||
dbus_connection_unref(conn);
|
||||
}
|
||||
} //namespace instance_check_internal
|
||||
|
||||
bool instance_check(int argc, char** argv, bool app_config_single_instance)
|
||||
{
|
||||
instance_check_internal::CommandLineAnalysis cla = instance_check_internal::process_command_line(argc, argv);
|
||||
if (!instance_check_internal::get_lock() && (cla.should_send || app_config_single_instance)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "instance check: Another instance found. This instance will terminate.";
|
||||
instance_check_internal::send_message(cla.cl_string);
|
||||
return true;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "instance check: Another instance not found or single-instance not set.";
|
||||
return false;
|
||||
}
|
||||
#endif //_WIN32/__APPLE__/__linux__
|
||||
|
||||
|
||||
|
||||
namespace GUI {
|
||||
|
||||
wxDEFINE_EVENT(EVT_LOAD_MODEL_OTHER_INSTANCE, LoadFromOtherInstanceEvent);
|
||||
wxDEFINE_EVENT(EVT_INSTANCE_GO_TO_FRONT, InstanceGoToFrontEvent);
|
||||
|
||||
void OtherInstanceMessageHandler::init(wxEvtHandler* callback_evt_handler)
|
||||
{
|
||||
assert(!m_initialized);
|
||||
assert(m_callback_evt_handler == nullptr);
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
m_initialized = true;
|
||||
m_callback_evt_handler = callback_evt_handler;
|
||||
|
||||
#if _WIN32
|
||||
//create_listener_window();
|
||||
#endif //_WIN32
|
||||
|
||||
#if defined(__APPLE__)
|
||||
this->register_for_messages();
|
||||
#endif //__APPLE__
|
||||
|
||||
#ifdef BACKGROUND_MESSAGE_LISTENER
|
||||
m_thread = boost::thread((boost::bind(&OtherInstanceMessageHandler::listen, this)));
|
||||
#endif //BACKGROUND_MESSAGE_LISTENER
|
||||
}
|
||||
void OtherInstanceMessageHandler::shutdown()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "message handler shutdown().";
|
||||
assert(m_initialized);
|
||||
if (m_initialized) {
|
||||
#if __APPLE__
|
||||
//delete macos implementation
|
||||
this->unregister_for_messages();
|
||||
#endif //__APPLE__
|
||||
#ifdef BACKGROUND_MESSAGE_LISTENER
|
||||
if (m_thread.joinable()) {
|
||||
// Stop the worker thread, if running.
|
||||
{
|
||||
// Notify the worker thread to cancel wait on detection polling.
|
||||
std::lock_guard<std::mutex> lck(m_thread_stop_mutex);
|
||||
m_stop = true;
|
||||
}
|
||||
m_thread_stop_condition.notify_all();
|
||||
// Wait for the worker thread to stop.
|
||||
m_thread.join();
|
||||
m_stop = false;
|
||||
}
|
||||
#endif //BACKGROUND_MESSAGE_LISTENER
|
||||
m_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MessageHandlerInternal
|
||||
{
|
||||
// returns ::path to possible model or empty ::path if input string is not existing path
|
||||
static boost::filesystem::path get_path(const std::string possible_path)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "message part: " << possible_path;
|
||||
|
||||
if (possible_path.empty() || possible_path.size() < 3) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "empty";
|
||||
return boost::filesystem::path();
|
||||
}
|
||||
if (boost::filesystem::exists(possible_path)) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "is path";
|
||||
return boost::filesystem::path(possible_path);
|
||||
} else if (possible_path[0] == '\"') {
|
||||
if(boost::filesystem::exists(possible_path.substr(1, possible_path.size() - 2))) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "is path in quotes";
|
||||
return boost::filesystem::path(possible_path.substr(1, possible_path.size() - 2));
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << "is NOT path";
|
||||
return boost::filesystem::path();
|
||||
}
|
||||
} //namespace MessageHandlerInternal
|
||||
|
||||
void OtherInstanceMessageHandler::handle_message(const std::string message) {
|
||||
std::vector<boost::filesystem::path> paths;
|
||||
auto next_space = message.find(' ');
|
||||
size_t last_space = 0;
|
||||
int counter = 0;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "message from other instance: " << message;
|
||||
|
||||
while (next_space != std::string::npos)
|
||||
{
|
||||
if (counter != 0) {
|
||||
const std::string possible_path = message.substr(last_space, next_space - last_space);
|
||||
boost::filesystem::path p = MessageHandlerInternal::get_path(possible_path);
|
||||
if(!p.string().empty())
|
||||
paths.emplace_back(p);
|
||||
}
|
||||
last_space = next_space;
|
||||
next_space = message.find(' ', last_space + 1);
|
||||
counter++;
|
||||
}
|
||||
if (counter != 0 ) {
|
||||
boost::filesystem::path p = MessageHandlerInternal::get_path(message.substr(last_space + 1));
|
||||
if (!p.string().empty())
|
||||
paths.emplace_back(p);
|
||||
}
|
||||
if (!paths.empty()) {
|
||||
//wxEvtHandler* evt_handler = wxGetApp().plater(); //assert here?
|
||||
//if (evt_handler) {
|
||||
wxPostEvent(m_callback_evt_handler, LoadFromOtherInstanceEvent(GUI::EVT_LOAD_MODEL_OTHER_INSTANCE, std::vector<boost::filesystem::path>(std::move(paths))));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BACKGROUND_MESSAGE_LISTENER
|
||||
|
||||
namespace MessageHandlerDBusInternal
|
||||
{
|
||||
//reply to introspect makes our DBus object visible for other programs like D-Feet
|
||||
static void respond_to_introspect(DBusConnection *connection, DBusMessage *request)
|
||||
{
|
||||
DBusMessage *reply;
|
||||
const char *introspection_data =
|
||||
" <!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">"
|
||||
" <!-- dbus-sharp 0.8.1 -->"
|
||||
" <node>"
|
||||
" <interface name=\"org.freedesktop.DBus.Introspectable\">"
|
||||
" <method name=\"Introspect\">"
|
||||
" <arg name=\"data\" direction=\"out\" type=\"s\" />"
|
||||
" </method>"
|
||||
" </interface>"
|
||||
" <interface name=\"com.prusa3d.prusaslicer.InstanceCheck\">"
|
||||
" <method name=\"AnotherInstace\">"
|
||||
" <arg name=\"data\" direction=\"in\" type=\"s\" />"
|
||||
" </method>"
|
||||
" </interface>"
|
||||
" </node>";
|
||||
|
||||
reply = dbus_message_new_method_return(request);
|
||||
dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_data, DBUS_TYPE_INVALID);
|
||||
dbus_connection_send(connection, reply, NULL);
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
//method AnotherInstance receives message from another PrusaSlicer instance
|
||||
static void handle_method_another_instance(DBusConnection *connection, DBusMessage *request)
|
||||
{
|
||||
DBusError err;
|
||||
char* text= "";
|
||||
wxEvtHandler* evt_handler;
|
||||
|
||||
dbus_error_init(&err);
|
||||
dbus_message_get_args(request, &err, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Dbus method AnotherInstance received with wrong arguments.";
|
||||
dbus_error_free(&err);
|
||||
return;
|
||||
}
|
||||
wxGetApp().other_instance_message_handler()->handle_message(text);
|
||||
|
||||
evt_handler = wxGetApp().plater();
|
||||
if (evt_handler) {
|
||||
wxPostEvent(evt_handler, InstanceGoToFrontEvent(EVT_INSTANCE_GO_TO_FRONT));
|
||||
}
|
||||
}
|
||||
//every dbus message received comes here
|
||||
static DBusHandlerResult handle_dbus_object_message(DBusConnection *connection, DBusMessage *message, void *user_data)
|
||||
{
|
||||
const char* interface_name = dbus_message_get_interface(message);
|
||||
const char* member_name = dbus_message_get_member(message);
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "DBus message received: interface: " << interface_name << ", member: " << member_name;
|
||||
|
||||
if (0 == strcmp("org.freedesktop.DBus.Introspectable", interface_name) && 0 == strcmp("Introspect", member_name)) {
|
||||
respond_to_introspect(connection, message);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
} else if (0 == strcmp("com.prusa3d.prusaslicer.InstanceCheck", interface_name) && 0 == strcmp("AnotherInstace", member_name)) {
|
||||
handle_method_another_instance(connection, message);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
} //namespace MessageHandlerDBusInternal
|
||||
|
||||
void OtherInstanceMessageHandler::listen()
|
||||
{
|
||||
DBusConnection* conn;
|
||||
DBusError err;
|
||||
int name_req_val;
|
||||
DBusObjectPathVTable vtable;
|
||||
std::string interface_name = "com.prusa3d.prusaslicer.InstanceCheck";
|
||||
std::string object_name = "/com/prusa3d/prusaslicer/InstanceCheck";
|
||||
|
||||
dbus_error_init(&err);
|
||||
|
||||
// connect to the bus and check for errors (use SESSION bus everywhere!)
|
||||
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Connection Error: "<< err.message;
|
||||
BOOST_LOG_TRIVIAL(error) << "Dbus Messages listening terminating.";
|
||||
dbus_error_free(&err);
|
||||
return;
|
||||
}
|
||||
if (NULL == conn) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Connection is NULL. Dbus Messages listening terminating.";
|
||||
return;
|
||||
}
|
||||
|
||||
// request our name on the bus and check for errors
|
||||
name_req_val = dbus_bus_request_name(conn, interface_name.c_str(), DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Request name Error: "<< err.message;
|
||||
BOOST_LOG_TRIVIAL(error) << "Dbus Messages listening terminating.";
|
||||
dbus_error_free(&err);
|
||||
dbus_connection_unref(conn);
|
||||
return;
|
||||
}
|
||||
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != name_req_val) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Not primary owner of DBus name - probably another PrusaSlicer instance is running.";
|
||||
BOOST_LOG_TRIVIAL(error) << "Dbus Messages listening terminating.";
|
||||
dbus_connection_unref(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set callbacks. Unregister function should not be nessary.
|
||||
vtable.message_function = MessageHandlerDBusInternal::handle_dbus_object_message;
|
||||
vtable.unregister_function = NULL;
|
||||
|
||||
// register new object - this is our access to DBus
|
||||
dbus_connection_try_register_object_path(conn, object_name.c_str(), &vtable, NULL, &err);
|
||||
if ( dbus_error_is_set(&err) ) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DBus Register object Error: "<< err.message;
|
||||
BOOST_LOG_TRIVIAL(error) << "Dbus Messages listening terminating.";
|
||||
dbus_connection_unref(conn);
|
||||
dbus_error_free(&err);
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "Dbus object registered. Starting listening for messages.";
|
||||
|
||||
for (;;) {
|
||||
// Wait for 1 second
|
||||
// Cancellable.
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(m_thread_stop_mutex);
|
||||
m_thread_stop_condition.wait_for(lck, std::chrono::seconds(1), [this] { return m_stop; });
|
||||
}
|
||||
if (m_stop)
|
||||
// Stop the worker thread.
|
||||
|
||||
break;
|
||||
//dispatch should do all the work with incoming messages
|
||||
//second parameter is blocking time that funciton waits for new messages
|
||||
//that is handled here with our own event loop above
|
||||
dbus_connection_read_write_dispatch(conn, 0);
|
||||
}
|
||||
|
||||
dbus_connection_unref(conn);
|
||||
}
|
||||
#endif //BACKGROUND_MESSAGE_LISTENER
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
91
src/slic3r/GUI/InstanceCheck.hpp
Normal file
91
src/slic3r/GUI/InstanceCheck.hpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#ifndef slic3r_InstanceCheck_hpp_
|
||||
#define slic3r_InstanceCheck_hpp_
|
||||
|
||||
#include "Event.hpp"
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif //_WIN32
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <tbb/mutex.h>
|
||||
#include <condition_variable>
|
||||
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
// checks for other running instances and sends them argv,
|
||||
// if there is --single-instance argument or AppConfig is set to single_instance=1
|
||||
// returns true if this instance should terminate
|
||||
bool instance_check(int argc, char** argv, bool app_config_single_instance);
|
||||
|
||||
#if __APPLE__
|
||||
// apple implementation of inner functions of instance_check
|
||||
// in InstanceCheckMac.mm
|
||||
void send_message_mac(const std::string msg);
|
||||
#endif //__APPLE__
|
||||
|
||||
namespace GUI {
|
||||
|
||||
#if __linux__
|
||||
#define BACKGROUND_MESSAGE_LISTENER
|
||||
#endif // __linux__
|
||||
|
||||
using LoadFromOtherInstanceEvent = Event<std::vector<boost::filesystem::path>>;
|
||||
wxDECLARE_EVENT(EVT_LOAD_MODEL_OTHER_INSTANCE, LoadFromOtherInstanceEvent);
|
||||
|
||||
using InstanceGoToFrontEvent = SimpleEvent;
|
||||
wxDECLARE_EVENT(EVT_INSTANCE_GO_TO_FRONT, InstanceGoToFrontEvent);
|
||||
|
||||
class OtherInstanceMessageHandler
|
||||
{
|
||||
public:
|
||||
OtherInstanceMessageHandler() = default;
|
||||
OtherInstanceMessageHandler(OtherInstanceMessageHandler const&) = delete;
|
||||
void operator=(OtherInstanceMessageHandler const&) = delete;
|
||||
~OtherInstanceMessageHandler() { assert(!m_initialized); }
|
||||
|
||||
// inits listening, on each platform different. On linux starts background thread
|
||||
void init(wxEvtHandler* callback_evt_handler);
|
||||
// stops listening, on linux stops the background thread
|
||||
void shutdown();
|
||||
|
||||
//finds paths to models in message(= command line arguments, first should be prusaSlicer executable)
|
||||
//and sends them to plater via LoadFromOtherInstanceEvent
|
||||
//security of messages: from message all existing paths are proccesed to load model
|
||||
// win32 - anybody who has hwnd can send message.
|
||||
// mac - anybody who posts notification with name:@"OtherPrusaSlicerTerminating"
|
||||
// linux - instrospectable on dbus
|
||||
void handle_message(const std::string message);
|
||||
private:
|
||||
bool m_initialized { false };
|
||||
wxEvtHandler* m_callback_evt_handler { nullptr };
|
||||
|
||||
#ifdef BACKGROUND_MESSAGE_LISTENER
|
||||
//worker thread to listen incoming dbus communication
|
||||
boost::thread m_thread;
|
||||
std::condition_variable m_thread_stop_condition;
|
||||
mutable std::mutex m_thread_stop_mutex;
|
||||
bool m_stop{ false };
|
||||
bool m_start{ true };
|
||||
|
||||
// background thread method
|
||||
void listen();
|
||||
#endif //BACKGROUND_MESSAGE_LISTENER
|
||||
|
||||
#if __APPLE__
|
||||
//implemented at InstanceCheckMac.mm
|
||||
void register_for_messages();
|
||||
void unregister_for_messages();
|
||||
// Opaque pointer to RemovableDriveManagerMM
|
||||
void* m_impl_osx;
|
||||
#endif //__APPLE__
|
||||
|
||||
};
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
#endif // slic3r_InstanceCheck_hpp_
|
8
src/slic3r/GUI/InstanceCheckMac.h
Normal file
8
src/slic3r/GUI/InstanceCheckMac.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface OtherInstanceMessageHandlerMac : NSObject
|
||||
|
||||
-(instancetype) init;
|
||||
-(void) add_observer;
|
||||
-(void) message_update:(NSNotification *)note;
|
||||
@end
|
68
src/slic3r/GUI/InstanceCheckMac.mm
Normal file
68
src/slic3r/GUI/InstanceCheckMac.mm
Normal file
|
@ -0,0 +1,68 @@
|
|||
#import "InstanceCheck.hpp"
|
||||
#import "InstanceCheckMac.h"
|
||||
#import "GUI_App.hpp"
|
||||
|
||||
@implementation OtherInstanceMessageHandlerMac
|
||||
|
||||
-(instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
return self;
|
||||
}
|
||||
-(void)add_observer
|
||||
{
|
||||
NSLog(@"adding observer");
|
||||
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(message_update:) name:@"OtherPrusaSlicerInstanceMessage" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
|
||||
}
|
||||
|
||||
-(void)message_update:(NSNotification *)msg
|
||||
{
|
||||
//NSLog(@"recieved msg %@", msg);
|
||||
//demiaturize all windows
|
||||
for(NSWindow* win in [NSApp windows])
|
||||
{
|
||||
if([win isMiniaturized])
|
||||
{
|
||||
[win deminiaturize:self];
|
||||
}
|
||||
}
|
||||
//bring window to front
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps : YES];
|
||||
//pass message
|
||||
Slic3r::GUI::wxGetApp().other_instance_message_handler()->handle_message(std::string([msg.userInfo[@"data"] UTF8String]));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void send_message_mac(const std::string msg)
|
||||
{
|
||||
NSString *nsmsg = [NSString stringWithCString:msg.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
//NSLog(@"sending msg %@", nsmsg);
|
||||
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"OtherPrusaSlicerInstanceMessage" object:nil userInfo:[NSDictionary dictionaryWithObject:nsmsg forKey:@"data"] deliverImmediately:YES];
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
void OtherInstanceMessageHandler::register_for_messages()
|
||||
{
|
||||
m_impl_osx = [[OtherInstanceMessageHandlerMac alloc] init];
|
||||
if(m_impl_osx) {
|
||||
[m_impl_osx add_observer];
|
||||
}
|
||||
}
|
||||
|
||||
void OtherInstanceMessageHandler::unregister_for_messages()
|
||||
{
|
||||
//NSLog(@"unreegistering other instance messages");
|
||||
if (m_impl_osx) {
|
||||
[m_impl_osx release];
|
||||
m_impl_osx = nullptr;
|
||||
} else {
|
||||
NSLog(@"unreegister not required");
|
||||
}
|
||||
}
|
||||
}//namespace GUI
|
||||
}//namespace Slicer
|
||||
|
||||
|
|
@ -134,6 +134,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
|||
{ ctrl + "C", L("Copy to clipboard") },
|
||||
{ ctrl + "V", L("Paste from clipboard") },
|
||||
{ "F5", L("Reload plater from disk") },
|
||||
{ ctrl + "F", L("Search") },
|
||||
// Window
|
||||
{ ctrl + "1", L("Select Plater Tab") },
|
||||
{ ctrl + "2", L("Select Print Settings Tab") },
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "GUI_ObjectList.hpp"
|
||||
#include "Mouse3DController.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
@ -89,6 +90,8 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
|||
|
||||
// initialize layout
|
||||
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||
if (m_plater)
|
||||
sizer->Add(m_plater, 1, wxEXPAND);
|
||||
if (m_tabpanel)
|
||||
sizer->Add(m_tabpanel, 1, wxEXPAND);
|
||||
sizer->SetSizeHints(this);
|
||||
|
@ -234,7 +237,8 @@ void MainFrame::shutdown()
|
|||
|
||||
// Stop the background thread of the removable drive manager, so that no new updates will be sent to the Plater.
|
||||
wxGetApp().removable_drive_manager()->shutdown();
|
||||
|
||||
//stop listening for messages from other instances
|
||||
wxGetApp().other_instance_message_handler()->shutdown();
|
||||
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
|
||||
// but in rare cases it may not have been called yet.
|
||||
wxGetApp().app_config->save();
|
||||
|
@ -304,11 +308,16 @@ void MainFrame::init_tabpanel()
|
|||
// before the MainFrame is fully set up.
|
||||
static_cast<Tab*>(panel)->OnActivate();
|
||||
}
|
||||
else
|
||||
select_tab(0);
|
||||
});
|
||||
|
||||
m_plater = new Slic3r::GUI::Plater(m_tabpanel, this);
|
||||
//! m_plater = new Slic3r::GUI::Plater(m_tabpanel, this);
|
||||
m_plater = new Plater(this, this);
|
||||
|
||||
wxGetApp().plater_ = m_plater;
|
||||
m_tabpanel->AddPage(m_plater, _(L("Plater")));
|
||||
// m_tabpanel->AddPage(m_plater, _(L("Plater")));
|
||||
m_tabpanel->AddPage(new wxPanel(m_tabpanel), _L("Plater")); // empty panel just for Plater tab
|
||||
|
||||
wxGetApp().obj_list()->create_popup_menus();
|
||||
|
||||
|
@ -334,6 +343,13 @@ void MainFrame::init_tabpanel()
|
|||
}
|
||||
}
|
||||
|
||||
void MainFrame::switch_to(bool plater)
|
||||
{
|
||||
this->m_plater->Show(plater);
|
||||
this->m_tabpanel->Show(!plater);
|
||||
this->Layout();
|
||||
}
|
||||
|
||||
void MainFrame::create_preset_tabs()
|
||||
{
|
||||
wxGetApp().update_label_colours_from_appconfig();
|
||||
|
@ -741,31 +757,37 @@ void MainFrame::init_menubar()
|
|||
append_menu_item(editMenu, wxID_ANY, _(L("Re&load from disk")) + sep + "F5",
|
||||
_(L("Reload the plater from disk")), [this](wxCommandEvent&) { m_plater->reload_all_from_disk(); },
|
||||
"", nullptr, [this]() {return !m_plater->model().objects.empty(); }, this);
|
||||
|
||||
editMenu->AppendSeparator();
|
||||
append_menu_item(editMenu, wxID_ANY, _(L("Searc&h")) + "\tCtrl+F",
|
||||
_(L("Find option")), [this](wxCommandEvent&) { m_plater->search(/*m_tabpanel->GetCurrentPage() == */m_plater->IsShown()); },
|
||||
"search", nullptr, [this]() {return true; }, this);
|
||||
}
|
||||
|
||||
// Window menu
|
||||
auto windowMenu = new wxMenu();
|
||||
{
|
||||
size_t tab_offset = 0;
|
||||
//! size_t tab_offset = 0;
|
||||
if (m_plater) {
|
||||
append_menu_item(windowMenu, wxID_HIGHEST + 1, _(L("&Plater Tab")) + "\tCtrl+1", _(L("Show the plater")),
|
||||
[this](wxCommandEvent&) { select_tab(0); }, "plater", nullptr,
|
||||
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*(size_t)(-1)*/0); }, "plater", nullptr,
|
||||
[this]() {return true; }, this);
|
||||
tab_offset += 1;
|
||||
}
|
||||
if (tab_offset > 0) {
|
||||
//! tab_offset += 1;
|
||||
//! }
|
||||
//! if (tab_offset > 0) {
|
||||
windowMenu->AppendSeparator();
|
||||
}
|
||||
append_menu_item(windowMenu, wxID_HIGHEST + 2, _(L("P&rint Settings Tab")) + "\tCtrl+2", _(L("Show the print settings")),
|
||||
[this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog", nullptr,
|
||||
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 0*/1); }, "cog", nullptr,
|
||||
[this]() {return true; }, this);
|
||||
wxMenuItem* item_material_tab = append_menu_item(windowMenu, wxID_HIGHEST + 3, _(L("&Filament Settings Tab")) + "\tCtrl+3", _(L("Show the filament settings")),
|
||||
[this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 1); }, "spool", nullptr,
|
||||
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 1*/2); }, "spool", nullptr,
|
||||
[this]() {return true; }, this);
|
||||
m_changeable_menu_items.push_back(item_material_tab);
|
||||
append_menu_item(windowMenu, wxID_HIGHEST + 4, _(L("Print&er Settings Tab")) + "\tCtrl+4", _(L("Show the printer settings")),
|
||||
[this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer", nullptr,
|
||||
wxMenuItem* item_printer_tab = append_menu_item(windowMenu, wxID_HIGHEST + 4, _(L("Print&er Settings Tab")) + "\tCtrl+4", _(L("Show the printer settings")),
|
||||
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 2*/3); }, "printer", nullptr,
|
||||
[this]() {return true; }, this);
|
||||
m_changeable_menu_items.push_back(item_printer_tab);
|
||||
if (m_plater) {
|
||||
windowMenu->AppendSeparator();
|
||||
append_menu_item(windowMenu, wxID_HIGHEST + 5, _(L("3&D")) + "\tCtrl+5", _(L("Show the 3D editing view")),
|
||||
|
@ -832,6 +854,9 @@ void MainFrame::init_menubar()
|
|||
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
|
||||
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
|
||||
#endif // ENABLE_SLOPE_RENDERING
|
||||
append_menu_check_item(viewMenu, wxID_ANY, _(L("&Collapse sidebar")), _(L("Collapse sidebar")),
|
||||
[this](wxCommandEvent&) { m_plater->collapse_sidebar(!m_plater->is_sidebar_collapsed()); }, this,
|
||||
[this]() { return true; }, [this]() { return m_plater->is_sidebar_collapsed(); }, this);
|
||||
}
|
||||
|
||||
// Help menu
|
||||
|
@ -906,7 +931,9 @@ void MainFrame::update_menubar()
|
|||
m_changeable_menu_items[miSend] ->SetItemLabel((is_fff ? _(L("S&end G-code")) : _(L("S&end to print"))) + dots + "\tCtrl+Shift+G");
|
||||
|
||||
m_changeable_menu_items[miMaterialTab] ->SetItemLabel((is_fff ? _(L("&Filament Settings Tab")) : _(L("Mate&rial Settings Tab"))) + "\tCtrl+3");
|
||||
m_changeable_menu_items[miMaterialTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "spool": "resin"));
|
||||
m_changeable_menu_items[miMaterialTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "spool" : "resin"));
|
||||
|
||||
m_changeable_menu_items[miPrinterTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "printer" : "sla_printer"));
|
||||
}
|
||||
|
||||
// To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG".
|
||||
|
@ -1222,9 +1249,17 @@ void MainFrame::load_config(const DynamicPrintConfig& config)
|
|||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::select_tab(size_t tab) const
|
||||
void MainFrame::select_tab(size_t tab)
|
||||
{
|
||||
m_tabpanel->SetSelection(tab);
|
||||
if (tab == /*(size_t)(-1)*/0) {
|
||||
if (m_plater && !m_plater->IsShown())
|
||||
this->switch_to(true);
|
||||
}
|
||||
else {
|
||||
if (m_plater && m_plater->IsShown())
|
||||
switch_to(false);
|
||||
m_tabpanel->SetSelection(tab);
|
||||
}
|
||||
}
|
||||
|
||||
// Set a camera direction, zoom to all objects.
|
||||
|
|
|
@ -86,6 +86,7 @@ class MainFrame : public DPIFrame
|
|||
miExport = 0, // Export G-code Export
|
||||
miSend, // Send G-code Send to print
|
||||
miMaterialTab, // Filament Settings Material Settings
|
||||
miPrinterTab, // Different bitmap for Printer Settings
|
||||
};
|
||||
|
||||
// vector of a MenuBar items changeable in respect to printer technology
|
||||
|
@ -108,6 +109,7 @@ public:
|
|||
void update_title();
|
||||
|
||||
void init_tabpanel();
|
||||
void switch_to(bool plater);
|
||||
void create_preset_tabs();
|
||||
void add_created_tab(Tab* panel);
|
||||
void init_menubar();
|
||||
|
@ -128,7 +130,7 @@ public:
|
|||
void export_configbundle();
|
||||
void load_configbundle(wxString file = wxEmptyString);
|
||||
void load_config(const DynamicPrintConfig& config);
|
||||
void select_tab(size_t tab) const;
|
||||
void select_tab(size_t tab);
|
||||
void select_view(const std::string& direction);
|
||||
// Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig
|
||||
void on_config_changed(DynamicPrintConfig* cfg) const ;
|
||||
|
|
|
@ -108,6 +108,7 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
|
|||
return;
|
||||
}
|
||||
|
||||
sizer->Add(field->m_blinking_bmp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 2);
|
||||
sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
}
|
||||
|
@ -378,6 +379,9 @@ Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index
|
|||
std::pair<std::string, int> pair(opt_key, opt_index);
|
||||
m_opt_map.emplace(opt_id, pair);
|
||||
|
||||
if (m_show_modified_btns) // fill group and category values just fro options from Settings Tab
|
||||
wxGetApp().sidebar().get_searcher().add_key(opt_id, title, config_category);
|
||||
|
||||
return Option(*m_config->def()->get(opt_key), opt_id);
|
||||
}
|
||||
|
||||
|
@ -680,6 +684,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
|||
opt_key == "fill_pattern" ) {
|
||||
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
|
||||
}
|
||||
else if (opt_key.compare("ironing_type") == 0 ) {
|
||||
ret = static_cast<int>(config.option<ConfigOptionEnum<IroningType>>(opt_key)->value);
|
||||
}
|
||||
else if (opt_key.compare("gcode_flavor") == 0 ) {
|
||||
ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "Field.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
// Translate the ifdef
|
||||
#ifdef __WXOSX__
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
m_extra_widgets.push_back(widget);
|
||||
}
|
||||
Line(wxString label, wxString tooltip) :
|
||||
label(label), label_tooltip(tooltip) {}
|
||||
label(_(label)), label_tooltip(_(tooltip)) {}
|
||||
|
||||
const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;}
|
||||
const std::vector<Option>& get_options() const { return m_options; }
|
||||
|
@ -78,7 +79,7 @@ class OptionsGroup {
|
|||
wxStaticBox* stb;
|
||||
public:
|
||||
const bool staticbox {true};
|
||||
const wxString title {wxString("")};
|
||||
const wxString title;
|
||||
size_t label_width = 20 ;// {200};
|
||||
wxSizer* sizer {nullptr};
|
||||
column_t extra_column {nullptr};
|
||||
|
@ -175,7 +176,7 @@ public:
|
|||
m_show_modified_btns(is_tab_opt),
|
||||
staticbox(title!=""), extra_column(extra_clmn) {
|
||||
if (staticbox) {
|
||||
stb = new wxStaticBox(_parent, wxID_ANY, title);
|
||||
stb = new wxStaticBox(_parent, wxID_ANY, _(title));
|
||||
if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
stb->SetFont(wxGetApp().bold_font());
|
||||
} else
|
||||
|
@ -194,6 +195,7 @@ public:
|
|||
#else
|
||||
sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
|
||||
#endif /* __WXGTK__ */
|
||||
|
||||
}
|
||||
|
||||
wxGridSizer* get_grid_sizer() { return m_grid_sizer; }
|
||||
|
@ -247,6 +249,8 @@ public:
|
|||
bool m_full_labels {0};
|
||||
t_opt_map m_opt_map;
|
||||
|
||||
std::string config_category;
|
||||
|
||||
void set_config(DynamicPrintConfig* config) { m_config = config; }
|
||||
Option get_option(const std::string& opt_key, int opt_index = -1);
|
||||
Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
#include "../Utils/FixModelByWin10.hpp"
|
||||
#include "../Utils/UndoRedo.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
#ifdef __APPLE__
|
||||
#include "Gizmos/GLGizmosManager.hpp"
|
||||
|
@ -355,6 +357,9 @@ PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)),
|
|||
|
||||
wxGetApp().tab_panel()->ChangeSelection(page_id);
|
||||
|
||||
// Switch to Settings NotePad
|
||||
wxGetApp().mainframe->switch_to(false);
|
||||
|
||||
/* In a case of a multi-material printing, for editing another Filament Preset
|
||||
* it's needed to select this preset for the "Filament settings" Tab
|
||||
*/
|
||||
|
@ -714,6 +719,9 @@ struct Sidebar::priv
|
|||
ScalableButton *btn_remove_device;
|
||||
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
|
||||
|
||||
bool is_collapsed {false};
|
||||
Search::OptionsSearcher searcher;
|
||||
|
||||
priv(Plater *plater) : plater(plater) {}
|
||||
~priv();
|
||||
|
||||
|
@ -762,6 +770,8 @@ Sidebar::Sidebar(Plater *parent)
|
|||
p->scrolled = new wxScrolledWindow(this);
|
||||
p->scrolled->SetScrollbars(0, 100, 1, 2);
|
||||
|
||||
SetFont(wxGetApp().normal_font());
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
// Sizer in the scrolled area
|
||||
auto *scrolled_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -1080,6 +1090,21 @@ void Sidebar::msw_rescale()
|
|||
p->scrolled->Layout();
|
||||
}
|
||||
|
||||
void Sidebar::search()
|
||||
{
|
||||
p->searcher.search();
|
||||
}
|
||||
|
||||
void Sidebar::jump_to_option(size_t selected)
|
||||
{
|
||||
const Search::Option& opt = p->searcher.get_option(selected);
|
||||
wxGetApp().get_tab(opt.type)->activate_option(opt.opt_key, opt.category);
|
||||
|
||||
// Switch to the Settings NotePad, if plater is shown
|
||||
if (p->plater->IsShown())
|
||||
wxGetApp().mainframe->switch_to(false);
|
||||
}
|
||||
|
||||
ObjectManipulation* Sidebar::obj_manipul()
|
||||
{
|
||||
return p->object_manipulation;
|
||||
|
@ -1346,6 +1371,23 @@ bool Sidebar::is_multifilament()
|
|||
return p->combos_filament.size() > 1;
|
||||
}
|
||||
|
||||
static std::vector<Search::InputInfo> get_search_inputs(ConfigOptionMode mode)
|
||||
{
|
||||
std::vector<Search::InputInfo> ret {};
|
||||
|
||||
auto& tabs_list = wxGetApp().tabs_list;
|
||||
auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
|
||||
for (auto tab : tabs_list)
|
||||
if (tab->supports_printer_technology(print_tech))
|
||||
ret.emplace_back(Search::InputInfo {tab->get_config(), tab->type(), mode});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Sidebar::update_searcher()
|
||||
{
|
||||
p->searcher.init(get_search_inputs(m_mode));
|
||||
}
|
||||
|
||||
void Sidebar::update_mode()
|
||||
{
|
||||
|
@ -1353,6 +1395,7 @@ void Sidebar::update_mode()
|
|||
|
||||
update_reslice_btn_tooltip();
|
||||
update_mode_sizer();
|
||||
update_searcher();
|
||||
|
||||
wxWindowUpdateLocker noUpdates(this);
|
||||
|
||||
|
@ -1365,6 +1408,20 @@ void Sidebar::update_mode()
|
|||
Layout();
|
||||
}
|
||||
|
||||
bool Sidebar::is_collapsed() { return p->is_collapsed; }
|
||||
|
||||
void Sidebar::collapse(bool collapse)
|
||||
{
|
||||
p->is_collapsed = collapse;
|
||||
|
||||
this->Show(!collapse);
|
||||
p->plater->Layout();
|
||||
|
||||
// save collapsing state to the AppConfig
|
||||
wxGetApp().app_config->set("collapsed_sidebar", collapse ? "1" : "0");
|
||||
}
|
||||
|
||||
|
||||
void Sidebar::update_ui_from_settings()
|
||||
{
|
||||
p->object_manipulation->update_ui_from_settings();
|
||||
|
@ -1377,6 +1434,16 @@ std::vector<PresetComboBox*>& Sidebar::combos_filament()
|
|||
return p->combos_filament;
|
||||
}
|
||||
|
||||
Search::OptionsSearcher& Sidebar::get_searcher()
|
||||
{
|
||||
return p->searcher;
|
||||
}
|
||||
|
||||
std::string& Sidebar::get_search_line()
|
||||
{
|
||||
return p->searcher.search_string();
|
||||
}
|
||||
|
||||
// Plater::DropTarget
|
||||
|
||||
class PlaterDropTarget : public wxFileDropTarget
|
||||
|
@ -1568,6 +1635,9 @@ struct Plater::priv
|
|||
bool are_view3D_labels_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->are_labels_shown(); }
|
||||
void show_view3D_labels(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_labels(show); }
|
||||
|
||||
bool is_sidebar_collapsed() const { return sidebar->is_collapsed(); }
|
||||
void collapse_sidebar(bool show) { sidebar->collapse(show); }
|
||||
|
||||
#if ENABLE_SLOPE_RENDERING
|
||||
bool is_view3D_slope_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_slope_shown(); }
|
||||
void show_view3D_slope(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_slope(show); }
|
||||
|
@ -1874,6 +1944,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event<float>& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); });
|
||||
|
@ -1962,6 +2033,31 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
|
||||
// Initialize the Undo / Redo stack with a first snapshot.
|
||||
this->take_snapshot(_L("New Project"));
|
||||
|
||||
this->q->Bind(EVT_LOAD_MODEL_OTHER_INSTANCE, [this](LoadFromOtherInstanceEvent &evt) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "received load from other instance event ";
|
||||
this->load_files(evt.data, true, true);
|
||||
});
|
||||
this->q->Bind(EVT_INSTANCE_GO_TO_FRONT, [this](InstanceGoToFrontEvent &) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "prusaslicer window going forward";
|
||||
//this code maximize app window on Fedora
|
||||
wxGetApp().mainframe->Iconize(false);
|
||||
if (wxGetApp().mainframe->IsMaximized())
|
||||
wxGetApp().mainframe->Maximize(true);
|
||||
else
|
||||
wxGetApp().mainframe->Maximize(false);
|
||||
//this code (without code above) maximize window on Ubuntu
|
||||
wxGetApp().mainframe->Restore();
|
||||
wxGetApp().GetTopWindow()->SetFocus(); // focus on my window
|
||||
wxGetApp().GetTopWindow()->Raise(); // bring window to front
|
||||
wxGetApp().GetTopWindow()->Show(true); // show the window
|
||||
|
||||
});
|
||||
wxGetApp().other_instance_message_handler()->init(this->q);
|
||||
|
||||
|
||||
// collapse sidebar according to saved value
|
||||
sidebar->collapse(wxGetApp().app_config->get("collapsed_sidebar") == "1");
|
||||
}
|
||||
|
||||
Plater::priv::~priv()
|
||||
|
@ -3239,13 +3335,14 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
|
|||
|
||||
// update plater with new config
|
||||
q->on_config_change(wxGetApp().preset_bundle->full_config());
|
||||
if (preset_type == Preset::TYPE_PRINTER) {
|
||||
/* Settings list can be changed after printer preset changing, so
|
||||
* update all settings items for all item had it.
|
||||
* Furthermore, Layers editing is implemented only for FFF printers
|
||||
* and for SLA presets they should be deleted
|
||||
*/
|
||||
if (preset_type == Preset::TYPE_PRINTER)
|
||||
wxGetApp().obj_list()->update_object_list_by_printer_technology();
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
||||
|
@ -4341,6 +4438,9 @@ bool Plater::is_view3D_shown() const { return p->is_view3D_shown(); }
|
|||
bool Plater::are_view3D_labels_shown() const { return p->are_view3D_labels_shown(); }
|
||||
void Plater::show_view3D_labels(bool show) { p->show_view3D_labels(show); }
|
||||
|
||||
bool Plater::is_sidebar_collapsed() const { return p->is_sidebar_collapsed(); }
|
||||
void Plater::collapse_sidebar(bool show) { p->collapse_sidebar(show); }
|
||||
|
||||
#if ENABLE_SLOPE_RENDERING
|
||||
bool Plater::is_view3D_slope_shown() const { return p->is_view3D_slope_shown(); }
|
||||
void Plater::show_view3D_slope(bool show) { p->show_view3D_slope(show); }
|
||||
|
@ -4913,6 +5013,18 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou
|
|||
out_text = "";
|
||||
}
|
||||
|
||||
bool Plater::search_string_getter(int idx, const char** label, const char** tooltip)
|
||||
{
|
||||
const Search::OptionsSearcher& search_list = p->sidebar->get_searcher();
|
||||
|
||||
if (0 <= idx && (size_t)idx < search_list.size()) {
|
||||
search_list[idx].get_marked_label_and_tooltip(label, tooltip);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Plater::on_extruders_change(size_t num_extruders)
|
||||
{
|
||||
auto& choices = sidebar().combos_filament();
|
||||
|
@ -4972,8 +5084,11 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
}
|
||||
|
||||
p->config->set_key_value(opt_key, config.option(opt_key)->clone());
|
||||
if (opt_key == "printer_technology")
|
||||
if (opt_key == "printer_technology") {
|
||||
this->set_printer_technology(config.opt_enum<PrinterTechnology>(opt_key));
|
||||
// print technology is changed, so we should to update a search list
|
||||
p->sidebar->update_searcher();
|
||||
}
|
||||
else if ((opt_key == "bed_shape") || (opt_key == "bed_custom_texture") || (opt_key == "bed_custom_model")) {
|
||||
bed_shape_changed = true;
|
||||
update_scheduled = true;
|
||||
|
@ -5283,6 +5398,27 @@ void Plater::paste_from_clipboard()
|
|||
p->view3D->get_canvas3d()->get_selection().paste_from_clipboard();
|
||||
}
|
||||
|
||||
void Plater::search(bool plater_is_active)
|
||||
{
|
||||
if (plater_is_active) {
|
||||
wxKeyEvent evt;
|
||||
#ifdef __APPLE__
|
||||
evt.m_keyCode = 'f';
|
||||
#else /* __APPLE__ */
|
||||
evt.m_keyCode = WXK_CONTROL_F;
|
||||
#endif /* __APPLE__ */
|
||||
evt.SetControlDown(true);
|
||||
canvas3D()->on_char(evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxPoint pos = this->ClientToScreen(wxPoint(0, 0));
|
||||
pos.x += em_unit(this) * 40;
|
||||
pos.y += em_unit(this) * 4;
|
||||
p->sidebar->get_searcher().search_dialog->Popup(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::msw_rescale()
|
||||
{
|
||||
p->preview->msw_rescale();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "Jobs/Job.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Search.hpp"
|
||||
|
||||
class wxButton;
|
||||
class ScalableButton;
|
||||
|
@ -106,6 +107,8 @@ public:
|
|||
void update_mode_sizer() const;
|
||||
void update_reslice_btn_tooltip() const;
|
||||
void msw_rescale();
|
||||
void search();
|
||||
void jump_to_option(size_t selected);
|
||||
|
||||
ObjectManipulation* obj_manipul();
|
||||
ObjectList* obj_list();
|
||||
|
@ -129,9 +132,15 @@ public:
|
|||
bool show_export_removable(bool show) const;
|
||||
bool is_multifilament();
|
||||
void update_mode();
|
||||
bool is_collapsed();
|
||||
void collapse(bool collapse);
|
||||
void update_searcher();
|
||||
void update_ui_from_settings();
|
||||
|
||||
std::vector<PresetComboBox*>& combos_filament();
|
||||
std::vector<PresetComboBox*>& combos_filament();
|
||||
Search::OptionsSearcher& get_searcher();
|
||||
std::string& get_search_line();
|
||||
|
||||
private:
|
||||
struct priv;
|
||||
std::unique_ptr<priv> p;
|
||||
|
@ -179,6 +188,9 @@ public:
|
|||
bool are_view3D_labels_shown() const;
|
||||
void show_view3D_labels(bool show);
|
||||
|
||||
bool is_sidebar_collapsed() const;
|
||||
void collapse_sidebar(bool show);
|
||||
|
||||
#if ENABLE_SLOPE_RENDERING
|
||||
bool is_view3D_slope_shown() const;
|
||||
void show_view3D_slope(bool show);
|
||||
|
@ -234,6 +246,7 @@ public:
|
|||
void redo_to(int selection);
|
||||
bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text);
|
||||
void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text);
|
||||
bool search_string_getter(int idx, const char** label, const char** tooltip);
|
||||
// For the memory statistics.
|
||||
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
|
||||
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
|
||||
|
@ -279,6 +292,7 @@ public:
|
|||
|
||||
void copy_selection_to_clipboard();
|
||||
void paste_from_clipboard();
|
||||
void search(bool plater_is_active);
|
||||
|
||||
bool can_delete() const;
|
||||
bool can_delete_all() const;
|
||||
|
|
|
@ -100,6 +100,13 @@ void PreferencesDialog::build()
|
|||
option = Option (def,"show_incompatible_presets");
|
||||
m_optgroup_general->append_single_option_line(option);
|
||||
|
||||
def.label = L("Single Instance");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If this is enabled, when staring PrusaSlicer and another instance is running, that instance will be reactivated instead.");
|
||||
def.set_default_value(new ConfigOptionBool{ app_config->has("single_instance") ? app_config->get("single_instance") == "1" : false });
|
||||
option = Option(def, "single_instance");
|
||||
m_optgroup_general->append_single_option_line(option);
|
||||
|
||||
#if __APPLE__
|
||||
def.label = L("Use Retina resolution for the 3D scene");
|
||||
def.type = coBool;
|
||||
|
@ -186,6 +193,8 @@ void PreferencesDialog::accept()
|
|||
app_config->set(it->first, it->second);
|
||||
}
|
||||
|
||||
app_config->save();
|
||||
|
||||
EndModal(wxID_OK);
|
||||
|
||||
// Nothify the UI to update itself from the ini file.
|
||||
|
|
|
@ -405,8 +405,9 @@ const std::vector<std::string>& Preset::print_options()
|
|||
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
|
||||
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
|
||||
"max_volumetric_speed",
|
||||
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
|
||||
"ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing",
|
||||
"max_print_speed", "max_volumetric_speed",
|
||||
#ifdef HAS_PRESSURE_EQUALIZER
|
||||
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
|
||||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
|
|
608
src/slic3r/GUI/Search.cpp
Normal file
608
src/slic3r/GUI/Search.cpp
Normal file
|
@ -0,0 +1,608 @@
|
|||
#include "Search.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
|
||||
#define FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
#include "fts_fuzzy_match.h"
|
||||
|
||||
#include "imgui/imconfig.h"
|
||||
|
||||
using boost::optional;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
using GUI::from_u8;
|
||||
using GUI::into_u8;
|
||||
|
||||
namespace Search {
|
||||
|
||||
static std::map<Preset::Type, std::string> NameByType = {
|
||||
{ Preset::TYPE_PRINT, L("Print") },
|
||||
{ Preset::TYPE_FILAMENT, L("Filament") },
|
||||
{ Preset::TYPE_SLA_MATERIAL, L("Material") },
|
||||
{ Preset::TYPE_SLA_PRINT, L("Print") },
|
||||
{ Preset::TYPE_PRINTER, L("Printer") }
|
||||
};
|
||||
|
||||
FMFlag Option::fuzzy_match_simple(char const * search_pattern) const
|
||||
{
|
||||
return fts::fuzzy_match_simple(search_pattern, label_local.utf8_str()) ? fmLabelLocal :
|
||||
fts::fuzzy_match_simple(search_pattern, group_local.utf8_str()) ? fmGroupLocal :
|
||||
fts::fuzzy_match_simple(search_pattern, category_local.utf8_str()) ? fmCategoryLocal :
|
||||
fts::fuzzy_match_simple(search_pattern, opt_key.c_str()) ? fmOptKey :
|
||||
fts::fuzzy_match_simple(search_pattern, label.utf8_str()) ? fmLabel :
|
||||
fts::fuzzy_match_simple(search_pattern, group.utf8_str()) ? fmGroup :
|
||||
fts::fuzzy_match_simple(search_pattern, category.utf8_str()) ? fmCategory : fmUndef ;
|
||||
}
|
||||
|
||||
FMFlag Option::fuzzy_match_simple(const wxString& search) const
|
||||
{
|
||||
char const* search_pattern = search.utf8_str();
|
||||
return fuzzy_match_simple(search_pattern);
|
||||
}
|
||||
|
||||
FMFlag Option::fuzzy_match_simple(const std::string& search) const
|
||||
{
|
||||
char const* search_pattern = search.c_str();
|
||||
return fuzzy_match_simple(search_pattern);
|
||||
}
|
||||
|
||||
FMFlag Option::fuzzy_match(char const* search_pattern, int& outScore) const
|
||||
{
|
||||
FMFlag flag = fmUndef;
|
||||
int score;
|
||||
|
||||
if (fts::fuzzy_match(search_pattern, label_local.utf8_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmLabelLocal ; }
|
||||
if (fts::fuzzy_match(search_pattern, group_local.utf8_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmGroupLocal ; }
|
||||
if (fts::fuzzy_match(search_pattern, category_local.utf8_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmCategoryLocal; }
|
||||
if (fts::fuzzy_match(search_pattern, opt_key.c_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmOptKey ; }
|
||||
if (fts::fuzzy_match(search_pattern, label.utf8_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmLabel ; }
|
||||
if (fts::fuzzy_match(search_pattern, group.utf8_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmGroup ; }
|
||||
if (fts::fuzzy_match(search_pattern, category.utf8_str(), score) && outScore < score) {
|
||||
outScore = score; flag = fmCategory ; }
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
FMFlag Option::fuzzy_match(const wxString& search, int& outScore) const
|
||||
{
|
||||
char const* search_pattern = search.utf8_str();
|
||||
return fuzzy_match(search_pattern, outScore);
|
||||
}
|
||||
|
||||
FMFlag Option::fuzzy_match(const std::string& search, int& outScore) const
|
||||
{
|
||||
char const* search_pattern = search.c_str();
|
||||
return fuzzy_match(search_pattern, outScore);
|
||||
}
|
||||
|
||||
void FoundOption::get_label(const char** out_text) const
|
||||
{
|
||||
*out_text = label.utf8_str();
|
||||
}
|
||||
|
||||
void FoundOption::get_marked_label_and_tooltip(const char** label_, const char** tooltip_) const
|
||||
{
|
||||
*label_ = marked_label.utf8_str();
|
||||
*tooltip_ = tooltip.utf8_str();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
//void change_opt_key(std::string& opt_key, DynamicPrintConfig* config)
|
||||
void change_opt_key(std::string& opt_key, DynamicPrintConfig* config, int& cnt)
|
||||
{
|
||||
T* opt_cur = static_cast<T*>(config->option(opt_key));
|
||||
cnt = opt_cur->values.size();
|
||||
return;
|
||||
|
||||
if (opt_cur->values.size() > 0)
|
||||
opt_key += "#" + std::to_string(0);
|
||||
}
|
||||
|
||||
void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode)
|
||||
{
|
||||
auto emplace = [this, type](const std::string opt_key, const wxString& label)
|
||||
{
|
||||
const GroupAndCategory& gc = groups_and_categories[opt_key];
|
||||
if (gc.group.IsEmpty() || gc.category.IsEmpty())
|
||||
return;
|
||||
|
||||
wxString suffix;
|
||||
if (gc.category == "Machine limits")
|
||||
suffix = opt_key.back()=='1' ? L("Stealth") : L("Normal");
|
||||
|
||||
if (!label.IsEmpty())
|
||||
options.emplace_back(Option{ opt_key, type,
|
||||
label+ " " + suffix, _(label)+ " " + _(suffix),
|
||||
gc.group, _(gc.group),
|
||||
gc.category, _(gc.category) });
|
||||
};
|
||||
|
||||
for (std::string opt_key : config->keys())
|
||||
{
|
||||
const ConfigOptionDef& opt = config->def()->options.at(opt_key);
|
||||
if (opt.mode > mode)
|
||||
continue;
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
if ( (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) && opt_key != "bed_shape")
|
||||
switch (config->option(opt_key)->type())
|
||||
{
|
||||
case coInts: change_opt_key<ConfigOptionInts >(opt_key, config, cnt); break;
|
||||
case coBools: change_opt_key<ConfigOptionBools >(opt_key, config, cnt); break;
|
||||
case coFloats: change_opt_key<ConfigOptionFloats >(opt_key, config, cnt); break;
|
||||
case coStrings: change_opt_key<ConfigOptionStrings >(opt_key, config, cnt); break;
|
||||
case coPercents:change_opt_key<ConfigOptionPercents >(opt_key, config, cnt); break;
|
||||
case coPoints: change_opt_key<ConfigOptionPoints >(opt_key, config, cnt); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
wxString label = opt.full_label.empty() ? opt.label : opt.full_label;
|
||||
|
||||
if (cnt == 0)
|
||||
emplace(opt_key, label);
|
||||
else
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
emplace(opt_key + "#" + std::to_string(i), label);
|
||||
|
||||
/*const GroupAndCategory& gc = groups_and_categories[opt_key];
|
||||
if (gc.group.IsEmpty() || gc.category.IsEmpty())
|
||||
continue;
|
||||
|
||||
if (!label.IsEmpty())
|
||||
options.emplace_back(Option{opt_key, type,
|
||||
label, _(label),
|
||||
gc.group, _(gc.group),
|
||||
gc.category, _(gc.category) });*/
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap a string with ColorMarkerStart and ColorMarkerEnd symbols
|
||||
static wxString wrap_string(const wxString& str)
|
||||
{
|
||||
return wxString::Format("%c%s%c", ImGui::ColorMarkerStart, str, ImGui::ColorMarkerEnd);
|
||||
}
|
||||
|
||||
// Mark a string using ColorMarkerStart and ColorMarkerEnd symbols
|
||||
static void mark_string(wxString& str, const wxString& search_str)
|
||||
{
|
||||
// Try to find whole search string
|
||||
if (str.Replace(search_str, wrap_string(search_str), false) != 0)
|
||||
return;
|
||||
|
||||
// Try to find whole capitalized search string
|
||||
wxString search_str_capitalized = search_str.Capitalize();
|
||||
if (str.Replace(search_str_capitalized, wrap_string(search_str_capitalized), false) != 0)
|
||||
return;
|
||||
|
||||
// if search string is just a one letter now, there is no reason to continue
|
||||
if (search_str.Len()==1)
|
||||
return;
|
||||
|
||||
// Split a search string for two strings (string without last letter and last letter)
|
||||
// and repeat a function with new search strings
|
||||
mark_string(str, search_str.SubString(0, search_str.Len() - 2));
|
||||
mark_string(str, search_str.Last());
|
||||
}
|
||||
|
||||
// clear marked string from a redundant use of ColorMarkers
|
||||
static void clear_marked_string(wxString& str)
|
||||
{
|
||||
// Check if the string has a several ColorMarkerStart in a row and replace them to only one, if any
|
||||
wxString delete_string = wxString::Format("%c%c", ImGui::ColorMarkerStart, ImGui::ColorMarkerStart);
|
||||
str.Replace(delete_string, ImGui::ColorMarkerStart, true);
|
||||
// If there were several ColorMarkerStart in a row, it means there should be a several ColorMarkerStop in a row,
|
||||
// replace them to only one
|
||||
delete_string = wxString::Format("%c%c", ImGui::ColorMarkerEnd, ImGui::ColorMarkerEnd);
|
||||
str.Replace(delete_string, ImGui::ColorMarkerEnd, true);
|
||||
|
||||
// And we should to remove redundant ColorMarkers, if they are in "End, Start" sequence in a row
|
||||
delete_string = wxString::Format("%c%c", ImGui::ColorMarkerEnd, ImGui::ColorMarkerStart);
|
||||
str.Replace(delete_string, wxEmptyString, true);
|
||||
}
|
||||
|
||||
bool OptionsSearcher::search()
|
||||
{
|
||||
return search(search_line, true);
|
||||
}
|
||||
|
||||
bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
|
||||
{
|
||||
if (search_line == search && !force)
|
||||
return false;
|
||||
|
||||
found.clear();
|
||||
|
||||
bool full_list = search.empty();
|
||||
wxString sep = " : ";
|
||||
|
||||
auto get_label = [this, sep](const Option& opt)
|
||||
{
|
||||
wxString label;
|
||||
if (view_params.type)
|
||||
label += _(NameByType[opt.type]) + sep;
|
||||
if (view_params.category)
|
||||
label += opt.category_local + sep;
|
||||
if (view_params.group)
|
||||
label += opt.group_local + sep;
|
||||
label += opt.label_local;
|
||||
return label;
|
||||
};
|
||||
|
||||
auto get_tooltip = [this, sep](const Option& opt)
|
||||
{
|
||||
return _(NameByType[opt.type]) + sep +
|
||||
opt.category_local + sep +
|
||||
opt.group_local + sep + opt.label_local;
|
||||
};
|
||||
|
||||
for (size_t i=0; i < options.size(); i++)
|
||||
{
|
||||
const Option &opt = options[i];
|
||||
if (full_list) {
|
||||
wxString label = get_label(opt);
|
||||
found.emplace_back(FoundOption{ label, label, get_tooltip(opt), i, 0 });
|
||||
continue;
|
||||
}
|
||||
|
||||
int score = 0;
|
||||
|
||||
FMFlag fuzzy_match_flag = opt.fuzzy_match(search, score);
|
||||
if (fuzzy_match_flag != fmUndef)
|
||||
{
|
||||
wxString label = get_label(opt);
|
||||
|
||||
if ( fuzzy_match_flag == fmLabel ) label += "(" + opt.label + ")";
|
||||
else if (fuzzy_match_flag == fmGroup ) label += "(" + opt.group + ")";
|
||||
else if (fuzzy_match_flag == fmCategory) label += "(" + opt.category + ")";
|
||||
else if (fuzzy_match_flag == fmOptKey ) label += "(" + opt.opt_key + ")";
|
||||
|
||||
wxString marked_label = label;
|
||||
mark_string(marked_label, from_u8(search));
|
||||
clear_marked_string(marked_label);
|
||||
|
||||
found.emplace_back(FoundOption{ label, marked_label, get_tooltip(opt), i, score });
|
||||
}
|
||||
}
|
||||
|
||||
if (!full_list)
|
||||
sort_found();
|
||||
|
||||
if (search_line != search)
|
||||
search_line = search;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
OptionsSearcher::OptionsSearcher()
|
||||
{
|
||||
search_dialog = new SearchDialog(this);
|
||||
}
|
||||
|
||||
OptionsSearcher::~OptionsSearcher()
|
||||
{
|
||||
if (search_dialog)
|
||||
search_dialog->Destroy();
|
||||
}
|
||||
|
||||
void OptionsSearcher::init(std::vector<InputInfo> input_values)
|
||||
{
|
||||
options.clear();
|
||||
for (auto i : input_values)
|
||||
append_options(i.config, i.type, i.mode);
|
||||
sort_options();
|
||||
|
||||
search(search_line, true);
|
||||
}
|
||||
|
||||
void OptionsSearcher::apply(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode)
|
||||
{
|
||||
if (options.empty())
|
||||
return;
|
||||
|
||||
options.erase(std::remove_if(options.begin(), options.end(), [type](Option opt) {
|
||||
return opt.type == type;
|
||||
}), options.end());
|
||||
|
||||
append_options(config, type, mode);
|
||||
|
||||
sort_options();
|
||||
|
||||
search(search_line, true);
|
||||
}
|
||||
|
||||
const Option& OptionsSearcher::get_option(size_t pos_in_filter) const
|
||||
{
|
||||
assert(pos_in_filter != size_t(-1) && found[pos_in_filter].option_idx != size_t(-1));
|
||||
return options[found[pos_in_filter].option_idx];
|
||||
}
|
||||
|
||||
void OptionsSearcher::add_key(const std::string& opt_key, const wxString& group, const wxString& category)
|
||||
{
|
||||
groups_and_categories[opt_key] = GroupAndCategory{group, category};
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
// SearchComboPopup
|
||||
//------------------------------------------
|
||||
|
||||
|
||||
void SearchComboPopup::Init()
|
||||
{
|
||||
this->Bind(wxEVT_MOTION, &SearchComboPopup::OnMouseMove, this);
|
||||
this->Bind(wxEVT_LEFT_UP, &SearchComboPopup::OnMouseClick, this);
|
||||
this->Bind(wxEVT_KEY_DOWN, &SearchComboPopup::OnKeyDown, this);
|
||||
}
|
||||
|
||||
bool SearchComboPopup::Create(wxWindow* parent)
|
||||
{
|
||||
return wxListBox::Create(parent, 1, wxPoint(0, 0), wxDefaultSize);
|
||||
}
|
||||
|
||||
void SearchComboPopup::SetStringValue(const wxString& s)
|
||||
{
|
||||
int n = wxListBox::FindString(s);
|
||||
if (n >= 0 && n < wxListBox::GetCount())
|
||||
wxListBox::Select(n);
|
||||
|
||||
// save a combo control's string
|
||||
m_input_string = s;
|
||||
}
|
||||
|
||||
void SearchComboPopup::ProcessSelection(int selection)
|
||||
{
|
||||
wxCommandEvent event(wxEVT_LISTBOX, GetId());
|
||||
event.SetInt(selection);
|
||||
event.SetEventObject(this);
|
||||
ProcessEvent(event);
|
||||
|
||||
Dismiss();
|
||||
}
|
||||
|
||||
void SearchComboPopup::OnMouseMove(wxMouseEvent& event)
|
||||
{
|
||||
wxPoint pt = wxGetMousePosition() - this->GetScreenPosition();
|
||||
int selection = this->HitTest(pt);
|
||||
wxListBox::Select(selection);
|
||||
}
|
||||
|
||||
void SearchComboPopup::OnMouseClick(wxMouseEvent&)
|
||||
{
|
||||
int selection = wxListBox::GetSelection();
|
||||
SetSelection(wxNOT_FOUND);
|
||||
ProcessSelection(selection);
|
||||
}
|
||||
|
||||
void SearchComboPopup::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
int key = event.GetKeyCode();
|
||||
|
||||
// change selected item in the list
|
||||
if (key == WXK_UP || key == WXK_DOWN)
|
||||
{
|
||||
int selection = wxListBox::GetSelection();
|
||||
|
||||
if (key == WXK_UP && selection > 0)
|
||||
selection--;
|
||||
if (key == WXK_DOWN && selection < int(wxListBox::GetCount() - 1))
|
||||
selection++;
|
||||
|
||||
wxListBox::Select(selection);
|
||||
}
|
||||
// send wxEVT_LISTBOX event if "Enter" was pushed
|
||||
else if (key == WXK_NUMPAD_ENTER || key == WXK_RETURN)
|
||||
ProcessSelection(wxListBox::GetSelection());
|
||||
else
|
||||
event.Skip(); // !Needed to have EVT_CHAR generated as well
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
// SearchDialog
|
||||
//------------------------------------------
|
||||
|
||||
SearchDialog::SearchDialog(OptionsSearcher* searcher)
|
||||
: GUI::DPIDialog(NULL, wxID_ANY, _L("Search"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
|
||||
searcher(searcher)
|
||||
{
|
||||
SetFont(GUI::wxGetApp().normal_font());
|
||||
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||
SetBackgroundColour(bgr_clr);
|
||||
|
||||
default_string = _L("Type here to search");
|
||||
int border = 10;
|
||||
|
||||
search_line = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
// wxWANTS_CHARS style is neede for process Enter key press
|
||||
search_list = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(em_unit() * 40, em_unit() * 30), 0, NULL, wxWANTS_CHARS);
|
||||
|
||||
wxBoxSizer* check_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
check_type = new wxCheckBox(this, wxID_ANY, _L("Type"));
|
||||
check_category = new wxCheckBox(this, wxID_ANY, _L("Category"));
|
||||
check_group = new wxCheckBox(this, wxID_ANY, _L("Group"));
|
||||
|
||||
wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL);
|
||||
|
||||
check_sizer->Add(check_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
|
||||
check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
|
||||
check_sizer->Add(check_group, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
|
||||
check_sizer->AddStretchSpacer(border);
|
||||
check_sizer->Add(cancel_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
topSizer->Add(search_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
|
||||
topSizer->Add(search_list, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
|
||||
topSizer->Add(check_sizer, 0, wxEXPAND | wxALL, border);
|
||||
|
||||
search_line->Bind(wxEVT_TEXT, &SearchDialog::OnInputText, this);
|
||||
search_line->Bind(wxEVT_LEFT_UP, &SearchDialog::OnLeftUpInTextCtrl, this);
|
||||
// process wxEVT_KEY_DOWN to navigate inside search_list, if ArrowUp/Down was pressed
|
||||
search_line->Bind(wxEVT_KEY_DOWN,&SearchDialog::OnKeyDown, this);
|
||||
|
||||
search_list->Bind(wxEVT_MOTION, &SearchDialog::OnMouseMove, this);
|
||||
search_list->Bind(wxEVT_LEFT_UP, &SearchDialog::OnMouseClick, this);
|
||||
search_list->Bind(wxEVT_KEY_DOWN,&SearchDialog::OnKeyDown, this);
|
||||
|
||||
check_type ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
|
||||
check_category->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
|
||||
check_group ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
|
||||
|
||||
this->Bind(wxEVT_LISTBOX, &SearchDialog::OnSelect, this);
|
||||
|
||||
SetSizer(topSizer);
|
||||
topSizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
void SearchDialog::Popup(wxPoint position /*= wxDefaultPosition*/)
|
||||
{
|
||||
const std::string& line = searcher->search_string();
|
||||
search_line->SetValue(line.empty() ? default_string : from_u8(line));
|
||||
search_line->SetFocus();
|
||||
search_line->SelectAll();
|
||||
|
||||
update_list();
|
||||
|
||||
const OptionViewParameters& params = searcher->view_params;
|
||||
check_type->SetValue(params.type);
|
||||
check_category->SetValue(params.category);
|
||||
check_group->SetValue(params.group);
|
||||
|
||||
this->SetPosition(position);
|
||||
this->ShowModal();
|
||||
}
|
||||
|
||||
void SearchDialog::ProcessSelection(int selection)
|
||||
{
|
||||
if (selection < 0)
|
||||
return;
|
||||
|
||||
GUI::wxGetApp().sidebar().jump_to_option(selection);
|
||||
this->EndModal(wxID_CLOSE);
|
||||
}
|
||||
|
||||
void SearchDialog::OnInputText(wxCommandEvent&)
|
||||
{
|
||||
search_line->SetInsertionPointEnd();
|
||||
|
||||
wxString input_string = search_line->GetValue();
|
||||
if (input_string == default_string)
|
||||
input_string.Clear();
|
||||
|
||||
searcher->search(into_u8(input_string));
|
||||
|
||||
update_list();
|
||||
}
|
||||
|
||||
void SearchDialog::OnLeftUpInTextCtrl(wxEvent& event)
|
||||
{
|
||||
if (search_line->GetValue() == default_string)
|
||||
search_line->SetValue("");
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void SearchDialog::OnMouseMove(wxMouseEvent& event)
|
||||
{
|
||||
wxPoint pt = wxGetMousePosition() - search_list->GetScreenPosition();
|
||||
int selection = search_list->HitTest(pt);
|
||||
search_list->Select(selection);
|
||||
}
|
||||
|
||||
void SearchDialog::OnMouseClick(wxMouseEvent&)
|
||||
{
|
||||
int selection = search_list->GetSelection();
|
||||
search_list->SetSelection(wxNOT_FOUND);
|
||||
|
||||
wxCommandEvent event(wxEVT_LISTBOX, search_list->GetId());
|
||||
event.SetInt(selection);
|
||||
event.SetEventObject(search_list);
|
||||
ProcessEvent(event);
|
||||
}
|
||||
|
||||
void SearchDialog::OnSelect(wxCommandEvent& event)
|
||||
{
|
||||
int selection = event.GetSelection();
|
||||
ProcessSelection(selection);
|
||||
}
|
||||
|
||||
void SearchDialog::update_list()
|
||||
{
|
||||
search_list->Clear();
|
||||
|
||||
const std::vector<FoundOption>& filters = searcher->found_options();
|
||||
for (const FoundOption& item : filters)
|
||||
search_list->Append(item.label);
|
||||
}
|
||||
|
||||
void SearchDialog::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
int key = event.GetKeyCode();
|
||||
|
||||
// change selected item in the list
|
||||
if (key == WXK_UP || key == WXK_DOWN)
|
||||
{
|
||||
int selection = search_list->GetSelection();
|
||||
|
||||
if (key == WXK_UP && selection > 0)
|
||||
selection--;
|
||||
if (key == WXK_DOWN && selection < int(search_list->GetCount() - 1))
|
||||
selection++;
|
||||
|
||||
search_list->Select(selection);
|
||||
// This function could be called from search_line,
|
||||
// So, for the next correct navigation, set focus on the search_list
|
||||
search_list->SetFocus();
|
||||
}
|
||||
// process "Enter" pressed
|
||||
else if (key == WXK_NUMPAD_ENTER || key == WXK_RETURN)
|
||||
ProcessSelection(search_list->GetSelection());
|
||||
else
|
||||
event.Skip(); // !Needed to have EVT_CHAR generated as well
|
||||
}
|
||||
|
||||
void SearchDialog::OnCheck(wxCommandEvent& event)
|
||||
{
|
||||
OptionViewParameters& params = searcher->view_params;
|
||||
params.type = check_type->GetValue();
|
||||
params.category = check_category->GetValue();
|
||||
params.group = check_group->GetValue();
|
||||
|
||||
searcher->search();
|
||||
update_list();
|
||||
}
|
||||
|
||||
void SearchDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
const int& em = em_unit();
|
||||
|
||||
msw_buttons_rescale(this, em, { wxID_CANCEL });
|
||||
|
||||
const wxSize& size = wxSize(40 * em, 30 * em);
|
||||
SetMinSize(size);
|
||||
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace Slic3r::GUI
|
220
src/slic3r/GUI/Search.hpp
Normal file
220
src/slic3r/GUI/Search.hpp
Normal file
|
@ -0,0 +1,220 @@
|
|||
#ifndef slic3r_SearchComboBox_hpp_
|
||||
#define slic3r_SearchComboBox_hpp_
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
#include <wx/combo.h>
|
||||
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "Preset.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace Search{
|
||||
|
||||
class SearchDialog;
|
||||
|
||||
struct InputInfo
|
||||
{
|
||||
DynamicPrintConfig* config {nullptr};
|
||||
Preset::Type type {Preset::TYPE_INVALID};
|
||||
ConfigOptionMode mode {comSimple};
|
||||
};
|
||||
|
||||
struct GroupAndCategory {
|
||||
wxString group;
|
||||
wxString category;
|
||||
};
|
||||
|
||||
// fuzzy_match flag
|
||||
enum FMFlag
|
||||
{
|
||||
fmUndef = 0, // didn't find
|
||||
fmOptKey,
|
||||
fmLabel,
|
||||
fmLabelLocal,
|
||||
fmGroup,
|
||||
fmGroupLocal,
|
||||
fmCategory,
|
||||
fmCategoryLocal
|
||||
};
|
||||
|
||||
struct Option {
|
||||
bool operator<(const Option& other) const { return other.label > this->label; }
|
||||
bool operator>(const Option& other) const { return other.label < this->label; }
|
||||
|
||||
std::string opt_key;
|
||||
Preset::Type type {Preset::TYPE_INVALID};
|
||||
wxString label;
|
||||
wxString label_local;
|
||||
wxString group;
|
||||
wxString group_local;
|
||||
wxString category;
|
||||
wxString category_local;
|
||||
|
||||
FMFlag fuzzy_match_simple(char const *search_pattern) const;
|
||||
FMFlag fuzzy_match_simple(const wxString& search) const;
|
||||
FMFlag fuzzy_match_simple(const std::string &search) const;
|
||||
FMFlag fuzzy_match(char const *search_pattern, int &outScore) const;
|
||||
FMFlag fuzzy_match(const wxString &search, int &outScore) const ;
|
||||
FMFlag fuzzy_match(const std::string &search, int &outScore) const ;
|
||||
};
|
||||
|
||||
struct FoundOption {
|
||||
wxString label;
|
||||
wxString marked_label;
|
||||
wxString tooltip;
|
||||
size_t option_idx {0};
|
||||
int outScore {0};
|
||||
|
||||
void get_label(const char** out_text) const;
|
||||
void get_marked_label_and_tooltip(const char** label, const char** tooltip) const;
|
||||
};
|
||||
|
||||
struct OptionViewParameters
|
||||
{
|
||||
bool type {false};
|
||||
bool category {false};
|
||||
bool group {true };
|
||||
|
||||
int hovered_id {-1};
|
||||
};
|
||||
|
||||
class OptionsSearcher
|
||||
{
|
||||
std::string search_line;
|
||||
std::map<std::string, GroupAndCategory> groups_and_categories;
|
||||
|
||||
std::vector<Option> options {};
|
||||
std::vector<FoundOption> found {};
|
||||
|
||||
void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode);
|
||||
|
||||
void sort_options() {
|
||||
std::sort(options.begin(), options.end(), [](const Option& o1, const Option& o2) {
|
||||
return o1.label < o2.label; });
|
||||
}
|
||||
void sort_found() {
|
||||
std::sort(found.begin(), found.end(), [](const FoundOption& f1, const FoundOption& f2) {
|
||||
return f1.outScore > f2.outScore; });
|
||||
};
|
||||
|
||||
size_t options_size() const { return options.size(); }
|
||||
size_t found_size() const { return found.size(); }
|
||||
|
||||
public:
|
||||
OptionViewParameters view_params;
|
||||
|
||||
SearchDialog* search_dialog { nullptr };
|
||||
|
||||
OptionsSearcher();
|
||||
~OptionsSearcher();
|
||||
|
||||
void init(std::vector<InputInfo> input_values);
|
||||
void apply(DynamicPrintConfig *config,
|
||||
Preset::Type type,
|
||||
ConfigOptionMode mode);
|
||||
bool search();
|
||||
bool search(const std::string& search, bool force = false);
|
||||
|
||||
void add_key(const std::string& opt_key, const wxString& group, const wxString& category);
|
||||
|
||||
size_t size() const { return found_size(); }
|
||||
|
||||
const FoundOption& operator[](const size_t pos) const noexcept { return found[pos]; }
|
||||
const Option& get_option(size_t pos_in_filter) const;
|
||||
|
||||
const std::vector<FoundOption>& found_options() { return found; }
|
||||
const GroupAndCategory& get_group_and_category (const std::string& opt_key) { return groups_and_categories[opt_key]; }
|
||||
std::string& search_string() { return search_line; }
|
||||
};
|
||||
|
||||
|
||||
class SearchComboPopup : public wxListBox, public wxComboPopup
|
||||
{
|
||||
public:
|
||||
// Initialize member variables
|
||||
void Init();
|
||||
|
||||
// Create popup control
|
||||
virtual bool Create(wxWindow* parent);
|
||||
// Return pointer to the created control
|
||||
virtual wxWindow* GetControl() { return this; }
|
||||
|
||||
// Translate string into a list selection
|
||||
virtual void SetStringValue(const wxString& s);
|
||||
// Get list selection as a string
|
||||
virtual wxString GetStringValue() const {
|
||||
// we shouldn't change a combo control's string
|
||||
return m_input_string;
|
||||
}
|
||||
|
||||
void ProcessSelection(int selection);
|
||||
|
||||
// Do mouse hot-tracking (which is typical in list popups)
|
||||
void OnMouseMove(wxMouseEvent& event);
|
||||
// On mouse left up, set the value and close the popup
|
||||
void OnMouseClick(wxMouseEvent& WXUNUSED(event));
|
||||
// process Up/Down arrows and Enter press
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
|
||||
protected:
|
||||
wxString m_input_string;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
// SearchDialog
|
||||
//------------------------------------------
|
||||
|
||||
class SearchDialog : public GUI::DPIDialog
|
||||
{
|
||||
wxString search_str;
|
||||
wxString default_string;
|
||||
|
||||
wxTextCtrl* search_line { nullptr };
|
||||
wxListBox* search_list { nullptr };
|
||||
wxCheckBox* check_type { nullptr };
|
||||
wxCheckBox* check_category { nullptr };
|
||||
wxCheckBox* check_group { nullptr };
|
||||
|
||||
OptionsSearcher* searcher;
|
||||
|
||||
void update_list();
|
||||
|
||||
void OnInputText(wxCommandEvent& event);
|
||||
void OnLeftUpInTextCtrl(wxEvent& event);
|
||||
|
||||
void OnMouseMove(wxMouseEvent& event);
|
||||
void OnMouseClick(wxMouseEvent& event);
|
||||
void OnSelect(wxCommandEvent& event);
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
|
||||
void OnCheck(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
SearchDialog(OptionsSearcher* searcher);
|
||||
~SearchDialog() {}
|
||||
|
||||
void Popup(wxPoint position = wxDefaultPosition);
|
||||
void ProcessSelection(int selection);
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
};
|
||||
|
||||
|
||||
} // Search namespace
|
||||
}
|
||||
|
||||
#endif //slic3r_SearchComboBox_hpp_
|
File diff suppressed because it is too large
Load diff
|
@ -33,6 +33,7 @@
|
|||
#include "Event.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "ConfigManipulation.hpp"
|
||||
#include "Search.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
@ -49,7 +50,7 @@ class Page : public wxScrolledWindow
|
|||
wxBoxSizer* m_vsizer;
|
||||
bool m_show = true;
|
||||
public:
|
||||
Page(wxWindow* parent, const wxString title, const int iconID, const std::vector<ScalableBitmap>& mode_bmp_cache) :
|
||||
Page(wxWindow* parent, const wxString& title, const int iconID, const std::vector<ScalableBitmap>& mode_bmp_cache) :
|
||||
m_parent(parent),
|
||||
m_title(title),
|
||||
m_iconID(iconID),
|
||||
|
@ -121,6 +122,7 @@ protected:
|
|||
std::string m_name;
|
||||
const wxString m_title;
|
||||
PresetBitmapComboBox* m_presets_choice;
|
||||
ScalableButton* m_search_btn;
|
||||
ScalableButton* m_btn_save_preset;
|
||||
ScalableButton* m_btn_delete_preset;
|
||||
ScalableButton* m_btn_hide_incompatible_presets;
|
||||
|
@ -221,6 +223,21 @@ protected:
|
|||
bool m_completed { false };
|
||||
ConfigOptionMode m_mode = comExpert; // to correct first Tab update_visibility() set mode to Expert
|
||||
|
||||
struct Highlighter
|
||||
{
|
||||
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
|
||||
void init(BlinkingBitmap* bmp);
|
||||
void blink();
|
||||
|
||||
private:
|
||||
void invalidate();
|
||||
|
||||
BlinkingBitmap* bbmp {nullptr};
|
||||
int blink_counter {0};
|
||||
wxTimer timer;
|
||||
}
|
||||
m_highlighter;
|
||||
|
||||
public:
|
||||
PresetBundle* m_preset_bundle;
|
||||
bool m_show_btn_incompatible_presets = false;
|
||||
|
@ -233,6 +250,10 @@ public:
|
|||
// Used for options which don't have corresponded field
|
||||
std::map<std::string, wxStaticText*> m_colored_Labels;
|
||||
|
||||
// map of option name -> BlinkingBitmap (blinking ikon, associated with option)
|
||||
// Used for options which don't have corresponded field
|
||||
std::map<std::string, BlinkingBitmap*> m_blinking_ikons;
|
||||
|
||||
// Counter for the updating (because of an update() function can have a recursive behavior):
|
||||
// 1. increase value from the very beginning of an update() function
|
||||
// 2. decrease value at the end of an update() function
|
||||
|
@ -299,6 +320,7 @@ public:
|
|||
void update_visibility();
|
||||
virtual void msw_rescale();
|
||||
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
|
||||
Field* get_field(const t_config_option_key &opt_key, Page** selected_page, int opt_index = -1);
|
||||
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
|
||||
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
|
||||
bool current_preset_is_dirty();
|
||||
|
@ -310,6 +332,8 @@ public:
|
|||
void on_value_change(const std::string& opt_key, const boost::any& value);
|
||||
|
||||
void update_wiping_button_visibility();
|
||||
void activate_option(const std::string& opt_key, const wxString& category);
|
||||
void apply_searcher();
|
||||
|
||||
protected:
|
||||
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, widget_t widget);
|
||||
|
|
223
src/slic3r/GUI/fts_fuzzy_match.h
Normal file
223
src/slic3r/GUI/fts_fuzzy_match.h
Normal file
|
@ -0,0 +1,223 @@
|
|||
// LICENSE
|
||||
//
|
||||
// This software is dual-licensed to the public domain and under the following
|
||||
// license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||
// publish, and distribute this file as you see fit.
|
||||
//
|
||||
// VERSION
|
||||
// 0.2.0 (2017-02-18) Scored matches perform exhaustive search for best score
|
||||
// 0.1.0 (2016-03-28) Initial release
|
||||
//
|
||||
// AUTHOR
|
||||
// Forrest Smith
|
||||
//
|
||||
// NOTES
|
||||
// Compiling
|
||||
// You MUST add '#define FTS_FUZZY_MATCH_IMPLEMENTATION' before including this header in ONE source file to create implementation.
|
||||
//
|
||||
// fuzzy_match_simple(...)
|
||||
// Returns true if each character in pattern is found sequentially within str
|
||||
//
|
||||
// fuzzy_match(...)
|
||||
// Returns true if pattern is found AND calculates a score.
|
||||
// Performs exhaustive search via recursion to find all possible matches and match with highest score.
|
||||
// Scores values have no intrinsic meaning. Possible score range is not normalized and varies with pattern.
|
||||
// Recursion is limited internally (default=10) to prevent degenerate cases (pattern="aaaaaa" str="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
||||
// Uses uint8_t for match indices. Therefore patterns are limited to 256 characters.
|
||||
// Score system should be tuned for YOUR use case. Words, sentences, file names, or method names all prefer different tuning.
|
||||
|
||||
|
||||
#ifndef FTS_FUZZY_MATCH_H
|
||||
#define FTS_FUZZY_MATCH_H
|
||||
|
||||
|
||||
#include <cstdint> // uint8_t
|
||||
#include <ctype.h> // ::tolower, ::toupper
|
||||
#include <cstring> // memcpy
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
// Public interface
|
||||
namespace fts {
|
||||
static bool fuzzy_match_simple(char const * pattern, char const * str);
|
||||
static bool fuzzy_match(char const * pattern, char const * str, int & outScore);
|
||||
static bool fuzzy_match(char const * pattern, char const * str, int & outScore, uint8_t * matches, int maxMatches);
|
||||
}
|
||||
|
||||
|
||||
#ifdef FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
namespace fts {
|
||||
|
||||
// Forward declarations for "private" implementation
|
||||
namespace fuzzy_internal {
|
||||
static bool fuzzy_match_recursive(const char * pattern, const char * str, int & outScore, const char * strBegin,
|
||||
uint8_t const * srcMatches, uint8_t * newMatches, int maxMatches, int nextMatch,
|
||||
int & recursionCount, int recursionLimit);
|
||||
}
|
||||
|
||||
// Public interface
|
||||
static bool fuzzy_match_simple(char const * pattern, char const * str) {
|
||||
while (*pattern != '\0' && *str != '\0') {
|
||||
if (tolower(*pattern) == tolower(*str))
|
||||
++pattern;
|
||||
++str;
|
||||
}
|
||||
|
||||
return *pattern == '\0' ? true : false;
|
||||
}
|
||||
|
||||
static bool fuzzy_match(char const * pattern, char const * str, int & outScore) {
|
||||
|
||||
uint8_t matches[256];
|
||||
return fuzzy_match(pattern, str, outScore, matches, sizeof(matches));
|
||||
}
|
||||
|
||||
static bool fuzzy_match(char const * pattern, char const * str, int & outScore, uint8_t * matches, int maxMatches) {
|
||||
int recursionCount = 0;
|
||||
int recursionLimit = 10;
|
||||
|
||||
return fuzzy_internal::fuzzy_match_recursive(pattern, str, outScore, str, nullptr, matches, maxMatches, 0, recursionCount, recursionLimit);
|
||||
}
|
||||
|
||||
// Private implementation
|
||||
static bool fuzzy_internal::fuzzy_match_recursive(const char * pattern, const char * str, int & outScore,
|
||||
const char * strBegin, uint8_t const * srcMatches, uint8_t * matches, int maxMatches,
|
||||
int nextMatch, int & recursionCount, int recursionLimit)
|
||||
{
|
||||
// Count recursions
|
||||
++recursionCount;
|
||||
if (recursionCount >= recursionLimit)
|
||||
return false;
|
||||
|
||||
// Detect end of strings
|
||||
if (*pattern == '\0' || *str == '\0')
|
||||
return false;
|
||||
|
||||
// Recursion params
|
||||
bool recursiveMatch = false;
|
||||
uint8_t bestRecursiveMatches[256];
|
||||
int bestRecursiveScore = 0;
|
||||
|
||||
// Loop through pattern and str looking for a match
|
||||
bool first_match = true;
|
||||
while (*pattern != '\0' && *str != '\0') {
|
||||
|
||||
// Found match
|
||||
if (tolower(*pattern) == tolower(*str)) {
|
||||
|
||||
// Supplied matches buffer was too short
|
||||
if (nextMatch >= maxMatches)
|
||||
return false;
|
||||
|
||||
// "Copy-on-Write" srcMatches into matches
|
||||
if (first_match && srcMatches) {
|
||||
memcpy(matches, srcMatches, nextMatch);
|
||||
first_match = false;
|
||||
}
|
||||
|
||||
// Recursive call that "skips" this match
|
||||
uint8_t recursiveMatches[256];
|
||||
int recursiveScore;
|
||||
if (fuzzy_match_recursive(pattern, str + 1, recursiveScore, strBegin, matches, recursiveMatches, sizeof(recursiveMatches), nextMatch, recursionCount, recursionLimit)) {
|
||||
|
||||
// Pick best recursive score
|
||||
if (!recursiveMatch || recursiveScore > bestRecursiveScore) {
|
||||
memcpy(bestRecursiveMatches, recursiveMatches, 256);
|
||||
bestRecursiveScore = recursiveScore;
|
||||
}
|
||||
recursiveMatch = true;
|
||||
}
|
||||
|
||||
// Advance
|
||||
matches[nextMatch++] = (uint8_t)(str - strBegin);
|
||||
++pattern;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
|
||||
// Determine if full pattern was matched
|
||||
bool matched = *pattern == '\0' ? true : false;
|
||||
|
||||
// Calculate score
|
||||
if (matched) {
|
||||
const int sequential_bonus = 15; // bonus for adjacent matches
|
||||
const int separator_bonus = 30; // bonus if match occurs after a separator
|
||||
const int camel_bonus = 30; // bonus if match is uppercase and prev is lower
|
||||
const int first_letter_bonus = 15; // bonus if the first letter is matched
|
||||
|
||||
const int leading_letter_penalty = -5; // penalty applied for every letter in str before the first match
|
||||
const int max_leading_letter_penalty = -15; // maximum penalty for leading letters
|
||||
const int unmatched_letter_penalty = -1; // penalty for every letter that doesn't matter
|
||||
|
||||
// Iterate str to end
|
||||
while (*str != '\0')
|
||||
++str;
|
||||
|
||||
// Initialize score
|
||||
outScore = 100;
|
||||
|
||||
// Apply leading letter penalty
|
||||
int penalty = leading_letter_penalty * matches[0];
|
||||
if (penalty < max_leading_letter_penalty)
|
||||
penalty = max_leading_letter_penalty;
|
||||
outScore += penalty;
|
||||
|
||||
// Apply unmatched penalty
|
||||
int unmatched = (int)(str - strBegin) - nextMatch;
|
||||
outScore += unmatched_letter_penalty * unmatched;
|
||||
|
||||
// Apply ordering bonuses
|
||||
for (int i = 0; i < nextMatch; ++i) {
|
||||
uint8_t currIdx = matches[i];
|
||||
|
||||
if (i > 0) {
|
||||
uint8_t prevIdx = matches[i - 1];
|
||||
|
||||
// Sequential
|
||||
if (currIdx == (prevIdx + 1))
|
||||
outScore += sequential_bonus;
|
||||
}
|
||||
|
||||
// Check for bonuses based on neighbor character value
|
||||
if (currIdx > 0) {
|
||||
// Camel case
|
||||
// ::islower() expects an unsigned char in range of 0 to 255.
|
||||
unsigned char uneighbor = ((unsigned char *)strBegin)[currIdx - 1];
|
||||
unsigned char ucurr = ((unsigned char*)strBegin)[currIdx];
|
||||
if (::islower(uneighbor) && ::isupper(ucurr))
|
||||
outScore += camel_bonus;
|
||||
|
||||
// Separator
|
||||
char neighbor = strBegin[currIdx - 1];
|
||||
bool neighborSeparator = neighbor == '_' || neighbor == ' ';
|
||||
if (neighborSeparator)
|
||||
outScore += separator_bonus;
|
||||
}
|
||||
else {
|
||||
// First letter
|
||||
outScore += first_letter_bonus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return best result
|
||||
if (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {
|
||||
// Recursive score is better than "this"
|
||||
memcpy(matches, bestRecursiveMatches, maxMatches);
|
||||
outScore = bestRecursiveScore;
|
||||
return true;
|
||||
}
|
||||
else if (matched) {
|
||||
// "this" score is better than recursive
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// no match
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace fts
|
||||
|
||||
#endif // FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
|
||||
#endif // FTS_FUZZY_MATCH_H
|
|
@ -943,5 +943,40 @@ void ScalableButton::msw_rescale()
|
|||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// BlinkingBitmap
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
BlinkingBitmap::BlinkingBitmap(wxWindow* parent, const std::string& icon_name) :
|
||||
wxStaticBitmap(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(int(1.6 * Slic3r::GUI::wxGetApp().em_unit()), -1))
|
||||
{
|
||||
bmp = ScalableBitmap(parent, icon_name);
|
||||
}
|
||||
|
||||
void BlinkingBitmap::msw_rescale()
|
||||
{
|
||||
bmp.msw_rescale();
|
||||
this->SetSize(bmp.GetBmpSize());
|
||||
this->SetMinSize(bmp.GetBmpSize());
|
||||
}
|
||||
|
||||
void BlinkingBitmap::invalidate()
|
||||
{
|
||||
this->SetBitmap(wxNullBitmap);
|
||||
}
|
||||
|
||||
void BlinkingBitmap::activate()
|
||||
{
|
||||
this->SetBitmap(bmp.bmp());
|
||||
show = true;
|
||||
}
|
||||
|
||||
void BlinkingBitmap::blink()
|
||||
{
|
||||
show = !show;
|
||||
this->SetBitmap(show ? bmp.bmp() : wxNullBitmap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue