Compare commits

...

45 Commits

Author SHA1 Message Date
Martchus 43435a1b6a Avoid warning about implicit conversion when compiling with clang 2024-05-18 13:06:39 +02:00
Martchus 8f1a49610c Bump patch version 2024-05-18 13:06:17 +02:00
Martchus d363a5c9b0 Apply clang-format 2024-02-29 14:10:01 +01:00
Martchus ef08f63715 Apply change of `global.h` template 2024-02-22 19:42:43 +01:00
Martchus bb2030c964 Avoid too big icons in certain cases
When setting the scale factor of the primary screen to e.g. 100 % and the
scale factor of the second screen to something higher like 200 % the icons
appear too big on buttons and tabs. This is because icons are apparently
just rendered with the required size and the scale factor should therefore
not be applied.

This change adds overloads to specify a scale factor manually and uses a
scale factor of 1.0 for icons. The icons do not look blurry afterwards but
are also not too big anymore in the mentioned case. So this is probably how
it is supposed to be done.
2024-02-22 00:59:42 +01:00
Martchus 44776c210e Allow associating a paint device with the renderer for device-pixel-ratio 2024-02-22 00:59:42 +01:00
Martchus ce8e535d0e Update copyright date 2024-02-22 00:59:42 +01:00
Martchus 63ce4c79c6 Bump minor version 2024-02-22 00:59:42 +01:00
Martchus 3ec0824d3e Update outdated link in "Providing the font file" section
* Releases seem to be no longer present
* Link directly to the relevant directories/files
* Mention the automatic download before going into all the details of
  supplying the files manually
2023-11-23 18:53:13 +01:00
Martchus 6c5b63ec3b Update copyright date 2023-09-09 00:04:07 +02:00
Martchus 79f421c624 Avoid CMake deprecation warning by bumping version 2023-07-23 21:00:45 +02:00
Martchus 29fb3ca956 Apply cmake-format 2023-04-02 18:31:40 +02:00
Martchus fd14d3c502 Workaround CMake being unable to override symlink on Windows
The documentation says "If <linkname> already exists, it will
be overwritten.". This seems to be the case on GNU/Linux but
on Windows with CMake 3.24.2 (as provided by the official Qt
installer) I've nevertheless got an error.
2023-03-23 21:10:05 +01:00
Martchus e3d82ad643 Verify TLS cert when downloading font 2023-03-04 19:04:55 +01:00
Martchus 2cb41fd6ba Add note about using Perl from MSYS2 2023-02-26 19:28:03 +01:00
Martchus f725c3bee3 Fail at configuration time if Perl can not be found with obvious error 2023-02-26 19:28:03 +01:00
Martchus c77be09ca0 Bump patch version 2023-02-26 19:28:03 +01:00
Martchus 48827d29d5 Avoid warning about shadowing variable 2022-10-30 21:23:10 +01:00
Martchus cc5aa18a5f Format tests 2022-10-16 15:12:55 +02:00
Martchus 5e614118d3 Allow clearing overrides 2022-10-16 15:12:44 +02:00
Martchus 34aacf236b Allow specifying icon for an override directly 2022-10-07 00:34:27 +02:00
Martchus 0add8e8f91 Improve theme override
* Add caching
* Allow adding multiple icon names
2022-10-06 23:21:59 +02:00
Martchus 855b3af38b Add experimental theme override
See https://github.com/Martchus/syncthingtray/issues/121
2022-10-03 14:34:17 +02:00
Martchus 65b3838b81 Bump minor version 2022-10-03 14:34:17 +02:00
Martchus 2fcc5debcd Add global renderer instance to allow accessing renderer of icon engine 2022-09-18 14:51:23 +02:00
Martchus 45dc4c7291 Remove extra handling for Qt 6 in `QuickImageProvider`
This is no longer required since qtdeclarative commit
b5d18be5a03406d0aac83856dd41e1525fd14a28.
2022-09-17 20:23:05 +02:00
Martchus 145fd5a8e1 Decouple ABI version from API version
Set the ABI version (used in so/DLL name) to 1 and increment it on an ABI
break (but only once within one release cycle). This way we don't need to
increment it on every patch release but also don't need to make a new major
release on every ABI break.

