Skip to content
This repository was archived by the owner on Sep 13, 2025. It is now read-only.

Commit 2ea59a3

Browse files
authored
Remote Layouts (#138)
* reorganize & add remote layout downloading Closes #137 Signed-off-by: swurl <swurl@swurl.xyz> * use v4 actions Signed-off-by: swurl <swurl@swurl.xyz> * readme update & add startwebserver Signed-off-by: swurl <swurl@swurl.xyz> --------- Signed-off-by: swurl <swurl@swurl.xyz>
1 parent 0c75def commit 2ea59a3

22 files changed

+487
-106
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,35 +212,35 @@ jobs:
212212

213213
- name: Upload portable tarball (Linux)
214214
if: runner.os == 'Linux'
215-
uses: actions/upload-artifact@v3
215+
uses: actions/upload-artifact@v4
216216
with:
217217
name: QFRCDashboard-${{ runner.os }}-Binary-${{ env.VERSION }}-${{ inputs.build_type }}
218218
path: QFRCDashboard.tar.gz
219219

220220
- name: Upload AppImage (Linux)
221221
if: runner.os == 'Linux'
222-
uses: actions/upload-artifact@v3
222+
uses: actions/upload-artifact@v4
223223
with:
224224
name: QFRCDashboard-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
225225
path: QFRCDashboard-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
226226

227227
- name: Upload tarball (macOS)
228228
if: runner.os == 'macOS'
229-
uses: actions/upload-artifact@v3
229+
uses: actions/upload-artifact@v4
230230
with:
231231
name: QFRCDashboard-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}
232232
path: QFRCDashboard.tar.gz
233233

234234
- name: Upload binary zip (Windows, portable)
235235
if: runner.os == 'Windows'
236-
uses: actions/upload-artifact@v3
236+
uses: actions/upload-artifact@v4
237237
with:
238238
name: QFRCDashboard-Windows-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
239239
path: ${{ env.INSTALL_DIR }}/**
240240

241241
- name: Upload installer (Windows)
242242
if: runner.os == 'Windows'
243-
uses: actions/upload-artifact@v3
243+
uses: actions/upload-artifact@v4
244244
with:
245245
name: QFRCDashboard-${{ runner.os }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }}
246246
path: Dashboard-Setup.exe

.github/workflows/trigger_release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ jobs:
2323
upload_url: ${{ steps.create_release.outputs.upload_url }}
2424
steps:
2525
- name: Checkout
26-
uses: actions/checkout@v3
26+
uses: actions/checkout@v4
2727
with:
2828
submodules: 'true'
2929
path: 'QFRCDashboard-source'
3030

3131
- name: Download artifacts
32-
uses: actions/download-artifact@v3
32+
uses: actions/download-artifact@v4
3333

3434
- name: Grab and store version
3535
run: |

CMakeLists.txt

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ set(CMAKE_AUTORCC ON)
1414
option(USE_SYSTEM_NTCORE OFF "Use the system NTCore (Linux only)")
1515
option(USE_SYSTEM_PROTOBUF OFF "Use the system protobuf (Linux only)")
1616

17-
find_package(Qt6 6.7 REQUIRED COMPONENTS Quick Multimedia QuickControls2)
17+
find_package(Qt6 6.7 REQUIRED COMPONENTS Quick Multimedia QuickControls2 Network)
1818
add_subdirectory(3rd_party EXCLUDE_FROM_ALL)
1919

2020
qt_standard_project_setup(REQUIRES 6.7)
@@ -80,7 +80,7 @@ set(QML_ELEMENTS
8080
items/MainScreen
8181
items/Tab
8282
items/GridHandler
83-
items/AccentDisplay
83+
items/TopicView
8484

8585
widgets/BaseWidget
8686
widgets/ResizeAnchor
@@ -116,18 +116,22 @@ set(QML_ELEMENTS
116116
widgets/config/ColorField
117117
widgets/config/SectionHeader
118118

119-
dialogs/TopicView
120-
dialogs/TabNameDialog
121-
dialogs/TabDialog
119+
dialogs/tab/TabNameDialog
120+
dialogs/tab/TabDialog
122121

123-
dialogs/ServerTab
124-
dialogs/MiscTab
125-
dialogs/AppearanceTab
126-
dialogs/SettingsDialog
127-
dialogs/SettingsTabButton
128-
dialogs/AppearanceComboBox
122+
dialogs/remote/RemoteLayoutsDialog
123+
dialogs/remote/RemoteLayout
124+
125+
dialogs/settings/ServerTab
126+
dialogs/settings/MiscTab
127+
dialogs/settings/AppearanceTab
128+
dialogs/settings/SettingsDialog
129+
dialogs/settings/SettingsTabButton
130+
dialogs/settings/AppearanceComboBox
131+
132+
dialogs/accent/AccentEditor
133+
dialogs/accent/AccentDisplay
129134

130-
dialogs/AccentEditor
131135
dialogs/AboutDialog
132136
)
133137

@@ -143,6 +147,7 @@ set(ELEMENTS
143147
models/TopicListModel
144148
models/MapModel
145149
models/AccentsListModel
150+
models/RemoteLayoutModel
146151

147152
stores/TopicStore
148153
)
@@ -187,6 +192,7 @@ target_link_libraries(${Dashboard_EXEC_NAME}
187192
PRIVATE Qt6::Quick
188193
Qt6::Multimedia
189194
Qt6::QuickControls2
195+
Qt6::Network
190196
BuildConfig
191197
ntcore
192198
)

Main.qml

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import QtCore
12
import QtQuick
23
import QtQuick.Controls
4+
import QtQuick.Dialogs
35

46
import QtQuick.Controls.Universal
57

@@ -15,6 +17,8 @@ ApplicationWindow {
1517
Universal.theme: settings.theme === "light" ? Universal.Light : Universal.Dark
1618
Universal.accent: accents.qml(settings.accent) // "qml" is the Universal Theme accent. Affects checkboxes, etc.
1719

20+
property string filename: ""
21+
1822
AccentEditor {
1923
id: accentEditor
2024

@@ -25,35 +29,111 @@ ApplicationWindow {
2529
id: about
2630
}
2731

32+
/** SAVE */
33+
FileDialog {
34+
id: saveDialog
35+
currentFolder: StandardPaths.writableLocation(
36+
StandardPaths.HomeLocation)
37+
fileMode: FileDialog.SaveFile
38+
defaultSuffix: "json"
39+
selectedNameFilter.index: 0
40+
nameFilters: ["JSON files (*.json)", "All files (*)"]
41+
42+
onAccepted: saveAs();
43+
}
44+
45+
function save() {
46+
if (filename === "")
47+
return saveDialog.open()
48+
49+
tlm.save(filename)
50+
}
51+
52+
function saveAs() {
53+
filename = saveDialog.selectedFile
54+
55+
tlm.save(filename)
56+
}
57+
58+
/** LOAD */
59+
FileDialog {
60+
id: loadDialog
61+
currentFolder: StandardPaths.writableLocation(
62+
StandardPaths.HomeLocation)
63+
fileMode: FileDialog.OpenFile
64+
defaultSuffix: "json"
65+
selectedNameFilter.index: 0
66+
nameFilters: ["JSON files (*.json)", "All files (*)"]
67+
68+
onAccepted: load()
69+
}
70+
71+
function load() {
72+
filename = loadDialog.selectedFile
73+
tlm.load(filename)
74+
}
75+
76+
/** SERVER SETTINGS */
77+
SettingsDialog {
78+
id: settingsDialog
79+
}
80+
81+
/** REMOTE LAYOUTS */
82+
MessageDialog {
83+
id: fail
84+
buttons: MessageDialog.Ok
85+
title: "Error"
86+
text: "You must be connected to a robot to download remote layouts.";
87+
88+
modality: Qt.WindowModal
89+
}
90+
91+
RemoteLayoutsDialog {
92+
id: remoteLayouts
93+
}
94+
95+
/** THE REST */
96+
97+
Component.onCompleted: {
98+
Constants.setTheme(settings.theme)
99+
Constants.setAccent(settings.accent)
100+
101+
if (settings.loadRecent && settings.recentFiles.length > 0) {
102+
filename = settings.recentFiles[0]
103+
if (filename === "" || filename === null) return;
104+
tlm.load(filename)
105+
}
106+
}
107+
28108
Shortcut {
29109
sequence: "Ctrl+,"
30-
onActivated: screen.settingsDialog()
110+
onActivated: settingsDialog.openDialog()
31111
}
32112

