Start Config App

Man... fuck... QT and Windows fucks me up...
Should've gone electron.
main
Peter Repukat 3 years ago
parent c050163a4d
commit 0692b4107e

@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31729.503
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlosSITarget", "GlosSITarget\GlosSITarget.vcxproj", "{076E263E-0687-4435-836E-8F4EF6668843}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlosSIConfig", "GlosSIConfig\GlosSIConfig.vcxproj", "{4B42920B-3CC6-475F-A5B3-441337968483}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -21,6 +23,12 @@ Global
{076E263E-0687-4435-836E-8F4EF6668843}.Release|x64.Build.0 = Release|x64
{076E263E-0687-4435-836E-8F4EF6668843}.Release|x86.ActiveCfg = Release|Win32
{076E263E-0687-4435-836E-8F4EF6668843}.Release|x86.Build.0 = Release|Win32
{4B42920B-3CC6-475F-A5B3-441337968483}.Debug|x64.ActiveCfg = Debug|x64
{4B42920B-3CC6-475F-A5B3-441337968483}.Debug|x64.Build.0 = Debug|x64
{4B42920B-3CC6-475F-A5B3-441337968483}.Debug|x86.ActiveCfg = Debug|x64
{4B42920B-3CC6-475F-A5B3-441337968483}.Release|x64.ActiveCfg = Release|x64
{4B42920B-3CC6-475F-A5B3-441337968483}.Release|x64.Build.0 = Release|x64
{4B42920B-3CC6-475F-A5B3-441337968483}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4B42920B-3CC6-475F-A5B3-441337968483}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
<QtInstall>6.2.0</QtInstall>
<QtModules>quick</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
<QtInstall>6.2.0</QtInstall>
<QtModules>quick</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>None</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="UIModel.cpp" />
<None Include="qml\RPane.qml" />
<QtRcc Include="qml.qrc" />
<None Include="qml\main.qml" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="UIModel.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="qml\WinEventFilter.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
<Filter Include="qml">
<UniqueIdentifier>{4abd6243-b275-40c0-8927-27cebe0e7b5a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<QtRcc Include="qml.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
<ClCompile Include="UIModel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="qml\main.qml">
<Filter>qml</Filter>
</None>
<None Include="qml\RPane.qml">
<Filter>qml</Filter>
</None>
</ItemGroup>
<ItemGroup>
<QtMoc Include="UIModel.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="qml\WinEventFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,40 @@
#include "UIModel.h"
#include <QDir>
UIModel::UIModel()
{
auto path = std::filesystem::temp_directory_path()
.parent_path()
.parent_path()
.parent_path();
path /= "Roaming";
path /= "GlosSI";
if (!std::filesystem::exists(path))
std::filesystem::create_directories(path);
config_path_ = path;
config_dir_name_ = (path /= "Targets").string().data();
}
QStringList UIModel::getTargetList() const
{
QDir dir(config_dir_name_);
auto entries = dir.entryList(QDir::Files, QDir::SortFlag::Name);
entries.removeIf([](const auto& entry) {
return entry.endsWith(".json");
});
QStringList res;
std::ranges::transform(entries, std::back_inserter(res), [](const auto& entry)
{
return entry.mid(0, entry.lastIndexOf(".json"));
});
res.push_back("Debug");
return res;
}
bool UIModel::getIsWindows() const
{
return is_windows_;
}

@ -0,0 +1,42 @@
/*
Copyright 2021 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <filesystem>
#include <QObject>
class UIModel : public QObject
{
Q_OBJECT
Q_PROPERTY(bool isWindows READ getIsWindows CONSTANT)
public:
UIModel();
Q_INVOKABLE QStringList getTargetList() const;
bool getIsWindows() const;
private:
std::filesystem::path config_path_;
QString config_dir_name_;
#ifdef _WIN32
bool is_windows_ = true;
#else
bool is_windows_ = false;
#endif
};

@ -0,0 +1,144 @@
/*
Copyright 2021 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QWindow>
#ifdef _WIN32
#define NOMINMAX
#include <Windows.h>
#include <dwmapi.h>
#pragma comment(lib, "Dwmapi.lib")
#endif
#include "UIModel.h"
#include "qml/WinEventFilter.h"
#ifdef _WIN32
// Some undocument stuff to enable aero on win10 or higher...
enum AccentState
{
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
};
struct AccentPolicy
{
AccentState AccentState;
int AccentFlags;
int GradientColor;
int AnimationId;
};
enum WindowCompositionAttribute
{
// ...
WCA_ACCENT_POLICY = 19
// ...
};
struct WindowCompositionAttributeData
{
WindowCompositionAttribute Attribute;
void* Data;
int SizeOfData;
};
typedef HRESULT(__stdcall* PSetWindowCompositionAttribute)(HWND hwnd, WindowCompositionAttributeData* pattrs);
#endif
int main(int argc, char* argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
UIModel uimodel;
engine.rootContext()->setContextProperty("uiModel", QVariant::fromValue(&uimodel));
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
#ifdef _WIN32
// As a Qt.Frameless window sucks ass, and doesn't support Aerosnap and resizing and all that stuff is cumbersome on windows...
// Use good old dwm...
// First get window from QML.
auto window = qobject_cast<QWindow*>(engine.rootObjects()[0]);
const HWND hwnd = reinterpret_cast<HWND>(window->winId());
// Clear it's title bar
// NO!(!!) We wan't to keep WS_THICKFRAME, as that's what gives us a shadow, aerosnap, proper resizing, win11 round corners
// ...and all that good stuff!
auto style = GetWindowLong(hwnd, GWL_STYLE);
style &= ~(WS_CAPTION | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
SetWindowLong(hwnd, GWL_STYLE, style);
// Enable blurbehind (not needed?) anyway gives nice background on win7 and 8
DWM_BLURBEHIND bb{ .dwFlags = DWM_BB_ENABLE, .fEnable = true, .hRgnBlur = nullptr };
DwmEnableBlurBehindWindow(hwnd, &bb);
//// undoc stuff for aero >= Win10
//// leave for now... performance is crap!
//// for now we have to live with unblurred transparency. lol
//AccentPolicy accPol = { .AccentState = ACCENT_ENABLE_BLURBEHIND };
//WindowCompositionAttributeData data = {
// .Attribute = WindowCompositionAttribute::WCA_ACCENT_POLICY,
// .Data = &accPol,
// .SizeOfData = sizeof(accPol)
//};
//auto user32dll = GetModuleHandle(L"user32.dll");
//if (user32dll) {
// PSetWindowCompositionAttribute SetWindowCompositionAttribute = (
// reinterpret_cast<PSetWindowCompositionAttribute>(GetProcAddress(user32dll, "SetWindowCompositionAttribute"))
// );
// if (SetWindowCompositionAttribute)
// {
// SetWindowCompositionAttribute(hwnd, &data);
// }
//}
// extend the frame fully into the client area => draw all outside the window frame.
MARGINS margins = { -1 };
DwmExtendFrameIntoClientArea(hwnd, &margins);
// To Fix top window frame, install native event filter
// basically the Qt. equivalent of having a own WndProc
// for more info see WinEventFilter.h
auto filter = std::make_shared<WinEventFilter>();
app.installNativeEventFilter(filter.get());
RECT rcClient;
GetWindowRect(hwnd, &rcClient);
// Inform the application of the frame change.
SetWindowPos(hwnd,
NULL,
rcClient.left, rcClient.top,
rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
SWP_FRAMECHANGED);
#endif
return app.exec();
}

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>qml/main.qml</file>
<file>qml/RPane.qml</file>
</qresource>
</RCC>

@ -0,0 +1,21 @@
import QtQuick 2.9
import QtQuick.Controls 2.9
import QtQuick.Controls.Material 2.9
import QtQuick.Controls.Material.impl 2.9
Pane {
id: control
property int radius: 0
property color color: control.Material.backgroundColor
property real bgOpacity: 1
background: Rectangle {
color: parent.color
opacity: parent.bgOpacity
radius: control.Material.elevation > 0 ? control.radius : 0
layer.enabled: control.enabled && control.Material.elevation > 0
layer.effect: ElevationEffect {
elevation: control.Material.elevation
}
}
}

@ -0,0 +1,32 @@
#pragma once
#include <QAbstractNativeEventFilter>
#include <QString>
#define NOMINMAX
#include <Windows.h>
class WinEventFilter : public QAbstractNativeEventFilter
{
public:
WinEventFilter() = default;
/*
* When having the DWM frame fully extended into client area
* ever since WIN10 a 6px border is displayed on top.
* to remove that one has to catch the WM_NCCALCSIZE event and re-calculate the window-rect
* https://stackoverflow.com/a/2135120/5106063
* https://docs.microsoft.com/en-us/windows/win32/dwm/customframe
*/
bool nativeEventFilter(const QByteArray& eventType, void* message, qintptr* result) override
{
if (QString(eventType) == "windows_generic_MSG") {
auto msg = static_cast<MSG*>(message)->message;
auto lParam = static_cast<MSG*>(message)->lParam;
if (msg == WM_NCCALCSIZE)
{
auto sz = reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam);
sz->rgrc[0].top -= 6;
}
}
return false;
}
};