Keep the API version as is (using semantic versioning).
2022-09-11 13:13:46 +02:00
Martchus 1c92ea5bce Declare publicly used Qt modules 2022-08-09 11:08:18 +02:00
Martchus f4ad5fefc3 Bump patch version 2022-08-09 10:34:02 +02:00
Martchus d6293b7084 Make use of improved linking against static platform plugins for tests 2022-04-28 21:50:26 +02:00
Martchus a0b31d8ddd Add stalebot config 2022-04-12 01:04:40 +02:00
Martchus 78ccb5c870 Add copyright notice 2022-04-05 20:11:47 +02:00
Martchus 8be5b2be7d Increment patch version 2022-03-15 21:32:49 +01:00
Martchus 2d2cf96eb9 Clarify that license is "GPL-2-or-later" 2022-03-15 21:30:27 +01:00
Martchus 860209ce7d Add property to set default color/size of QuickImageProvider 2022-02-02 22:31:14 +01:00
Martchus 4e15167f51 Add link to ForkAwesome website 2021-11-02 18:04:18 +01:00
Martchus 10d694a7fa
Merge pull request #3 from hrittich/upstream-patches
Create symbolic link to font file.
2021-10-31 02:26:05 +02:00
Hannah Rittich c4946f9a67 Create symbolic link to font file. 2021-10-30 23:17:09 +02:00
Martchus 2a25904331 Mention dependency to Qt Quick 2021-10-25 18:44:18 +02:00
Martchus 9b71eff21b Mark all renderer functions as const as they don't change the object 2021-10-15 22:57:19 +02:00
Martchus 5c9fe92ff6 Enable `qtquickforkawesome` by default 2021-10-15 22:13:59 +02:00
Martchus 009c722c89 Rename library for QQuickImageProvider to `qtquickforkawesome`
It makes sense to have *one* extra library for all Qt Quick related
features so the library should just be called `qtquickforkawesome` instead
of using a name specific to `QQuickImageProvider`.
2021-10-15 19:58:06 +02:00
Martchus 8d872ca461 Add a QQuickImageProvider 2021-10-10 23:24:41 +02:00
Martchus 5c818baf0b Bump patch version 2021-10-07 18:29:56 +02:00
Martchus 0c342a5055 Fix compilation against Qt 5.6 2021-10-06 01:00:23 +02:00
16 changed files with 462 additions and 50 deletions

