From 56a4bdccce604e7057c1b30c2f90f5a32d2fb8a4 Mon Sep 17 00:00:00 2001 From: greek Date: Tue, 4 Jun 2024 21:10:39 +0100 Subject: [PATCH] Little clean up, documentation, and column bets. --- BetInputDialog.qml | 6 +-- CMakeLists.txt | 7 +++ Columns.qml | 104 ++++++++++++++++++++++++++++++++++++++++++++ MainWindow.cpp | 7 ++- PlayerAreaModel.cpp | 4 +- PlayerAreaModel.h | 5 ++- PlayerAreaView.qml | 11 +++++ Root.qml | 2 +- Roulette.qml | 6 ++- StreetBetsView.qml | 15 ++++--- 10 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 Columns.qml diff --git a/BetInputDialog.qml b/BetInputDialog.qml index 7b6e2d3..8fda10f 100644 --- a/BetInputDialog.qml +++ b/BetInputDialog.qml @@ -4,8 +4,7 @@ import QtQuick.Controls import roulette Dialog { - property alias input: input - required property int betType /* It wouldn't accept the type defined in PlayerAreaModel so I just used the int since that's what it is*/ + required property int betType /* It wouldn't accept the BetType type defined in PlayerAreaModel so I just used the int since that's what it is*/ required property int n required property int squareX required property int squareY @@ -41,6 +40,7 @@ Dialog { text: "g" anchors { + /* Can not 'left: indicator.right'; Only anchor the same side once, which was done in 'input' */ right: parent.right verticalCenter: input.verticalCenter } @@ -57,6 +57,6 @@ Dialog { } onRejected: { - PlayerAreaModel.cancelBet(n) + PlayerAreaModel.cancelBet(betType, n) } } diff --git a/CMakeLists.txt b/CMakeLists.txt index edf13f7..bbd58ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,11 @@ qt_add_executable(roulette-payout qt_add_qml_module(roulette-payout URI roulette + # without this no resource flag, when you load qml files with qrc:// urls + # qt will look for the files in RESOURCE_PREFIX + URI aka /roulette + # we don't want a roulette folder in our project, so we use this flag + # to ignore the "+ URI" part + NO_RESOURCE_TARGET_PATH VERSION 1.0 RESOURCE_PREFIX "/" QML_FILES @@ -33,6 +38,8 @@ qt_add_qml_module(roulette-payout PlayerAreaView.qml Roulette.qml StreetBetsView.qml + Columns.qml + ) target_link_libraries(roulette-payout PRIVATE diff --git a/Columns.qml b/Columns.qml new file mode 100644 index 0000000..fa54c15 --- /dev/null +++ b/Columns.qml @@ -0,0 +1,104 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import roulette + +Item { + ColumnLayout { + + anchors { + left: parent.left + leftMargin: 532 + top: parent.top + topMargin: 68 + } + + spacing: 2 + + Repeater { + model: 3 + + Item { + + id: betButton + height: 43 + width: 35 + + Rectangle { + id: selected + visible: true + height: parent.height + width: parent.width + border.color: "blue" + border.width: 0 + + color: { + if (rouletteTable.numberOfBets < 2 || border.width == 2) { + if (tapHandler1.pressed) { + "#AA999999" + } else if (hoverHandler.hovered) { + "#AAEEEEEE" + } else { + "#00000000" + } + } else { + "#00000000" + } + } + + HoverHandler { + id: hoverHandler + } + TapHandler { + id: tapHandler1 + + onTapped: { + if (rouletteTable.numberOfBets < 2 && parent.border.width == 0) { + parent.border.width = 2 + roulette.showBetInputDialog(PlayerAreaModel.COLUMN, index, betButton.x, betButton.y) + } else if (parent.border.width == 2) { + parent.border.width = 0 + PlayerAreaModel.removeBet(PlayerAreaModel.COLUMN, index) + rouletteTable.numberOfBets -= 1 + } + } + } + + Connections { + target: PlayerAreaModel + + function onFocusedPlayerChanged(b1, n1, b2, n2) { + if (b1 == PlayerAreaModel.COLUMN && n1 == index) { + if (selected.border.width != 0) { + rouletteTable.numberOfBets -=1 + } + + selected.border.width = 2; + rouletteTable.numberOfBets += 1 + } else if (b2 == PlayerAreaModel.COLUMN && n2 == index) { + if (selected.border.width != 0) { + rouletteTable.numberOfBets -=1 + } + + selected.border.width = 2; + rouletteTable.numberOfBets += 1 + } else { + if (selected.border.width != 0) { + rouletteTable.numberOfBets -=1 + } + selected.border.width = 0; + } + } + + function onBetCanceled(b, n) { + if (b == PlayerAreaModel.COLUMN && index == n) { + selected.border.width = 0 + } + } + } + } + } + } + } +} diff --git a/MainWindow.cpp b/MainWindow.cpp index de149f7..b78ca81 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -9,5 +9,10 @@ MainWindow::MainWindow(QWindow *parent) { - load(QUrl("../Root.qml")); + /* + * MainWindow is a QQmlApplicationEngine, so a .show() isn't needed + * it will load a Window or ApplicationWindow that will set its own + * visibility status + */ + load(QUrl("qrc:///Root.qml")); } diff --git a/PlayerAreaModel.cpp b/PlayerAreaModel.cpp index 097ccc6..be79580 100644 --- a/PlayerAreaModel.cpp +++ b/PlayerAreaModel.cpp @@ -60,7 +60,7 @@ void PlayerAreaModel::removeBet(BetType b, int n) } } -void PlayerAreaModel::cancelBet(int n) { - emit betCanceled(n); +void PlayerAreaModel::cancelBet(BetType b, int n) { + emit betCanceled(b, n); } diff --git a/PlayerAreaModel.h b/PlayerAreaModel.h index fb5f14b..e8ce063 100644 --- a/PlayerAreaModel.h +++ b/PlayerAreaModel.h @@ -32,20 +32,21 @@ public: DOZEN, STREET, SINGLE, + COLUMN, SPLIT }; Q_ENUM(BetType) signals: void focusedPlayerChanged(BetType b1, uint n1, BetType b2, uint n2); - void betCanceled(uint n); + void betCanceled(BetType b, uint n); public slots: void setPlayerName(QString s, int n); void bet(BetType b, int n, int bet); void removeBet(BetType b, int n); QString getPlayerName(int n); - void cancelBet(int n); + void cancelBet(BetType b, int n); private: diff --git a/PlayerAreaView.qml b/PlayerAreaView.qml index 579dea5..82e484e 100644 --- a/PlayerAreaView.qml +++ b/PlayerAreaView.qml @@ -23,6 +23,12 @@ Item { spacing: 60 + /* + * A repeater can only have one delegate model + * i.e. it can only have one object template defined in it. + * To repeat both a Text, and Rectangle AND a TextField, we put them inside an Item + * and use anchors to sort them inside the Item + */ Repeater { model: 7 @@ -37,6 +43,10 @@ Item { color: "red" height: 10 width: 10 + /* + * This check will run once when the object is created, but then only refresh + * when the NOTIFY signal for .focusedPlayer is sent + */ visible: PlayerAreaModel.focusedPlayer == index opacity: 0.5 @@ -54,6 +64,7 @@ Item { onTextEdited: PlayerAreaModel.setPlayerName(text, index) onActiveFocusChanged: { + /* focusReason 0, 1 and 2 are mouse, tab forward, and tab backward, respectively */ if (activeFocus && (focusReason == 0 || focusReason == 1 || focusReason == 2)) { PlayerAreaModel.focusedPlayer = index } diff --git a/Root.qml b/Root.qml index c9b9b80..6f00759 100644 --- a/Root.qml +++ b/Root.qml @@ -1,7 +1,7 @@ import QtQuick import QtQuick.Controls -import roulette +import roulette /* this is importing the target "roulette-payout" defined in CMakeLists.txt */ Window { height: 500 diff --git a/Roulette.qml b/Roulette.qml index 3be3f7d..a9d4d7a 100644 --- a/Roulette.qml +++ b/Roulette.qml @@ -9,7 +9,7 @@ Item { id: rouletteTable Image { - source: "qrc:/roulette.png" + source: "qrc:///roulette.png" height: parent.height width: parent.width @@ -22,6 +22,9 @@ Item { StreetBetsView { id: streetBets } + + Columns { + } } function destroyOnClose(obj) { @@ -31,6 +34,7 @@ Item { obj.aboutToHide.connect(() => obj.destroy(1000)); } + /* Call this function to dynamically create a dialog box */ function showBetInputDialog(betType, n, squareX, squareY) { var component = Qt.createComponent("BetInputDialog.qml") diff --git a/StreetBetsView.qml b/StreetBetsView.qml index 841bbf6..1cf2c46 100644 --- a/StreetBetsView.qml +++ b/StreetBetsView.qml @@ -10,8 +10,6 @@ import roulette Item { RowLayout { - id: layout - property int indexForDialog anchors { left: parent.left @@ -23,11 +21,9 @@ Item { spacing: 1.8 Repeater { - id: repeater model: 12 Item { - property alias selected: selected id: betButton height: 45 @@ -64,7 +60,7 @@ Item { onTapped: { if (rouletteTable.numberOfBets < 2 && parent.border.width == 0) { parent.border.width = 2 - layout.indexForDialog = index + /* this is where we create the dialog box on demand */ roulette.showBetInputDialog(PlayerAreaModel.STREET, index, betButton.x, betButton.y) } else if (parent.border.width == 2) { parent.border.width = 0 @@ -74,6 +70,11 @@ Item { } } + /* + * PlayerAreaModel is a singleton (AKA global) object, and Connections is used + * to make these "onReceivedSignal" slots to do something after PlayerAreaModel + * acts + */ Connections { target: PlayerAreaModel @@ -100,8 +101,8 @@ Item { } } - function onBetCanceled(n) { - if (index == n) { + function onBetCanceled(b, n) { + if (b == PlayerAreaModel.STREET && index == n) { selected.border.width = 0 } }