update
parent
312418aded
commit
31d563d2f6
|
@ -0,0 +1,21 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Window {
|
||||
id:app
|
||||
|
||||
Component.onCompleted: {
|
||||
FluApp.setAppWindow(app)
|
||||
FluApp.routes = {
|
||||
"/":"qrc:/MainPage.qml",
|
||||
"/Setting":"qrc:/SettingPage.qml"
|
||||
}
|
||||
FluApp.initialRoute = "/"
|
||||
FluApp.run()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Rectangle {
|
||||
id:rootwindow
|
||||
width: 800
|
||||
height: 600
|
||||
color : "#F3F3F3"
|
||||
|
||||
ListModel{
|
||||
id:nav_items
|
||||
ListElement{
|
||||
text:"Controls"
|
||||
page:"qrc:/T_Controls.qml"
|
||||
}
|
||||
ListElement{
|
||||
text:"Typography"
|
||||
page:"qrc:/T_Typography.qml"
|
||||
}
|
||||
}
|
||||
|
||||
ListView{
|
||||
id:nav_list
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
topMargin: 20
|
||||
bottomMargin: 20
|
||||
}
|
||||
width: 160
|
||||
model: nav_items
|
||||
delegate: Item{
|
||||
height: 38
|
||||
width: nav_list.width
|
||||
|
||||
Rectangle{
|
||||
color: {
|
||||
if(nav_list.currentIndex === index){
|
||||
return "#EAEAEB"
|
||||
}
|
||||
return item_mouse.containsMouse? "#EAEAEA" : "#00000000"
|
||||
}
|
||||
radius: 4
|
||||
anchors{
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
topMargin: 2
|
||||
bottomMargin: 2
|
||||
leftMargin: 6
|
||||
rightMargin: 6
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
nav_list.currentIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
Text{
|
||||
text:model.text
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
color: "#FFFFFF"
|
||||
radius: 10
|
||||
clip: true
|
||||
anchors{
|
||||
left: nav_list.right
|
||||
leftMargin: 2
|
||||
top: parent.top
|
||||
topMargin: 20
|
||||
right: parent.right
|
||||
rightMargin: 10
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 20
|
||||
}
|
||||
border.width: 1
|
||||
border.color: "#EEEEEE"
|
||||
|
||||
Loader{
|
||||
anchors.fill: parent
|
||||
anchors.margins:20
|
||||
source: nav_items.get(nav_list.currentIndex).page
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import QtQuick 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
|
||||
width: 500
|
||||
height: 500
|
||||
|
||||
|
||||
FluText{
|
||||
text:"Display"
|
||||
fontStyle: FluText.Display
|
||||
anchors.centerIn: parent
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Window 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
|
||||
ColumnLayout{
|
||||
spacing: 5
|
||||
|
||||
|
||||
FluText{
|
||||
text:"Controls"
|
||||
fontStyle: FluText.TitleLarge
|
||||
}
|
||||
|
||||
|
||||
|
||||
FluButton{
|
||||
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
|
||||
FluFilledButton{
|
||||
onClicked:{
|
||||
FluApp.navigate("/Setting")
|
||||
console.debug("FluFilledButton:"+Window.window.x)
|
||||
}
|
||||
}
|
||||
|
||||
FluFilledButton{
|
||||
disabled: true
|
||||
onClicked:{
|
||||
console.debug("FluFilledButton-disabled")
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
Component.onCompleted: {
|
||||
|
||||
}
|
||||
icon:FluentIcons.FA_android
|
||||
}
|
||||
|
||||
FluToggleSwitch{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
|
||||
ColumnLayout{
|
||||
|
||||
spacing: 5
|
||||
|
||||
FluText{
|
||||
text:"Display"
|
||||
fontStyle: FluText.Display
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Title Large"
|
||||
fontStyle: FluText.TitleLarge
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Title"
|
||||
fontStyle: FluText.Title
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Subtitle"
|
||||
fontStyle: FluText.Subtitle
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Body Large"
|
||||
fontStyle: FluText.BodyLarge
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Body Strong"
|
||||
fontStyle: FluText.BodyStrong
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Body"
|
||||
fontStyle: FluText.Body
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"Caption"
|
||||
fontStyle: FluText.Caption
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QQuickView>
|
||||
#include <QRegion>
|
||||
|
||||
//无边框窗口,主要用来实现自定义标题栏。
|
||||
//Windows平台支持拖动和改变大小,支持Aero效果
|
||||
//非Windows平台,去掉边框,不做其它处理。由Qml模拟resize和拖动。
|
||||
class TaoFrameLessViewPrivate;
|
||||
class TaoFrameLessView : public QQuickView
|
||||
{
|
||||
Q_OBJECT
|
||||
using Super = QQuickView;
|
||||
Q_PROPERTY(bool isMax READ isMax NOTIFY isMaxChanged)
|
||||
Q_PROPERTY(bool isFull READ isFull NOTIFY isFullChanged)
|
||||
public:
|
||||
explicit TaoFrameLessView(QWindow *parent = nullptr);
|
||||
~TaoFrameLessView();
|
||||
void moveToScreenCenter();
|
||||
bool isMax() const;
|
||||
bool isFull() const;
|
||||
QQuickItem *titleItem() const;
|
||||
|
||||
static QRect calcCenterGeo(const QRect &screenGeo, const QSize &normalSize);
|
||||
public slots:
|
||||
void setIsMax(bool isMax);
|
||||
void setIsFull(bool isFull);
|
||||
void setTitleItem(QQuickItem* item);
|
||||
|
||||
signals:
|
||||
void isMaxChanged(bool isMax);
|
||||
void isFullChanged(bool isFull);
|
||||
void mousePressed(int xPos, int yPos, int button);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
# else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||
# endif
|
||||
void mousePressEvent(QMouseEvent* event) override
|
||||
{
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
emit mousePressed(event->position().x(), event->position().y(), event->button());
|
||||
#else
|
||||
emit mousePressed(event->x(), event->y(), event->button());
|
||||
#endif
|
||||
Super::mousePressEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
TaoFrameLessViewPrivate *d;
|
||||
};
|
|
@ -0,0 +1,106 @@
|
|||
#include "TaoFrameLessView.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
class TaoFrameLessViewPrivate
|
||||
{
|
||||
public:
|
||||
bool m_isMax = false;
|
||||
bool m_isFull = false;
|
||||
QQuickItem *m_titleItem = nullptr;
|
||||
};
|
||||
TaoFrameLessView::TaoFrameLessView(QWindow *parent) : Super(parent), d(new TaoFrameLessViewPrivate)
|
||||
{
|
||||
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
(void)state;
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
}
|
||||
TaoFrameLessView::~TaoFrameLessView()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
void TaoFrameLessView::showEvent(QShowEvent *e)
|
||||
{
|
||||
Super::showEvent(e);
|
||||
}
|
||||
QRect TaoFrameLessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
int h = normalSize.height();
|
||||
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
|
||||
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
|
||||
if (screenGeo.width() < w) {
|
||||
x = screenGeo.x();
|
||||
w = screenGeo.width();
|
||||
}
|
||||
if (screenGeo.height() < h) {
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
|
||||
return { x, y, w, h };
|
||||
}
|
||||
void TaoFrameLessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
|
||||
setMinimumSize(geo.size());
|
||||
}
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
bool TaoFrameLessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
bool TaoFrameLessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
QQuickItem *TaoFrameLessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
void TaoFrameLessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
return;
|
||||
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
void TaoFrameLessView::setIsFull(bool isFull)
|
||||
{
|
||||
if(d->m_isFull == isFull)
|
||||
return;
|
||||
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
void TaoFrameLessView::setTitleItem(QQuickItem *item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
|
||||
{
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
void TaoFrameLessView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Super::resizeEvent(e);
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
#include "TaoFrameLessView.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
#include <VersionHelpers.h>
|
||||
#include <WinUser.h>
|
||||
#include <dwmapi.h>
|
||||
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <wtypes.h>
|
||||
#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved
|
||||
#pragma comment(lib, "User32.lib")
|
||||
#pragma comment(lib, "Gdi32.lib")
|
||||
// we cannot just use WS_POPUP style
|
||||
// WS_THICKFRAME: without this the window cannot be resized and so aero snap, de-maximizing and minimizing won't work
|
||||
// WS_SYSMENU: enables the context menu with the move, close, maximize, minize... commands (shift + right-click on the task bar item)
|
||||
// WS_CAPTION: enables aero minimize animation/transition
|
||||
// WS_MAXIMIZEBOX, WS_MINIMIZEBOX: enable minimize/maximize
|
||||
enum class Style : DWORD
|
||||
{
|
||||
windowed = WS_OVERLAPPEDWINDOW | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
||||
aero_borderless = WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
||||
basic_borderless = WS_POPUP | WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX
|
||||
};
|
||||
static bool isCompositionEnabled()
|
||||
{
|
||||
BOOL composition_enabled = FALSE;
|
||||
bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK;
|
||||
return composition_enabled && success;
|
||||
}
|
||||
static Style selectBorderLessStyle()
|
||||
{
|
||||
return isCompositionEnabled() ? Style::aero_borderless : Style::basic_borderless;
|
||||
}
|
||||
static void setShadow(HWND handle, bool enabled)
|
||||
{
|
||||
if (isCompositionEnabled())
|
||||
{
|
||||
static const MARGINS shadow_state[2] { { 0, 0, 0, 0 }, { 1, 1, 1, 1 } };
|
||||
::DwmExtendFrameIntoClientArea(handle, &shadow_state[enabled]);
|
||||
}
|
||||
}
|
||||
static long hitTest(RECT winrect, long x, long y, int borderWidth)
|
||||
{
|
||||
// 鼠标区域位于窗体边框,进行缩放
|
||||
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top) && (y < winrect.top + borderWidth))
|
||||
{
|
||||
return HTTOPLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth)
|
||||
{
|
||||
return HTTOPRIGHT;
|
||||
}
|
||||
else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOMLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOMRIGHT;
|
||||
}
|
||||
else if (x >= winrect.left && x < winrect.left + borderWidth)
|
||||
{
|
||||
return HTLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth)
|
||||
{
|
||||
return HTRIGHT;
|
||||
}
|
||||
else if (y >= winrect.top && y < winrect.top + borderWidth)
|
||||
{
|
||||
return HTTOP;
|
||||
}
|
||||
else if (y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isMaxWin(QWindow* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowMaximized;
|
||||
}
|
||||
static bool isFullWin(QQuickView* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowFullScreen;
|
||||
}
|
||||
|
||||
class TaoFrameLessViewPrivate
|
||||
{
|
||||
public:
|
||||
bool m_firstRun = true;
|
||||
bool m_isMax = false;
|
||||
bool m_isFull = false;
|
||||
QQuickItem* m_titleItem = nullptr;
|
||||
HMENU mMenuHandler = NULL;
|
||||
bool borderless = true; // is the window currently borderless
|
||||
bool borderless_resize = true; // should the window allow resizing by dragging the borders while borderless
|
||||
bool borderless_drag = true; // should the window allow moving my dragging the client area
|
||||
bool borderless_shadow = true; // should the window display a native aero shadow while borderless
|
||||
void setBorderLess(HWND handle, bool enabled)
|
||||
{
|
||||
auto newStyle = enabled ? selectBorderLessStyle() : Style::windowed;
|
||||
auto oldStyle = static_cast<Style>(::GetWindowLongPtrW(handle, GWL_STYLE));
|
||||
if (oldStyle != newStyle)
|
||||
{
|
||||
borderless = enabled;
|
||||
::SetWindowLongPtrW(handle, GWL_STYLE, static_cast<LONG>(newStyle));
|
||||
|
||||
// when switching between borderless and windowed, restore appropriate shadow state
|
||||
setShadow(handle, borderless_shadow && (newStyle != Style::windowed));
|
||||
|
||||
// redraw frame
|
||||
::SetWindowPos(handle, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||
::ShowWindow(handle, SW_SHOW);
|
||||
}
|
||||
}
|
||||
void setBorderLessShadow(HWND handle, bool enabled)
|
||||
{
|
||||
if (borderless)
|
||||
{
|
||||
borderless_shadow = enabled;
|
||||
setShadow(handle, enabled);
|
||||
}
|
||||
}
|
||||
};
|
||||
TaoFrameLessView::TaoFrameLessView(QWindow* parent)
|
||||
: QQuickView(parent)
|
||||
, d(new TaoFrameLessViewPrivate)
|
||||
{
|
||||
//此处不需要设置flags
|
||||
// setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint |
|
||||
// Qt::WindowSystemMenuHint);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
(void)state;
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
}
|
||||
void TaoFrameLessView::showEvent(QShowEvent* e)
|
||||
{
|
||||
if (d->m_firstRun)
|
||||
{
|
||||
d->m_firstRun = false;
|
||||
//第一次show的时候,设置无边框。不在构造函数中设置。取winId会触发QWindowsWindow::create,直接创建win32窗口,引起错乱(win7 或者虚拟机启动即黑屏)。
|
||||
d->setBorderLess((HWND)(winId()), d->borderless);
|
||||
{
|
||||
// Qt 5.15.2 的bug; 问题复现及解决方法:当使用WM_NCCALCSIZE 修改非客户区大小后,移动窗口到其他屏幕时,qwindows.dll 源码 qwindowswindow.cpp:2447
|
||||
// updateFullFrameMargins() 函数 处会调用qwindowswindow.cpp:2453 的
|
||||
// calculateFullFrameMargins函数重新获取默认的非客户区大小,导致最外层窗口移动屏幕时会触发resize消息,引起40像素左右的黑边;故此处创建Menu
|
||||
// 使其调用qwindowswindow.cpp:2451 的 QWindowsContext::forceNcCalcSize() 函数计算非客户区大小
|
||||
|
||||
//已知负面效果: 引入win32 MENU后,Qt程序中如果有alt开头的快捷键,会不生效,被Qt滤掉了,需要修改Qt源码
|
||||
// QWindowsKeyMapper::translateKeyEventInternal 中的
|
||||
// if (msgType == WM_SYSKEYDOWN && (nModifiers & AltAny) != 0 && GetMenu(msg.hwnd) != nullptr)
|
||||
// return false;
|
||||
// 这两行屏蔽掉
|
||||
|
||||
d->mMenuHandler = ::CreateMenu();
|
||||
::SetMenu((HWND)winId(), d->mMenuHandler);
|
||||
}
|
||||
}
|
||||
Super::showEvent(e);
|
||||
}
|
||||
TaoFrameLessView::~TaoFrameLessView()
|
||||
{
|
||||
if (d->mMenuHandler != NULL)
|
||||
{
|
||||
::DestroyMenu(d->mMenuHandler);
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool TaoFrameLessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
|
||||
bool TaoFrameLessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
QQuickItem* TaoFrameLessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
void TaoFrameLessView::setTitleItem(QQuickItem* item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
}
|
||||
QRect TaoFrameLessView::calcCenterGeo(const QRect& screenGeo, const QSize& normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
int h = normalSize.height();
|
||||
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
|
||||
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
|
||||
if (screenGeo.width() < w)
|
||||
{
|
||||
x = screenGeo.x();
|
||||
w = screenGeo.width();
|
||||
}
|
||||
if (screenGeo.height() < h)
|
||||
{
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
|
||||
return { x, y, w, h };
|
||||
}
|
||||
void TaoFrameLessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
if (minimumWidth() > geo.width() || minimumHeight() > geo.height())
|
||||
{
|
||||
setMinimumSize(geo.size());
|
||||
}
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
|
||||
void TaoFrameLessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
return;
|
||||
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
void TaoFrameLessView::setIsFull(bool isFull)
|
||||
{
|
||||
if (d->m_isFull == isFull)
|
||||
return;
|
||||
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
void TaoFrameLessView::resizeEvent(QResizeEvent* e)
|
||||
{
|
||||
// SetWindowRgn(HWND(winId()), CreateRoundRectRgn(0, 0, width(), height(), 4, 4), true);
|
||||
Super::resizeEvent(e);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool TaoFrameLessView::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
|
||||
#else
|
||||
bool TaoFrameLessView::nativeEvent(const QByteArray& eventType, void* message, long* result)
|
||||
#endif
|
||||
|
||||
{
|
||||
const long border_width = 4;
|
||||
if (!result)
|
||||
{
|
||||
//防御式编程
|
||||
//一般不会发生这种情况,win7一些极端情况,会传空指针进来。解决方案是升级驱动、切换到basic主题。
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1))
|
||||
// Work-around a bug caused by typo which only exists in Qt 5.11.1
|
||||
const auto msg = *reinterpret_cast<MSG**>(message);
|
||||
#else
|
||||
const auto msg = static_cast<LPMSG>(message);
|
||||
#endif
|
||||
|
||||
if (!msg || !msg->hwnd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_NCCALCSIZE: {
|
||||
#if 1
|
||||
const auto mode = static_cast<BOOL>(msg->wParam);
|
||||
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
|
||||
if (mode == TRUE && d->borderless)
|
||||
{
|
||||
*result = WVR_REDRAW;
|
||||
//规避 拖动border进行resize时界面闪烁
|
||||
if (!isMaxWin(this) && !isFullWin(this))
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top -= 0.1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top += 0.1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
*result = 0;
|
||||
return true;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case WM_NCACTIVATE: {
|
||||
if (!isCompositionEnabled())
|
||||
{
|
||||
// Prevents window frame reappearing on window activation
|
||||
// in "basic" theme, where no aero shadow is present.
|
||||
*result = 1;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_NCHITTEST: {
|
||||
if (d->borderless)
|
||||
{
|
||||
RECT winrect;
|
||||
GetWindowRect(HWND(winId()), &winrect);
|
||||
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
|
||||
*result = 0;
|
||||
if (!isMaxWin(this) && !isFullWin(this))
|
||||
{ //非最大化、非全屏时,进行命中测试,处理边框拖拽
|
||||
*result = hitTest(winrect, x, y, border_width);
|
||||
if (0 != *result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->m_titleItem)
|
||||
{
|
||||
auto titlePos = d->m_titleItem->mapToGlobal({ 0, 0 });
|
||||
titlePos = mapFromGlobal(titlePos.toPoint());
|
||||
auto titleRect = QRect(titlePos.x(), titlePos.y(), d->m_titleItem->width(), d->m_titleItem->height());
|
||||
double dpr = qApp->devicePixelRatio();
|
||||
QPoint pos = mapFromGlobal(QPoint(x / dpr, y / dpr));
|
||||
if (titleRect.contains(pos))
|
||||
{
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
} // end case WM_NCHITTEST
|
||||
}
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
|
@ -7,6 +7,14 @@ DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
|
|||
SOURCES += \
|
||||
main.cpp
|
||||
|
||||
win32 {
|
||||
SOURCES += \
|
||||
TaoFrameLessView_win.cpp
|
||||
} else {
|
||||
SOURCES += \
|
||||
TaoFrameLessView_unix.cpp
|
||||
}
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
|
||||
|
@ -19,28 +27,32 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
|
|||
#### 如果你正在使用静态库.a 那么你还需要将下面的配置注释取消掉。
|
||||
#### 其它项目使用方法也是如此。
|
||||
|
||||
# DEFINES += STATICLIB
|
||||
DEFINES += STATICLIB
|
||||
|
||||
# LIBNAME = FluentUI
|
||||
LIBNAME = FluentUI
|
||||
|
||||
# CONFIG(debug, debug|release) {
|
||||
# contains(QMAKE_HOST.os,Windows) {
|
||||
# LIBNAME = FluentUI
|
||||
# }else{
|
||||
# LIBNAME = FluentUI_debug
|
||||
# }
|
||||
# }
|
||||
CONFIG(debug, debug|release) {
|
||||
contains(QMAKE_HOST.os,Windows) {
|
||||
LIBNAME = FluentUI
|
||||
}else{
|
||||
LIBNAME = FluentUI_debug
|
||||
}
|
||||
}
|
||||
|
||||
# # Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
# QML_IMPORT_PATH = $$OUT_PWD/../bin/
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH = $$OUT_PWD/../bin/
|
||||
|
||||
# # Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
# QML_DESIGNER_IMPORT_PATH = $$OUT_PWD/../bin/
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH = $$OUT_PWD/../bin/
|
||||
|
||||
# INCLUDEPATH += $$OUT_PWD/../bin/FluentUI/
|
||||
# DEPENDPATH += $$OUT_PWD/../bin/FluentUI/
|
||||
INCLUDEPATH += $$OUT_PWD/../bin/FluentUI/
|
||||
DEPENDPATH += $$OUT_PWD/../bin/FluentUI/
|
||||
|
||||
# LIBS += -L$$OUT_PWD/../bin/FluentUI/ -l$${LIBNAME}
|
||||
LIBS += -L$$OUT_PWD/../bin/FluentUI/ -l$${LIBNAME}
|
||||
# PRE_TARGETDEPS += $$OUT_PWD/../bin/FluentUI/lib$${LIBNAME}.a
|
||||
|
||||
### 注意:静态库 .so .dylib .dll 是自动安装的Qt qml plugin目录中,不需要此步配置
|
||||
|
||||
HEADERS += \
|
||||
Frameless.h \
|
||||
TaoFrameLessView.h
|
||||
|
|
|
@ -1,22 +1,52 @@
|
|||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <time.h>
|
||||
#include <QDebug>
|
||||
#include "TaoFrameLessView.h"
|
||||
|
||||
#if defined(STATICLIB)
|
||||
#include <FluentUI.h>
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
clock_t start,finish;
|
||||
double totaltime;
|
||||
start=clock();
|
||||
qputenv("QSG_RENDER_LOOP","basic");
|
||||
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||
if (engine.rootObjects().isEmpty())
|
||||
return -1;
|
||||
finish=clock();
|
||||
totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
|
||||
qDebug() << "startup time :" << totaltime << "s";
|
||||
#if defined(STATICLIB)
|
||||
FluentUI::create(&engine);
|
||||
#endif
|
||||
const QUrl url(QStringLiteral("qrc:/App.qml"));
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
if (!obj && url == objUrl)
|
||||
QCoreApplication::exit(-1);
|
||||
}, Qt::QueuedConnection);
|
||||
engine.load(url);
|
||||
|
||||
|
||||
|
||||
// TaoFrameLessView view;
|
||||
//#if defined(STATICLIB)
|
||||
// FluentUI::create(view.engine());
|
||||
//#endif
|
||||
// const QUrl url(QStringLiteral("qrc:/main.qml"));
|
||||
// QObject::connect(&view, &QQuickView::statusChanged, &view, [&](QQuickView::Status status) {
|
||||
// if (status == QQuickView::Status::Ready) {
|
||||
|
||||
// }
|
||||
// });
|
||||
// //qml call 'Qt.quit()' will emit engine::quit, here should call qApp->quit
|
||||
// QObject::connect(view.engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
|
||||
// //qml clear content before quit
|
||||
// QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view](){view.setSource({});});
|
||||
|
||||
// view.setSource(url);
|
||||
// view.moveToScreenCenter();
|
||||
// view.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Window {
|
||||
id:rootwindow
|
||||
visible: true
|
||||
width: 480
|
||||
height: 700
|
||||
|
||||
ColumnLayout{
|
||||
spacing: 5
|
||||
|
||||
FluentUI{
|
||||
width: 20
|
||||
height: 20
|
||||
}
|
||||
|
||||
StandardButton{
|
||||
|
||||
}
|
||||
|
||||
FilledButton{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>T_Controls.qml</file>
|
||||
<file>T_Typography.qml</file>
|
||||
<file>App.qml</file>
|
||||
<file>MainPage.qml</file>
|
||||
<file>SettingPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#include "Def.h"
|
||||
|
||||
|
|
@ -0,0 +1,798 @@
|
|||
#ifndef DEF_H
|
||||
#define DEF_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace Fluent_Awesome {
|
||||
Q_NAMESPACE
|
||||
enum class Fluent_AwesomeType{
|
||||
FA_glass = 0xf000,
|
||||
FA_music = 0xf001,
|
||||
FA_search = 0xf002,
|
||||
FA_envelope_o = 0xf003,
|
||||
FA_heart = 0xf004,
|
||||
FA_star = 0xf005,
|
||||
FA_star_o = 0xf006,
|
||||
FA_user = 0xf007,
|
||||
FA_film = 0xf008,
|
||||
FA_th_large = 0xf009,
|
||||
FA_th = 0xf00a,
|
||||
FA_th_list = 0xf00b,
|
||||
FA_check = 0xf00c,
|
||||
FA_remove = 0xf00d,
|
||||
FA_close = 0xf00d,
|
||||
FA_times = 0xf00d,
|
||||
FA_search_plus = 0xf00e,
|
||||
FA_search_minus = 0xf010,
|
||||
FA_power_off = 0xf011,
|
||||
FA_signal = 0xf012,
|
||||
FA_gear = 0xf013,
|
||||
FA_cog = 0xf013,
|
||||
FA_trash_o = 0xf014,
|
||||
FA_home = 0xf015,
|
||||
FA_file_o = 0xf016,
|
||||
FA_clock_o = 0xf017,
|
||||
FA_road = 0xf018,
|
||||
FA_download = 0xf019,
|
||||
FA_arrow_circle_o_down = 0xf01a,
|
||||
FA_arrow_circle_o_up = 0xf01b,
|
||||
FA_inbox = 0xf01c,
|
||||
FA_play_circle_o = 0xf01d,
|
||||
FA_rotate_right = 0xf01e,
|
||||
FA_repeat = 0xf01e,
|
||||
FA_refresh = 0xf021,
|
||||
FA_list_alt = 0xf022,
|
||||
FA_lock = 0xf023,
|
||||
FA_flag = 0xf024,
|
||||
FA_headphones = 0xf025,
|
||||
FA_volume_off = 0xf026,
|
||||
FA_volume_down = 0xf027,
|
||||
FA_volume_up = 0xf028,
|
||||
FA_qrcode = 0xf029,
|
||||
FA_barcode = 0xf02a,
|
||||
FA_tag = 0xf02b,
|
||||
FA_tags = 0xf02c,
|
||||
FA_book = 0xf02d,
|
||||
FA_bookmark = 0xf02e,
|
||||
FA_print = 0xf02f,
|
||||
FA_camera = 0xf030,
|
||||
FA_font = 0xf031,
|
||||
FA_bold = 0xf032,
|
||||
FA_italic = 0xf033,
|
||||
FA_text_height = 0xf034,
|
||||
FA_text_width = 0xf035,
|
||||
FA_align_left = 0xf036,
|
||||
FA_align_center = 0xf037,
|
||||
FA_align_right = 0xf038,
|
||||
FA_align_justify = 0xf039,
|
||||
FA_list = 0xf03a,
|
||||
FA_dedent = 0xf03b,
|
||||
FA_outdent = 0xf03b,
|
||||
FA_indent = 0xf03c,
|
||||
FA_video_camera = 0xf03d,
|
||||
FA_photo = 0xf03e,
|
||||
FA_image = 0xf03e,
|
||||
FA_picture_o = 0xf03e,
|
||||
FA_pencil = 0xf040,
|
||||
FA_map_marker = 0xf041,
|
||||
FA_adjust = 0xf042,
|
||||
FA_tint = 0xf043,
|
||||
FA_edit = 0xf044,
|
||||
FA_pencil_square_o = 0xf044,
|
||||
FA_share_square_o = 0xf045,
|
||||
FA_check_square_o = 0xf046,
|
||||
FA_arrows = 0xf047,
|
||||
FA_step_backward = 0xf048,
|
||||
FA_fast_backward = 0xf049,
|
||||
FA_backward = 0xf04a,
|
||||
FA_play = 0xf04b,
|
||||
FA_pause = 0xf04c,
|
||||
FA_stop = 0xf04d,
|
||||
FA_forward = 0xf04e,
|
||||
FA_fast_forward = 0xf050,
|
||||
FA_step_forward = 0xf051,
|
||||
FA_eject = 0xf052,
|
||||
FA_chevron_left = 0xf053,
|
||||
FA_chevron_right = 0xf054,
|
||||
FA_plus_circle = 0xf055,
|
||||
FA_minus_circle = 0xf056,
|
||||
FA_times_circle = 0xf057,
|
||||
FA_check_circle = 0xf058,
|
||||
FA_question_circle = 0xf059,
|
||||
FA_info_circle = 0xf05a,
|
||||
FA_crosshairs = 0xf05b,
|
||||
FA_times_circle_o = 0xf05c,
|
||||
FA_check_circle_o = 0xf05d,
|
||||
FA_ban = 0xf05e,
|
||||
FA_arrow_left = 0xf060,
|
||||
FA_arrow_right = 0xf061,
|
||||
FA_arrow_up = 0xf062,
|
||||
FA_arrow_down = 0xf063,
|
||||
FA_mail_forward = 0xf064,
|
||||
FA_share = 0xf064,
|
||||
FA_expand = 0xf065,
|
||||
FA_compress = 0xf066,
|
||||
FA_plus = 0xf067,
|
||||
FA_minus = 0xf068,
|
||||
FA_asterisk = 0xf069,
|
||||
FA_exclamation_circle = 0xf06a,
|
||||
FA_gift = 0xf06b,
|
||||
FA_leaf = 0xf06c,
|
||||
FA_fire = 0xf06d,
|
||||
FA_eye = 0xf06e,
|
||||
FA_eye_slash = 0xf070,
|
||||
FA_warning = 0xf071,
|
||||
FA_exclamation_triangle = 0xf071,
|
||||
FA_plane = 0xf072,
|
||||
FA_calendar = 0xf073,
|
||||
FA_random = 0xf074,
|
||||
FA_comment = 0xf075,
|
||||
FA_magnet = 0xf076,
|
||||
FA_chevron_up = 0xf077,
|
||||
FA_chevron_down = 0xf078,
|
||||
FA_retweet = 0xf079,
|
||||
FA_shopping_cart = 0xf07a,
|
||||
FA_folder = 0xf07b,
|
||||
FA_folder_open = 0xf07c,
|
||||
FA_arrows_v = 0xf07d,
|
||||
FA_arrows_h = 0xf07e,
|
||||
FA_bar_chart_o = 0xf080,
|
||||
FA_bar_chart = 0xf080,
|
||||
FA_twitter_square = 0xf081,
|
||||
FA_facebook_square = 0xf082,
|
||||
FA_camera_retro = 0xf083,
|
||||
FA_key = 0xf084,
|
||||
FA_gears = 0xf085,
|
||||
FA_cogs = 0xf085,
|
||||
FA_comments = 0xf086,
|
||||
FA_thumbs_o_up = 0xf087,
|
||||
FA_thumbs_o_down = 0xf088,
|
||||
FA_star_half = 0xf089,
|
||||
FA_heart_o = 0xf08a,
|
||||
FA_sign_out = 0xf08b,
|
||||
FA_linkedin_square = 0xf08c,
|
||||
FA_thumb_tack = 0xf08d,
|
||||
FA_external_link = 0xf08e,
|
||||
FA_sign_in = 0xf090,
|
||||
FA_trophy = 0xf091,
|
||||
FA_github_square = 0xf092,
|
||||
FA_upload = 0xf093,
|
||||
FA_lemon_o = 0xf094,
|
||||
FA_phone = 0xf095,
|
||||
FA_square_o = 0xf096,
|
||||
FA_bookmark_o = 0xf097,
|
||||
FA_phone_square = 0xf098,
|
||||
FA_twitter = 0xf099,
|
||||
FA_facebook_f = 0xf09a,
|
||||
FA_facebook = 0xf09a,
|
||||
FA_github = 0xf09b,
|
||||
FA_unlock = 0xf09c,
|
||||
FA_credit_card = 0xf09d,
|
||||
FA_feed = 0xf09e,
|
||||
FA_rss = 0xf09e,
|
||||
FA_hdd_o = 0xf0a0,
|
||||
FA_bullhorn = 0xf0a1,
|
||||
FA_bell = 0xf0f3,
|
||||
FA_certificate = 0xf0a3,
|
||||
FA_hand_o_right = 0xf0a4,
|
||||
FA_hand_o_left = 0xf0a5,
|
||||
FA_hand_o_up = 0xf0a6,
|
||||
FA_hand_o_down = 0xf0a7,
|
||||
FA_arrow_circle_left = 0xf0a8,
|
||||
FA_arrow_circle_right = 0xf0a9,
|
||||
FA_arrow_circle_up = 0xf0aa,
|
||||
FA_arrow_circle_down = 0xf0ab,
|
||||
FA_globe = 0xf0ac,
|
||||
FA_wrench = 0xf0ad,
|
||||
FA_tasks = 0xf0ae,
|
||||
FA_filter = 0xf0b0,
|
||||
FA_briefcase = 0xf0b1,
|
||||
FA_arrows_alt = 0xf0b2,
|
||||
FA_group = 0xf0c0,
|
||||
FA_users = 0xf0c0,
|
||||
FA_chain = 0xf0c1,
|
||||
FA_link = 0xf0c1,
|
||||
FA_cloud = 0xf0c2,
|
||||
FA_flask = 0xf0c3,
|
||||
FA_cut = 0xf0c4,
|
||||
FA_scissors = 0xf0c4,
|
||||
FA_copy = 0xf0c5,
|
||||
FA_files_o = 0xf0c5,
|
||||
FA_paperclip = 0xf0c6,
|
||||
FA_save = 0xf0c7,
|
||||
FA_floppy_o = 0xf0c7,
|
||||
FA_square = 0xf0c8,
|
||||
FA_navicon = 0xf0c9,
|
||||
FA_reorder = 0xf0c9,
|
||||
FA_bars = 0xf0c9,
|
||||
FA_list_ul = 0xf0ca,
|
||||
FA_list_ol = 0xf0cb,
|
||||
FA_strikethrough = 0xf0cc,
|
||||
FA_underline = 0xf0cd,
|
||||
FA_table = 0xf0ce,
|
||||
FA_magic = 0xf0d0,
|
||||
FA_truck = 0xf0d1,
|
||||
FA_pinterest = 0xf0d2,
|
||||
FA_pinterest_square = 0xf0d3,
|
||||
FA_google_plus_square = 0xf0d4,
|
||||
FA_google_plus = 0xf0d5,
|
||||
FA_money = 0xf0d6,
|
||||
FA_caret_down = 0xf0d7,
|
||||
FA_caret_up = 0xf0d8,
|
||||
FA_caret_left = 0xf0d9,
|
||||
FA_caret_right = 0xf0da,
|
||||
FA_columns = 0xf0db,
|
||||
FA_unsorted = 0xf0dc,
|
||||
FA_sort = 0xf0dc,
|
||||
FA_sort_down = 0xf0dd,
|
||||
FA_sort_desc = 0xf0dd,
|
||||
FA_sort_up = 0xf0de,
|
||||
FA_sort_asc = 0xf0de,
|
||||
FA_envelope = 0xf0e0,
|
||||
FA_linkedin = 0xf0e1,
|
||||
FA_rotate_left = 0xf0e2,
|
||||
FA_undo = 0xf0e2,
|
||||
FA_legal = 0xf0e3,
|
||||
FA_gavel = 0xf0e3,
|
||||
FA_dashboard = 0xf0e4,
|
||||
FA_tachometer = 0xf0e4,
|
||||
FA_comment_o = 0xf0e5,
|
||||
FA_comments_o = 0xf0e6,
|
||||
FA_flash = 0xf0e7,
|
||||
FA_bolt = 0xf0e7,
|
||||
FA_sitemap = 0xf0e8,
|
||||
FA_umbrella = 0xf0e9,
|
||||
FA_paste = 0xf0ea,
|
||||
FA_clipboard = 0xf0ea,
|
||||
FA_lightbulb_o = 0xf0eb,
|
||||
FA_exchange = 0xf0ec,
|
||||
FA_cloud_download = 0xf0ed,
|
||||
FA_cloud_upload = 0xf0ee,
|
||||
FA_user_md = 0xf0f0,
|
||||
FA_stethoscope = 0xf0f1,
|
||||
FA_suitcase = 0xf0f2,
|
||||
FA_bell_o = 0xf0a2,
|
||||
FA_coffee = 0xf0f4,
|
||||
FA_cutlery = 0xf0f5,
|
||||
FA_file_text_o = 0xf0f6,
|
||||
FA_building_o = 0xf0f7,
|
||||
FA_hospital_o = 0xf0f8,
|
||||
FA_ambulance = 0xf0f9,
|
||||
FA_medkit = 0xf0fa,
|
||||
FA_fighter_jet = 0xf0fb,
|
||||
FA_beer = 0xf0fc,
|
||||
FA_h_square = 0xf0fd,
|
||||
FA_plus_square = 0xf0fe,
|
||||
FA_angle_double_left = 0xf100,
|
||||
FA_angle_double_right = 0xf101,
|
||||
FA_angle_double_up = 0xf102,
|
||||
FA_angle_double_down = 0xf103,
|
||||
FA_angle_left = 0xf104,
|
||||
FA_angle_right = 0xf105,
|
||||
FA_angle_up = 0xf106,
|
||||
FA_angle_down = 0xf107,
|
||||
FA_desktop = 0xf108,
|
||||
FA_laptop = 0xf109,
|
||||
FA_tablet = 0xf10a,
|
||||
FA_mobile_phone = 0xf10b,
|
||||
FA_mobile = 0xf10b,
|
||||
FA_circle_o = 0xf10c,
|
||||
FA_quote_left = 0xf10d,
|
||||
FA_quote_right = 0xf10e,
|
||||
FA_spinner = 0xf110,
|
||||
FA_circle = 0xf111,
|
||||
FA_mail_reply = 0xf112,
|
||||
FA_reply = 0xf112,
|
||||
FA_github_alt = 0xf113,
|
||||
FA_folder_o = 0xf114,
|
||||
FA_folder_open_o = 0xf115,
|
||||
FA_smile_o = 0xf118,
|
||||
FA_frown_o = 0xf119,
|
||||
FA_meh_o = 0xf11a,
|
||||
FA_gamepad = 0xf11b,
|
||||
FA_keyboard_o = 0xf11c,
|
||||
FA_flag_o = 0xf11d,
|
||||
FA_flag_checkered = 0xf11e,
|
||||
FA_terminal = 0xf120,
|
||||
FA_code = 0xf121,
|
||||
FA_mail_reply_all = 0xf122,
|
||||
FA_reply_all = 0xf122,
|
||||
FA_star_half_empty = 0xf123,
|
||||
FA_star_half_full = 0xf123,
|
||||
FA_star_half_o = 0xf123,
|
||||
FA_location_arrow = 0xf124,
|
||||
FA_crop = 0xf125,
|
||||
FA_code_fork = 0xf126,
|
||||
FA_unlink = 0xf127,
|
||||
FA_chain_broken = 0xf127,
|
||||
FA_question = 0xf128,
|
||||
FA_info = 0xf129,
|
||||
FA_exclamation = 0xf12a,
|
||||
FA_superscript = 0xf12b,
|
||||
FA_subscript = 0xf12c,
|
||||
FA_eraser = 0xf12d,
|
||||
FA_puzzle_piece = 0xf12e,
|
||||
FA_microphone = 0xf130,
|
||||
FA_microphone_slash = 0xf131,
|
||||
FA_shield = 0xf132,
|
||||
FA_calendar_o = 0xf133,
|
||||
FA_fire_extinguisher = 0xf134,
|
||||
FA_rocket = 0xf135,
|
||||
FA_maxcdn = 0xf136,
|
||||
FA_chevron_circle_left = 0xf137,
|
||||
FA_chevron_circle_right = 0xf138,
|
||||
FA_chevron_circle_up = 0xf139,
|
||||
FA_chevron_circle_down = 0xf13a,
|
||||
FA_html5 = 0xf13b,
|
||||
FA_css3 = 0xf13c,
|
||||
FA_anchor = 0xf13d,
|
||||
FA_unlock_alt = 0xf13e,
|
||||
FA_bullseye = 0xf140,
|
||||
FA_ellipsis_h = 0xf141,
|
||||
FA_ellipsis_v = 0xf142,
|
||||
FA_rss_square = 0xf143,
|
||||
FA_play_circle = 0xf144,
|
||||
FA_ticket = 0xf145,
|
||||
FA_minus_square = 0xf146,
|
||||
FA_minus_square_o = 0xf147,
|
||||
FA_level_up = 0xf148,
|
||||
FA_level_down = 0xf149,
|
||||
FA_check_square = 0xf14a,
|
||||
FA_pencil_square = 0xf14b,
|
||||
FA_external_link_square = 0xf14c,
|
||||
FA_share_square = 0xf14d,
|
||||
FA_compass = 0xf14e,
|
||||
FA_toggle_down = 0xf150,
|
||||
FA_caret_square_o_down = 0xf150,
|
||||
FA_toggle_up = 0xf151,
|
||||
FA_caret_square_o_up = 0xf151,
|
||||
FA_toggle_right = 0xf152,
|
||||
FA_caret_square_o_right = 0xf152,
|
||||
FA_euro = 0xf153,
|
||||
FA_eur = 0xf153,
|
||||
FA_gbp = 0xf154,
|
||||
FA_dollar = 0xf155,
|
||||
FA_usd = 0xf155,
|
||||
FA_rupee = 0xf156,
|
||||
FA_inr = 0xf156,
|
||||
FA_cny = 0xf157,
|
||||
FA_rmb = 0xf157,
|
||||
FA_yen = 0xf157,
|
||||
FA_jpy = 0xf157,
|
||||
FA_ruble = 0xf158,
|
||||
FA_rouble = 0xf158,
|
||||
FA_rub = 0xf158,
|
||||
FA_won = 0xf159,
|
||||
FA_krw = 0xf159,
|
||||
FA_bitcoin = 0xf15a,
|
||||
FA_btc = 0xf15a,
|
||||
FA_file = 0xf15b,
|
||||
FA_file_text = 0xf15c,
|
||||
FA_sort_alpha_asc = 0xf15d,
|
||||
FA_sort_alpha_desc = 0xf15e,
|
||||
FA_sort_amount_asc = 0xf160,
|
||||
FA_sort_amount_desc = 0xf161,
|
||||
FA_sort_numeric_asc = 0xf162,
|
||||
FA_sort_numeric_desc = 0xf163,
|
||||
FA_thumbs_up = 0xf164,
|
||||
FA_thumbs_down = 0xf165,
|
||||
FA_youtube_square = 0xf166,
|
||||
FA_youtube = 0xf167,
|
||||
FA_xing = 0xf168,
|
||||
FA_xing_square = 0xf169,
|
||||
FA_youtube_play = 0xf16a,
|
||||
FA_dropbox = 0xf16b,
|
||||
FA_stack_overflow = 0xf16c,
|
||||
FA_instagram = 0xf16d,
|
||||
FA_flickr = 0xf16e,
|
||||
FA_adn = 0xf170,
|
||||
FA_bitbucket = 0xf171,
|
||||
FA_bitbucket_square = 0xf172,
|
||||
FA_tumblr = 0xf173,
|
||||
FA_tumblr_square = 0xf174,
|
||||
FA_long_arrow_down = 0xf175,
|
||||
FA_long_arrow_up = 0xf176,
|
||||
FA_long_arrow_left = 0xf177,
|
||||
FA_long_arrow_right = 0xf178,
|
||||
FA_apple = 0xf179,
|
||||
FA_windows = 0xf17a,
|
||||
FA_android = 0xf17b,
|
||||
FA_linux = 0xf17c,
|
||||
FA_dribbble = 0xf17d,
|
||||
FA_skype = 0xf17e,
|
||||
FA_foursquare = 0xf180,
|
||||
FA_trello = 0xf181,
|
||||
FA_female = 0xf182,
|
||||
FA_male = 0xf183,
|
||||
FA_gittip = 0xf184,
|
||||
FA_gratipay = 0xf184,
|
||||
FA_sun_o = 0xf185,
|
||||
FA_moon_o = 0xf186,
|
||||
FA_archive = 0xf187,
|
||||
FA_bug = 0xf188,
|
||||
FA_vk = 0xf189,
|
||||
FA_weibo = 0xf18a,
|
||||
FA_renren = 0xf18b,
|
||||
FA_pagelines = 0xf18c,
|
||||
FA_stack_exchange = 0xf18d,
|
||||
FA_arrow_circle_o_right = 0xf18e,
|
||||
FA_arrow_circle_o_left = 0xf190,
|
||||
FA_toggle_left = 0xf191,
|
||||
FA_caret_square_o_left = 0xf191,
|
||||
FA_dot_circle_o = 0xf192,
|
||||
FA_wheelchair = 0xf193,
|
||||
FA_vimeo_square = 0xf194,
|
||||
FA_turkish_lira = 0xf195,
|
||||
FA_try = 0xf195,
|
||||
FA_plus_square_o = 0xf196,
|
||||
FA_space_shuttle = 0xf197,
|
||||
FA_slack = 0xf198,
|
||||
FA_envelope_square = 0xf199,
|
||||
FA_wordpress = 0xf19a,
|
||||
FA_openid = 0xf19b,
|
||||
FA_institution = 0xf19c,
|
||||
FA_bank = 0xf19c,
|
||||
FA_university = 0xf19c,
|
||||
FA_mortar_board = 0xf19d,
|
||||
FA_graduation_cap = 0xf19d,
|
||||
FA_yahoo = 0xf19e,
|
||||
FA_google = 0xf1a0,
|
||||
FA_reddit = 0xf1a1,
|
||||
FA_reddit_square = 0xf1a2,
|
||||
FA_stumbleupon_circle = 0xf1a3,
|
||||
FA_stumbleupon = 0xf1a4,
|
||||
FA_delicious = 0xf1a5,
|
||||
FA_digg = 0xf1a6,
|
||||
FA_pied_piper_pp = 0xf1a7,
|
||||
FA_pied_piper_alt = 0xf1a8,
|
||||
FA_drupal = 0xf1a9,
|
||||
FA_joomla = 0xf1aa,
|
||||
FA_language = 0xf1ab,
|
||||
FA_fax = 0xf1ac,
|
||||
FA_building = 0xf1ad,
|
||||
FA_child = 0xf1ae,
|
||||
FA_paw = 0xf1b0,
|
||||
FA_spoon = 0xf1b1,
|
||||
FA_cube = 0xf1b2,
|
||||
FA_cubes = 0xf1b3,
|
||||
FA_behance = 0xf1b4,
|
||||
FA_behance_square = 0xf1b5,
|
||||
FA_steam = 0xf1b6,
|
||||
FA_steam_square = 0xf1b7,
|
||||
FA_recycle = 0xf1b8,
|
||||
FA_automobile = 0xf1b9,
|
||||
FA_car = 0xf1b9,
|
||||
FA_cab = 0xf1ba,
|
||||
FA_taxi = 0xf1ba,
|
||||
FA_tree = 0xf1bb,
|
||||
FA_spotify = 0xf1bc,
|
||||
FA_deviantart = 0xf1bd,
|
||||
FA_soundcloud = 0xf1be,
|
||||
FA_database = 0xf1c0,
|
||||
FA_file_pdf_o = 0xf1c1,
|
||||
FA_file_word_o = 0xf1c2,
|
||||
FA_file_excel_o = 0xf1c3,
|
||||
FA_file_powerpoint_o = 0xf1c4,
|
||||
FA_file_photo_o = 0xf1c5,
|
||||
FA_file_picture_o = 0xf1c5,
|
||||
FA_file_image_o = 0xf1c5,
|
||||
FA_file_zip_o = 0xf1c6,
|
||||
FA_file_archive_o = 0xf1c6,
|
||||
FA_file_sound_o = 0xf1c7,
|
||||
FA_file_audio_o = 0xf1c7,
|
||||
FA_file_movie_o = 0xf1c8,
|
||||
FA_file_video_o = 0xf1c8,
|
||||
FA_file_code_o = 0xf1c9,
|
||||
FA_vine = 0xf1ca,
|
||||
FA_codepen = 0xf1cb,
|
||||
FA_jsfiddle = 0xf1cc,
|
||||
FA_life_bouy = 0xf1cd,
|
||||
FA_life_buoy = 0xf1cd,
|
||||
FA_life_saver = 0xf1cd,
|
||||
FA_support = 0xf1cd,
|
||||
FA_life_ring = 0xf1cd,
|
||||
FA_circle_o_notch = 0xf1ce,
|
||||
FA_ra = 0xf1d0,
|
||||
FA_resistance = 0xf1d0,
|
||||
FA_rebel = 0xf1d0,
|
||||
FA_ge = 0xf1d1,
|
||||
FA_empire = 0xf1d1,
|
||||
FA_git_square = 0xf1d2,
|
||||
FA_git = 0xf1d3,
|
||||
FA_y_combinator_square = 0xf1d4,
|
||||
FA_yc_square = 0xf1d4,
|
||||
FA_hacker_news = 0xf1d4,
|
||||
FA_tencent_weibo = 0xf1d5,
|
||||
FA_qq = 0xf1d6,
|
||||
FA_wechat = 0xf1d7,
|
||||
FA_weixin = 0xf1d7,
|
||||
FA_send = 0xf1d8,
|
||||
FA_paper_plane = 0xf1d8,
|
||||
FA_send_o = 0xf1d9,
|
||||
FA_paper_plane_o = 0xf1d9,
|
||||
FA_history = 0xf1da,
|
||||
FA_circle_thin = 0xf1db,
|
||||
FA_header = 0xf1dc,
|
||||
FA_paragraph = 0xf1dd,
|
||||
FA_sliders = 0xf1de,
|
||||
FA_share_alt = 0xf1e0,
|
||||
FA_share_alt_square = 0xf1e1,
|
||||
FA_bomb = 0xf1e2,
|
||||
FA_soccer_ball_o = 0xf1e3,
|
||||
FA_futbol_o = 0xf1e3,
|
||||
FA_tty = 0xf1e4,
|
||||
FA_binoculars = 0xf1e5,
|
||||
FA_plug = 0xf1e6,
|
||||
FA_slideshare = 0xf1e7,
|
||||
FA_twitch = 0xf1e8,
|
||||
FA_yelp = 0xf1e9,
|
||||
FA_newspaper_o = 0xf1ea,
|
||||
FA_wifi = 0xf1eb,
|
||||
FA_calculator = 0xf1ec,
|
||||
FA_paypal = 0xf1ed,
|
||||
FA_google_wallet = 0xf1ee,
|
||||
FA_cc_visa = 0xf1f0,
|
||||
FA_cc_mastercard = 0xf1f1,
|
||||
FA_cc_discover = 0xf1f2,
|
||||
FA_cc_amex = 0xf1f3,
|
||||
FA_cc_paypal = 0xf1f4,
|
||||
FA_cc_stripe = 0xf1f5,
|
||||
FA_bell_slash = 0xf1f6,
|
||||
FA_bell_slash_o = 0xf1f7,
|
||||
FA_trash = 0xf1f8,
|
||||
FA_copyright = 0xf1f9,
|
||||
FA_at = 0xf1fa,
|
||||
FA_eyedropper = 0xf1fb,
|
||||
FA_paint_brush = 0xf1fc,
|
||||
FA_birthday_cake = 0xf1fd,
|
||||
FA_area_chart = 0xf1fe,
|
||||
FA_pie_chart = 0xf200,
|
||||
FA_line_chart = 0xf201,
|
||||
FA_lastfm = 0xf202,
|
||||
FA_lastfm_square = 0xf203,
|
||||
FA_toggle_off = 0xf204,
|
||||
FA_toggle_on = 0xf205,
|
||||
FA_bicycle = 0xf206,
|
||||
FA_bus = 0xf207,
|
||||
FA_ioxhost = 0xf208,
|
||||
FA_angellist = 0xf209,
|
||||
FA_cc = 0xf20a,
|
||||
FA_shekel = 0xf20b,
|
||||
FA_sheqel = 0xf20b,
|
||||
FA_ils = 0xf20b,
|
||||
FA_meanpath = 0xf20c,
|
||||
FA_buysellads = 0xf20d,
|
||||
FA_connectdevelop = 0xf20e,
|
||||
FA_dashcube = 0xf210,
|
||||
FA_forumbee = 0xf211,
|
||||
FA_leanpub = 0xf212,
|
||||
FA_sellsy = 0xf213,
|
||||
FA_shirtsinbulk = 0xf214,
|
||||
FA_simplybuilt = 0xf215,
|
||||
FA_skyatlas = 0xf216,
|
||||
FA_cart_plus = 0xf217,
|
||||
FA_cart_arrow_down = 0xf218,
|
||||
FA_diamond = 0xf219,
|
||||
FA_ship = 0xf21a,
|
||||
FA_user_secret = 0xf21b,
|
||||
FA_motorcycle = 0xf21c,
|
||||
FA_street_view = 0xf21d,
|
||||
FA_heartbeat = 0xf21e,
|
||||
FA_venus = 0xf221,
|
||||
FA_mars = 0xf222,
|
||||
FA_mercury = 0xf223,
|
||||
FA_intersex = 0xf224,
|
||||
FA_transgender = 0xf224,
|
||||
FA_transgender_alt = 0xf225,
|
||||
FA_venus_double = 0xf226,
|
||||
FA_mars_double = 0xf227,
|
||||
FA_venus_mars = 0xf228,
|
||||
FA_mars_stroke = 0xf229,
|
||||
FA_mars_stroke_v = 0xf22a,
|
||||
FA_mars_stroke_h = 0xf22b,
|
||||
FA_neuter = 0xf22c,
|
||||
FA_genderless = 0xf22d,
|
||||
FA_facebook_official = 0xf230,
|
||||
FA_pinterest_p = 0xf231,
|
||||
FA_whatsapp = 0xf232,
|
||||
FA_server = 0xf233,
|
||||
FA_user_plus = 0xf234,
|
||||
FA_user_times = 0xf235,
|
||||
FA_hotel = 0xf236,
|
||||
FA_bed = 0xf236,
|
||||
FA_viacoin = 0xf237,
|
||||
FA_train = 0xf238,
|
||||
FA_subway = 0xf239,
|
||||
FA_medium = 0xf23a,
|
||||
FA_yc = 0xf23b,
|
||||
FA_y_combinator = 0xf23b,
|
||||
FA_optin_monster = 0xf23c,
|
||||
FA_opencart = 0xf23d,
|
||||
FA_expeditedssl = 0xf23e,
|
||||
FA_battery_4 = 0xf240,
|
||||
FA_battery = 0xf240,
|
||||
FA_battery_full = 0xf240,
|
||||
FA_battery_3 = 0xf241,
|
||||
FA_battery_three_quarters = 0xf241,
|
||||
FA_battery_2 = 0xf242,
|
||||
FA_battery_half = 0xf242,
|
||||
FA_battery_1 = 0xf243,
|
||||
FA_battery_quarter = 0xf243,
|
||||
FA_battery_0 = 0xf244,
|
||||
FA_battery_empty = 0xf244,
|
||||
FA_mouse_pointer = 0xf245,
|
||||
FA_i_cursor = 0xf246,
|
||||
FA_object_group = 0xf247,
|
||||
FA_object_ungroup = 0xf248,
|
||||
FA_sticky_note = 0xf249,
|
||||
FA_sticky_note_o = 0xf24a,
|
||||
FA_cc_jcb = 0xf24b,
|
||||
FA_cc_diners_club = 0xf24c,
|
||||
FA_clone = 0xf24d,
|
||||
FA_balance_scale = 0xf24e,
|
||||
FA_hourglass_o = 0xf250,
|
||||
FA_hourglass_1 = 0xf251,
|
||||
FA_hourglass_start = 0xf251,
|
||||
FA_hourglass_2 = 0xf252,
|
||||
FA_hourglass_half = 0xf252,
|
||||
FA_hourglass_3 = 0xf253,
|
||||
FA_hourglass_end = 0xf253,
|
||||
FA_hourglass = 0xf254,
|
||||
FA_hand_grab_o = 0xf255,
|
||||
FA_hand_rock_o = 0xf255,
|
||||
FA_hand_stop_o = 0xf256,
|
||||
FA_hand_paper_o = 0xf256,
|
||||
FA_hand_scissors_o = 0xf257,
|
||||
FA_hand_lizard_o = 0xf258,
|
||||
FA_hand_spock_o = 0xf259,
|
||||
FA_hand_pointer_o = 0xf25a,
|
||||
FA_hand_peace_o = 0xf25b,
|
||||
FA_trademark = 0xf25c,
|
||||
FA_registered = 0xf25d,
|
||||
FA_creative_commons = 0xf25e,
|
||||
FA_gg = 0xf260,
|
||||
FA_gg_circle = 0xf261,
|
||||
FA_tripadvisor = 0xf262,
|
||||
FA_odnoklassniki = 0xf263,
|
||||
FA_odnoklassniki_square = 0xf264,
|
||||
FA_get_pocket = 0xf265,
|
||||
FA_wikipedia_w = 0xf266,
|
||||
FA_safari = 0xf267,
|
||||
FA_chrome = 0xf268,
|
||||
FA_firefox = 0xf269,
|
||||
FA_opera = 0xf26a,
|
||||
FA_internet_explorer = 0xf26b,
|
||||
FA_tv = 0xf26c,
|
||||
FA_television = 0xf26c,
|
||||
FA_contao = 0xf26d,
|
||||
FA_amazon = 0xf270,
|
||||
FA_calendar_plus_o = 0xf271,
|
||||
FA_calendar_minus_o = 0xf272,
|
||||
FA_calendar_times_o = 0xf273,
|
||||
FA_calendar_check_o = 0xf274,
|
||||
FA_industry = 0xf275,
|
||||
FA_map_pin = 0xf276,
|
||||
FA_map_signs = 0xf277,
|
||||
FA_map_o = 0xf278,
|
||||
FA_map = 0xf279,
|
||||
FA_commenting = 0xf27a,
|
||||
FA_commenting_o = 0xf27b,
|
||||
FA_houzz = 0xf27c,
|
||||
FA_vimeo = 0xf27d,
|
||||
FA_black_tie = 0xf27e,
|
||||
FA_fonticons = 0xf280,
|
||||
FA_reddit_alien = 0xf281,
|
||||
FA_edge = 0xf282,
|
||||
FA_credit_card_alt = 0xf283,
|
||||
FA_codiepie = 0xf284,
|
||||
FA_modx = 0xf285,
|
||||
FA_fort_awesome = 0xf286,
|
||||
FA_usb = 0xf287,
|
||||
FA_product_hunt = 0xf288,
|
||||
FA_mixcloud = 0xf289,
|
||||
FA_scribd = 0xf28a,
|
||||
FA_pause_circle = 0xf28b,
|
||||
FA_pause_circle_o = 0xf28c,
|
||||
FA_stop_circle = 0xf28d,
|
||||
FA_stop_circle_o = 0xf28e,
|
||||
FA_shopping_bag = 0xf290,
|
||||
FA_shopping_basket = 0xf291,
|
||||
FA_hashtag = 0xf292,
|
||||
FA_bluetooth = 0xf293,
|
||||
FA_bluetooth_b = 0xf294,
|
||||
FA_percent = 0xf295,
|
||||
FA_gitlab = 0xf296,
|
||||
FA_wpbeginner = 0xf297,
|
||||
FA_wpforms = 0xf298,
|
||||
FA_envira = 0xf299,
|
||||
FA_universal_access = 0xf29a,
|
||||
FA_wheelchair_alt = 0xf29b,
|
||||
FA_question_circle_o = 0xf29c,
|
||||
FA_blind = 0xf29d,
|
||||
FA_audio_description = 0xf29e,
|
||||
FA_volume_control_phone = 0xf2a0,
|
||||
FA_braille = 0xf2a1,
|
||||
FA_assistive_listening_systems = 0xf2a2,
|
||||
FA_asl_interpreting = 0xf2a3,
|
||||
FA_american_sign_language_interpreting = 0xf2a3,
|
||||
FA_deafness = 0xf2a4,
|
||||
FA_hard_of_hearing = 0xf2a4,
|
||||
FA_deaf = 0xf2a4,
|
||||
FA_glide = 0xf2a5,
|
||||
FA_glide_g = 0xf2a6,
|
||||
FA_signing = 0xf2a7,
|
||||
FA_sign_language = 0xf2a7,
|
||||
FA_low_vision = 0xf2a8,
|
||||
FA_viadeo = 0xf2a9,
|
||||
FA_viadeo_square = 0xf2aa,
|
||||
FA_snapchat = 0xf2ab,
|
||||
FA_snapchat_ghost = 0xf2ac,
|
||||
FA_snapchat_square = 0xf2ad,
|
||||
FA_pied_piper = 0xf2ae,
|
||||
FA_first_order = 0xf2b0,
|
||||
FA_yoast = 0xf2b1,
|
||||
FA_themeisle = 0xf2b2,
|
||||
FA_google_plus_circle = 0xf2b3,
|
||||
FA_google_plus_official = 0xf2b3,
|
||||
FA_fa = 0xf2b4,
|
||||
FA_font_awesome = 0xf2b4,
|
||||
FA_handshake_o = 0xf2b5,
|
||||
FA_envelope_open = 0xf2b6,
|
||||
FA_envelope_open_o = 0xf2b7,
|
||||
FA_linode = 0xf2b8,
|
||||
FA_address_book = 0xf2b9,
|
||||
FA_address_book_o = 0xf2ba,
|
||||
FA_vcard = 0xf2bb,
|
||||
FA_address_card = 0xf2bb,
|
||||
FA_vcard_o = 0xf2bc,
|
||||
FA_address_card_o = 0xf2bc,
|
||||
FA_user_circle = 0xf2bd,
|
||||
FA_user_circle_o = 0xf2be,
|
||||
FA_user_o = 0xf2c0,
|
||||
FA_id_badge = 0xf2c1,
|
||||
FA_drivers_license = 0xf2c2,
|
||||
FA_id_card = 0xf2c2,
|
||||
FA_drivers_license_o = 0xf2c3,
|
||||
FA_id_card_o = 0xf2c3,
|
||||
FA_quora = 0xf2c4,
|
||||
FA_free_code_camp = 0xf2c5,
|
||||
FA_telegram = 0xf2c6,
|
||||
FA_thermometer_4 = 0xf2c7,
|
||||
FA_thermometer = 0xf2c7,
|
||||
FA_thermometer_full = 0xf2c7,
|
||||
FA_thermometer_3 = 0xf2c8,
|
||||
FA_thermometer_three_quarters = 0xf2c8,
|
||||
FA_thermometer_2 = 0xf2c9,
|
||||
FA_thermometer_half = 0xf2c9,
|
||||
FA_thermometer_1 = 0xf2ca,
|
||||
FA_thermometer_quarter = 0xf2ca,
|
||||
FA_thermometer_0 = 0xf2cb,
|
||||
FA_thermometer_empty = 0xf2cb,
|
||||
FA_shower = 0xf2cc,
|
||||
FA_bathtub = 0xf2cd,
|
||||
FA_s15 = 0xf2cd,
|
||||
FA_bath = 0xf2cd,
|
||||
FA_podcast = 0xf2ce,
|
||||
FA_window_maximize = 0xf2d0,
|
||||
FA_window_minimize = 0xf2d1,
|
||||
FA_window_restore = 0xf2d2,
|
||||
FA_times_rectangle = 0xf2d3,
|
||||
FA_window_close = 0xf2d3,
|
||||
FA_times_rectangle_o = 0xf2d4,
|
||||
FA_window_close_o = 0xf2d4,
|
||||
FA_bandcamp = 0xf2d5,
|
||||
FA_grav = 0xf2d6,
|
||||
FA_etsy = 0xf2d7,
|
||||
FA_imdb = 0xf2d8,
|
||||
FA_ravelry = 0xf2d9,
|
||||
FA_eercast = 0xf2da,
|
||||
FA_microchip = 0xf2db,
|
||||
FA_snowflake_o = 0xf2dc,
|
||||
FA_superpowers = 0xf2dd,
|
||||
FA_wpexplorer = 0xf2de,
|
||||
FA_meetup = 0xf2e0
|
||||
};
|
||||
Q_ENUMS(Fluent_AwesomeType)
|
||||
}
|
||||
|
||||
#endif // DEF_H
|
|
@ -0,0 +1,56 @@
|
|||
#include "FluApp.h"
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlContext>
|
||||
#include "FramelessView.h"
|
||||
|
||||
|
||||
FluApp* FluApp::m_instance = nullptr;
|
||||
|
||||
FluApp *FluApp::getInstance()
|
||||
{
|
||||
if(FluApp::m_instance == nullptr){
|
||||
FluApp::m_instance = new FluApp;
|
||||
}
|
||||
return FluApp::m_instance;
|
||||
}
|
||||
|
||||
|
||||
void FluApp::setAppWindow(QWindow *window){
|
||||
appWindow = window;
|
||||
}
|
||||
|
||||
void FluApp::run(){
|
||||
if(!routes().contains(initialRoute())){
|
||||
qErrnoWarning("没有找到当前路由");
|
||||
return;
|
||||
}
|
||||
FramelessView *view = new FramelessView();
|
||||
view->engine()->rootContext()->setContextProperty("FluApp",FluApp::getInstance());
|
||||
const QUrl url(routes().value(initialRoute()).toString());
|
||||
QObject::connect(view, &QQuickView::statusChanged, view, [&](QQuickView::Status status) {
|
||||
if (status == QQuickView::Status::Ready) {
|
||||
|
||||
}
|
||||
});
|
||||
QObject::connect(view->engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
|
||||
QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view](){view->setSource({});});
|
||||
view->setSource(url);
|
||||
view->moveToScreenCenter();
|
||||
view->show();
|
||||
}
|
||||
|
||||
void FluApp::navigate(const QString& route){
|
||||
qDebug()<<"开始路由跳转->"<<route;
|
||||
if(!routes().contains(route)){
|
||||
qErrnoWarning("没有找到当前路由");
|
||||
return;
|
||||
}
|
||||
FramelessView *view = new FramelessView();
|
||||
view->engine()->rootContext()->setContextProperty("FluApp",FluApp::getInstance());
|
||||
view->setSource((routes().value(route).toString()));
|
||||
view->closeDeleteLater();
|
||||
view->moveToScreenCenter();
|
||||
view->show();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef FLUAPP_H
|
||||
#define FLUAPP_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QWindow>
|
||||
#include <QJsonObject>
|
||||
#include "stdafx.h"
|
||||
|
||||
class FluApp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,initialRoute);
|
||||
Q_PROPERTY_AUTO(QJsonObject,routes);
|
||||
public:
|
||||
|
||||
static FluApp *getInstance();
|
||||
|
||||
Q_INVOKABLE void run();
|
||||
|
||||
Q_INVOKABLE void navigate(const QString& route);
|
||||
|
||||
Q_INVOKABLE void setAppWindow(QWindow *window);
|
||||
|
||||
private:
|
||||
static FluApp* m_instance;
|
||||
QWindow *appWindow;
|
||||
|
||||
};
|
||||
|
||||
#endif // FLUAPP_H
|
|
@ -0,0 +1,59 @@
|
|||
#include "Fluent.h"
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QQmlContext>
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickWindow>
|
||||
#include "FluApp.h"
|
||||
#include "Def.h"
|
||||
|
||||
Fluent* Fluent::m_instance = nullptr;
|
||||
|
||||
Fluent *Fluent::getInstance()
|
||||
{
|
||||
if(Fluent::m_instance == nullptr){
|
||||
Fluent::m_instance = new Fluent;
|
||||
}
|
||||
return Fluent::m_instance;
|
||||
}
|
||||
|
||||
QString Fluent::version() const
|
||||
{
|
||||
return QStringLiteral(VERSION_IN);
|
||||
}
|
||||
|
||||
void Fluent::registerTypes(const char *uri){
|
||||
Q_INIT_RESOURCE(res);
|
||||
int major = 1;
|
||||
int minor = 0;
|
||||
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluButton.qml"),uri,major,minor,"FluButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluCheckBox.qml"),uri,major,minor,"FluCheckBox");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluComboBox.qml"),uri,major,minor,"FluComboBox");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDropDownButton.qml"),uri,major,minor,"FluDropDownButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIconButton.qml"),uri,major,minor,"FluIconButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluProgressBar.qml"),uri,major,minor,"FluProgressBar");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluProgressRing.qml"),uri,major,minor,"FluProgressRing");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluRadioButton.qml"),uri,major,minor,"FluRadioButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluSlider.qml"),uri,major,minor,"FluSlider");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextBox.qml"),uri,major,minor,"FluTextBox");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluText.qml"),uri,major,minor,"FluText");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTimePicker.qml"),uri,major,minor,"FluTimePicker");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluToggleSwitch.qml"),uri,major,minor,"FluToggleSwitch");
|
||||
|
||||
qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only");
|
||||
}
|
||||
|
||||
void Fluent::initializeEngine(QQmlEngine *engine, const char *uri)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(uri)
|
||||
QFont font;
|
||||
font.setFamily("Microsoft YaHei");
|
||||
QGuiApplication::setFont(font);
|
||||
QQuickWindow::setTextRenderType(QQuickWindow::NativeTextRendering);
|
||||
QFontDatabase::addApplicationFont(":/com.zhuzichu/res/font/fontawesome-webfont.ttf");
|
||||
engine->rootContext()->setContextProperty("FluApp",FluApp::getInstance());
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef FLUENT_H
|
||||
#define FLUENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class Fluent: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Fluent *getInstance();
|
||||
|
||||
Q_INVOKABLE QString version() const;
|
||||
|
||||
void registerTypes(const char *uri);
|
||||
|
||||
void initializeEngine(QQmlEngine *engine, const char *uri);
|
||||
private:
|
||||
static Fluent* m_instance;
|
||||
};
|
||||
|
||||
#endif // FLUENT_H
|
|
@ -1,27 +1,15 @@
|
|||
#include "FluentUI.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include "Fluent.h"
|
||||
|
||||
FluentUI::FluentUI(QQuickItem *parent)
|
||||
: QQuickPaintedItem(parent)
|
||||
void FluentUI::create(QQmlEngine *engine)
|
||||
{
|
||||
// By default, QQuickItem does not draw anything. If you subclass
|
||||
// QQuickItem to create a visual item, you will need to uncomment the
|
||||
// following line and re-implement updatePaintNode()
|
||||
|
||||
// setFlag(ItemHasContents, true);
|
||||
Fluent::getInstance()->registerTypes(URI_STR);
|
||||
Fluent::getInstance()->initializeEngine(engine,URI_STR);
|
||||
engine->addImportPath("/");
|
||||
}
|
||||
|
||||
void FluentUI::paint(QPainter *painter)
|
||||
{
|
||||
QPen pen(QColorConstants::Red, 2);
|
||||
QBrush brush(QColorConstants::Red);
|
||||
|
||||
painter->setPen(pen);
|
||||
painter->setBrush(brush);
|
||||
painter->drawRect(0, 0, 100, 100);
|
||||
}
|
||||
|
||||
FluentUI::~FluentUI()
|
||||
QString FluentUI::version()
|
||||
{
|
||||
return Fluent::getInstance()->version();
|
||||
}
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
#ifndef FLUENTUI_H
|
||||
#define FLUENTUI_H
|
||||
|
||||
#include <QtQuick/QQuickPaintedItem>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class FluentUI : public QQuickPaintedItem
|
||||
class FluentUI
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
Q_DISABLE_COPY(FluentUI)
|
||||
public:
|
||||
explicit FluentUI(QQuickItem *parent = nullptr);
|
||||
void paint(QPainter *painter) override;
|
||||
~FluentUI() override;
|
||||
signals:
|
||||
|
||||
public:
|
||||
static void create(QQmlEngine* engine);
|
||||
static QString version();
|
||||
};
|
||||
|
||||
#endif // FLUENTUI_H
|
||||
|
|
|
@ -6,7 +6,7 @@ TARGET = $$qtLibraryTarget($$TARGET)
|
|||
uri = FluentUI
|
||||
|
||||
##########################################
|
||||
CONFIG += sharedlib # staticlib or sharedlib
|
||||
CONFIG += staticlib # staticlib or sharedlib
|
||||
#** 多次切换编译构建模式,建议先清理缓存。项目右键->清理
|
||||
|
||||
#*[staticlib] 构建静态库.a
|
||||
|
@ -24,14 +24,29 @@ RESOURCES += \
|
|||
|
||||
# Input
|
||||
HEADERS += \
|
||||
Def.h \
|
||||
FluApp.h \
|
||||
Fluent.h \
|
||||
FluentUI.h \
|
||||
qml_plugin.h \
|
||||
FramelessView.h \
|
||||
qml_plugin.h \
|
||||
stdafx.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
Def.cpp \
|
||||
FluApp.cpp \
|
||||
Fluent.cpp \
|
||||
FluentUI.cpp \
|
||||
qml_plugin.cpp \
|
||||
qml_plugin.cpp \
|
||||
|
||||
win32 {
|
||||
SOURCES += \
|
||||
FramelessView_win.cpp
|
||||
} else {
|
||||
SOURCES += \
|
||||
FramelessView_unix.cpp
|
||||
}
|
||||
|
||||
|
||||
DEFINES += VERSION_IN=\\\"1.0.0\\\"
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QQuickView>
|
||||
#include <QRegion>
|
||||
|
||||
//无边框窗口,主要用来实现自定义标题栏。
|
||||
//Windows平台支持拖动和改变大小,支持Aero效果
|
||||
//非Windows平台,去掉边框,不做其它处理。由Qml模拟resize和拖动。
|
||||
class FramelessViewPrivate;
|
||||
class FramelessView : public QQuickView
|
||||
{
|
||||
Q_OBJECT
|
||||
using Super = QQuickView;
|
||||
Q_PROPERTY(bool isMax READ isMax NOTIFY isMaxChanged)
|
||||
Q_PROPERTY(bool isFull READ isFull NOTIFY isFullChanged)
|
||||
public:
|
||||
explicit FramelessView(QWindow *parent = nullptr);
|
||||
~FramelessView();
|
||||
void moveToScreenCenter();
|
||||
void closeDeleteLater();
|
||||
bool isMax() const;
|
||||
bool isFull() const;
|
||||
QQuickItem *titleItem() const;
|
||||
|
||||
static QRect calcCenterGeo(const QRect &screenGeo, const QSize &normalSize);
|
||||
public slots:
|
||||
void setIsMax(bool isMax);
|
||||
void setIsFull(bool isFull);
|
||||
void setTitleItem(QQuickItem* item);
|
||||
|
||||
signals:
|
||||
void isMaxChanged(bool isMax);
|
||||
void isFullChanged(bool isFull);
|
||||
void mousePressed(int xPos, int yPos, int button);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
# else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||
# endif
|
||||
void mousePressEvent(QMouseEvent* event) override
|
||||
{
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
emit mousePressed(event->position().x(), event->position().y(), event->button());
|
||||
#else
|
||||
emit mousePressed(event->x(), event->y(), event->button());
|
||||
#endif
|
||||
Super::mousePressEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
FramelessViewPrivate *d;
|
||||
};
|
|
@ -0,0 +1,106 @@
|
|||
#include "FramelessView.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
class FramelessViewPrivate
|
||||
{
|
||||
public:
|
||||
bool m_isMax = false;
|
||||
bool m_isFull = false;
|
||||
QQuickItem *m_titleItem = nullptr;
|
||||
};
|
||||
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
|
||||
{
|
||||
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
(void)state;
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
}
|
||||
FramelessView::~FramelessView()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
void FramelessView::showEvent(QShowEvent *e)
|
||||
{
|
||||
Super::showEvent(e);
|
||||
}
|
||||
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
int h = normalSize.height();
|
||||
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
|
||||
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
|
||||
if (screenGeo.width() < w) {
|
||||
x = screenGeo.x();
|
||||
w = screenGeo.width();
|
||||
}
|
||||
if (screenGeo.height() < h) {
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
|
||||
return { x, y, w, h };
|
||||
}
|
||||
void FramelessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
|
||||
setMinimumSize(geo.size());
|
||||
}
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
bool FramelessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
bool FramelessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
QQuickItem *FramelessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
void FramelessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
return;
|
||||
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
void FramelessView::setIsFull(bool isFull)
|
||||
{
|
||||
if(d->m_isFull == isFull)
|
||||
return;
|
||||
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
void FramelessView::setTitleItem(QQuickItem *item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
|
||||
{
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
void FramelessView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Super::resizeEvent(e);
|
||||
}
|
|
@ -0,0 +1,372 @@
|
|||
#include "FramelessView.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
#include <VersionHelpers.h>
|
||||
#include <WinUser.h>
|
||||
#include <dwmapi.h>
|
||||
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <wtypes.h>
|
||||
#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved
|
||||
#pragma comment(lib, "User32.lib")
|
||||
#pragma comment(lib, "Gdi32.lib")
|
||||
// we cannot just use WS_POPUP style
|
||||
// WS_THICKFRAME: without this the window cannot be resized and so aero snap, de-maximizing and minimizing won't work
|
||||
// WS_SYSMENU: enables the context menu with the move, close, maximize, minize... commands (shift + right-click on the task bar item)
|
||||
// WS_CAPTION: enables aero minimize animation/transition
|
||||
// WS_MAXIMIZEBOX, WS_MINIMIZEBOX: enable minimize/maximize
|
||||
enum class Style : DWORD
|
||||
{
|
||||
windowed = WS_OVERLAPPEDWINDOW | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
||||
aero_borderless = WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
||||
basic_borderless = WS_POPUP | WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX
|
||||
};
|
||||
static bool isCompositionEnabled()
|
||||
{
|
||||
BOOL composition_enabled = FALSE;
|
||||
bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK;
|
||||
return composition_enabled && success;
|
||||
}
|
||||
static Style selectBorderLessStyle()
|
||||
{
|
||||
return isCompositionEnabled() ? Style::aero_borderless : Style::basic_borderless;
|
||||
}
|
||||
static void setShadow(HWND handle, bool enabled)
|
||||
{
|
||||
if (isCompositionEnabled())
|
||||
{
|
||||
static const MARGINS shadow_state[2] { { 0, 0, 0, 0 }, { 1, 1, 1, 1 } };
|
||||
::DwmExtendFrameIntoClientArea(handle, &shadow_state[enabled]);
|
||||
}
|
||||
}
|
||||
static long hitTest(RECT winrect, long x, long y, int borderWidth)
|
||||
{
|
||||
// 鼠标区域位于窗体边框,进行缩放
|
||||
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top) && (y < winrect.top + borderWidth))
|
||||
{
|
||||
return HTTOPLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth)
|
||||
{
|
||||
return HTTOPRIGHT;
|
||||
}
|
||||
else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOMLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOMRIGHT;
|
||||
}
|
||||
else if (x >= winrect.left && x < winrect.left + borderWidth)
|
||||
{
|
||||
return HTLEFT;
|
||||
}
|
||||
else if (x < winrect.right && x >= winrect.right - borderWidth)
|
||||
{
|
||||
return HTRIGHT;
|
||||
}
|
||||
else if (y >= winrect.top && y < winrect.top + borderWidth)
|
||||
{
|
||||
return HTTOP;
|
||||
}
|
||||
else if (y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
||||
{
|
||||
return HTBOTTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isMaxWin(QWindow* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowMaximized;
|
||||
}
|
||||
static bool isFullWin(QQuickView* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowFullScreen;
|
||||
}
|
||||
|
||||
class FramelessViewPrivate
|
||||
{
|
||||
public:
|
||||
bool m_firstRun = true;
|
||||
bool m_isMax = false;
|
||||
bool m_isFull = false;
|
||||
bool m_deleteLater = false;
|
||||
QQuickItem* m_titleItem = nullptr;
|
||||
HMENU mMenuHandler = NULL;
|
||||
bool borderless = true; // is the window currently borderless
|
||||
bool borderless_resize = true; // should the window allow resizing by dragging the borders while borderless
|
||||
bool borderless_drag = true; // should the window allow moving my dragging the client area
|
||||
bool borderless_shadow = true; // should the window display a native aero shadow while borderless
|
||||
void setBorderLess(HWND handle, bool enabled)
|
||||
{
|
||||
auto newStyle = enabled ? selectBorderLessStyle() : Style::windowed;
|
||||
auto oldStyle = static_cast<Style>(::GetWindowLongPtrW(handle, GWL_STYLE));
|
||||
if (oldStyle != newStyle)
|
||||
{
|
||||
borderless = enabled;
|
||||
::SetWindowLongPtrW(handle, GWL_STYLE, static_cast<LONG>(newStyle));
|
||||
|
||||
// when switching between borderless and windowed, restore appropriate shadow state
|
||||
setShadow(handle, borderless_shadow && (newStyle != Style::windowed));
|
||||
|
||||
// redraw frame
|
||||
::SetWindowPos(handle, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||
::ShowWindow(handle, SW_SHOW);
|
||||
}
|
||||
}
|
||||
void setBorderLessShadow(HWND handle, bool enabled)
|
||||
{
|
||||
if (borderless)
|
||||
{
|
||||
borderless_shadow = enabled;
|
||||
setShadow(handle, enabled);
|
||||
}
|
||||
}
|
||||
};
|
||||
FramelessView::FramelessView(QWindow* parent)
|
||||
: QQuickView(parent)
|
||||
, d(new FramelessViewPrivate)
|
||||
{
|
||||
//此处不需要设置flags
|
||||
// setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint |
|
||||
// Qt::WindowSystemMenuHint);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
(void)state;
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
}
|
||||
void FramelessView::showEvent(QShowEvent* e)
|
||||
{
|
||||
if (d->m_firstRun)
|
||||
{
|
||||
d->m_firstRun = false;
|
||||
//第一次show的时候,设置无边框。不在构造函数中设置。取winId会触发QWindowsWindow::create,直接创建win32窗口,引起错乱(win7 或者虚拟机启动即黑屏)。
|
||||
d->setBorderLess((HWND)(winId()), d->borderless);
|
||||
{
|
||||
// Qt 5.15.2 的bug; 问题复现及解决方法:当使用WM_NCCALCSIZE 修改非客户区大小后,移动窗口到其他屏幕时,qwindows.dll 源码 qwindowswindow.cpp:2447
|
||||
// updateFullFrameMargins() 函数 处会调用qwindowswindow.cpp:2453 的
|
||||
// calculateFullFrameMargins函数重新获取默认的非客户区大小,导致最外层窗口移动屏幕时会触发resize消息,引起40像素左右的黑边;故此处创建Menu
|
||||
// 使其调用qwindowswindow.cpp:2451 的 QWindowsContext::forceNcCalcSize() 函数计算非客户区大小
|
||||
|
||||
//已知负面效果: 引入win32 MENU后,Qt程序中如果有alt开头的快捷键,会不生效,被Qt滤掉了,需要修改Qt源码
|
||||
// QWindowsKeyMapper::translateKeyEventInternal 中的
|
||||
// if (msgType == WM_SYSKEYDOWN && (nModifiers & AltAny) != 0 && GetMenu(msg.hwnd) != nullptr)
|
||||
// return false;
|
||||
// 这两行屏蔽掉
|
||||
|
||||
d->mMenuHandler = ::CreateMenu();
|
||||
::SetMenu((HWND)winId(), d->mMenuHandler);
|
||||
}
|
||||
}
|
||||
Super::showEvent(e);
|
||||
}
|
||||
FramelessView::~FramelessView()
|
||||
{
|
||||
qInfo()<<"FramelessView析构了";
|
||||
if (d->mMenuHandler != NULL)
|
||||
{
|
||||
::DestroyMenu(d->mMenuHandler);
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool FramelessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
|
||||
bool FramelessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
QQuickItem* FramelessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
void FramelessView::setTitleItem(QQuickItem* item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
}
|
||||
QRect FramelessView::calcCenterGeo(const QRect& screenGeo, const QSize& normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
int h = normalSize.height();
|
||||
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
|
||||
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
|
||||
if (screenGeo.width() < w)
|
||||
{
|
||||
x = screenGeo.x();
|
||||
w = screenGeo.width();
|
||||
}
|
||||
if (screenGeo.height() < h)
|
||||
{
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
|
||||
return { x, y, w, h };
|
||||
}
|
||||
void FramelessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
if (minimumWidth() > geo.width() || minimumHeight() > geo.height())
|
||||
{
|
||||
setMinimumSize(geo.size());
|
||||
}
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
|
||||
void FramelessView::closeDeleteLater(){
|
||||
d->m_deleteLater = true;
|
||||
}
|
||||
|
||||
void FramelessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
return;
|
||||
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
void FramelessView::setIsFull(bool isFull)
|
||||
{
|
||||
if (d->m_isFull == isFull)
|
||||
return;
|
||||
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
void FramelessView::resizeEvent(QResizeEvent* e)
|
||||
{
|
||||
// SetWindowRgn(HWND(winId()), CreateRoundRectRgn(0, 0, width(), height(), 4, 4), true);
|
||||
Super::resizeEvent(e);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool FramelessView::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
|
||||
#else
|
||||
bool FramelessView::nativeEvent(const QByteArray& eventType, void* message, long* result)
|
||||
#endif
|
||||
|
||||
{
|
||||
const long border_width = 4;
|
||||
if (!result)
|
||||
{
|
||||
//防御式编程
|
||||
//一般不会发生这种情况,win7一些极端情况,会传空指针进来。解决方案是升级驱动、切换到basic主题。
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1))
|
||||
// Work-around a bug caused by typo which only exists in Qt 5.11.1
|
||||
const auto msg = *reinterpret_cast<MSG**>(message);
|
||||
#else
|
||||
const auto msg = static_cast<LPMSG>(message);
|
||||
#endif
|
||||
|
||||
if (!msg || !msg->hwnd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_CLOSE:{
|
||||
if(d->m_deleteLater){
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
case WM_NCCALCSIZE: {
|
||||
#if 1
|
||||
const auto mode = static_cast<BOOL>(msg->wParam);
|
||||
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
|
||||
if (mode == TRUE && d->borderless)
|
||||
{
|
||||
*result = WVR_REDRAW;
|
||||
//规避 拖动border进行resize时界面闪烁
|
||||
if (!isMaxWin(this) && !isFullWin(this))
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top -= 0.1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top += 0.1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
*result = 0;
|
||||
return true;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case WM_NCACTIVATE: {
|
||||
if (!isCompositionEnabled())
|
||||
{
|
||||
// Prevents window frame reappearing on window activation
|
||||
// in "basic" theme, where no aero shadow is present.
|
||||
*result = 1;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_NCHITTEST: {
|
||||
if (d->borderless)
|
||||
{
|
||||
RECT winrect;
|
||||
GetWindowRect(HWND(winId()), &winrect);
|
||||
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
|
||||
*result = 0;
|
||||
if (!isMaxWin(this) && !isFullWin(this))
|
||||
{ //非最大化、非全屏时,进行命中测试,处理边框拖拽
|
||||
*result = hitTest(winrect, x, y, border_width);
|
||||
if (0 != *result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->m_titleItem)
|
||||
{
|
||||
auto titlePos = d->m_titleItem->mapToGlobal({ 0, 0 });
|
||||
titlePos = mapFromGlobal(titlePos.toPoint());
|
||||
auto titleRect = QRect(titlePos.x(), titlePos.y(), d->m_titleItem->width(), d->m_titleItem->height());
|
||||
double dpr = qApp->devicePixelRatio();
|
||||
QPoint pos = mapFromGlobal(QPoint(x / dpr, y / dpr));
|
||||
if (titleRect.contains(pos))
|
||||
{
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
} // end case WM_NCHITTEST
|
||||
}
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
module FluentUI
|
||||
plugin FluentUI
|
||||
classname FluentUIQmlPlugin
|
||||
typeinfo plugin.qmltypes
|
||||
typeinfo plugin.qmltypes
|
|
@ -5,12 +5,6 @@ PRESET_PATH = $$PWD/build-preset
|
|||
SOLIBFILE_PATH = $$OUT_PWD/libFluentUI.so
|
||||
ANDROID = NO
|
||||
|
||||
#QT_BIN_PATH = $$[QT_INSTALL_BINS]
|
||||
#PLUGIN_NAME = $$uri
|
||||
#PLUGIN_VERSION = "1.0"
|
||||
#PLUGIN_PARENT_PATH = $$BUILD_ROOT/build-preset/plugins
|
||||
#PLUGIN_QMLTYPES_PATH = $$BUILD_ROOT/build-preset/plugins/$$uri/plugin.qmltypes
|
||||
|
||||
android{
|
||||
ANDROID=YES
|
||||
QMAKE_PRE_LINK *= md $$replace(OUTP, /, \\)
|
||||
|
@ -18,12 +12,9 @@ android{
|
|||
DESTDIR += $$OUTP
|
||||
}
|
||||
|
||||
#QMLTYPESSCRIPT = "$$PWD\create_qmltypes.bat" "$$QT_BIN_PATH" "$$PLUGIN_NAME" "$$PLUGIN_VERSION" "$$PLUGIN_PARENT_PATH" "$$PLUGIN_QMLTYPES_PATH"
|
||||
SHAREDSCRIPT = "$$PWD\win_install.bat" SHARED "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
|
||||
STATICSCRIPT = "$$PWD\win_install.bat" STATIC "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
|
||||
|
||||
#QMAKE_POST_LINK *= $$replace(QMLTYPESSCRIPT, /, \\)
|
||||
|
||||
CONFIG(sharedlib){
|
||||
QMAKE_POST_LINK *= $$replace(SHAREDSCRIPT, /, \\)
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
//@uri FluentUI
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Controls.Material 2.15
|
||||
|
||||
Rectangle {
|
||||
id: button
|
||||
width: 100
|
||||
height: 40
|
||||
radius: 4
|
||||
color: Material.accent
|
||||
border.color: Material.accent
|
||||
|
||||
Text {
|
||||
id: buttonText
|
||||
text: "Button"
|
||||
color: "white"
|
||||
font.pixelSize: 14
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.log("Button clicked")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,17 +10,16 @@ Rectangle {
|
|||
property int topPadding: 8
|
||||
property int bottomPadding: 8
|
||||
property bool disabled: false
|
||||
signal clicked
|
||||
radius: 4
|
||||
color: "#FFFFFF"
|
||||
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
border.color: "#eeeeee"
|
||||
color: button_mouse.containsMouse ? "#eeeeee" : "#FFFFFF"
|
||||
width: button_text.implicitWidth
|
||||
height: button_text.implicitHeight
|
||||
border.color: "#cccccc"
|
||||
border.width: 1
|
||||
|
||||
Text {
|
||||
id: buttonText
|
||||
id: button_text
|
||||
text: "Standard Button"
|
||||
color: "#000000"
|
||||
font.pixelSize: 13
|
||||
|
@ -32,9 +31,11 @@ Rectangle {
|
|||
}
|
||||
|
||||
MouseArea {
|
||||
id:button_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
console.log("Button clicked")
|
||||
button.clicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Controls.Material 2.15
|
||||
|
||||
Rectangle {
|
||||
id: button
|
||||
|
||||
property int startPadding : 15
|
||||
property int endPadding : 15
|
||||
property int topPadding: 8
|
||||
property int bottomPadding: 8
|
||||
property bool disabled: false
|
||||
property color primaryColor : "#0064B0"
|
||||
signal clicked
|
||||
radius: 4
|
||||
color:{
|
||||
if(disabled){
|
||||
return "#C7C7C7"
|
||||
}
|
||||
return button_mouse.containsMouse ? Qt.lighter(primaryColor,1.15) : primaryColor
|
||||
}
|
||||
width: button_text.implicitWidth
|
||||
height: button_text.implicitHeight
|
||||
border.color: "#cccccc"
|
||||
border.width: 1
|
||||
|
||||
Text {
|
||||
id: button_text
|
||||
text: "Standard Button"
|
||||
color: "#FFFFFFFF"
|
||||
font.pixelSize: 13
|
||||
leftPadding: button.startPadding
|
||||
rightPadding: button.endPadding
|
||||
topPadding: button.topPadding
|
||||
bottomPadding: button.bottomPadding
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id:button_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if(disabled)
|
||||
return
|
||||
button.clicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Rectangle {
|
||||
|
||||
width: text.implicitWidth
|
||||
height: text.implicitHeight
|
||||
|
||||
property int icon
|
||||
|
||||
Text {
|
||||
id:text
|
||||
font.family: "fontawesome"
|
||||
font.pixelSize: 16
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
// text:icon
|
||||
text: (String.fromCharCode(icon).toString(16));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
|
||||
Text {
|
||||
|
||||
id:text
|
||||
|
||||
enum FontStyle {
|
||||
Display,
|
||||
TitleLarge,
|
||||
Title,
|
||||
Subtitle,
|
||||
BodyLarge,
|
||||
BodyStrong,
|
||||
Body,
|
||||
Caption
|
||||
}
|
||||
|
||||
property int fontStyle: FluText.Display
|
||||
property color textColor: "#333333"
|
||||
|
||||
property int pixelSize : 16
|
||||
|
||||
color: textColor
|
||||
|
||||
Component.onCompleted: {
|
||||
setFontStyle(fontStyle)
|
||||
}
|
||||
|
||||
onStyleChanged: {
|
||||
setFontStyle(fontStyle)
|
||||
}
|
||||
|
||||
function setFontStyle(fontStyle) {
|
||||
switch (fontStyle) {
|
||||
case FluText.Display:
|
||||
font.bold = true
|
||||
font.pixelSize = text.pixelSize * 4
|
||||
break
|
||||
case FluText.TitleLarge:
|
||||
font.bold = true
|
||||
font.pixelSize = text.pixelSize * 2
|
||||
break
|
||||
case FluText.Title:
|
||||
font.bold = true
|
||||
font.pixelSize = text.pixelSize * 1.5
|
||||
break
|
||||
case FluText.Subtitle:
|
||||
font.bold = true
|
||||
font.pixelSize = text.pixelSize * 0.9
|
||||
break
|
||||
case FluText.BodyLarge:
|
||||
font.bold = false
|
||||
font.pixelSize = text.pixelSize * 1.1
|
||||
break
|
||||
case FluText.BodyStrong:
|
||||
font.bold = true
|
||||
font.pixelSize = text.pixelSize * 1.0
|
||||
break
|
||||
case FluText.Body:
|
||||
font.bold = false
|
||||
font.pixelSize = text.pixelSize
|
||||
break
|
||||
case FluText.Caption:
|
||||
font.bold = false
|
||||
font.pixelSize = text.pixelSize * 0.8
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Shapes 1.15
|
||||
|
||||
Item {
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
Switch {
|
||||
id: root
|
||||
property color checkedColor: "#0064B0"
|
||||
|
||||
indicator: Rectangle {
|
||||
width: 40
|
||||
height: 20
|
||||
radius: height / 2
|
||||
color: root.checked ? checkedColor : "white"
|
||||
border.width: 1
|
||||
border.color: root.checked ? checkedColor : "#666666"
|
||||
|
||||
Rectangle {
|
||||
x: root.checked ? parent.width - width - 4 : 4
|
||||
width: root.checked ? parent.height - 8 : parent.height - 8
|
||||
height: width
|
||||
radius: width / 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: root.checked ? "#FFFFFF" : "#666666"
|
||||
// border.color: "#D5D5D5"
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation { duration: 200 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
SET QT_BIN_PATH=%1
|
||||
SET BAT_PLUGIN_NAME=%2
|
||||
SET BAT_PLUGIN_VERSION=%3
|
||||
SET BAT_PLUGIN_PARENT_PATH=%4
|
||||
SET BAT_PLUGIN_QMLTYPES_PATH=%5
|
||||
|
||||
echo "------create_qmltypes-------"
|
||||
echo %QT_BIN_PATH%
|
||||
echo %BAT_PLUGIN_NAME%
|
||||
echo %BAT_PLUGIN_VERSION%
|
||||
echo %BAT_PLUGIN_PARENT_PATH%
|
||||
echo %BAT_PLUGIN_QMLTYPES_PATH%
|
||||
echo "-------------"
|
||||
|
||||
%QT_BIN_PATH%\qmlplugindump.exe -nonrelocatable %BAT_PLUGIN_NAME% %BAT_PLUGIN_VERSION% %BAT_PLUGIN_PARENT_PATH% > %BAT_PLUGIN_QMLTYPES_PATH%
|
|
@ -1,16 +1,14 @@
|
|||
#include "qml_plugin.h"
|
||||
|
||||
#include "Fluent.h"
|
||||
|
||||
void FluentUIQmlPlugin::registerTypes(const char *uri)
|
||||
{
|
||||
int major = 1;
|
||||
int minor = 0;
|
||||
qmlRegisterType<FluentUI>(uri, major, minor, "FluentUI");
|
||||
qmlRegisterType(QUrl("qrc:/com.zzc/controls/StandardButton.qml"),uri,major,minor,"StandardButton");
|
||||
qmlRegisterType(QUrl("qrc:/com.zzc/controls/FilledButton.qml"),uri,major,minor,"FilledButton");
|
||||
Fluent::getInstance()->registerTypes(uri);
|
||||
}
|
||||
|
||||
void FluentUIQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
|
||||
{
|
||||
|
||||
Fluent::getInstance()->initializeEngine(engine,uri);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <QQmlExtensionPlugin>
|
||||
#include <FluentUI.h>
|
||||
|
||||
class FluentUIQmlPlugin : public QQmlExtensionPlugin
|
||||
{
|
||||
|
@ -10,6 +9,5 @@ class FluentUIQmlPlugin : public QQmlExtensionPlugin
|
|||
|
||||
public:
|
||||
void registerTypes(const char *uri) override;
|
||||
|
||||
void initializeEngine(QQmlEngine *engine, const char *uri) override;
|
||||
};
|
||||
|
|
19
src/res.qrc
19
src/res.qrc
|
@ -1,6 +1,19 @@
|
|||
<RCC>
|
||||
<qresource prefix="/com.zzc">
|
||||
<file>controls/StandardButton.qml</file>
|
||||
<file>controls/FilledButton.qml</file>
|
||||
<qresource prefix="/com.zhuzichu">
|
||||
<file>controls/FluButton.qml</file>
|
||||
<file>controls/FluFilledButton.qml</file>
|
||||
<file>controls/FluText.qml</file>
|
||||
<file>controls/FluToggleSwitch.qml</file>
|
||||
<file>controls/FluIconButton.qml</file>
|
||||
<file>controls/FluCheckBox.qml</file>
|
||||
<file>controls/FluRadioButton.qml</file>
|
||||
<file>controls/FluSlider.qml</file>
|
||||
<file>controls/FluProgressRing.qml</file>
|
||||
<file>controls/FluProgressBar.qml</file>
|
||||
<file>controls/FluComboBox.qml</file>
|
||||
<file>controls/FluDropDownButton.qml</file>
|
||||
<file>controls/FluTextBox.qml</file>
|
||||
<file>controls/FluTimePicker.qml</file>
|
||||
<file>res/font/fontawesome-webfont.ttf</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,21 @@
|
|||
#ifndef STDAFX_H
|
||||
#define STDAFX_H
|
||||
|
||||
#define Q_PROPERTY_AUTO(TYPE, M) \
|
||||
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
|
||||
public: \
|
||||
Q_SIGNAL void M##Changed(); \
|
||||
void M(TYPE in_##M) \
|
||||
{ \
|
||||
_##M = in_##M; \
|
||||
Q_EMIT M##Changed(); \
|
||||
} \
|
||||
TYPE M() \
|
||||
{ \
|
||||
return _##M; \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
TYPE _##M;
|
||||
|
||||
#endif // STDAFX_H
|
|
@ -14,7 +14,7 @@ echo %BUILDER_BIN_PATH%
|
|||
echo %QT_QML_FLUENT_PATH%
|
||||
echo "--------------------------"
|
||||
|
||||
copy /y %PWD_PATH%\Toou2D.h %BUILDER_BIN_PATH% & copy /y %PRESET_PATH%\* %BUILDER_BIN_PATH%\
|
||||
copy /y %PWD_PATH%\FluentUI.h %BUILDER_BIN_PATH% & copy /y %PRESET_PATH%\* %BUILDER_BIN_PATH%\
|
||||
|
||||
if %ANDROID% == YES copy /y %LIBFILE_PATH% %BUILDER_BIN_PATH%
|
||||
|
||||
|
@ -22,4 +22,5 @@ if %1 == SHARED (
|
|||
echo running install to qtqml folder
|
||||
rmdir /s /q %QT_QML_FLUENT_PATH% & md %QT_QML_FLUENT_PATH%
|
||||
copy /y %BUILDER_BIN_PATH% %QT_QML_FLUENT_PATH%
|
||||
cd %QT_QML_FLUENT_PATH%
|
||||
)
|
Loading…
Reference in New Issue