19
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,19 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- feature request
- enhancement
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -1,14 +1,14 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
# meta data
set(META_PROJECT_NAME qtforkawesome)
set(META_APP_AUTHOR "Martchus")
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_VERSION_MAJOR 0)
set(META_VERSION_MINOR 0)
set(META_VERSION_MINOR 2)
set(META_VERSION_PATCH 1)
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
set(META_VERSION_EXACT_SONAME ON) # while still on 0.x.x release
set(META_SOVERSION 1)
set(META_PUBLIC_QT_MODULES Core Gui)
set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION OFF)
@ -37,3 +37,8 @@ find_package(${PACKAGE_NAMESPACE_PREFIX}qtutilities${CONFIGURATION_PACKAGE_SUFFI
add_subdirectory(${META_PROJECT_NAME})
set(${PACKAGE_NAMESPACE_PREFIX}${META_PROJECT_NAME}${CONFIGURATION_PACKAGE_SUFFIX_QTFORKAWESOME}_DIR "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}")
add_subdirectory(iconengineplugin)
option(ENABLE_QT_QUICK_LIBRARY "enables building the library for Qt Quick integration" ON)
if (ENABLE_QT_QUICK_LIBRARY)
add_subdirectory(qtquickforkawesome)
endif ()

View File

@ -1,5 +1,6 @@
# Qt ForkAwesome
Library that bundles ForkAwesome for use within Qt applications
Library that bundles [ForkAwesome](https://forkaweso.me) for use within Qt
applications
## Build instructions
@ -7,26 +8,36 @@ Library that bundles ForkAwesome for use within Qt applications
The library depends on the following Qt modules (version 5.6 or higher):
`core`, `gui`
The additional library for Qt Quick integration (currently only providing a
`QQuickImageProvider`) depends on the following further Qt modules: `quick`
At build time `qtutilities` and `c++utilities` are required. This library is
built in the same way as these libraries so checkout the `c++utilities`
repository for detailed instructions.
To generate the header with icon definitions, Perl and the module `YAML::XS` (or
`YAML`) are required. To use a specific Perl binary, one can set the CMake
variable `PERL`.
variable `PERL_BIN`. Under Windows, one can simply install `perl-YAML` via MSYS2
and set `PERL_BIN` to the path of `perl.exe` from the MSYS2 installation.
### Providing the font file
Of course the font file and icon definitions for ForkAwesome need to be
supplied as well.
Just download an archive from https://github.com/ForkAwesome/Fork-Awesome/releases
and specify its path via the CMake variables `FORK_AWESOME_FONT_FILE`
and `FORK_AWESOME_ICON_DEFINITIONS`, e.g. add
`-DFORK_AWESOME_FONT_FILE=/path/to/Fork-Awesome-1.2.0/fonts/forkawesome-webfont.woff2`
supplied as well. If none of the variables mentioned in the next paragraph are
specified, the build system will attempt to download the files from GitHub
automatically.
To supply the files manually, just download the `ttf`, `woff` or `woff2`
file from
[ForkAwesome's fonts directory](https://github.com/ForkAwesome/Fork-Awesome/tree/master/fonts)
and the
[icon definitions file](https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/icons.yml).
Then specify the path of the downloaded files via the CMake variables
`FORK_AWESOME_FONT_FILE` and `FORK_AWESOME_ICON_DEFINITIONS`, e.g. add
`-DFORK_AWESOME_FONT_FILE=/path/to/Fork-Awesome/fonts/forkawesome-webfont.woff2`
and
`-DFORK_AWESOME_ICON_DEFINITIONS=/path/to/Fork-Awesome-1.2.0/src/icons/icons.yml`
`-DFORK_AWESOME_ICON_DEFINITIONS=/path/to/Fork-Awesome/src/icons/icons.yml`
to the CMake invocation. The font file will be built into the library and
is hence only required at build time. If none of the variables are specified,
the build system will attempt to download the files from GitHub.
is hence only required at build time.
The Web Open Font Format (the `.woff`/`.woff2` file) might not be supported by
the font renderer. Notably, Window's native font rendering which Qt uses by
@ -77,8 +88,36 @@ To link against the plugin statically, find the CMake module
`qtforkawesomeiconengine` and add `Q_IMPORT_PLUGIN(ForkAwesomeIconEnginePlugin)`
to one of your source files.
### QQuickImageProvider
A `QQuickImageProvider` is provided as well in form of the additional library
`qtquickforkawesome`.
Then just include the header:
```
#include <qtquickforkawesome/imageprovider.h>
```
Create an instance and add it to your `QQmlEngine`:
```
engine->addImageProvider(QStringLiteral("fa"), new QtForkAwesome::QuickImageProvider(renderer));
```
And use it like this:
```
Image {
source: "image://fa/syncthing"
}
```
### Bundling
It is also possible to build the library as part of your project. Simply add
it via `add_subdirectory`. Checkout the
[Syncthing Tray's project file](https://github.com/Martchus/syncthingtray/blob/master/CMakeLists.txt)
for an example.
## Copyright notice and license
Copyright © 2021-2024 Marius Kittler
All code is licensed under [GPL-2-or-later](LICENSE).

View File

@ -4,6 +4,7 @@
#ifndef QT_FORK_AWESOME_ICON_ENGINE_GLOBAL
#define QT_FORK_AWESOME_ICON_ENGINE_GLOBAL
#include "qtforkawesomeiconengine-definitions.h"
#include <c++utilities/application/global.h>
#ifdef QT_FORK_AWESOME_ICON_ENGINE_STATIC

View File

@ -19,7 +19,7 @@
namespace QtForkAwesome {
IconEngine::IconEngine(Renderer &renderer)
IconEngine::IconEngine(const Renderer &renderer)
: m_renderer(renderer)
, m_char(0)
, m_color()
@ -63,7 +63,7 @@ QPixmap IconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State sta
color = QGuiApplication::palette().color(group, role);
}
auto pixmap = m_renderer.pixmap(QChar(m_char), size, color);
auto pixmap = m_renderer.pixmap(QChar(m_char), size, color, 1.0);
#ifdef QT_FORK_AWESOME_ICON_ENGINE_ENABLE_STYLE_SUPPORT
auto *const app = qobject_cast<QApplication *>(QApplication::instance());
if (auto *const style = app ? app->style() : nullptr) {
@ -95,7 +95,7 @@ void IconEngine::addFile(const QString &fileName, const QSize &, QIcon::Mode mod
return;
}
m_char = static_cast<IconBaseType>(iconFromId(parts.at(0).toString()));
m_color = parts.size() > 1 ? QColor(parts.at(1)) : QColor();
m_color = parts.size() > 1 ? QColor(parts.at(1).toString()) : QColor();
}
QString IconEngine::key() const

View File

@ -13,7 +13,7 @@ class Renderer;
class QT_FORK_AWESOME_ICON_ENGINE_EXPORT IconEngine : public QIconEngine {
public:
IconEngine(Renderer &renderer);
IconEngine(const Renderer &renderer);
IconEngine(const IconEngine &other);
~IconEngine() override;
@ -24,7 +24,7 @@ public:
QIconEngine *clone() const override;
private:
Renderer &m_renderer;
const Renderer &m_renderer;
IconBaseType m_char;
QColor m_color;
};

View File

@ -22,14 +22,11 @@ class QT_FORK_AWESOME_ICON_ENGINE_EXPORT ForkAwesomeIconEnginePlugin : public QI
public:
QIconEngine *create(const QString &filename = QString()) override;
private:
Renderer m_renderer;
};
QIconEngine *ForkAwesomeIconEnginePlugin::create(const QString &file)
{
auto *const engine = new IconEngine(m_renderer);
auto *const engine = new IconEngine(Renderer::global());
if (!file.isNull()) {
engine->addFile(file, QSize(), QIcon::Normal, QIcon::Off);
}

View File

@ -32,7 +32,10 @@ function (checkout_file VARIABLE)
get_filename_component(FILE_NAME "${${VARIABLE}}" NAME)
if (NOT EXISTS "${DOWNLOAD_DIR}/${FILE_NAME}")
message(STATUS "Downloading ${${VARIABLE}}")
file(DOWNLOAD "${${VARIABLE}}" "${DOWNLOAD_DIR}/${FILE_NAME}" SHOW_PROGRESS)
file(
DOWNLOAD "${${VARIABLE}}" "${DOWNLOAD_DIR}/${FILE_NAME}"
SHOW_PROGRESS
TLS_VERIFY ON)
endif ()
set("${VARIABLE}"
"${DOWNLOAD_DIR}/${FILE_NAME}"
@ -52,7 +55,11 @@ set(META_CUSTOM_CONFIG
set(RES_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}_font.qrc")
set(RES_FILE_DATA "<RCC><qresource prefix=\"/\"><file>${META_FONT_FILE_NAME}</file></qresource></RCC>")
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.14")
file(CREATE_LINK "${FORK_AWESOME_FONT_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_FONT_FILE_NAME}")
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows" AND EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${META_FONT_FILE_NAME}")
# avoid running into error when symlink already exists (should not be necassary according to docs)
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${META_FONT_FILE_NAME}")
endif ()
file(CREATE_LINK "${FORK_AWESOME_FONT_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_FONT_FILE_NAME}" SYMBOLIC)
else ()
file(COPY "${FORK_AWESOME_FONT_FILE}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif ()
@ -60,7 +67,10 @@ file(WRITE "${RES_FILE_PATH}" "${RES_FILE_DATA}")
list(APPEND RES_FILES "${RES_FILE_PATH}")
# create rule for generating header file
find_program(PERL perl)
find_program(PERL_BIN perl)
if (NOT PERL_BIN)
message(FATAL_ERROR "Unable to find Perl, set PERL_BIN to the path of Perl's executable.")
endif ()
set(GENERATED_HEADERS_PATH "${CMAKE_CURRENT_BINARY_DIR}/headers")
set(ICONS_HEADER_FILE "${GENERATED_HEADERS_PATH}/private/icons.h")
set(ID_MAPPING_HEADER_FILE "${GENERATED_HEADERS_PATH}/private/idmapping.h")
@ -69,7 +79,7 @@ list(APPEND SRC_FILES "${ICONS_HEADER_FILE}" "${ID_MAPPING_HEADER_FILE}")
set(META_TIDY_EXCLUDE_REGEX ".*/headers/private.*")
add_custom_command(
OUTPUT "${ICONS_HEADER_FILE}" "${ID_MAPPING_HEADER_FILE}"
COMMAND "${PERL}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/yaml2enum.pl" "${FORK_AWESOME_ICON_DEFINITIONS}"
COMMAND "${PERL_BIN}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/yaml2enum.pl" "${FORK_AWESOME_ICON_DEFINITIONS}"
"${ICONS_HEADER_FILE}" "${ID_MAPPING_HEADER_FILE}"
DEPENDS "${FORK_AWESOME_ICON_DEFINITIONS}"
COMMENT "Icon header")
@ -85,8 +95,9 @@ endif ()
use_cpp_utilities(ONLY_HEADERS VISIBILITY PUBLIC)
use_qt_utilities(ONLY_HEADERS VISIBILITY PRIVATE)
# use Qt Gui module
# set required Qt modules and declare their use as public
list(APPEND ADDITIONAL_QT_MODULES Gui)
set(META_PUBLIC_QT_MODULES Core ${ADDITIONAL_QT_MODULES})
# include modules to apply configuration
include(BasicConfig)
@ -98,7 +109,7 @@ include(ConfigHeader)
# configure test target
include(TestUtilities)
set(QT_TEST_LIBRARIES ${CPP_UTILITIES_LIB} ${META_TARGET_NAME})
list(APPEND QT_TEST_LIBRARIES ${CPP_UTILITIES_LIB} ${META_TARGET_NAME})
use_qt_module(LIBRARIES_VARIABLE "QT_TEST_LIBRARIES" PREFIX "${QT_PACKAGE_PREFIX}" MODULE "Test")
foreach (TEST ${QT_TESTS})
configure_test_target(TEST_NAME "${TEST}_tests" SRC_FILES "tests/${TEST}.cpp" LIBRARIES "${QT_TEST_LIBRARIES}")

View File

@ -4,6 +4,7 @@
#ifndef QT_FORK_AWESOME_GLOBAL
#define QT_FORK_AWESOME_GLOBAL
#include "qtforkawesome-definitions.h"
#include <c++utilities/application/global.h>
#ifdef QT_FORK_AWESOME_STATIC

View File

@ -4,6 +4,9 @@
#include <QFontDatabase>
#include <QGuiApplication>
#include <QHash>
#include <QIcon>
#include <QPaintDevice>
#include <QPainter>
/// \brief Contains classes provided by the QtForkAwesome library.
@ -11,17 +14,58 @@ namespace QtForkAwesome {
/// \cond
struct IconOverride {
void setIcon(const QIcon &icon);
void addIconName(const QString &iconName);
const QIcon &locateIcon();
private:
QStringList iconNames;
QIcon cachedIcon;
};
void IconOverride::setIcon(const QIcon &icon)
{
iconNames.clear();
cachedIcon = icon;
}
void IconOverride::addIconName(const QString &iconName)
{
iconNames.append(iconName);
if (!cachedIcon.isNull()) {
cachedIcon = QIcon();
}
}
const QIcon &IconOverride::locateIcon()
{
if (!cachedIcon.isNull()) {
return cachedIcon;
}
for (const auto &iconName : iconNames) {
cachedIcon = QIcon::fromTheme(iconName);
if (!cachedIcon.isNull()) {
return cachedIcon;
}
}
return cachedIcon;
}
struct Renderer::InternalData {
explicit InternalData(int id);
static constexpr int invalidId = -1;
int id;
QStringList fontFamilies;
QHash<QChar, IconOverride> overrides;
QPaintDevice *paintDevice;
};
Renderer::InternalData::InternalData(int id)
: id(id)
, fontFamilies(id != invalidId ? QFontDatabase::applicationFontFamilies(id) : QStringList())
, paintDevice(nullptr)
{
}
@ -69,15 +113,9 @@ Renderer::operator bool() const
return !m_d->fontFamilies.empty();
}
/*!
* \brief Renders the specified \a icon using the specified \a painter.
*/
void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const QRect &rect, const QColor &color)
/// \cond
static void renderInternally(QChar character, QPainter *painter, QFont &&font, const QRect &rect, const QColor &color)
{
if (!*this) {
return;
}
auto font = QFont(m_d->fontFamilies.front());
font.setPixelSize(rect.height());
painter->save();
painter->setFont(font);
@ -85,22 +123,52 @@ void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const Q
painter->drawText(rect, QString(character), QTextOption(Qt::AlignCenter));
painter->restore();
}
/// \endcond
/*!
* \brief Renders the specified \a icon using the specified \a painter.
*/
void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
{
if (auto override = m_d->overrides.find(character); override != m_d->overrides.end()) {
if (const auto &overrideIcon = override->locateIcon(); !overrideIcon.isNull()) {
painter->drawPixmap(rect, overrideIcon.pixmap(rect.size(), QIcon::Normal, QIcon::On));
return;
}
}
if (*this) {
renderInternally(character, painter, QFont(m_d->fontFamilies.front()), rect, color);
}
}
/*!
* \brief Renders the specified \a character as pixmap of the specified \a size.
*/
QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QColor &color)
QPixmap Renderer::pixmap(QChar icon, const QSize &size, const QColor &color, qreal scaleFactor) const
{
const auto scaleFactor =
if (auto override = m_d->overrides.find(icon); override != m_d->overrides.end()) {
if (const auto &overrideIcon = override->locateIcon(); !overrideIcon.isNull()) {
return overrideIcon.pixmap(size, QIcon::Normal, QIcon::On);
}
}
if (!static_cast<bool>(scaleFactor)) {
scaleFactor =
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
!QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1.0 :
!QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps)
? 1.0
:
#endif
qGuiApp->devicePixelRatio();
(m_d->paintDevice ? m_d->paintDevice->devicePixelRatioF() : qGuiApp->devicePixelRatio());
}
const auto scaledSize = QSize(size * scaleFactor);
auto pm = QPixmap(scaledSize);
pm.fill(QColor(Qt::transparent));
auto painter = QPainter(&pm);
render(icon, &painter, QRect(QPoint(), scaledSize), color);
if (*this) {
auto painter = QPainter(&pm);
renderInternally(icon, &painter, QFont(m_d->fontFamilies.front()), QRect(QPoint(), scaledSize), color);
}
pm.setDevicePixelRatio(scaleFactor);
return pm;
}
@ -108,9 +176,79 @@ QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QCo
/*!
* \brief Renders the specified \a icon as pixmap of the specified \a size.
*/
QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color)
QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color, qreal scaleFactor) const
{
return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color);
return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color, scaleFactor);
}
/*!
* \brief Renders the specified \a character as pixmap of the specified \a size.
* \remarks
* - The pixmap will be scaled for the associated paint device or use the global device-dixel-ratio if not paint
* device has been associated.
* - When rendering a QPixmap for a QIcon, better the other overloads with the actual size (and a scale factor of
* one).
*/
QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QColor &color) const
{
return pixmap(icon, size, color, 0.0);
}
/*!
* \brief Renders the specified \a icon as pixmap of the specified \a size.
* \remarks
* - The pixmap will be scaled for the associated paint device or use the global device-dixel-ratio if not paint
* device has been associated.
* - When rendering a QPixmap for a QIcon, better the other overloads with the actual size (and a scale factor of
* one).
*/
QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color) const
{
return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color, 0.0);
}
/*!
* \brief Uses the icon from the current icon theme obtained via QIcon::fromTheme() for \a character if it exists.
*/
void Renderer::addThemeOverride(QChar character, const QString &iconNameInTheme)
{
m_d->overrides[character].addIconName(iconNameInTheme);
}
/*!
* \brief Uses the specified \a override icon for \a character if it is not null.
*/
void Renderer::addOverride(QChar character, const QIcon &override)
{
m_d->overrides[character].setIcon(override);
}
/*!
* \brief Clears all overrides added via addThemeOverride() or addOverride().
*/
void Renderer::clearOverrides()
{
m_d->overrides.clear();
}
/*!
* \brief Sets the associated \a paintDevice.
* \remarks
* The device-pixel-ratio of the specified device will be used when rendering pixmaps using the overloads that
* do *not* take a scale factor.
*/
void Renderer::setAssociatedPaintDevice(QPaintDevice *paintDevice)
{
m_d->paintDevice = paintDevice;
}
/*!
* \brief Returns the global instance (which is so far only used by the icon engine plugin).
*/
Renderer &Renderer::global()
{
static auto globalRenderer = Renderer();
return globalRenderer;
}
} // namespace QtForkAwesome

