Merge branch 'master' into material-theme

This commit is contained in:
Uwe Rathmann 2022-04-16 12:27:25 +02:00
commit 87c9bcd85c
59 changed files with 1170 additions and 446 deletions

121
.github/workflows/qmake.yml vendored Normal file
View File

@ -0,0 +1,121 @@
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build-linux:
name: Linux build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Cache Qt
id: cache-qt
uses: actions/cache@v1 # not v2!
with:
path: ../Qt
key: ${{ runner.os }}-QtCache
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: '5.15.2'
host: 'linux'
target: 'desktop'
install-deps: 'true'
modules: 'qtwebengine'
cached: ${{ steps.cache-qt.outputs.cache-hit }}
setup-python: 'true'
tools: ''
set-env: 'true'
tools-only: 'false'
- name: Ubuntu and Qt version
run: |
cat /etc/issue
echo number of processors: $(nproc)
qmake -v
- name: qmake
run: qmake qskinny.pro
- name: make
run: make -j$(nproc)
build-windows:
name: Windows build
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Cache Qt
id: cache-qt
uses: actions/cache@v1 # not v2!
with:
path: ../Qt
key: ${{ runner.os }}-QtCache
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: '5.15.2'
host: 'windows'
target: 'desktop'
arch: 'win64_msvc2019_64'
install-deps: 'true'
modules: 'qtwebengine'
cached: ${{ steps.cache-qt.outputs.cache-hit }}
setup-python: 'true'
tools: ''
set-env: 'true'
tools-only: 'false'
- uses: ilammy/msvc-dev-cmd@v1
- name: Qt version
run: qmake -v
- name: qmake
run: qmake qskinny.pro
- name: jom
run: |
Invoke-WebRequest -Uri "https://download.qt.io/official_releases/jom/jom.zip" -OutFile jom.zip
unzip jom.zip
.\jom
build-mac:
name: MacOS build
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Cache Qt
id: cache-qt
uses: actions/cache@v1 # not v2!
with:
path: ../Qt
key: ${{ runner.os }}-QtCache
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: '5.15.2'
host: 'mac'
target: 'desktop'
install-deps: 'true'
modules: 'qtwebengine'
cached: ${{ steps.cache-qt.outputs.cache-hit }}
setup-python: 'true'
tools: ''
set-env: 'true'
tools-only: 'false'
- name: MacOS and Qt version
run: |
sw_vers
echo number of processors: $(sysctl -n hw.ncpu)
qmake -v
- name: qmake
run: qmake qskinny.pro
- name: make
run: make -j$(sysctl -n hw.ncpu)

View File

