From 46af5ac7d654a0ae2d7d12dea6bcdd68f129a320 Mon Sep 17 00:00:00 2001 From: Artur Twardy Date: Mon, 21 Oct 2024 23:39:38 +0200 Subject: [PATCH] Add IconDisplay class and expose it to lua Change-Id: I5cc9725de1666e5e19d869f3249d3b287de8a4b9 Reviewed-by: Artur Twardy Reviewed-by: Marcus Tillmanns --- src/libs/utils/CMakeLists.txt | 1 + src/libs/utils/icondisplay.cpp | 64 ++++++++++++++++++++++++++++++++ src/libs/utils/icondisplay.h | 39 +++++++++++++++++++ src/libs/utils/layoutbuilder.cpp | 12 ++++++ src/libs/utils/layoutbuilder.h | 12 ++++++ src/plugins/lua/bindings/gui.cpp | 16 ++++++++ src/plugins/lua/meta/gui.lua | 11 ++++++ 7 files changed, 155 insertions(+) create mode 100644 src/libs/utils/icondisplay.cpp create mode 100644 src/libs/utils/icondisplay.h diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index e0bfdc13e4e..f1f730dd389 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -83,6 +83,7 @@ add_qtc_library(Utils htmldocextractor.cpp htmldocextractor.h icon.cpp icon.h iconbutton.cpp iconbutton.h + icondisplay.h icondisplay.cpp id.cpp id.h indexedcontainerproxyconstiterator.h infobar.cpp infobar.h diff --git a/src/libs/utils/icondisplay.cpp b/src/libs/utils/icondisplay.cpp new file mode 100644 index 00000000000..1c9f9f6520f --- /dev/null +++ b/src/libs/utils/icondisplay.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "icondisplay.h" + +#include "icon.h" + +#include +#include +#include + +namespace Utils +{ + +class IconDisplayPrivate +{ +public: + QSize m_iconSize; + QIcon m_icon; +}; + +Utils::IconDisplay::IconDisplay(QWidget *parent) : + QWidget(parent), + d(std::make_unique()) +{ + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); +} + +IconDisplay::~IconDisplay() = default; + +void IconDisplay::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + + qreal dpr = devicePixelRatio(); + QSize actualSize = size(); + auto px = d->m_icon.pixmap(actualSize, dpr); + px.setDevicePixelRatio(dpr); + + QRect r(QPoint(0, 0), actualSize); + r.moveCenter(rect().center()); + + painter.drawPixmap(r, px); +} + +QSize IconDisplay::sizeHint() const +{ + if (d->m_icon.isNull()) + return {}; + + return d->m_icon.availableSizes().first(); +} + +void IconDisplay::setIcon(const Icon &icon) +{ + d->m_icon = icon.icon(); + update(); +} + +} // namespace Utils diff --git a/src/libs/utils/icondisplay.h b/src/libs/utils/icondisplay.h new file mode 100644 index 00000000000..69a7973613c --- /dev/null +++ b/src/libs/utils/icondisplay.h @@ -0,0 +1,39 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "utils_global.h" + +#include + +#include + +QT_BEGIN_NAMESPACE +class QPaintEvent; +QT_END_NAMESPACE + +namespace Utils { + +class Icon; +class IconDisplayPrivate; + +class QTCREATOR_UTILS_EXPORT IconDisplay : public QWidget +{ + Q_OBJECT +public: + IconDisplay(QWidget *parent = nullptr); + ~IconDisplay() override; + + void setIcon(const Utils::Icon &); + + void paintEvent(QPaintEvent *event) override; + QSize sizeHint() const override; + +private: + friend class IconDisplayPrivates; + + std::unique_ptr d; +}; + +} // namespace Utils diff --git a/src/libs/utils/layoutbuilder.cpp b/src/libs/utils/layoutbuilder.cpp index 42c947095f3..f453154f2e9 100644 --- a/src/libs/utils/layoutbuilder.cpp +++ b/src/libs/utils/layoutbuilder.cpp @@ -6,6 +6,7 @@ #include "fancylineedit.h" #include "filepath.h" #include "icon.h" +#include "icondisplay.h" #include "markdownbrowser.h" #include "qtcassert.h" #include "spinner/spinner.h" @@ -1211,6 +1212,17 @@ void Spinner::setDecorated(bool on) access(this)->setDecorated(on); } +IconDisplay::IconDisplay(std::initializer_list ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void IconDisplay::setIcon(const Utils::Icon &icon) +{ + access(this)->setIcon(icon); +} + // void createItem(LayoutItem *item, QWidget *t) // { // if (auto l = qobject_cast(t)) diff --git a/src/libs/utils/layoutbuilder.h b/src/libs/utils/layoutbuilder.h index 0aaaa8f0bc9..1b7f337367d 100644 --- a/src/libs/utils/layoutbuilder.h +++ b/src/libs/utils/layoutbuilder.h @@ -50,6 +50,8 @@ namespace Utils { class FancyLineEdit; class FilePath; class MarkdownBrowser; +class Icon; +class IconDisplay; } // namespace Utils namespace Layouting { @@ -362,6 +364,16 @@ public: void setChildrenCollapsible(bool collapsible); }; +class QTCREATOR_UTILS_EXPORT IconDisplay : public Widget +{ +public: + using Implementation = Utils::IconDisplay; + using I = Building::BuilderItem; + + IconDisplay(std::initializer_list ps); + void setIcon(const Utils::Icon &icon); +}; + class QTCREATOR_UTILS_EXPORT ScrollArea : public Widget { public: diff --git a/src/plugins/lua/bindings/gui.cpp b/src/plugins/lua/bindings/gui.cpp index f1858a7d0dd..74711c20599 100644 --- a/src/plugins/lua/bindings/gui.cpp +++ b/src/plugins/lua/bindings/gui.cpp @@ -110,6 +110,7 @@ CREATE_HAS_FUNC(onRightSideIconClicked, nullptr, nullptr) CREATE_HAS_FUNC(setTextInteractionFlags, Qt::TextInteractionFlags()) CREATE_HAS_FUNC(setFixedSize, QSize()) CREATE_HAS_FUNC(setVisible, bool()) +CREATE_HAS_FUNC(setIcon, Utils::Icon()); template void setProperties(std::unique_ptr &item, const sol::table &children, QObject *guard) @@ -120,6 +121,12 @@ void setProperties(std::unique_ptr &item, const sol::table &children, QObject item->setVisible(*visible); } + if constexpr (has_setIcon) { + const auto icon = children.get>("icon"); + if (icon) + item->setIcon(*toIcon(*icon)); + } + if constexpr (has_setTextInteractionFlags) { const auto interactionFlags = children.get>("interactionFlags"); if (interactionFlags) { @@ -628,6 +635,15 @@ void setupGuiModule() sol::base_classes, sol::bases()); + gui.new_usertype( + "IconDisplay", + sol::call_constructor, + sol::factories([guard](const sol::table &children) { + return constructWidgetType(children, guard); + }), + sol::base_classes, + sol::bases()); + gui["br"] = &br; gui["st"] = &st; gui["empty"] = ∅ diff --git a/src/plugins/lua/meta/gui.lua b/src/plugins/lua/meta/gui.lua index d2487eda713..d16837c3c0e 100644 --- a/src/plugins/lua/meta/gui.lua +++ b/src/plugins/lua/meta/gui.lua @@ -224,6 +224,17 @@ function gui.TabWidget(name, child) end ---@field decorated bool Display spinner with custom styleSheet defined inside control (default true) local spinner = {} +---@class IconDisplay : Widget +local IconDisplay = {} + +---@class (exact) IconDisplayOptions : BaseWidgetOptions +---@param icon? Utils.Icon|FilePath|string The icon to display +gui.iconDisplayOptions = {} + +---@param options IconDisplayOptions +---@return IconDisplay +function gui.IconDisplay(options) end + ---A "Line break" in the gui. function gui.br() end