View File

@ -13,6 +13,7 @@ QT_FORWARD_DECLARE_CLASS(QColor)
QT_FORWARD_DECLARE_CLASS(QPainter)
QT_FORWARD_DECLARE_CLASS(QRect)
QT_FORWARD_DECLARE_CLASS(QSize)
QT_FORWARD_DECLARE_CLASS(QPaintDevice)
QT_FORWARD_DECLARE_CLASS(QPixmap)
QT_FORWARD_DECLARE_CLASS(QIcon)
@ -27,11 +28,22 @@ public:
~Renderer();
operator bool() const;
void render(QChar character, QPainter *painter, const QRect &rect, const QColor &color);
void render(Icon icon, QPainter *painter, const QRect &rect, const QColor &color);
void render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const;
void render(Icon icon, QPainter *painter, const QRect &rect, const QColor &color) const;
QPixmap pixmap(QChar icon, const QSize &size, const QColor &color);
QPixmap pixmap(Icon icon, const QSize &size, const QColor &color);
QPixmap pixmap(QChar icon, const QSize &size, const QColor &color, qreal scaleFactor) const;
QPixmap pixmap(Icon icon, const QSize &size, const QColor &color, qreal scaleFactor) const;
QPixmap pixmap(QChar icon, const QSize &size, const QColor &color) const;
QPixmap pixmap(Icon icon, const QSize &size, const QColor &color) const;
void addThemeOverride(QChar character, const QString &iconNameInTheme);
void addThemeOverride(Icon icon, const QString &iconNameInTheme);
void addOverride(QChar character, const QIcon &override);
void addOverride(Icon icon, const QIcon &override);
void setAssociatedPaintDevice(QPaintDevice *paintDevice);
void clearOverrides();
static Renderer &global();
private:
std::unique_ptr<Renderer::InternalData> m_d;
@ -40,11 +52,27 @@ private:
/*!
* \brief Renders the specified \a icon using the specified \a painter.
*/
inline void Renderer::render(Icon icon, QPainter *painter, const QRect &rect, const QColor &color)
inline void Renderer::render(Icon icon, QPainter *painter, const QRect &rect, const QColor &color) const
{
render(QChar(static_cast<IconBaseType>(icon)), painter, rect, color);
}
/*!
* \brief Uses the icon from the current icon theme obtained via QIcon::fromTheme() for \a icon if it exists.
*/
inline void Renderer::addThemeOverride(Icon icon, const QString &iconNameInTheme)
{
addThemeOverride(QChar(static_cast<IconBaseType>(icon)), iconNameInTheme);
}
/*!
* \brief Uses the specified \a override icon for \a icon if it is not null.
*/
inline void Renderer::addOverride(Icon icon, const QIcon &override)
{
addOverride(QChar(static_cast<IconBaseType>(icon)), override);
}
} // namespace QtForkAwesome
#endif // QT_FORK_AWESOME_RENDERER

