dialog: Add first qml util

This commit is contained in:
Vaxry 2024-10-27 14:40:05 +00:00
parent 44c4a1172c
commit 0c74719c98
10 changed files with 410 additions and 0 deletions

65
.clang-format Normal file
View file

@ -0,0 +1,65 @@
---
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
ColumnLimit: 180
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
IncludeBlocks: Preserve
IndentCaseLabels: true
IndentWidth: 4
PointerAlignment: Left
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never
AllowShortEnumsOnASingleLine: false
BraceWrapping:
AfterEnum: false
AlignConsecutiveDeclarations: AcrossEmptyLines
NamespaceIndentation: All

3
.gitignore vendored
View file

@ -30,3 +30,6 @@
*.exe *.exe
*.out *.out
*.app *.app
build/
.cache/

66
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,66 @@
{
"files.associations": {
"cmath": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstdint": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string_view": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stdfloat": "cpp",
"streambuf": "cpp",
"cctype": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"__bit_reference": "cpp",
"__hash_table": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__tree": "cpp",
"__verbose_abort": "cpp",
"cwctype": "cpp",
"locale": "cpp"
}
}

20
CMakeLists.txt Normal file
View file

@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.16)
# Get version
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
string(STRIP ${VER_RAW} VER)
project(hyprland-qtutils VERSION ${VER} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 6.5 REQUIRED COMPONENTS Widgets Quick QuickControls2 WaylandClient)
find_package(PkgConfig REQUIRED)
pkg_check_modules(hyprutils REQUIRED IMPORTED_TARGET hyprutils)
qt_standard_project_setup(REQUIRES 6.5)
add_subdirectory(utils/dialog)

1
VERSION Normal file
View file

@ -0,0 +1 @@
0.1.0