@ -1,5 +1,7 @@
# QSkinny
![](https://github.com/uwerat/qskinny/workflows/CI/badge.svg)
The (Q)Skinny library is a framework built on top of the Qt scene graph
and very few core classes from Qt/Quick. It offers a set of lightweight controls,
that can be used from C++ and/or QML.

View File

@ -1,4 +1,4 @@
# Doxyfile 1.9.1
# Doxyfile 1.9.3
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@ -93,14 +93,6 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@ -248,16 +240,16 @@ TAB_SIZE = 4
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# "sideeffect=@par Side Effects:^^"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
# "Side Effects:". Note that you cannot put \n's in the value part of an alias
# to insert newlines (in the resulting output). You can put ^^ in the value part
# of an alias to insert a newline as if a physical newline was in the original
# file. When you need a literal { or } or , in the value part of an alias you
# have to escape them by means of a backslash (\), this can lead to conflicts
# with the commands \{ and \} for these it is advised to use the version @{ and
# @} or use a double escape (\\{ and \\})
ALIASES = "accessors=\par Access functions:^^" \
"subcontrols=\par Subcontrols:^^" \
@ -307,8 +299,8 @@ OPTIMIZE_OUTPUT_SLICE = NO
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,
# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files). For instance to make doxygen treat .inc files
@ -461,7 +453,7 @@ LOOKUP_CACHE_SIZE = 0
# than 0 to get more control over the balance between CPU load and processing
# speed. At this moment only the input processing can be done using multiple
# threads. Since this is still an experimental feature the default is set to 1,
# which efficively disables parallel processing. Please report any issues you
# which effectively disables parallel processing. Please report any issues you
# encounter. Generating dot graphs in parallel is controlled by the
# DOT_NUM_THREADS setting.
# Minimum value: 0, maximum value: 32, default value: 1.
@ -605,6 +597,12 @@ HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class
# will show which file needs to be included to use the class.
# The default value is: YES.
SHOW_HEADERFILE = YES
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
# The default value is: YES.
@ -762,7 +760,8 @@ FILE_VERSION_FILTER =
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option. You can
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
# will be used as the name of the layout file.
# will be used as the name of the layout file. See also section "Changing the
# layout of pages" for information.
#
# Note that if you run doxygen from a directory containing a file called
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
@ -808,18 +807,26 @@ WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some parameters
# in a documented function, or documenting parameters that don't exist or using
# markup commands wrongly.
# potential errors in the documentation, such as documenting some parameters in
# a documented function twice, or documenting parameters that don't exist or
# using markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete
# function parameter documentation. If set to NO, doxygen will accept that some
# parameters have no documentation without warning.
# The default value is: YES.
WARN_IF_INCOMPLETE_DOC = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# value. If set to NO, doxygen will only warn about wrong parameter
# documentation, but not about the absence of documentation. If EXTRACT_ALL is
# set to YES then this flag will automatically be disabled. See also
# WARN_IF_INCOMPLETE_DOC
# The default value is: NO.
WARN_NO_PARAMDOC = NO
@ -845,7 +852,10 @@ WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
# error (stderr).
# error (stderr). In case the file specified cannot be opened for writing the
# warning and error messages are written to standard error. When as file - is
# specified the warning and error messages are written to standard output
# (stdout).
WARN_LOGFILE = Doxygen.log
@ -885,10 +895,10 @@ INPUT_ENCODING = UTF-8
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
# *.ucf, *.qsf and *.ice.
# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS =
@ -927,7 +937,7 @@ EXCLUDE_PATTERNS = *Private.* moc*.cpp *.moc
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
# ANamespace::AClass, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
@ -1104,44 +1114,6 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see:
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
# performance. This can be particularly helpful with template rich C++ code for
# which doxygen's built-in parser lacks the necessary type information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = YES
# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
# YES then doxygen will add the directory of each input to the include path.
# The default value is: YES.
CLANG_ADD_INC_PATHS = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the directory containing a file called compile_commands.json. This
# file is the compilation database (see:
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
# options used when the source files were built. This is equivalent to
# specifying the -p option to a clang tool, such as clang-check. These options
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
# will be added as well.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@ -1253,7 +1225,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# this color. Hue is specified as an angle on a color-wheel, see
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
@ -1263,7 +1235,7 @@ HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 30
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
# in the HTML output. For a value of 0 the output will use gray-scales only. A
# value of 255 will produce the most vivid colors.
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
@ -1345,6 +1317,13 @@ GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
# This tag determines the URL of the docset feed. A documentation feed provides
# an umbrella under which multiple documentation sets from a single provider
# (such as a company or product suite) can be grouped.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_FEEDURL =
# This tag specifies a string that should uniquely identify the documentation
# set bundle. This should be a reverse domain-name style string, e.g.
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
@ -1370,8 +1349,12 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see:
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
# on Windows. In the beginning of 2021 Microsoft took the original page, with
# a.o. the download links, offline the HTML help workshop was already many years
# in maintenance mode). You can download the HTML help workshop from the web
# archives at Installation executable (see:
# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo
# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
@ -1530,16 +1513,28 @@ DISABLE_INDEX = NO
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
# the same information as the tab index, you could consider setting
# DISABLE_INDEX to YES when enabling this option.
# further fine tune the look of the index (see "Fine-tuning the output"). As an
# example, the default style sheet generated by doxygen has an example that
# shows how to put an image at the root of the tree instead of the PROJECT_NAME.
# Since the tree basically has the same information as the tab index, you could
# consider setting DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = YES
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
# area (value NO) or if it should extend to the full height of the window (value
# YES). Setting this to YES gives a layout similar to
# https://docs.readthedocs.io with more room for contents, but less room for the
# project logo, title, and description. If either GENERATE_TREEVIEW or
# DISABLE_INDEX is set to NO, this option has no effect.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
FULL_SIDEBAR = YES
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
#
@ -1564,6 +1559,13 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
# addresses.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
OBFUSCATE_EMAILS = YES
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
@ -1612,11 +1614,29 @@ FORMULA_MACROFILE =
USE_MATHJAX = NO
# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.
# Note that the different versions of MathJax have different requirements with
# regards to the different settings, so it is possible that also other MathJax
# settings have to be changed when switching between the different MathJax
# versions.
# Possible values are: MathJax_2 and MathJax_3.
# The default value is: MathJax_2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_VERSION = MathJax_2
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
# the MathJax output. For more details about the output format see MathJax
# version 2 (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3
# (see:
# http://docs.mathjax.org/en/latest/web/components/output.html).
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# compatibility. This is the name for Mathjax version 2, for MathJax version 3
# this will be translated into chtml), NativeMML (i.e. MathML. Only supported
# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This
# is the name for Mathjax version 3, for MathJax version 2 this will be
# translated into HTML-CSS) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.
@ -1629,15 +1649,21 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# MathJax from https://www.mathjax.org before deployment. The default value is:
# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2
# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# for MathJax version 2 (see
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# For example for MathJax version 3 (see
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
# MATHJAX_EXTENSIONS = ams
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
@ -1817,29 +1843,31 @@ PAPER_TYPE = a4
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
# chapter. If it is left blank doxygen will generate a standard header. See
# section "Doxygen usage" for information on how to let doxygen write the
# default header to a separate file.
# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for
# the generated LaTeX document. The header should contain everything until the
# first chapter. If it is left blank doxygen will generate a standard header. It
# is highly recommended to start with a default header using
# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty
# and then modify the file new_header.tex. See also section "Doxygen usage" for
# information on how to generate the default header that doxygen normally uses.
#
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
# string, for the replacement values of the other commands the user is referred
# to HTML_HEADER.
# Note: Only use a user-defined header if you know what you are doing!
# Note: The header is subject to change so you typically have to regenerate the
# default header when upgrading to a newer version of doxygen. The following
# commands have a special meaning inside the header (and footer): For a
# description of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
# chapter. If it is left blank doxygen will generate a standard footer. See
# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for
# the generated LaTeX document. The footer should contain everything after the
# last chapter. If it is left blank doxygen will generate a standard footer. See
# LATEX_HEADER for more information on how to generate a default footer and what
# special commands can be used inside the footer.
#
# Note: Only use a user-defined footer if you know what you are doing!
# special commands can be used inside the footer. See also section "Doxygen
# usage" for information on how to generate the default footer that doxygen
# normally uses. Note: Only use a user-defined footer if you know what you are
# doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
@ -1884,8 +1912,7 @@ USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
# command to the generated LaTeX files. This will instruct LaTeX to keep running
# if errors occur, instead of asking the user for help. This option is also used
# when generating formulas in HTML.
# if errors occur, instead of asking the user for help.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@ -1898,16 +1925,6 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@ -1988,16 +2005,6 @@ RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@ -2094,15 +2101,6 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@ -2249,7 +2247,7 @@ SKIP_FUNCTION_MACROS = YES
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
TAGFILES = # TODO: see https://www.qt.io/blog/2014/08/13/qt-weekly-17-linking-qt-classes-in-documentation-generated-with-doxygen
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
@ -2282,15 +2280,6 @@ EXTERNAL_PAGES = YES
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
@ -2309,7 +2298,7 @@ HIDE_UNDOC_RELATIONS = YES
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: YES.
# The default value is: NO.
HAVE_DOT = YES
@ -2347,11 +2336,14 @@ DOT_FONTSIZE = 10
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
# graph for each documented class showing the direct and indirect inheritance
# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
# to TEXT the direct and indirect inheritance relations will be shown as texts /
# links.
# Possible values are: NO, YES, TEXT and GRAPH.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
@ -2480,6 +2472,13 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
# of child directories generated in directory dependency graphs by dot.
# Minimum value: 1, maximum value: 25, default value: 1.
# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
DIR_GRAPH_MAX_DEPTH = 1
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
@ -2487,9 +2486,7 @@ DIRECTORY_GRAPH = YES
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png.
@ -2535,10 +2532,10 @@ MSCFILE_DIRS =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
# PlantUML is not used or called during a preprocessing step. Doxygen will
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
# path where java can find the plantuml.jar file or to the filename of jar file
# to be used. If left blank, it is assumed PlantUML is not used or called during
# a preprocessing step. Doxygen will generate a warning when it encounters a
# \startuml command in this case and will not generate output for the diagram.
PLANTUML_JAR_PATH =
@ -2600,6 +2597,8 @@ DOT_MULTI_TARGETS = NO
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
# graphical representation for inheritance and collaboration diagrams is used.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@ -2608,8 +2607,8 @@ GENERATE_LEGEND = NO
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# files that are used to generate the various graphs.
#
# Note: This setting is not only used for dot files but also for msc and
# plantuml temporary files.
# Note: This setting is not only used for dot files but also for msc temporary
# files.
# The default value is: YES.
DOT_CLEANUP = YES

View File

@ -43,27 +43,6 @@
QQuickItem::focusOutEvent()
*/
/*!
\enum QskControl::LayoutHint
Hints, that can be used by the layout code
\sa setLayoutHint(), testLayoutHint(), setLayoutHints(), layoutHints()
setAutoLayoutChildren(), QskLinearBox, QskGridBox, QskStackBox
\var QskControl::RetainSizeWhenHidden
When being enabled the layout code should retain the necessary space
for the control even when it is hidden.
\saqt QSizePolicy::retainSizeWhenHidden()
\var QskControl::LayoutWhenHidden
When being enabled the layout code should set the geometry
to the control - even if it is not visible.
*/
/*!
\property QLocale QskControl::locale
@ -168,6 +147,14 @@
\property QskSizePolicy QskControl::sizePolicy
\accessors sizePolicy(), setSizePolicy()
\sa placementPolicy
*/
/*!
\property QskPlacementPolicy QskControl::placementPolicy
\accessors placementPolicy(), setPlacementPolicy()
\sa sizePolicy, effectivePlacementPolicy()
*/
/*!
@ -553,6 +540,40 @@
\return Height or width related part of the \ref sizePolicy property
*/
/*!
\fn QskControl::setPlacementPolicy( QskPlacementPolicy )
\sa placementPolicy, effectivePlacementPolicy
*/
/*!
QskControl::setPlacementPolicy( QskPlacementPolicy::Policy, QskPlacementPolicy::Policy )
\sa placementPolicy, effectivePlacementPolicy
/*!
void QskControl::setPlacementPolicy( Qsk::Visibilities, QskPlacementPolicy::Policy );
\sa placementPolicy, effectivePlacementPolicy()
*/
/*!
QskControl::placementPolicy() const;
\sa placementPolicy, effectivePlacementPolicy()
*/
/*!
QskControl::placementPolicy( Qsk::Visibility ) const;
\sa placementPolicy, effectivePlacementPolicy()
*/
/*!
QskControl::effectivePlacementPolicy() const;
*/
/*!
\fn QskControl::setLayoutAlignmentHint
@ -563,26 +584,6 @@
*/
/*!
\fn QskControl::setLayoutHint
*/
/*!
\fn QskControl::testLayoutHint
*/
/*!
\fn QskControl::setLayoutHints
*/
/*!
\fn QskControl::layoutHints
*/
/*!
\fn QskControl::isVisibleToLayout

View File

@ -0,0 +1,37 @@
/*!
\namespace Qsk
\ingroup Framework
\brief Global definitions
*/
/*!
\enum Qsk::Direction
\brief This enum type specifies a horizontal ot vertical direction
\var Qsk::LeftToRight
Horizontally from left to right
\var Qsk::RightToLeft
Horizontally from right to left
\var Qsk::TopToBottom
Vertically from top to bottom
\var Qsk::BottomToTop
Vertically from bottom to top
*/
/*!
\enum Qsk::Visibility
\brief Visibility of an object
\var Qsk::Visible
The object is visible
\var Qsk::Hidden
The object is not visible
*/

View File

@ -0,0 +1,183 @@
/*!
\class QskPlacementPolicy QskPlacementPolicy.h
\ingroup Framework
QskPlacementPolicy is a hint for layout code how to deal with
the geometry of an item depending on its visibility.
\sa QskControl::placementPolicy(), qskPlacementPolicy()
*/
/*!
\enum QskPlacementPolicy::Policy
Hint for the layout code how to deal with the geometry of an
item. QskPlacementPolicy has two values: one for the visible,
the other for the hidden state.
\var QskPlacementPolicy::Ignore
Ignore the item for all type of layout calculations
\var QskPlacementPolicy::Reserve
Reseve space without giving the item its geometry
\var QskPlacementPolicy::Adjust
Reserve space and adjust the geometry of the item
\sa visiblePolicy, hiddenPolicy
*/
/*!
\property QskPlacementPolicy::Policy QskPlacementPolicy::visiblePolicy
\brief Policy for the item, when being visible ( to its parent )
- QskPlacementPolicy::Ignore
For situations where a parent takes care of the geometry for its children,
but the specific item should be omitted. F.e a focus indicator.
- QskPlacementPolicy::Reserve
There are not many relevant scenarios for reserving space for visible items
without adjusting them. An example might be when an item is inside of a
grid box, where all the size hints should have an effect, but the final
alignment of the item inside of the cell has to be done manually.
- QskPlacementPolicy::Adjust:
The default value
\accessors visiblePolicy(), setVisiblePolicy()
\sa hiddenPolicy, QskQuickItem::isVisibleToParent(), qskIsVisibleToParent()
\note QskPlacementPolicy::Ignore is stored in the transparentForPositioner
bit in QQuickItem and might have an impact on Qt/Quick layout code.
*/
/*!
\property QskPlacementPolicy::Policy QskPlacementPolicy::hiddenPolicy
\brief Policy for the item, when being hidden ( to its parent )
- QskPlacementPolicy::Ignore
The default value
- QskPlacementPolicy::Reserve:
In combination with a visiblePolicy != QskPlacementPolicy::Ignore
the layout of the parent does not change, when the item is shown/hidden.
- QskPlacementPolicy::Adjust:
Sometimes an item wants to have its proper size even when being hidden.
\accessors hiddenPolicy(), setHiddenPolicy()
\sa visiblePolicy, QskQuickItem::isVisibleToParent(), qskIsVisibleToParent()
\note QskPlacementPolicy::Ignore is stored in the transparentForPositioner
bit in QQuickItem and might have an impact on Qt/Quick layout code.
\note QskPlacementPolicy::Reserve is equivalent to what is offered by
\saqt QSizePolicy::retainSizeWhenHidden().
*/
/*!
\fn QskPlacementPolicy::QskPlacementPolicy()
\brief Default constructor
QskPlacementPolicy::Adjust is set for Qsk::Visible, while
QskPlacementPolicy::Ignore is used for Qsk::Hidden.
\sa visiblePolicy, hiddenPolicy
*/
/*!
\fn QskPlacementPolicy::QskPlacementPolicy( Policy policy )
visiblePolicy and hiddenPolicy are set to policy
*/
/*!
\fn QskPlacementPolicy::QskPlacementPolicy( Policy visiblePolicy, Policy hiddenPolicy )
Initialization from visiblePolicy and hiddenPolicy
*/
/*!
\fn QskPlacementPolicy::QskPlacementPolicy( Qsk::Visibilities visiblities, Policy policy )
Initialize visiblePolicy and hiddenPolicy depending on visiblities
*/
/*!
\fn QskPlacementPolicy::operator==( const QskPlacementPolicy& )
"Equal to" operator
\sa operator!=(), operator<()
*/
/*!
\fn QskPlacementPolicy::operator!=( const QskPlacementPolicy& )
"Not equal to" operator
\sa operator==(), operator<()
*/
/*!
\fn QskPlacementPolicy::setPolicy( Qsk::Visibilities, Policy )
*/
/*!
\fn QskPlacementPolicy::policy( Qsk::Visibility )
*/
/*!
\fn QskPlacementPolicy::isEffective()
\return true, when visiblePolicy or hiddenPolicy is not QskPlacementPolicy::Ignore
\sa isIgnoring()
*/
/*!
\fn QskPlacementPolicy::isIgnoring( Qsk::Visibility )
\return true, when visiblePolicy and hiddenPolicy are set to QskPlacementPolicy::Ignore
\sa isEffective()
*/
/*!
\fn QskPlacementPolicy::isAdjusting( Qsk::Visibility )
\return true, when QskPlacementPolicy::Adjust is set for the visibility
*/
/*!
\fn QskPlacementPolicy::setVisiblePolicy( Policy )
\sa visiblePolicy(), setHiddenPolicy()
*/
/*!
\fn QskPlacementPolicy::visiblePolicy()
\sa setVisiblePolicy(), hiddenPolicy()
*/
/*!
\fn QskPlacementPolicy::setHiddenPolicy( Policy )
\sa hiddenPolicy(), setVisiblePolicy()
*/
/*!
\fn QskPlacementPolicy::hiddenPolicy()
\sa setHiddenPolicy(), visiblePolicy()
*/

View File

@ -137,7 +137,7 @@
it is necessary to know which children would stay hidden when the container
becomes visible.
\sa isVisibleToParent()
\sa setHidden(), show(), hide(), isVisibleToParent(), qskIsVisibleToParent()
\saqt QQuickItem::setVisible()
*/
@ -226,7 +226,7 @@
\return true once setVisible( false ) has been called
\sa visibleToParent
\sa visibleToParent(), qskIsVisibleToParent()
\saqt QQuickItem::setVisible()
*/
@ -562,7 +562,7 @@
An alternative way to call setVisible( true ).
Useful for signal/slot connections
\sa hide()
\sa hide(), setHidden()
\saqt QQuickItem::setVisible()
*/
@ -579,8 +579,10 @@
/*!
\fn QskQuickItem::setHidden
Convenience function, equivalent to setVisible( !on ).
\saqt QQuickItem::setVisible()
Convenience function, equivalent to setVisible( !on ).
\sa show(), hide()
\saqt QQuickItem::setVisible()
*/
/*!

69
doc/generate-website.md Normal file
View File

@ -0,0 +1,69 @@
# Generating the website
## Prerequisites
You will need:
1. The `documentation-xml-website` branch of the Edelhirsch QSkinny repository
at https://github.com/edelhirsch/qskinny/tree/documentation-xml-website .
1. A recent version of doxygen; The currently used version is 1.9.1 built from
github sources. The `doxygen` binary needs to be in the $PATH.
1. A recent version of doxybook2 with some custom patches. The script
`generate-website.sh` should download and build the right version, however
the script might need some adaptation of paths.
For reference, the required version can be found at
https://github.com/edelhirsch/doxybook2/tree/jekyll .
1. A recent version of Jekyll (see https://jekyllrb.com/), which will generate
the static html pages. This and other required packages can be installed via
```
gem install jekyll:3.9.0
gem install bundler:2.1.4
```
There might be some packages missing from the list above; in this case the
Gemfile in the qskinny-website repository might help.
1. Checkout the current website repository via
`git clone git@github.com:qskinny/qskinny.github.io.git`
## Generating the website
Generating the static HTML sites is done with the `generate-website.sh` script
in the `qskinny/doc` directory. The script has some hardcoded paths and probably
needs some adaptation to run correctly.
It will do the following:
1. Generate HTML from doxygen. This step is needed because for some reason when
generating XML from doxygen there are no images with dependency graphs.
*Note*: This step is only executed if the `html` folder doesn't exist,
because otherwise it would take too long.
1. Generate XML from doxygen. The generated XML is used with doxybook2 in the
next step.
*Note*: This step is only executed if the `xml` folder doesn't exist,
because otherwise it would take too long.
1. Generate markdown from XML with doxybook2. This markdown will be used by
Jekyll to either server the website content locally or generate static
HTML from it, see below.
### Generating the website locally
When the command line switch `-local` is used with the `generate-website.sh`
script, it will generate the content to a local folder `doxybook-out`. This is
meant to be able to copy selected files to the website directory at
`~/dev/qskinny-website`.
Otherwise, the script will copy the content to the website repository for
uploading (again, paths are hardcoded as of now). So when generating content
for the first time, just run the script without any switches, which should
generate the website to `~/dev/qskinny-website`.
### Testing the website locally
After having generated the website as described above, go to
`~/dev/qskinny-website` and run `jekyll serve --livereload`. This should start
a browser at http://127.0.0.1:4000/, which will display the website.
### Generating the website publicly
When the command line switch `-publish` is used, the script will automatically
generate a new version of the homepage and publish it at
https://qskinny.github.io . This wil only work with the proper user rights of
course.

View File

@ -5,7 +5,7 @@
\defgroup Animation Animation
\defgroup Themeing Themeing
\defgroup Controls Controls
\defgroup container Container
\defgroup Container Container
\defgroup Layouts Layouts
\defgroup Dialogs Dialogs
\defgroup Skinlets Skinlets

View File

@ -5,16 +5,16 @@ Qsk.PushButton
{
sizePolicy
{
// long texts, should not have an effect
// long texts, should not have an effect
horizontalPolicy: Qsk.SizePolicy.Ignored
verticalPolicy: Qsk.SizePolicy.Ignored
}
minimumSize
{
width: 80
height: 60
}
minimumSize
{
width: 80
height: 60
}
shape
{

View File

@ -133,7 +133,7 @@ class IconGrid : public QskLinearBox
if ( auto control = qskControlCast( itemAtIndex( i ) ) )
{
// to support the optimizations in ScrollArea::updateVisibilities
control->setLayoutHint( RetainSizeWhenHidden, true );
control->setPlacementPolicy( Qsk::Hidden, QskPlacementPolicy::Reserve );
control->setVisible( false );
}
}
@ -158,7 +158,7 @@ class IconGrid : public QskLinearBox
const int dim = dimension();
// we know, that all items have the same size
const auto itemSize = qskItemSize( itemAtIndex( 0 ) );
const auto itemSize = itemAtIndex( 0 )->size();
const int rowMin = rect.top() / ( itemSize.height() + spacing() );
const int rowMax = rect.bottom() / ( itemSize.height() + spacing() );

View File

@ -119,7 +119,10 @@ void GridSkinny::setAlignmentAt( int index, Qt::Alignment alignment )
void GridSkinny::setRetainSizeWhenHiddenAt( int index, bool on )
{
if ( auto control = qskControlCast( m_grid->itemAtIndex( index ) ) )
control->setLayoutHint( QskControl::RetainSizeWhenHidden, on );
{
control->setPlacementPolicy( Qsk::Hidden,
on ? QskPlacementPolicy::Reserve : QskPlacementPolicy::Ignore );
}
}
void GridSkinny::setVisibleAt( int index, bool on )

View File

@ -5,6 +5,8 @@
#include "TestBox.h"
#include <SkinnyNamespace.h>
#include <QskSizePolicy.h>
#include <QskFunctions.h>
@ -386,6 +388,7 @@ class MainWidget : public QWidget
int main( int argc, char** argv )
{
QApplication app( argc, argv );
Skinny::init();
int testcase = 0;
if ( argc == 2 )

View File

@ -5,13 +5,14 @@
#include "Image.h"
// QQuickImagePrivate is not exported, so we
// we can't derive here
QSK_QT_PRIVATE_BEGIN
#include <private/qquickimage_p_p.h>
QSK_QT_PRIVATE_END
class Image::PrivateData
class ImagePrivate : public QQuickImagePrivate
{
public:
PrivateData()
ImagePrivate()
: sourceSizeAdjustment( false )
, deferredUpdates( true )
, dirtyPolish( false )
@ -27,8 +28,7 @@ class Image::PrivateData
};
Image::Image( QQuickItem* parent )
: Inherited( parent )
, m_data( new PrivateData() )
: QQuickImage( *( new ImagePrivate() ), parent )
{
}
@ -36,50 +36,48 @@ Image::~Image()
{
}
void Image::setVisible( bool on )
{
// QQuickItem::setVisible is no slot
Inherited::setVisible( on );
}
void Image::show()
{
Inherited::setVisible( true );
setVisible( true );
}
void Image::hide()
{
Inherited::setVisible( false );
setVisible( false );
}
void Image::setSourceSizeAdjustment( bool on )
{
if ( on != m_data->sourceSizeAdjustment )
Q_D( Image );
if ( on != d->sourceSizeAdjustment )
{
m_data->sourceSizeAdjustment = on;
d->sourceSizeAdjustment = on;
Q_EMIT sourceSizeAdjustmentChanged();
}
}
bool Image::sourceSizeAdjustment() const
{
return m_data->sourceSizeAdjustment;
return d_func()->sourceSizeAdjustment;
}
void Image::setDeferredUpdates( bool on )
{
if ( on != m_data->deferredUpdates )
Q_D( Image );
if ( on != d->deferredUpdates )
{
m_data->deferredUpdates = on;
d->deferredUpdates = on;
if ( !on )
{
// when having blocked updates we reschedule them
if ( m_data->dirtyPolish )
if ( d->dirtyPolish )
polish();
if ( m_data->dirtyUpdate )
if ( d->dirtyUpdate )
update();
}
}
@ -87,18 +85,20 @@ void Image::setDeferredUpdates( bool on )
bool Image::deferredUpdates() const
{
return m_data->deferredUpdates;
return d_func()->deferredUpdates;
}
void Image::setSourceSize( const QSize& size )
{
if ( !( size.isEmpty() && sourceSize().isEmpty() ) )
QQuickImage::setSourceSize( size );
Inherited::setSourceSize( size );
}
void Image::componentComplete()
{
if ( m_data->deferredUpdates && m_data->sourceSizeAdjustment )
Q_D( const Image );
if ( d->deferredUpdates && d->sourceSizeAdjustment )
{
// QQuickImage::componentComplete() calls load
// long before we have the final geometry
@ -119,12 +119,14 @@ void Image::itemChange( QQuickItem::ItemChange change,
if ( change == ItemVisibleHasChanged )
{
Q_D( const Image );
if ( value.boolValue )
{
if ( m_data->dirtyPolish )
if ( d->dirtyPolish )
polish();
if ( m_data->dirtyUpdate )
if ( d->dirtyUpdate )
update();
}
}
@ -156,9 +158,11 @@ void Image::geometryChanged(
void Image::adjustSourceSize( const QSizeF& size )
{
if ( m_data->sourceSizeAdjustment )
Q_D( const Image );
if ( d->sourceSizeAdjustment )
{
if ( m_data->deferredUpdates )
if ( d->deferredUpdates )
{
setImplicitSize( size.width(), size.height() );
polish();
@ -172,35 +176,39 @@ void Image::adjustSourceSize( const QSizeF& size )
void Image::updatePolish()
{
if ( m_data->deferredUpdates )
Q_D( Image );
if ( d->deferredUpdates )
{
if ( !isVisible() )
{
m_data->dirtyPolish = true;
d->dirtyPolish = true;
return;
}
if ( m_data->sourceSizeAdjustment )
if ( d->sourceSizeAdjustment )
setSourceSize( QSize( int( width() ), int( height() ) ) );
}
m_data->dirtyPolish = false;
d->dirtyPolish = false;
Inherited::updatePolish();
}
QSGNode* Image::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* data )
{
if ( m_data->deferredUpdates )
Q_D( Image );
if ( d->deferredUpdates )
{
if ( !isVisible() )
{
m_data->dirtyUpdate = true;
d->dirtyUpdate = true;
return oldNode;
}
}
m_data->dirtyUpdate = false;
d->dirtyUpdate = false;
return Inherited::updatePaintNode( oldNode, data );
}

View File

@ -19,7 +19,7 @@ QSK_QT_PRIVATE_BEGIN
QSK_QT_PRIVATE_END
#include <memory>
class ImagePrivate;
class Image : public QQuickImage
{
@ -54,7 +54,12 @@ class Image : public QQuickImage
public Q_SLOTS:
void show();
void hide();
#ifdef Q_MOC_RUN
// methods from QQuickItem, we want to be available as string based slots
void setVisible( bool );
void setEnabled( bool );
#endif
Q_SIGNALS:
void sourceSizeAdjustmentChanged();
@ -75,6 +80,5 @@ class Image : public QQuickImage
private:
void adjustSourceSize( const QSizeF& );
class PrivateData;
std::unique_ptr< PrivateData > m_data;
Q_DECLARE_PRIVATE( Image )
};

View File

@ -14,6 +14,26 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
namespace
{
class ImageProvider : public QskGraphicImageProvider
{
public:
ImageProvider( const QString& id )
: QskGraphicImageProvider( id, type() )
{
}
private:
static ImageType type()
{
const auto backend = QQuickWindow::sceneGraphBackend();
return ( backend == "software" ) ? Image : Texture;
}
};
}
int main( int argc, char* argv[] )
{
@ -33,12 +53,10 @@ int main( int argc, char* argv[] )
SkinnyShortcut::enable( SkinnyShortcut::Quit |
SkinnyShortcut::DebugShortcuts );
// image provider that falls back to the graphic provider
QskGraphicImageProvider* imageProvider =
new QskGraphicImageProvider( providerId, QQuickImageProvider::Texture );
QQmlApplicationEngine engine( QUrl( "qrc:/qml/images.qml" ) );
engine.addImageProvider( imageProvider->graphicProviderId(), imageProvider );
// image provider that falls back to the graphic provider above
engine.addImageProvider( providerId, new ImageProvider( providerId ) );
return app.exec();
}

View File

@ -191,8 +191,7 @@ void Editor::setupMenu()
setGradient( Q::Panel, m_pal.background );
const bool isCascading = qskMaybeDesktopPlatform();
setFlagHint( Q::Panel | A::Style, isCascading );
setFlagHint( Q::Panel | A::Style, false ); // not cascading
#if 0
setPadding( Q::Separator, QMarginsF( 10, 0, 10, 0 ) );

View File

@ -194,7 +194,7 @@ static QByteArray qskStatesToString(
for ( int i = 0; i < 16; i++ )
{
const quint16 mask = 1 << i;
const uint mask = 1 << i;
if ( states & mask )
{

View File

@ -39,6 +39,16 @@ namespace Qsk
Sunken
};
Q_ENUM_NS( TextStyle )
enum Visibility
{
Visible = 1 << 0,
Hidden = 1 << 1
};
Q_ENUM_NS( Visibility )
Q_DECLARE_FLAGS( Visibilities, Visibility )
Q_DECLARE_OPERATORS_FOR_FLAGS( Visibilities )
}
#endif

View File

@ -0,0 +1,25 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskPlacementPolicy.h"
#ifndef QT_NO_DEBUG_STREAM
#include <qdebug.h>
QDebug operator<<( QDebug debug, const QskPlacementPolicy policy )
{
QDebugStateSaver saver( debug );
debug.nospace();
debug << "PlacementPolicy" << '(';
debug << policy.visiblePolicy() << ", " << policy.hiddenPolicy();
debug << ')';
return debug;
}
#endif
#include "moc_QskPlacementPolicy.cpp"

View File

@ -0,0 +1,159 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_PLACEMENT_POLICY_H
#define QSK_PLACEMENT_POLICY_H
#include "QskGlobal.h"
#include "QskNamespace.h"
#include <qmetaobject.h>
class QskPlacementPolicy
{
Q_GADGET
Q_PROPERTY( Policy visiblePolicy READ visiblePolicy WRITE setVisiblePolicy )
Q_PROPERTY( Policy hiddenPolicy READ hiddenPolicy WRITE setHiddenPolicy )
public:
enum Policy
{
Ignore,
Reserve,
Adjust
};
Q_ENUM( Policy )
constexpr QskPlacementPolicy() noexcept;
constexpr QskPlacementPolicy( Policy ) noexcept;
constexpr QskPlacementPolicy( Policy visiblePolicy, Policy hiddenPolicy ) noexcept;
constexpr QskPlacementPolicy( Qsk::Visibilities, Policy ) noexcept;
constexpr bool operator==( const QskPlacementPolicy& ) const noexcept;
constexpr bool operator!=( const QskPlacementPolicy& ) const noexcept;
void setPolicy( Qsk::Visibilities, Policy ) noexcept;
constexpr Policy policy( Qsk::Visibility ) const noexcept;
constexpr bool isEffective() const noexcept;
constexpr bool isIgnoring( Qsk::Visibility ) const noexcept;
constexpr bool isAdjusting( Qsk::Visibility ) const noexcept;
void setVisiblePolicy( Policy ) noexcept;
constexpr Policy visiblePolicy() const noexcept;
void setHiddenPolicy( Policy ) noexcept;
constexpr Policy hiddenPolicy() const noexcept;
private:
Policy m_visiblePolicy : 2;
Policy m_hiddenPolicy : 2;
};
inline constexpr QskPlacementPolicy::QskPlacementPolicy() noexcept
: m_visiblePolicy( Adjust )
, m_hiddenPolicy( Ignore )
{
}
inline constexpr QskPlacementPolicy::QskPlacementPolicy(
Policy visiblePolicy, Policy hiddenPolicy ) noexcept
: m_visiblePolicy( visiblePolicy )
, m_hiddenPolicy( hiddenPolicy )
{
}
constexpr QskPlacementPolicy::QskPlacementPolicy( Policy policy ) noexcept
: m_visiblePolicy( policy )
, m_hiddenPolicy( policy )
{
}
constexpr QskPlacementPolicy::QskPlacementPolicy(
Qsk::Visibilities visibilities, Policy policy ) noexcept
: m_visiblePolicy( visibilities & Qsk::Visible ? policy : Adjust )
, m_hiddenPolicy( visibilities & Qsk::Hidden ? policy : Ignore )
{
}
inline constexpr bool QskPlacementPolicy::operator==(
const QskPlacementPolicy& other ) const noexcept
{
return ( other.m_visiblePolicy == m_visiblePolicy ) &&
( other.m_hiddenPolicy == m_hiddenPolicy );
}
inline constexpr bool QskPlacementPolicy::operator!=(
const QskPlacementPolicy& other ) const noexcept
{
return !( *this == other );
}
inline void QskPlacementPolicy::setPolicy(
Qsk::Visibilities visibilities, Policy policy ) noexcept
{
if ( visibilities & Qsk::Visible )
m_visiblePolicy = policy;
if ( visibilities & Qsk::Hidden )
m_hiddenPolicy = policy;
}
inline constexpr QskPlacementPolicy::Policy
QskPlacementPolicy::policy( Qsk::Visibility visibility ) const noexcept
{
return ( visibility == Qsk::Hidden ) ? m_hiddenPolicy : m_visiblePolicy;
}
inline void QskPlacementPolicy::setVisiblePolicy( Policy policy ) noexcept
{
m_visiblePolicy = policy;
}
inline constexpr QskPlacementPolicy::Policy QskPlacementPolicy::visiblePolicy() const noexcept
{
return m_visiblePolicy;
}
inline void QskPlacementPolicy::setHiddenPolicy( Policy policy ) noexcept
{
m_hiddenPolicy = policy;
}
inline constexpr QskPlacementPolicy::Policy QskPlacementPolicy::hiddenPolicy() const noexcept
{
return m_hiddenPolicy;
}
inline constexpr bool QskPlacementPolicy::isEffective() const noexcept
{
return ( m_visiblePolicy != Ignore ) || ( m_hiddenPolicy != Ignore );
}
inline constexpr bool QskPlacementPolicy::isIgnoring( Qsk::Visibility visibility ) const noexcept
{
return ( visibility == Qsk::Visible )
? ( m_visiblePolicy == Ignore ) : ( m_hiddenPolicy == Ignore );
}
inline constexpr bool QskPlacementPolicy::isAdjusting( Qsk::Visibility visibility ) const noexcept
{
return ( visibility == Qsk::Visible )
? ( m_visiblePolicy == Adjust ) : ( m_hiddenPolicy == Adjust );
}
Q_DECLARE_TYPEINFO( QskPlacementPolicy, Q_MOVABLE_TYPE );
Q_DECLARE_METATYPE( QskPlacementPolicy )
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
QSK_EXPORT QDebug operator<<( QDebug, QskPlacementPolicy );
#endif
#endif

View File

@ -42,16 +42,10 @@ const QPlatformIntegration* qskPlatformIntegration()
bool qskMaybeDesktopPlatform()
{
// this is what QC2 is doing for menus ?
#if QT_VERSION >= QT_VERSION_CHECK( 5, 15, 0 )
#if !QT_CONFIG(cursor)
return false;
#endif
#endif
#if QT_CONFIG(cursor)
if ( const auto platform = QGuiApplicationPrivate::platformIntegration() )
return platform->hasCapability( QPlatformIntegration::MultipleWindows );
#endif
return false;
}

View File

@ -188,8 +188,8 @@ void QskRgb::debugColor( QDebug debug, QRgb rgb )
debug << '[';
debug << qRed( rgb ) << "r," << qGreen( rgb ) << "g,"
<< qBlue( rgb ) << 'b';
debug << qRed( rgb ) << "r,"
<< qGreen( rgb ) << "g," << qBlue( rgb ) << 'b';
if ( qAlpha( rgb ) != 255 )
debug << ',' << qAlpha( rgb ) << 'a';

View File

@ -57,7 +57,7 @@ namespace
points[1].set( x + w / 3, y + h );
points[2].set( x + w, y );
}
markDirty( QSGNode::DirtyGeometry );
}
}

View File

@ -350,44 +350,55 @@ Qt::Alignment QskControl::layoutAlignmentHint() const
return static_cast< Qt::Alignment >( d_func()->layoutAlignmentHint );
}
void QskControl::setLayoutHint( LayoutHint flag, bool on )
void QskControl::setPlacementPolicy(
Qsk::Visibilities visibilities, QskPlacementPolicy::Policy policy )
{
auto placementPolicy = this->placementPolicy();
placementPolicy.setPolicy( visibilities, policy );
setPlacementPolicy( placementPolicy );
}
void QskControl::setPlacementPolicy(
QskPlacementPolicy::Policy visiblePolicy, QskPlacementPolicy::Policy hiddenPolicy )
{
setPlacementPolicy( QskPlacementPolicy( visiblePolicy, hiddenPolicy ) );
}
void QskControl::setPlacementPolicy( QskPlacementPolicy policy )
{
Q_D( QskControl );
if ( ( d->layoutHints & flag ) != on )
if ( policy != placementPolicy() )
{
if ( on )
d->layoutHints |= flag;
else
d->layoutHints &= ~flag;
d->setPlacementPolicy( true, policy.visiblePolicy() );
d->setPlacementPolicy( false, policy.hiddenPolicy() );
d->layoutConstraintChanged();
}
}
bool QskControl::testLayoutHint( LayoutHint hint ) const
QskPlacementPolicy QskControl::placementPolicy() const
{
return d_func()->layoutHints & hint;
Q_D( const QskControl );
return QskPlacementPolicy(
d->placementPolicy( true ), d->placementPolicy( false ) );
}
void QskControl::setLayoutHints( LayoutHints hints )
QskPlacementPolicy::Policy QskControl::placementPolicy( Qsk::Visibility visiblity ) const
{
Q_D( QskControl );
if ( hints != layoutHints() )
{
d->layoutHints = hints;
d->layoutConstraintChanged();
}
return d_func()->placementPolicy( visiblity == Qsk::Visible );
}
QskControl::LayoutHints QskControl::layoutHints() const
QskPlacementPolicy::Policy QskControl::effectivePlacementPolicy() const
{
return static_cast< LayoutHints >( d_func()->layoutHints );
return d_func()->placementPolicy( isVisibleToParent() );
}
bool QskControl::isVisibleToLayout() const
{
return !isTransparentForPositioner()
&& ( isVisibleToParent() || ( layoutHints() & RetainSizeWhenHidden ) );
return qskIsVisibleToLayout( this );
}
void QskControl::setPreferredSize( const QSizeF& size )
@ -804,7 +815,7 @@ void QskControl::itemChange( QQuickItem::ItemChange change,
}
case QQuickItem::ItemChildAddedChange:
{
if ( autoLayoutChildren() && !qskIsTransparentForPositioner( value.item ) )
if ( autoLayoutChildren() && qskIsAdjustableByLayout( value.item ) )
polish();
break;
@ -844,13 +855,7 @@ void QskControl::updateItemPolish()
const auto children = childItems();
for ( auto child : children )
{
/*
We don't want to resize invisible children, but then
we would need to set up connections to know when a child
becomes visible. So we don't use qskIsVisibleToLayout here.
And what about using QskControl::LayoutOutWhenHidden ?
*/
if ( !qskIsTransparentForPositioner( child ) )
if ( qskIsAdjustableByLayout( child ) )
{
const auto r = qskConstrainedItemRect( child, rect );
qskSetItemGeometry( child, r );

View File

@ -11,6 +11,7 @@
#include "QskAspect.h"
#include "QskGradient.h"
#include "QskSizePolicy.h"
#include "QskPlacementPolicy.h"
#include <qlocale.h>
#include <memory>
@ -46,6 +47,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
WRITE setBackground RESET resetBackground NOTIFY backgroundChanged )
Q_PROPERTY( QskSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy )
Q_PROPERTY( QskPlacementPolicy placementPolicy READ placementPolicy WRITE setPlacementPolicy )
Q_PROPERTY( QSizeF minimumSize READ minimumSize WRITE setMinimumSize )
Q_PROPERTY( QSizeF maximumSize READ maximumSize WRITE setMaximumSize )
@ -57,22 +59,6 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
public:
QSK_STATES( Disabled, Hovered, Focused )
enum LayoutHint
{
// How to be treated by layouts
RetainSizeWhenHidden = 1 << 0,
/*
Adjust the item even, even when being hidden
Depending on the type of layout the value only works
in combination with RetainSizeWhenHidden
*/
LayoutWhenHidden = 1 << 1
};
Q_ENUM( LayoutHint )
Q_DECLARE_FLAGS( LayoutHints, LayoutHint )
QskControl( QQuickItem* parent = nullptr );
~QskControl() override;
@ -117,8 +103,8 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
void setFocusPolicy( Qt::FocusPolicy );
Qt::FocusPolicy focusPolicy() const;
void setSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy );
void setSizePolicy( QskSizePolicy );
void setSizePolicy( QskSizePolicy::Policy, QskSizePolicy::Policy );
void setSizePolicy( Qt::Orientation, QskSizePolicy::Policy );
QskSizePolicy sizePolicy() const;
@ -128,11 +114,14 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
void setLayoutAlignmentHint( Qt::Alignment );
Qt::Alignment layoutAlignmentHint() const;
void setLayoutHint( LayoutHint, bool on = true );
bool testLayoutHint( LayoutHint ) const;
void setPlacementPolicy( QskPlacementPolicy );
void setPlacementPolicy( QskPlacementPolicy::Policy, QskPlacementPolicy::Policy );
void setPlacementPolicy( Qsk::Visibilities, QskPlacementPolicy::Policy );
void setLayoutHints( LayoutHints );
LayoutHints layoutHints() const;
QskPlacementPolicy placementPolicy() const;
QskPlacementPolicy::Policy placementPolicy( Qsk::Visibility ) const;
QskPlacementPolicy::Policy effectivePlacementPolicy() const;
bool isVisibleToLayout() const;