View File

@ -1,5 +1,5 @@
#include "../icon.h"
#include "../renderer.h"
#include "../icon.h"
#include <c++utilities/tests/testutils.h>

View File

@ -0,0 +1,34 @@
# additional meta data
set(META_PROJECT_NAME qtquickforkawesome)
set(META_PROJECT_VARNAME QT_QUICK_FORK_AWESOME)
set(META_APP_NAME "QQuickImageProvider for ForkAwesome")
set(META_APP_DESCRIPTION "QQuickImageProvider for ForkAwesome")
# add project files
set(HEADER_FILES imageprovider.h)
set(SRC_FILES imageprovider.cpp)
set(DOC_FILES ../README.md)
# use headers and CMake modules from c++utilities and qtutilities
use_cpp_utilities(ONLY_HEADERS VISIBILITY PUBLIC)
use_qt_utilities(ONLY_HEADERS VISIBILITY PRIVATE)
if (NAMESPACE)
set(NAMESPACE_PREFIX "${NAMESPACE}-")
endif ()
# use main qtforkawesome library
find_package(${NAMESPACE_PREFIX}qtforkawesome${CONFIGURATION_PACKAGE_SUFFIX_QTFORKAWESOME} ${META_APP_VERSION} REQUIRED)
use_qt_fork_awesome()
# set required Qt modules and declare their use as public
list(APPEND ADDITIONAL_QT_MODULES Gui Quick)
set(META_PUBLIC_QT_MODULES Core ${ADDITIONAL_QT_MODULES})
# include modules to apply configuration
include(BasicConfig)
include(QtConfig)
include(WindowsResources)
include(LibraryTarget)
include(Doxygen)
include(ConfigHeader)