View file

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.16)
project(hyprland-dialog VERSION ${VER} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 6.5 REQUIRED COMPONENTS Widgets Quick QuickControls2 WaylandClient)
find_package(PkgConfig REQUIRED)
pkg_check_modules(hyprutils REQUIRED IMPORTED_TARGET hyprutils)
qt_standard_project_setup(REQUIRES 6.5)
qt_add_executable(hyprland-dialog
main.cpp
Dialog.cpp
)
qt_add_qml_module(hyprland-dialog
URI org.hyprland.dialog
VERSION 1.0
QML_FILES main.qml
)
target_link_libraries(hyprland-dialog PRIVATE
Qt6::Widgets Qt6::QuickControls2 Qt6::WaylandClientPrivate PkgConfig::hyprutils
)
include(GNUInstallDirs)
install(TARGETS hyprland-dialog
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

13
utils/dialog/Dialog.cpp Normal file
View file

@ -0,0 +1,13 @@
#include "Dialog.hpp"
#include <print>
#include <hyprutils/string/String.hpp>
using namespace Hyprutils::String;
CDialog::CDialog(QObject* parent) : QObject(parent) {
;
}
void CDialog::onButtonPress(QString buttonName) {
std::print("{}\n", trim(buttonName.toStdString()));
exit(0);
}

26
utils/dialog/Dialog.hpp Normal file
View file

@ -0,0 +1,26 @@
#pragma once
#include <QObject>
#include <QQmlApplicationEngine>
#include <QPixmap>
#include <QIcon>
#include <qcontainerfwd.h>
#include <qqmlintegration.h>
#include <qtmetamacros.h>
class CDialog : public QObject {
Q_OBJECT;
QML_NAMED_ELEMENT(Dialog);
QML_SINGLETON;
Q_PROPERTY(QString dialogTitle MEMBER title CONSTANT);
Q_PROPERTY(QString dialogText MEMBER text CONSTANT);
Q_PROPERTY(QVector<QString> dialogButtons MEMBER buttons CONSTANT);
public:
explicit CDialog(QObject* parent = nullptr);
QString title, text;
QVector<QString> buttons;
Q_INVOKABLE void onButtonPress(QString buttonName = "");
};

89
utils/dialog/main.cpp Normal file
View file

@ -0,0 +1,89 @@
#include "Dialog.hpp"
#include <hyprutils/string/VarList.hpp>
#include <print>
#include <qapplication.h>
#include <qqmlapplicationengine.h>
#include <qquickstyle.h>
#include <qtenvironmentvariables.h>
#include <QQmlContext>
using namespace Hyprutils::String;
int main(int argc, char* argv[]) {
// disable logs to not trash the stdout
qputenv("QT_LOGGING_RULES", QByteArray("*.debug=false;qml=false"));
QString appTitle;
auto dialog = new CDialog();
for (int i = 1; i < argc; ++i) {
std::string_view arg = argv[i];
if (arg == "--title") {
if (i + 1 >= argc) {
std::print(stderr, "--title requires a parameter\n");
return 1;
}
dialog->title = argv[i + 1];
i++;
continue;
}
if (arg == "--apptitle") {
if (i + 1 >= argc) {
std::print(stderr, "--apptitle requires a parameter\n");
return 1;
}
appTitle = argv[i + 1];
i++;
continue;
}
if (arg == "--text") {
if (i + 1 >= argc) {
std::print(stderr, "--text requires a parameter\n");
return 1;
}
dialog->text = argv[i + 1];
i++;
continue;
}
if (arg == "--buttons") {
if (i + 1 >= argc) {
std::print(stderr, "--buttons requires a parameter\n");
return 1;
}
CVarList buttonz(argv[i + 1], 0, ';', true);
for (auto& b : buttonz) {
dialog->buttons.emplace_back(b.c_str());
}
i++;
continue;
}
std::print(stderr, "invalid arg {}\n", argv[i]);
return 1;
}
QApplication app(argc, argv);
app.setApplicationName(appTitle.isEmpty() ? dialog->title : appTitle);
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE"))
QQuickStyle::setStyle("org.kde.desktop");
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("dialog", dialog);
engine.load("qrc:/qt/qml/org/hyprland/dialog/main.qml");
return app.exec();
}

91
utils/dialog/main.qml Normal file
View file

@ -0,0 +1,91 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ApplicationWindow {
id: window
FontMetrics { id: fontMetrics }
property var windowPadding: 10
minimumWidth: Math.max(fontMetrics.height * 10, mainLayout.Layout.minimumWidth) + mainLayout.anchors.margins * 2 + windowPadding * 2
minimumHeight: Math.max(fontMetrics.height * 10, mainLayout.Layout.minimumHeight) + mainLayout.anchors.margins * 2 + windowPadding * 2
maximumWidth: minimumWidth
maximumHeight: minimumHeight
visible: true
component Separator: Rectangle {
color: Qt.darker(system.windowText, 1.5)
}
component VSeparator: Separator {
implicitWidth: 1
Layout.fillHeight: true
Layout.topMargin: fontMetrics.height
Layout.bottomMargin: fontMetrics.height
}
component HSeparator: Separator {
implicitHeight: 1
Layout.fillWidth: true
Layout.leftMargin: fontMetrics.height * 8
Layout.rightMargin: fontMetrics.height * 8
}
SystemPalette {
id: system
colorGroup: SystemPalette.Active
}
ColumnLayout {
id: mainLayout
spacing: fontMetrics.height
anchors {
fill: parent
margins: 4
}
Text {
font.pointSize: fontMetrics.height
color: system.windowText
text: dialog.dialogTitle
Layout.alignment: Qt.AlignHCenter
}
HSeparator {}
Text {
color: system.windowText
text: dialog.dialogText
Layout.alignment: Qt.AlignHCenter
}
Rectangle {
color: "transparent"
Layout.minimumHeight: 10
Layout.fillHeight: true
}
RowLayout {
spacing: 6
Layout.leftMargin: 20
Layout.alignment: Qt.AlignRight
Repeater {
model: dialog.dialogButtons
Button {
required property int index;
text: dialog.dialogButtons[index]
onClicked: (e) => {
dialog.onButtonPress(dialog.dialogButtons[index])
}
}
}
}
}
}