View File

@ -48,7 +48,8 @@ static inline QPointF qskScenePosition( const QMouseEvent* event )
QskControlPrivate::QskControlPrivate()
: explicitSizeHints( nullptr )
, sizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred )
, layoutHints( 0 )
, visiblePlacementPolicy( 0 )
, hiddenPlacementPolicy( 0 )
, layoutAlignmentHint( 0 )
, explicitLocale( false )
, autoFillBackground( false )
@ -265,3 +266,41 @@ void QskControlPrivate::resolveLocale( QskControl* control )
qskSetup->inheritLocale( control, locale );
}
}
void QskControlPrivate::setPlacementPolicy(
bool visible, QskPlacementPolicy::Policy policy )
{
if ( visible )
{
/*
Ignore corresponds to transparentForPositioner() what is
also respected by Qt/Quick layout classes. So we use this
bit instead of storing it locally.
*/
if ( policy == QskPlacementPolicy::Ignore )
{
this->visiblePlacementPolicy = 0;
setTransparentForPositioner( true );
}
else
{
this->visiblePlacementPolicy =
( policy == QskPlacementPolicy::Reserve ) ? 1 : 0;
if ( isTransparentForPositioner() )
{
/*
This bit is stored in an extra data section, that
gets allocated, when being used the first time.
This also happens when setting it to false, what does
not make much sense, when it has not been allocated before.
*/
setTransparentForPositioner( false );
}
}
}
else
{
this->hiddenPlacementPolicy = policy;
}
}