View File

@ -0,0 +1,28 @@
// Created via CMake from template global.h.in
// WARNING! Any changes to this file will be overwritten by the next CMake run!
#ifndef QT_QUICK_FORK_AWESOME_GLOBAL
#define QT_QUICK_FORK_AWESOME_GLOBAL
#include "qtquickforkawesome-definitions.h"
#include <c++utilities/application/global.h>
#ifdef QT_QUICK_FORK_AWESOME_STATIC
#define QT_QUICK_FORK_AWESOME_EXPORT
#define QT_QUICK_FORK_AWESOME_IMPORT
#else
#define QT_QUICK_FORK_AWESOME_EXPORT CPP_UTILITIES_GENERIC_LIB_EXPORT
#define QT_QUICK_FORK_AWESOME_IMPORT CPP_UTILITIES_GENERIC_LIB_IMPORT
#endif
/*!
* \def QT_QUICK_FORK_AWESOME_EXPORT
* \brief Marks the symbol to be exported by the qtquickforkawesome library.
*/
/*!
* \def QT_QUICK_FORK_AWESOME_IMPORT
* \brief Marks the symbol to be imported from the qtquickforkawesome library.
*/
#endif // QT_QUICK_FORK_AWESOME_GLOBAL

View File

@ -0,0 +1,49 @@
#include "./imageprovider.h"
#include <qtforkawesome/renderer.h>
#include <qtforkawesome/utils.h>
#include <qtutilities/misc/compat.h>
#include <QGuiApplication>
#include <QPalette>
/// \brief Contains classes provided by the QtForkAwesome library.
namespace QtForkAwesome {
QuickImageProvider::QuickImageProvider(
const Renderer &renderer, const QColor &defaultColor, const QSize &defaultSize, QQuickImageProvider::ImageType type)
: QQuickImageProvider(type)
, m_renderer(renderer)
, m_defaultColor(defaultColor)
, m_defaultSize(defaultSize)
{
}
QPixmap QuickImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
const auto parts = QtUtilities::splitRef(id, QChar(':'));
if (parts.empty()) {
return QPixmap();
}
const auto icon = iconFromId(parts.front().toString());
if (!isIconValid(icon)) {
return QPixmap();
}
auto color = parts.size() > 1 ? QColor(parts.at(1).toString()) : m_defaultColor;
if (!color.isValid()) {
color = QGuiApplication::palette().color(QPalette::Normal, QPalette::Text);
}
const auto renderSize = requestedSize.isValid() ? requestedSize : m_defaultSize;
if (size) {
*size = renderSize;
}
return m_renderer.pixmap(icon, renderSize, color);
}
QImage QuickImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
return requestPixmap(id, size, requestedSize).toImage();
}
} // namespace QtForkAwesome