33113
menuBar: MenuBar {
34114
contentWidth: parent.width
35115

36116
MenuBarItem {
37117
text: qsTr("&Settings")
38-
onTriggered: screen.settingsDialog()
118+
onTriggered: settingsDialog.openDialog()
39119
}
40120

41121
Menu {
42122
contentWidth: 175
43123
title: qsTr("&File")
44124
Action {
45125
text: qsTr("&Save")
46-
onTriggered: screen.save()
126+
onTriggered: save()
47127
shortcut: "Ctrl+S"
48128
}
49129
Action {
50130
text: qsTr("Save &As")
51-
onTriggered: screen.saveAsAction()
131+
onTriggered: saveDialog.open()
52132
shortcut: "Ctrl+Shift+S"
53133
}
54134
Action {
55135
text: qsTr("&Open...")
56-
onTriggered: screen.loadAction()
136+
onTriggered: loadDialog.open()
57137
shortcut: "Ctrl+O"
58138
}
59139
Menu {
@@ -72,6 +152,11 @@ ApplicationWindow {
72152
}
73153
}
74154
}
155+
Action {
156+
text: qsTr("Remote &Layouts...")
157+
onTriggered: remoteLayouts.openDialog();
158+
shortcut: "Ctrl+L"
159+
}
75160
}
76161