View File

@ -35,6 +35,9 @@ class QskControlPrivate : public QskQuickItemPrivate
bool maybeGesture( QQuickItem*, QEvent* );
QskPlacementPolicy::Policy placementPolicy( bool visible ) const noexcept;
void setPlacementPolicy( bool visible, QskPlacementPolicy::Policy );
private:
Q_DECLARE_PUBLIC( QskControl )
@ -43,7 +46,10 @@ class QskControlPrivate : public QskQuickItemPrivate
QLocale locale;
QskSizePolicy sizePolicy;
int layoutHints : 4;
unsigned int visiblePlacementPolicy : 1;
unsigned int hiddenPlacementPolicy : 2;
unsigned int layoutAlignmentHint : 8;
bool explicitLocale : 1;
@ -57,4 +63,22 @@ class QskControlPrivate : public QskQuickItemPrivate
mutable bool blockLayoutRequestEvents : 1;
};
inline QskPlacementPolicy::Policy
QskControlPrivate::placementPolicy( const bool visible ) const noexcept
{
using PP = QskPlacementPolicy;
if ( visible )
{
if ( isTransparentForPositioner() )
return PP::Ignore;
return this->visiblePlacementPolicy ? PP::Reserve : PP::Adjust;
}
else
{
return static_cast< PP::Policy >( this->hiddenPlacementPolicy );
}
}
#endif