View File

@ -0,0 +1,62 @@
#ifndef QT_FORK_AWESOME_QUICK_IMAGE_PROVIDER
#define QT_FORK_AWESOME_QUICK_IMAGE_PROVIDER
#include "./global.h"
#include <QColor>
#include <QQuickImageProvider>
#include <QSize>
QT_FORWARD_DECLARE_CLASS(QPixmap)
QT_FORWARD_DECLARE_CLASS(QSize)
namespace QtForkAwesome {
class Renderer;
class QT_QUICK_FORK_AWESOME_EXPORT QuickImageProvider : public QQuickImageProvider {
Q_PROPERTY(QColor defaultColor defaultColor name WRITE setDefaultColor)
Q_PROPERTY(QSize defaultColor defaultSize name WRITE setDefaultSize)
public:
QuickImageProvider(const Renderer &renderer, const QColor &defaultColor = QColor(), const QSize &defaultSize = QSize(64, 64),
QQuickImageProvider::ImageType type = QQuickImageProvider::Pixmap);
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
QColor defaultColor() const;
QSize defaultSize() const;
public Q_SLOTS:
void setDefaultColor(const QColor &color);
void setDefaultSize(const QSize &size);
private:
const Renderer &m_renderer;
QColor m_defaultColor;
QSize m_defaultSize;
};
inline QColor QuickImageProvider::defaultColor() const
{
return m_defaultColor;
}
inline QSize QuickImageProvider::defaultSize() const
{
return m_defaultSize;
}
inline void QuickImageProvider::setDefaultColor(const QColor &color)
{
m_defaultColor = color;
}
inline void QuickImageProvider::setDefaultSize(const QSize &size)
{
m_defaultSize = size;
}
} // namespace QtForkAwesome
#endif // QT_FORK_AWESOME_QUICK_IMAGE_PROVIDER