@ -0,0 +1,197 @@
/*
Copyright 2021 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import QtQuick 6.2
import QtQuick.Layouts 6.2
import QtQuick.Controls.Material 6.2
import QtQuick.Dialogs
Window {
id: window
visible: true
width: 1280
height: 719
Material.theme: Material.Dark
Material.accent: Material.color(Material.Blue, Material.Shade900)
property bool itemSelected: false;
title: qsTr("GlosSI - Config")
color: colorAlpha(Material.background, 0.98)
function toggleMaximized() {
if (window.visibility === Window.Maximized || window.visibility === Window.FullScreen) {
window.visibility = Window.Windowed
} else {
window.visibility = Window.Maximized
}
}
function colorAlpha(color, alpha) {
return Qt.rgba(color.r, color.g, color.b, alpha);
}
Rectangle {
id: titleBar
visible: uiModel.isWindows
color: colorAlpha(Qt.darker(Material.background, 1.1), 0.90)
height: visible ? 24 : 0
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
TapHandler {
onTapped: if (tapCount === 2) toggleMaximized()
gesturePolicy: TapHandler.DragThreshold
}
DragHandler {
grabPermissions: TapHandler.CanTakeOverFromAnything
onActiveChanged: if (active) { window.startSystemMove(); }
}
Label {
text: window.title
font.bold: true
anchors.leftMargin: 16
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
}
RowLayout {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 0
ToolButton {
text: "🗕"
onClicked: window.showMinimized();
}
ToolButton {
text: window.visibility === Window.Maximized || window.visibility === Window.FullScreen ? "🗗" : "🗖"
onClicked: window.toggleMaximized()
}
ToolButton {
id: closbtn
text: "🗙"
onClicked: window.close()
background: Rectangle {
implicitWidth: 32
implicitHeight: 32
radius: 16
color: Qt.darker("red", closbtn.enabled && (closbtn.checked || closbtn.highlighted) ? 1.6 : 1.2)
opacity: closbtn.hovered ? 0.5 : 0
Behavior on opacity {
NumberAnimation {
duration: 350
easing.type: Easing.InOutQuad
}
}
}
}
}
}
Item {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: titleBar.bottom
anchors.bottom: parent.bottom
RPane {
id: existingTargetsPane
anchors.left: parent.left
width:window.width / 3.301 + 16
Component.onCompleted: console.log(width)
anchors.top: parent.top
anchors.bottom: parent.bottom
Material.elevation: 6
anchors.leftMargin: -16
radius: 16
color: Qt.lighter(Material.background, 1.6)
bgOpacity: 0.8
Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
clip: true
ListView {
anchors.fill: parent
spacing: 0
model: uiModel.getTargetList();
delegate: Item {
width: parent.width
height: lbl.height + lbl.anchors.topMargin + lbl.anchors.bottomMargin
// TODO: Left size App icon
Label {
id: lbl
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 48
anchors.topMargin: 8
anchors.bottomMargin: 8
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
text: modelData
font.pixelSize: 16
}
// TODO: Right side icon if in steam
Rectangle {
width: parent.width
height: 1
anchors.bottom: parent.bottom
color: Qt.rgba(1,1,1,0.3)
}
}
}
}
}
RoundButton {
id: addBtn
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 24
width: 64
height: 64
text: "+"
contentItem: Label {
anchors.centerIn: parent
text: addBtn.text
font.pixelSize: 32
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
highlighted: true
onClicked: fileDialog.open();
}
FileDialog {
id: fileDialog
title: qsTr("Please choose a Program to Launch")
nameFilters: uiModel.isWindows ? ["Executable files (*.exe *.bat *.ps1)"] : []
onAccepted: {
console.log("You chose: " + fileDialog.selectedFile)
}
onRejected: {
console.log("Canceled")
}
}
}
}

@ -1,5 +1,8 @@
{
"folders": [
{
"path": "GlosSIConfig"
},
{
"path": "GlosSITarget"
},

Loading…
Cancel
Save