View File

@ -63,7 +63,7 @@ QskFocusIndicator::QskFocusIndicator( QQuickItem* parent )
: Inherited( parent ) // parentItem() might change, but parent() stays
, m_data( new PrivateData() )
{
setTransparentForPositioner( true );
setPlacementPolicy( QskPlacementPolicy::Ignore );
connectWindow( window(), true );
}

View File

@ -112,7 +112,7 @@ QskInputGrabber::QskInputGrabber( QQuickItem* parent )
setAcceptTouchEvents( true );
setAcceptHoverEvents( true );
setTransparentForPositioner( true );
setPlacementPolicy( QskPlacementPolicy::Ignore );
setFlag( QQuickItem::ItemHasContents, false );
m_data->setup( parent );

View File

@ -6,6 +6,7 @@
#include <QskColorFilter.h>
#include <QskSkinlet.h>
#include <QskEvent.h>
#include <QskPlatform.h>
#include <qvector.h>
#include <qvariant.h>
@ -85,7 +86,7 @@ QskMenu::~QskMenu()
// has no effect as we do not offer submenus yet. TODO ...
bool QskMenu::isCascading() const
{
return flagHint( QskMenu::Panel | QskAspect::Style );
return flagHint( QskMenu::Panel | QskAspect::Style, qskMaybeDesktopPlatform() );
}
void QskMenu::setCascading( bool on )

