draftomen 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- draftomen/__init__.py +17 -0
- draftomen/assets/draftomen.icns +0 -0
- draftomen/assets/draftomen.ico +0 -0
- draftomen/assets/draftomen_logo.png +0 -0
- draftomen/audit.py +606 -0
- draftomen/backtest.py +449 -0
- draftomen/benchmark.py +834 -0
- draftomen/carddb.py +1869 -0
- draftomen/cardimages.py +313 -0
- draftomen/cli.py +891 -0
- draftomen/config.py +133 -0
- draftomen/deckbuilder.py +2723 -0
- draftomen/events.py +772 -0
- draftomen/logfollow.py +451 -0
- draftomen/mock_session.py +745 -0
- draftomen/paths.py +120 -0
- draftomen/pickengine.py +1117 -0
- draftomen/pool.py +1259 -0
- draftomen/preferences.py +289 -0
- draftomen/qml/AboutDialog.qml +156 -0
- draftomen/qml/AppBar.qml +120 -0
- draftomen/qml/BacktestView.qml +316 -0
- draftomen/qml/BuildView.qml +1151 -0
- draftomen/qml/CardPreview.qml +434 -0
- draftomen/qml/DimensionalButton.qml +42 -0
- draftomen/qml/DimensionalComboBox.qml +182 -0
- draftomen/qml/DimensionalSurface.qml +118 -0
- draftomen/qml/DimensionalTabButton.qml +41 -0
- draftomen/qml/LiveDraftView.qml +468 -0
- draftomen/qml/Main.qml +175 -0
- draftomen/qml/NavigationRail.qml +226 -0
- draftomen/qml/PoolSummaryPanel.qml +322 -0
- draftomen/qml/PrivacyDialog.qml +96 -0
- draftomen/qml/RecentPickThumbnail.qml +83 -0
- draftomen/qml/RecentPicksGallery.qml +333 -0
- draftomen/qml/RecommendationRow.qml +404 -0
- draftomen/qml/SettingsSwitch.qml +141 -0
- draftomen/qml/SettingsView.qml +531 -0
- draftomen/qml/StateBanner.qml +189 -0
- draftomen/qml/StatusStrip.qml +84 -0
- draftomen/qml/Theme.qml +71 -0
- draftomen/qml/qmldir +23 -0
- draftomen/qt_adapter.py +884 -0
- draftomen/qt_gui.py +338 -0
- draftomen/qt_mock.py +63 -0
- draftomen/ranking.py +126 -0
- draftomen/replay.py +480 -0
- draftomen/session.py +3668 -0
- draftomen/setinfo.py +26 -0
- draftomen/seventeen.py +2766 -0
- draftomen/splash.py +617 -0
- draftomen/tui.py +4007 -0
- draftomen/watch.py +336 -0
- draftomen-0.3.0.dist-info/METADATA +156 -0
- draftomen-0.3.0.dist-info/RECORD +59 -0
- draftomen-0.3.0.dist-info/WHEEL +5 -0
- draftomen-0.3.0.dist-info/entry_points.txt +6 -0
- draftomen-0.3.0.dist-info/licenses/LICENSE +21 -0
- draftomen-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
pragma ComponentBehavior: Bound
|
|
2
|
+
|
|
3
|
+
import QtQuick 2.15
|
|
4
|
+
import QtQuick.Controls 2.15
|
|
5
|
+
|
|
6
|
+
Item {
|
|
7
|
+
id: root
|
|
8
|
+
|
|
9
|
+
required property var pool
|
|
10
|
+
required property bool narrow
|
|
11
|
+
|
|
12
|
+
readonly property var recentPicks: root.pool && root.pool.recent_picks
|
|
13
|
+
? root.pool.recent_picks : []
|
|
14
|
+
readonly property int targetColumns: root.narrow ? 4 : 6
|
|
15
|
+
readonly property int gap: 6
|
|
16
|
+
readonly property int hoverDelay: 501
|
|
17
|
+
readonly property int dismissDelay: 100
|
|
18
|
+
|
|
19
|
+
property var hoveredThumbnail: null
|
|
20
|
+
property var previewedPick: null
|
|
21
|
+
property bool thumbnailHovered: false
|
|
22
|
+
property bool previewHovered: false
|
|
23
|
+
|
|
24
|
+
implicitHeight: galleryColumn.implicitHeight
|
|
25
|
+
Accessible.role: Accessible.Pane
|
|
26
|
+
Accessible.name: "Recent picks"
|
|
27
|
+
Accessible.description: "Cards picked most recently, newest first."
|
|
28
|
+
|
|
29
|
+
function pickForThumbnail(thumbnail) {
|
|
30
|
+
return thumbnail && thumbnail.recentPick && thumbnail.recentPick.card
|
|
31
|
+
? thumbnail.recentPick : null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function containsPick(pick) {
|
|
35
|
+
if (!pick || !pick.card)
|
|
36
|
+
return false
|
|
37
|
+
for (let index = 0; index < root.recentPicks.length; index++) {
|
|
38
|
+
const recentPick = root.recentPicks[index]
|
|
39
|
+
if (recentPick && recentPick.card
|
|
40
|
+
&& recentPick.card.grp_id === pick.card.grp_id)
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
function handleThumbnailEntered(thumbnail) {
|
|
46
|
+
const pick = root.pickForThumbnail(thumbnail)
|
|
47
|
+
if (!pick)
|
|
48
|
+
return
|
|
49
|
+
dismissTimer.stop()
|
|
50
|
+
if (root.hoveredThumbnail === thumbnail && root.thumbnailHovered)
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
if (root.hoveredThumbnail === thumbnail && previewCard.visible
|
|
54
|
+
&& root.previewedPick && root.previewedPick.card
|
|
55
|
+
&& pick.card
|
|
56
|
+
&& root.previewedPick.card.grp_id === pick.card.grp_id) {
|
|
57
|
+
root.thumbnailHovered = true
|
|
58
|
+
root.previewedPick = pick
|
|
59
|
+
previewTimer.stop()
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
root.hoveredThumbnail = thumbnail
|
|
64
|
+
root.thumbnailHovered = true
|
|
65
|
+
root.previewedPick = null
|
|
66
|
+
previewTimer.restart()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function handleThumbnailExited(thumbnail) {
|
|
70
|
+
if (root.hoveredThumbnail !== thumbnail)
|
|
71
|
+
return
|
|
72
|
+
root.thumbnailHovered = false
|
|
73
|
+
previewTimer.stop()
|
|
74
|
+
dismissTimer.restart()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function dismissPreviewIfOutside() {
|
|
78
|
+
if (root.thumbnailHovered || root.previewHovered)
|
|
79
|
+
return
|
|
80
|
+
root.clearHoverState()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function showCurrentPreview() {
|
|
84
|
+
const pick = root.pickForThumbnail(root.hoveredThumbnail)
|
|
85
|
+
if (!root.thumbnailHovered || !pick
|
|
86
|
+
|| !root.containsPick(pick))
|
|
87
|
+
return
|
|
88
|
+
root.previewedPick = pick
|
|
89
|
+
root.schedulePreviewGeometry()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function schedulePreviewGeometry() {
|
|
93
|
+
if (!root.previewedPick || !previewCard.parent)
|
|
94
|
+
return
|
|
95
|
+
Qt.callLater(root.updatePreviewGeometry)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function updatePreviewGeometry() {
|
|
99
|
+
const overlay = previewCard.parent
|
|
100
|
+
if (!overlay || !root.hoveredThumbnail || !root.previewedPick
|
|
101
|
+
|| !previewCard.visible)
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
const galleryTopLeft = root.mapToItem(overlay, 0, 0)
|
|
105
|
+
const galleryBottomRight = root.mapToItem(
|
|
106
|
+
overlay, root.width, root.height
|
|
107
|
+
)
|
|
108
|
+
const margin = 8
|
|
109
|
+
const gap = 8
|
|
110
|
+
const availableAbove = Math.max(
|
|
111
|
+
0, galleryTopLeft.y - gap - margin
|
|
112
|
+
)
|
|
113
|
+
const availableBelow = Math.max(
|
|
114
|
+
0, overlay.height - galleryBottomRight.y - gap - margin
|
|
115
|
+
)
|
|
116
|
+
const maximumWidth = Math.min(
|
|
117
|
+
260, Math.max(1, overlay.width - margin * 2)
|
|
118
|
+
)
|
|
119
|
+
previewCard.previewWidth = Math.min(
|
|
120
|
+
maximumWidth,
|
|
121
|
+
Math.max(1, Math.max(availableAbove, availableBelow) / 1.4)
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
const maximumX = Math.max(
|
|
125
|
+
margin, overlay.width - previewCard.width - margin
|
|
126
|
+
)
|
|
127
|
+
const nextX = Math.max(
|
|
128
|
+
margin, Math.min(galleryTopLeft.x, maximumX)
|
|
129
|
+
)
|
|
130
|
+
const belowY = galleryBottomRight.y + gap
|
|
131
|
+
const aboveY = galleryTopLeft.y - previewCard.height - gap
|
|
132
|
+
const maximumY = Math.max(
|
|
133
|
+
margin, overlay.height - previewCard.height - margin
|
|
134
|
+
)
|
|
135
|
+
const belowFits = belowY >= margin && belowY <= maximumY
|
|
136
|
+
const aboveFits = aboveY >= margin && aboveY <= maximumY
|
|
137
|
+
let nextY
|
|
138
|
+
if (availableBelow >= availableAbove && belowFits) {
|
|
139
|
+
nextY = belowY
|
|
140
|
+
} else if (aboveFits) {
|
|
141
|
+
nextY = aboveY
|
|
142
|
+
} else {
|
|
143
|
+
nextY = availableBelow >= availableAbove ? belowY : aboveY
|
|
144
|
+
nextY = Math.max(margin, Math.min(nextY, maximumY))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
previewCard.x = nextX
|
|
148
|
+
previewCard.y = nextY
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function syncRecentPicks() {
|
|
152
|
+
const hoveredPick = root.pickForThumbnail(root.hoveredThumbnail)
|
|
153
|
+
if (hoveredPick && root.containsPick(hoveredPick)) {
|
|
154
|
+
if (root.previewedPick)
|
|
155
|
+
root.previewedPick = hoveredPick
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
root.clearHoverState()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function clearHoverState() {
|
|
162
|
+
previewTimer.stop()
|
|
163
|
+
dismissTimer.stop()
|
|
164
|
+
root.hoveredThumbnail = null
|
|
165
|
+
root.thumbnailHovered = false
|
|
166
|
+
root.previewHovered = false
|
|
167
|
+
root.previewedPick = null
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
onRecentPicksChanged: Qt.callLater(root.syncRecentPicks)
|
|
171
|
+
onWidthChanged: root.schedulePreviewGeometry()
|
|
172
|
+
onHeightChanged: root.schedulePreviewGeometry()
|
|
173
|
+
onVisibleChanged: {
|
|
174
|
+
if (!root.visible)
|
|
175
|
+
root.clearHoverState()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Column {
|
|
179
|
+
id: galleryColumn
|
|
180
|
+
width: root.width
|
|
181
|
+
spacing: 8
|
|
182
|
+
|
|
183
|
+
Label {
|
|
184
|
+
id: heading
|
|
185
|
+
width: parent.width
|
|
186
|
+
text: "RECENT PICKS"
|
|
187
|
+
color: Theme.textMuted
|
|
188
|
+
font.pixelSize: Theme.textPixelSize(11)
|
|
189
|
+
font.bold: true
|
|
190
|
+
font.letterSpacing: 1
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
Grid {
|
|
194
|
+
id: recentPicksGrid
|
|
195
|
+
objectName: "recentPicksGrid"
|
|
196
|
+
width: parent.width
|
|
197
|
+
columns: Math.min(root.targetColumns, Math.max(1,
|
|
198
|
+
Math.floor((width + root.gap) / (64 + root.gap))))
|
|
199
|
+
columnSpacing: root.gap
|
|
200
|
+
rowSpacing: root.gap
|
|
201
|
+
height: childrenRect.height
|
|
202
|
+
|
|
203
|
+
Repeater {
|
|
204
|
+
model: root.recentPicks
|
|
205
|
+
|
|
206
|
+
delegate: RecentPickThumbnail {
|
|
207
|
+
required property int index
|
|
208
|
+
required property var modelData
|
|
209
|
+
|
|
210
|
+
pickIndex: index
|
|
211
|
+
recentPick: modelData
|
|
212
|
+
width: Math.max(1, (recentPicksGrid.width
|
|
213
|
+
- (recentPicksGrid.columns - 1) * root.gap)
|
|
214
|
+
/ recentPicksGrid.columns)
|
|
215
|
+
onHoverEntered: root.handleThumbnailEntered(this)
|
|
216
|
+
onHoverExited: root.handleThumbnailExited(this)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
Rectangle {
|
|
222
|
+
id: previewCard
|
|
223
|
+
objectName: "recentPickPreview"
|
|
224
|
+
parent: Overlay.overlay
|
|
225
|
+
z: 100
|
|
226
|
+
property bool modal: false
|
|
227
|
+
property real previewWidth: Math.min(
|
|
228
|
+
260, Math.max(200, parent ? parent.width - 16 : 200)
|
|
229
|
+
)
|
|
230
|
+
focus: false
|
|
231
|
+
width: previewWidth
|
|
232
|
+
height: width * 1.4
|
|
233
|
+
visible: root.previewedPick !== null
|
|
234
|
+
color: Theme.surface
|
|
235
|
+
border.color: Theme.outline
|
|
236
|
+
border.width: 1
|
|
237
|
+
radius: Theme.radius
|
|
238
|
+
clip: true
|
|
239
|
+
Accessible.role: Accessible.Pane
|
|
240
|
+
Accessible.name: root.previewedPick && root.previewedPick.card
|
|
241
|
+
? root.previewedPick.card.name + " preview" : "Card preview"
|
|
242
|
+
|
|
243
|
+
Image {
|
|
244
|
+
id: previewImage
|
|
245
|
+
objectName: "recentPickPreviewImage"
|
|
246
|
+
anchors.fill: parent
|
|
247
|
+
anchors.margins: 12
|
|
248
|
+
source: root.previewedPick && root.previewedPick.image
|
|
249
|
+
&& root.previewedPick.image.phase === "ready"
|
|
250
|
+
&& root.previewedPick.image.image_path
|
|
251
|
+
? root.previewedPick.image.image_path : ""
|
|
252
|
+
fillMode: Image.PreserveAspectFit
|
|
253
|
+
asynchronous: true
|
|
254
|
+
visible: status === Image.Ready
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
Label {
|
|
258
|
+
id: previewFallbackLabel
|
|
259
|
+
objectName: "recentPickPreviewFallbackLabel"
|
|
260
|
+
anchors.fill: parent
|
|
261
|
+
anchors.margins: 28
|
|
262
|
+
text: {
|
|
263
|
+
const image = root.previewedPick
|
|
264
|
+
? root.previewedPick.image : null
|
|
265
|
+
if (previewImage.status === Image.Error)
|
|
266
|
+
return "Image failed to display"
|
|
267
|
+
if (image && image.phase === "loading")
|
|
268
|
+
return "Loading image"
|
|
269
|
+
if (image && image.phase === "failed")
|
|
270
|
+
return "Image unavailable"
|
|
271
|
+
if (image && image.phase === "ready"
|
|
272
|
+
&& previewImage.source.toString().length > 0)
|
|
273
|
+
return "Loading image"
|
|
274
|
+
return "No image available"
|
|
275
|
+
}
|
|
276
|
+
color: Theme.textMuted
|
|
277
|
+
font.pixelSize: Theme.textPixelSize(15)
|
|
278
|
+
font.bold: true
|
|
279
|
+
horizontalAlignment: Text.AlignHCenter
|
|
280
|
+
verticalAlignment: Text.AlignVCenter
|
|
281
|
+
wrapMode: Text.Wrap
|
|
282
|
+
visible: !previewImage.visible
|
|
283
|
+
Accessible.name: text
|
|
284
|
+
}
|
|
285
|
+
MouseArea {
|
|
286
|
+
id: previewHoverArea
|
|
287
|
+
anchors.fill: parent
|
|
288
|
+
z: 1
|
|
289
|
+
hoverEnabled: true
|
|
290
|
+
acceptedButtons: Qt.NoButton
|
|
291
|
+
|
|
292
|
+
onEntered: {
|
|
293
|
+
root.previewHovered = true
|
|
294
|
+
dismissTimer.stop()
|
|
295
|
+
}
|
|
296
|
+
onExited: {
|
|
297
|
+
root.previewHovered = false
|
|
298
|
+
if (root.thumbnailHovered)
|
|
299
|
+
dismissTimer.stop()
|
|
300
|
+
else
|
|
301
|
+
dismissTimer.restart()
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
Connections {
|
|
306
|
+
id: previewOverlayConnections
|
|
307
|
+
target: previewCard.parent
|
|
308
|
+
|
|
309
|
+
function onWidthChanged() {
|
|
310
|
+
root.schedulePreviewGeometry()
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function onHeightChanged() {
|
|
314
|
+
root.schedulePreviewGeometry()
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
Timer {
|
|
319
|
+
id: previewTimer
|
|
320
|
+
objectName: "recentPickHoverTimer"
|
|
321
|
+
interval: root.hoverDelay
|
|
322
|
+
repeat: false
|
|
323
|
+
onTriggered: root.showCurrentPreview()
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
Timer {
|
|
327
|
+
id: dismissTimer
|
|
328
|
+
objectName: "recentPickDismissTimer"
|
|
329
|
+
interval: root.dismissDelay
|
|
330
|
+
repeat: false
|
|
331
|
+
onTriggered: root.dismissPreviewIfOutside()
|
|
332
|
+
}
|
|
333
|
+
}
|