Files
ts-qt/modern-qt/widget/buttons/icon-button.hh
2025-10-20 00:32:01 +08:00

134 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <qabstractbutton.h>
#include <qpainter.h>
#include "modern-qt/utility/qt_wrapper/enter_event.hh"
#include "modern-qt/utility/theme/theme.hh"
#include "modern-qt/utility/wrapper/common.hh"
#include "modern-qt/utility/wrapper/pimpl.hh"
#include "modern-qt/utility/wrapper/property.hh"
#include "modern-qt/utility/wrapper/widget.hh"
namespace creeper::icon_button::internal {
class IconButton : public QAbstractButton {
CREEPER_PIMPL_DEFINITION(IconButton);
public:
enum class Types { DEFAULT, TOGGLE_UNSELECTED, TOGGLE_SELECTED };
enum class Shape { DEFAULT_ROUND, SQUARE };
enum class Color { DEFAULT_FILLED, TONAL, OUTLINED, STANDARD };
enum class Width { DEFAULT, NARROW, WIDE };
/// @brief
/// 依照文档 https://m3.material.io/components/icon-buttons/specs
/// 给出如下标准容器尺寸,图标尺寸和字体大小
/// @note
/// 该组件支持 Material Symbols只要安装相关字体即可使用下面的
/// FontIcon Size 也是根据字体的大小而定的, utility/material-icon.hh
/// 文件中有一些预定义的字体和图标编码
// Extra Small
static constexpr auto kExtraSmallContainerSize = QSize { 32, 32 };
static constexpr auto kExtraSmallIconSize = QSize { 20, 20 };
static constexpr auto kExtraSmallFontIconSize = int { 15 };
// Small
static constexpr auto kSmallContainerSize = QSize { 40, 40 };
static constexpr auto kSmallIconSize = QSize { 24, 24 };
static constexpr auto kSmallFontIconSize = int { 18 };
// Medium
static constexpr auto kMediumContainerSize = QSize { 56, 56 };
static constexpr auto kMediumIconSize = QSize { 24, 24 };
static constexpr auto kMediumFontIconSize = int { 18 };
// Large
static constexpr auto kLargeContainerSize = QSize { 96, 96 };
static constexpr auto kLargeIconSize = QSize { 32, 32 };
static constexpr auto kLargeFontIconSize = int { 24 };
// Extra Large
static constexpr auto kExtraLargeContainerSize = QSize { 136, 136 };
static constexpr auto kExtraLargeIconSize = QSize { 40, 40 };
static constexpr auto kExtraLargeFontIconSize = int { 32 };
public:
auto set_color_scheme(const ColorScheme&) noexcept -> void;
auto load_theme_manager(ThemeManager&) noexcept -> void;
auto set_icon(const QString&) noexcept -> void;
auto set_icon(const QIcon&) noexcept -> void;
auto set_types(Types) noexcept -> void;
auto set_shape(Shape) noexcept -> void;
auto set_color(Color) noexcept -> void;
auto set_width(Width) noexcept -> void;
auto types_enum() const noexcept -> Types;
auto shape_enum() const noexcept -> Shape;
auto color_enum() const noexcept -> Color;
auto width_enum() const noexcept -> Width;
auto selected() const noexcept -> bool;
auto set_selected(bool) noexcept -> void;
// TODO: 详细的颜色自定义接口有缘再写
protected:
auto enterEvent(qt::EnterEvent*) -> void override;
auto leaveEvent(QEvent*) -> void override;
auto paintEvent(QPaintEvent*) -> void override;
};
}
namespace creeper::icon_button::pro {
using Token = common::Token<internal::IconButton>;
using Icon =
creeper::DerivedProp<Token, QIcon, [](auto& self, const auto& v) { self.set_icon(v); }>;
using FontIcon =
creeper::DerivedProp<Token, QString, [](auto& self, const auto& v) { self.set_icon(v); }>;
using Color = creeper::SetterProp<Token, internal::IconButton::Color,
[](auto& self, const auto& v) { self.set_color(v); }>;
using Shape = creeper::SetterProp<Token, internal::IconButton::Shape,
[](auto& self, const auto& v) { self.set_shape(v); }>;
using Types = creeper::SetterProp<Token, internal::IconButton::Types,
[](auto& self, const auto& v) { self.set_types(v); }>;
using Width = creeper::SetterProp<Token, internal::IconButton::Width,
[](auto& self, const auto& v) { self.set_width(v); }>;
constexpr auto ColorFilled = Color { internal::IconButton::Color::DEFAULT_FILLED };
constexpr auto ColorOutlined = Color { internal::IconButton::Color::OUTLINED };
constexpr auto ColorStandard = Color { internal::IconButton::Color::STANDARD };
constexpr auto ColorTonal = Color { internal::IconButton::Color::TONAL };
constexpr auto ShapeRound = Shape { internal::IconButton::Shape::DEFAULT_ROUND };
constexpr auto ShapeSquare = Shape { internal::IconButton::Shape::SQUARE };
constexpr auto TypesDefault = Types { internal::IconButton::Types::DEFAULT };
constexpr auto TypesToggleSelected = Types { internal::IconButton::Types::TOGGLE_SELECTED };
constexpr auto TypesToggleUnselected = Types { internal::IconButton::Types::TOGGLE_UNSELECTED };
constexpr auto WidthDefault = Width { internal::IconButton::Width::DEFAULT };
constexpr auto WidthNarrow = Width { internal::IconButton::Width::NARROW };
constexpr auto WidthWide = Width { internal::IconButton::Width::WIDE };
template <typename Callback>
using Clickable = common::pro::Clickable<Callback, Token>;
template <class T>
concept trait = std::derived_from<T, Token>;
CREEPER_DEFINE_CHECKER(trait);
using namespace widget::pro;
using namespace theme::pro;
}
namespace creeper {
using IconButton = Declarative<icon_button::internal::IconButton,
CheckerOr<icon_button::pro::checker, widget::pro::checker, theme::pro::checker>>;
}