View File

@ -229,6 +229,8 @@ QskMenuSkinlet::QskMenuSkinlet( QskSkin* skin )
appendNodeRoles( { PanelRole } );
}
QskMenuSkinlet::~QskMenuSkinlet() = default;
QRectF QskMenuSkinlet::cursorRect(
const QskSkinnable* skinnable, const QRectF& contentsRect, int index ) const
{

View File

@ -19,7 +19,7 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
};
Q_INVOKABLE QskMenuSkinlet( QskSkin* = nullptr );
~QskMenuSkinlet() = default;
~QskMenuSkinlet();
QRectF subControlRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol ) const override;

View File

@ -168,7 +168,7 @@ QskPopup::QskPopup( QQuickItem* parent )
setWheelEnabled( true );
// we don't want to be resized by layout code
setTransparentForPositioner( true );
setPlacementPolicy( QskPlacementPolicy::Ignore );
setFlag( ItemIsFocusScope, true );
setTabFence( true );

View File

@ -16,13 +16,6 @@ QSK_QT_PRIVATE_END
#include <qpa/qplatforminputcontext.h>
#include <qpa/qplatformintegration.h>
QSizeF qskItemSize( const QQuickItem* item )
{
// obsolete for Qt >= 5.10
auto d = QQuickItemPrivate::get( item );
return QSizeF( d->width, d->height );
}
QRectF qskItemRect( const QQuickItem* item )
{
auto d = QQuickItemPrivate::get( item );
@ -41,7 +34,7 @@ void qskSetItemGeometry( QQuickItem* item, const QRectF& rect )
{
control->setGeometry( rect );
}
else
else if ( item )
{
item->setPosition( rect.topLeft() );
item->setSize( rect.size() );
@ -63,10 +56,10 @@ bool qskIsAncestorOf( const QQuickItem* item, const QQuickItem* child )
bool qskIsVisibleToParent( const QQuickItem* item )
{
if ( item )
return QQuickItemPrivate::get( item )->explicitVisible;
if ( item == nullptr )
return false;
return false;
return QQuickItemPrivate::get( item )->explicitVisible;
}
bool qskIsVisibleTo( const QQuickItem* item, const QQuickItem* ancestor )
@ -124,30 +117,14 @@ bool qskIsShortcutScope( const QQuickItem* item )
return item->isFocusScope() && QQuickItemPrivate::get( item )->isTabFence;
}
void qskSetTransparentForPositioner( QQuickItem* item, bool on )
{
if ( item )
QQuickItemPrivate::get( item )->setTransparentForPositioner( on );
}
bool qskIsTransparentForPositioner( const QQuickItem* item )
{
if ( item == nullptr )
return true;
return QQuickItemPrivate::get( item )->isTransparentForPositioner();
}
bool qskIsVisibleToLayout( const QQuickItem* item )
{
if ( item )
{
const auto d = QQuickItemPrivate::get( item );
return !d->isTransparentForPositioner()
&& ( d->explicitVisible || qskRetainSizeWhenHidden( item ) );
}
return qskEffectivePlacementPolicy( item ) != QskPlacementPolicy::Ignore;
}
return false;
bool qskIsAdjustableByLayout( const QQuickItem* item )
{
return qskEffectivePlacementPolicy( item ) == QskPlacementPolicy::Adjust;
}
QskSizePolicy qskSizePolicy( const QQuickItem* item )
@ -180,19 +157,65 @@ Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* item )
return Qt::Alignment();
}
bool qskRetainSizeWhenHidden( const QQuickItem* item )
void qskSetPlacementPolicy( QQuickItem* item, const QskPlacementPolicy policy )
{
if ( item == nullptr )
return;
if ( auto control = qskControlCast( item ) )
return control->layoutHints() & QskControl::RetainSizeWhenHidden;
if ( item )
{
const QVariant v = item->property( "retainSizeWhenHidden" );
if ( v.canConvert< bool >() )
return v.value< bool >();
control->setPlacementPolicy( policy );
}
else
{
item->setProperty( "layoutPolicy", QVariant::fromValue( policy ) );
return false;
auto d = QQuickItemPrivate::get( item );
const bool ignore = policy.visiblePolicy() == QskPlacementPolicy::Ignore;
if ( ignore != d->isTransparentForPositioner() )
d->setTransparentForPositioner( ignore );
// sending a LayoutRequest ?
}
}
QskPlacementPolicy qskPlacementPolicy( const QQuickItem* item )
{
if ( item == nullptr )
return QskPlacementPolicy( QskPlacementPolicy::Ignore, QskPlacementPolicy::Ignore );
if ( auto control = qskControlCast( item ) )
{
return control->placementPolicy();
}
else
{
QskPlacementPolicy policy;
const auto v = item->property( "layoutPolicy" );
if ( v.canConvert< QskPlacementPolicy >() )
policy = v.value< QskPlacementPolicy >();
auto d = QQuickItemPrivate::get( item );
if ( d->isTransparentForPositioner() )
policy.setVisiblePolicy( QskPlacementPolicy::Ignore );
return policy;
}
}
QskPlacementPolicy::Policy qskEffectivePlacementPolicy( const QQuickItem* item )
{
if ( item == nullptr )
return QskPlacementPolicy::Ignore;
const auto policy = qskPlacementPolicy( item );
if ( qskIsVisibleToParent( item ) )
return policy.visiblePolicy();
else
return policy.hiddenPolicy();
}
QQuickItem* qskNearestFocusScope( const QQuickItem* item )