77162
Menu {

README.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
![QFRCDashboard](QFRCDashboard-display.png "QFRCDashboard")
22
A reliable, high-performance, low-footprint dashboard for use with FRC.
33

4-
A mirror of this repository is available on my [Gitea](https://git.swurl.xyz/swirl/qfrcdashboard.git) instance.
4+
A mirror of this repository is available on my [git](https://git.swurl.xyz/Q-FRC/Dashboard.git) instance.
55

66
## Lightweight
77
Dashboards don't have to be resource hogs. In fact, dashboards should be designed to take up as few resources as possible. Dashboards that use up resources like nobody's business will cause **packet loss** and **comms issues** when run on driver stations!
@@ -26,18 +26,15 @@ QFRCDashboard excels with its lightweight performance thanks to many factors:
2626
## Download
2727
Windows, Linux, and macOS builds are available via GitHub Actions. Currently, all use WPILib 2024.3.1. Release builds are available either through Actions or in the releases tab:
2828

29-
[![Release](https://github.com/binex-dsk/QFRCDashboard/actions/workflows/trigger_release.yml/badge.svg)](https://github.com/binex-dsk/QFRCDashboard/actions/workflows/trigger_release.yml)
29+
[![Release](https://github.com/Q-FRC/Dashboard/actions/workflows/trigger_release.yml/badge.svg)](https://github.com/Q-FRC/Dashboard/actions/workflows/trigger_release.yml)
3030

3131
Development/debug builds are also available on a per-commit basis. These builds are generally unstable, have far larger executable sizes, and will perform slower, but are useful for users who wish to have the latest features or for developers who want to contribute and test.
3232

33-
[![Debug](https://github.com/binex-dsk/QFRCDashboard/actions/workflows/trigger_builds.yml/badge.svg)](https://github.com/binex-dsk/QFRCDashboard/actions/workflows/trigger_builds.yml)
33+
[![Debug](https://github.com/Q-FRC/Dashboard/actions/workflows/trigger_builds.yml/badge.svg)](https://github.com/Q-FRC/Dashboard/actions/workflows/trigger_builds.yml)
3434

3535
## Forking
3636
Follow the [GPL3](LICENSE) of this project, credit the original project, and make it clear that your application is not QFRCDashboard itself.
3737

38-
## Contributing
39-
Write code.
40-
4138
## Building
4239
This project uses CMake. Additionally, you must initialize git submodules first.
4340

@@ -64,18 +61,17 @@ If you don't want to install protobuf and ntcore to your system, CMake options a
6461
Examples:
6562

6663
```bash
67-
cmake -S . -B build -DUSE_SYSTEM_NTCORE=OFF
68-
cmake -S . -B build -DUSE_SYSTEM_NTCORE=OFF -DUSE_SYSTEM_PROTOBUF=OFF
64+
cmake -S . -B build -DUSE_SYSTEM_NTCORE=ON
65+
cmake -S . -B build -DUSE_SYSTEM_NTCORE=ON -DUSE_SYSTEM_PROTOBUF=ON
6966
```
7067

7168
Using the system ntcore with the bundled protobuf is unnecessary and will break things. If you have ntcore installed to the system, protobuf will also be installed.
7269

73-
Because Windows sucks with system libraries you'll have to enable them anyways. I think with Qt Creator you have to explicitly set them.
74-
75-
### Ubuntu
70+
### Linux
7671
```bash
72+
# or whatever your distribution uses
7773
sudo apt install qt6-base-dev build-essential qt6-multimedia-dev ninja-build
78-
git clone https://github.com/binex-dsk/QFRCDashboard.git
74+
git clone https://github.com/Q-FRC/Dashboard.git
7975
cd QFRCDashboard
8076
mkdir build && cd build
8177
cmake ..
@@ -87,7 +83,7 @@ make -j$(nproc)
8783
* Note that you will need to create a Qt account.
8884
- Install CMake https://cmake.org/download/ (add to `PATH`)
8985
```bash
90-
git clone https://github.com/binex-dsk/QFRCDashboard.git
86+
git clone https://github.com/Q-FRC/Dashboard.git
9187
cd QFRCDashboard
9288
mkdir build && cd build
9389
cmake -DCMAKE_PREFIX_PATH="C:\\Qt6\\6.6.1\\msvc2019_64" ..

dialogs/remote/RemoteLayout.qml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import QtQuick
2+
3+
import QFRCDashboard
4+
5+
Rectangle {
6+
id: rem
7+
8+
signal clicked
9+
signal activated
10+
11+
color: Constants.palette.dialogBg
12+
radius: 5
13+
14+
border {
15+
color: Constants.palette.text
16+
width: 2
17+
}
18+
19+
MouseArea {
20+
anchors.fill: parent
21+
hoverEnabled: true
22+
23+
onDoubleClicked: activated()
24+
onContainsMouseChanged: {
25+
if (containsMouse) {
26+
parent.color = "#2abcff"
27+
} else {
28+
parent.color = Constants.palette.dialogBg
29+
}
30+
}
31+
32+
onClicked: rem.clicked()
33+
}
34+
35+
Text {
36+
anchors.fill: parent
37+
anchors.leftMargin: 20
38+
39+
color: Constants.palette.text
40+
text: model.name
41+
font.pixelSize: 18
42+
43+
horizontalAlignment: Text.AlignLeft
44+
verticalAlignment: Text.AlignVCenter
45+
}
46+
}

0 commit comments

Comments
 (0)