View File

@ -7,6 +7,8 @@
#define QSK_QUICK_H
#include "QskGlobal.h"
#include "QskPlacementPolicy.h"
#include <qnamespace.h>
#include <qquickitem.h>
@ -30,9 +32,8 @@ QSK_EXPORT bool qskIsVisibleTo( const QQuickItem* item, const QQuickItem* ancest
QSK_EXPORT bool qskIsVisibleToParent( const QQuickItem* );
QSK_EXPORT bool qskIsPolishScheduled( const QQuickItem* );
QSK_EXPORT void qskSetTransparentForPositioner( QQuickItem*, bool );
QSK_EXPORT bool qskIsTransparentForPositioner( const QQuickItem* );
QSK_EXPORT bool qskIsVisibleToLayout( const QQuickItem* );
QSK_EXPORT bool qskIsAdjustableByLayout( const QQuickItem* );
QSK_EXPORT QSizeF qskEffectiveSizeHint( const QQuickItem*,
Qt::SizeHint, const QSizeF& constraint = QSizeF() );
@ -46,9 +47,12 @@ QSK_EXPORT QRectF qskConstrainedItemRect(
QSK_EXPORT QskSizePolicy qskSizePolicy( const QQuickItem* );
QSK_EXPORT Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* );
QSK_EXPORT bool qskRetainSizeWhenHidden( const QQuickItem* );
QSK_EXPORT QSizeF qskItemSize( const QQuickItem* );
QSK_EXPORT QskPlacementPolicy qskPlacementPolicy( const QQuickItem* );
QSK_EXPORT void qskSetPlacementPolicy( QQuickItem*, QskPlacementPolicy );
QSK_EXPORT QskPlacementPolicy::Policy qskEffectivePlacementPolicy( const QQuickItem* );
QSK_EXPORT QRectF qskItemRect( const QQuickItem* );
QSK_EXPORT QRectF qskItemGeometry( const QQuickItem* );

View File

@ -323,21 +323,6 @@ QRectF QskQuickItem::geometry() const
return QRectF( d->x, d->y, d->width, d->height );
}
void QskQuickItem::setTransparentForPositioner( bool on )
{
Q_D( QQuickItem );
if ( on != d->isTransparentForPositioner() )
{
d->setTransparentForPositioner( on );
Q_EMIT itemFlagsChanged();
}
}
bool QskQuickItem::isTransparentForPositioner() const
{
return d_func()->isTransparentForPositioner();
}
void QskQuickItem::setTabFence( bool on )
{
Q_D( QQuickItem );

View File

@ -20,9 +20,6 @@ class QSK_EXPORT QskQuickItem : public QQuickItem
Q_PROPERTY( QRectF geometry READ geometry WRITE setGeometry )
Q_PROPERTY( QRectF rect READ rect )
Q_PROPERTY( bool transparentForPositioners READ isTransparentForPositioner
WRITE setTransparentForPositioner NOTIFY itemFlagsChanged )
Q_PROPERTY( bool tabFence READ isTabFence
WRITE setTabFence NOTIFY itemFlagsChanged )
@ -78,9 +75,6 @@ class QSK_EXPORT QskQuickItem : public QQuickItem
void setPolishOnResize( bool );
bool polishOnResize() const;
void setTransparentForPositioner( bool );
bool isTransparentForPositioner() const;
void setTabFence( bool );
bool isTabFence() const;

View File

@ -500,7 +500,7 @@ QSizeF QskScrollArea::layoutSizeHint( Qt::SizeHint which, const QSizeF& constrai
}
else
{
hint = qskItemSize( contentItem );
hint = contentItem->size();
}
if ( verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff )

View File

@ -229,7 +229,7 @@ void QskSkin::setupFonts( const QString& family, int weight, bool italic )
for ( int i = TinyFont; i <= HugeFont; i++ )
{
font.setPixelSize( qskDpiScaled( sizes[i-1] ) );
font.setPixelSize( qskDpiScaled( sizes[i - 1] ) );
m_data->fonts[ i ] = font;
}

View File

@ -248,7 +248,7 @@ void QskSubWindow::itemChange( QQuickItem::ItemChange change,
case QQuickItem::ItemChildAddedChange:
case QQuickItem::ItemChildRemovedChange:
{
if ( !qskIsTransparentForPositioner( value.item ) )
if ( qskIsVisibleToLayout( value.item ) )
{
resetImplicitSize();
polish();

View File

@ -126,8 +126,8 @@ void QskSubWindowArea::itemChange(
{
// the child is not fully constructed
// and we have to delay checking for sub windows
QTimer::singleShot( 0, this,
[ this ] { qskUpdateEventFilter( this ); } );
QMetaObject::invokeMethod( this,
[ this ] { qskUpdateEventFilter( this ); }, Qt::QueuedConnection );
break;
}

View File

@ -489,10 +489,9 @@ QSize QskWindow::sizeConstraint() const
const auto children = contentItem()->childItems();
for ( auto child : children )
{
if ( !qskIsTransparentForPositioner( child ) )
if ( qskIsVisibleToLayout( child ) )
{
const auto size = qskSizeConstraint( child, Qt::PreferredSize );
qDebug() << child << size;
if ( doWidth )
constraint.setWidth( qMax( constraint.width(), size.width() ) );
@ -528,7 +527,7 @@ void QskWindow::layoutItems()
const auto children = contentItem()->childItems();
for ( auto child : children )
{
if ( !qskIsTransparentForPositioner( child ) )
if ( qskIsAdjustableByLayout( child ) )
{
const auto r = qskConstrainedItemRect( child, rect );
qskSetItemGeometry( child, r );

View File

@ -103,7 +103,8 @@ QskHunspellTextPredictor::QskHunspellTextPredictor(
m_data->locale = locale;
// make sure we call virtual functions:
QTimer::singleShot( 0, this, &QskHunspellTextPredictor::loadDictionaries );
QMetaObject::invokeMethod( this,
&QskHunspellTextPredictor::loadDictionaries, Qt::QueuedConnection );
}
QskHunspellTextPredictor::~QskHunspellTextPredictor()

View File

@ -183,13 +183,12 @@ static QPointer< QskInputContext > qskInputContext;
static void qskSendToPlatformContext( QEvent::Type type )
{
const auto platformInputContext =
QGuiApplicationPrivate::platformIntegration()->inputContext();
const auto integration = QGuiApplicationPrivate::platformIntegration();
if ( platformInputContext )
if ( const auto inputContext = integration->inputContext() )
{
QEvent event( type );
QCoreApplication::sendEvent( platformInputContext, &event );
QCoreApplication::sendEvent( inputContext, &event );
}
}
@ -208,9 +207,12 @@ void QskInputContext::setInstance( QskInputContext* inputContext )
qskInputContext = inputContext;
if ( oldContext && oldContext->parent() == nullptr )
{
delete oldContext;
qskSendToPlatformContext( QEvent::PlatformPanel );
// still needed with > Qt 5.15 ?
qskSendToPlatformContext( QEvent::PlatformPanel );
}
}
}
@ -249,7 +251,7 @@ class QskInputContext::PrivateData
auto popup = new QskPopup();
popup->setAutoLayoutChildren( true );
popup->setTransparentForPositioner( false );
popup->setPlacementPolicy( QskPlacementPolicy() );
popup->setMargins( 5 );
popup->setModal( true );

View File

@ -88,7 +88,7 @@ QskInputPredictionBar::QskInputPredictionBar( QQuickItem* parent )
if ( i == 0 )
{
// to keep the height
button->setLayoutHint( QskControl::RetainSizeWhenHidden, true );
button->setPlacementPolicy( Qsk::Hidden, QskPlacementPolicy::Reserve );
}
}
}

View File

@ -133,12 +133,12 @@ int QskGridBox::addItem( QQuickItem* item,
if ( item == nullptr || item == this || row < 0 || column < 0 )
return -1;
if ( qskIsTransparentForPositioner( item ) )
if ( !qskPlacementPolicy( item ).isEffective() )
{
qWarning() << "Inserting an item that is marked as transparent for layouting:"
qWarning() << "Inserting an item that is to be ignored for layouting:"
<< item->metaObject()->className();
qskSetTransparentForPositioner( item, false );
qskSetPlacementPolicy( item, QskPlacementPolicy() );
}
rowSpan = qMax( rowSpan, -1 );

View File

@ -592,7 +592,7 @@ void QskGridLayoutEngine::layoutItems()
{
auto item = element.item();
if ( requiresAdjustment( item ) )
if ( qskIsAdjustableByLayout( item ) )
{
const auto grid = m_data->effectiveGrid( element );
layoutItem( item, grid );

View File

@ -53,7 +53,7 @@ void QskIndexedLayoutBox::itemChange(
{
if ( m_data->autoAddChildren && !m_data->blockChildAddedRemoved )
{
if ( !qskIsTransparentForPositioner( value.item ) )
if ( qskPlacementPolicy( value.item ).isEffective() )
autoAddItem( value.item );
}

View File

@ -652,20 +652,3 @@ QskSizePolicy::ConstraintType QskLayoutEngine2D::constraintType() const
return static_cast< QskSizePolicy::ConstraintType >( m_data->constraintType );
}
bool QskLayoutEngine2D::requiresAdjustment( const QQuickItem* item ) const
{
if ( qskIsVisibleToParent( item ) )
return true;
if ( auto control = qskControlCast( item ) )
{
constexpr auto mask =
QskControl::RetainSizeWhenHidden | QskControl::LayoutWhenHidden;
if ( control->layoutHints() & mask )
return true;
}
return false;
}

View File

@ -67,7 +67,6 @@ class QskLayoutEngine2D
};
void invalidate( int what );
bool requiresAdjustment( const QQuickItem* ) const;
private:
Q_DISABLE_COPY( QskLayoutEngine2D )

View File

@ -403,12 +403,12 @@ int QskLinearBox::insertItem( int index, QQuickItem* item )
if ( item == nullptr || item == this )
return -1;
if ( qskIsTransparentForPositioner( item ) )
if ( !qskPlacementPolicy( item ).isEffective() )
{
qWarning() << "Inserting an item that is marked as transparent for layouting:"
qWarning() << "Inserting an item that is to be ignored for layouting:"
<< item->metaObject()->className();
qskSetTransparentForPositioner( item, false );
qskSetPlacementPolicy( item, QskPlacementPolicy() );
}
auto& engine = m_data->engine;

View File

@ -359,7 +359,7 @@ void QskLinearLayoutEngine::layoutItems()
if ( auto item = element.item() )
{
if ( requiresAdjustment( item ) )
if ( qskIsAdjustableByLayout( item ) )
{
const QRect grid( col, row, 1, 1 );
layoutItem( item, grid );

View File

@ -201,10 +201,12 @@ void QskStackBox::insertItem( int index, QQuickItem* item )
reparentItem( item );
if ( qskIsTransparentForPositioner( item ) )
if ( !qskPlacementPolicy( item ).isEffective() )
{
// giving a warning, or ignoring the insert ???
qskSetTransparentForPositioner( item, false );
qWarning() << "Inserting an item that is to be ignored for layouting"
<< item->metaObject()->className();
qskSetPlacementPolicy( item, QskPlacementPolicy() );
}
const bool doAppend = ( index < 0 ) || ( index >= itemCount() );
@ -354,16 +356,18 @@ void QskStackBox::updateLayout()
if ( maybeUnresized() )
return;
#if 1
// what about QskControl::LayoutOutWhenHidden
#endif
const auto index = m_data->currentIndex;
if ( index >= 0 )
for ( int i = 0; i < m_data->items.count(); i++ )
{
const auto rect = geometryForItemAt( index );
qskSetItemGeometry( m_data->items[ index ], rect );
auto item = m_data->items[ i ];
const auto visibility =
( i == m_data->currentIndex ) ? Qsk::Visible : Qsk::Hidden;
if ( qskPlacementPolicy( item ).isAdjusting( visibility ) )
{
const auto rect = geometryForItemAt( i );
qskSetItemGeometry( m_data->items[ i ], rect );
}
}
}

View File

@ -25,6 +25,15 @@
#include <qsgtexture_platform.h>
#endif
static inline bool qskHasOpenGLRenderer( const QQuickWindow* window )
{
if ( window == nullptr )
return false;
const auto renderer = window->rendererInterface();
return renderer->graphicsApi() == QSGRendererInterface::OpenGL;
}
static uint qskCreateTextureOpenGL( QQuickWindow* window,
const QSize& size, QskTextureRenderer::PaintHelper* helper )
{
@ -180,6 +189,13 @@ uint QskTextureRenderer::createTexture(
// Qt6.0.0 is buggy when using FBOs. So let's disable it for the moment TODO ...
renderMode = Raster;
#endif
if ( renderMode != Raster )
{
if ( !qskHasOpenGLRenderer( window ) )
renderMode = Raster;
}
if ( renderMode == AutoDetect )
{
if ( qskSetup->testItemUpdateFlag( QskQuickItem::PreferRasterForTextures ) )

View File

@ -30,6 +30,7 @@ HEADERS += \
common/QskMetaInvokable.h \
common/QskNamespace.h \
common/QskObjectCounter.h \
common/QskPlacementPolicy.h \
common/QskPlatform.h \
common/QskRgbValue.h \
common/QskRgbPalette.h \
@ -57,6 +58,7 @@ SOURCES += \
common/QskMetaInvokable.cpp \
common/QskObjectCounter.cpp \
common/QskPlatform.cpp \
common/QskPlacementPolicy.cpp \
common/QskRgbValue.cpp \
common/QskRgbPalette.cpp \
common/QskScaleEngine.cpp \
@ -299,7 +301,7 @@ HEADERS += \
layouts/QskGridLayoutEngine.h \
layouts/QskIndexedLayoutBox.h \
layouts/QskLayoutChain.h \
layouts/QskLayoutEngine2D.cpp \
layouts/QskLayoutEngine2D.h \
layouts/QskLayoutMetrics.h \
layouts/QskLinearBox.h \
layouts/QskLinearLayoutEngine.h \

View File

@ -138,3 +138,11 @@ void Skinny::changeFonts( int increment )
Q_EMIT qskSetup->skinChanged( skin );
}
void Skinny::init()
{
/*
a dummy call - has no reason beside, that applications can load
the lib and all initializaion take place
*/
}

View File

@ -12,4 +12,5 @@ namespace Skinny
{
SKINNY_EXPORT void changeSkin( QskAnimationHint hint = 500 );
SKINNY_EXPORT void changeFonts( int increment );
SKINNY_EXPORT void init();
}

View File

@ -0,0 +1,6 @@
#!/bin/sh
LD_LIBRARY_PATH=/home/uwe/qskinny/config/qsk1/Qt/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
QT_PLUGIN_PATH=/home/uwe/qskinny/config/qsk1/Qt/plugins${QT_PLUGIN_PATH:+:$QT_PLUGIN_PATH}
export QT_PLUGIN_PATH
exec "$@"