Kstars

main.qml
1 // SPDX-FileCopyrightText: 2016 Artem Fedoskin <[email protected]>
2 // SPDX-License-Identifier: GPL-2.0-or-later
3 
4 import QtQuick 2.7
5 
6 import QtQuick.Controls 2.0
7 import QtQuick.Controls.Material 2.0
8 
9 import QtQuick.Window 2.2 as Window
10 import QtQuick.Layouts 1.1
11 
12 import "modules"
13 import "modules/helpers"
14 import "modules/popups"
15 import "modules/menus"
16 import "modules/tutorial"
17 
18 
19 import "dialogs"
20 import "dialogs/menus"
21 import "dialogs/helpers"
22 
23 import "constants" 1.0
24 import "indi"
25 
26 ApplicationWindow {
27  id: window
28  objectName: "window"
29  width: Window.Screen.desktopAvailableWidth
30  height: Window.Screen.desktopAvailableHeight
31  visible: true
32 
33  //Application properties
34  property bool isLoaded: false
35  property bool isPortrait: width < height ? true: false
36  property bool isSkyMapVisible: stackView.currentItem == initPage
37  signal loaded();
38 
39  onIsLoadedChanged: {
40  if(isLoaded) {
41  loaded()
42  if(KStarsLite.runTutorial) tutorialPopup.open()
43  }
44  }
45 
46  header: ToolBar {
47  id: toolBar
48  Material.foreground: "white"
49  height: stackView.currentItem != initPage ? backButton.height : 0
50  visible: stackView.currentItem != initPage
51 
52  /*background: Rectangle {
53  anchors.fill: parent
54  color: Num.sysPalette.dark
55  }*/
56 
57  Behavior on height {
58  NumberAnimation {
59  duration: 200
60  easing.type: Easing.InOutQuad
61  }
62  }
63 
64  Row {
65  id: toolRow
66  spacing: 20
67  height: parent.height
68  width: parent.width
69 
70  ToolButton {
71  id: backButton
72  contentItem: Image {
73  fillMode: Image.Pad
74  horizontalAlignment: Image.AlignHCenter
75  verticalAlignment: Image.AlignVCenter
76  source: "images/back.png"
77  }
78  onClicked: {
79  if(stackView.depth != 1) stackView.pop()
80  }
81  }
82 
83  KSLabel {
84  id: titleLabel
85  text: stackView.currentItem.title
86 
87  font.pixelSize: 20
88  width: parent.width - backButton.width - toolRow.spacing //To allow ellision of the text
89 
90  elide: Label.ElideRight
91  wrapMode: Label.Wrap
92  maximumLineCount: 1
93 
94  anchors.verticalCenter: parent.verticalCenter
95  }
96  }
97  }
98 
99  Splash {
100  z:1
101  anchors.fill:parent
102  onTimeout: {
103  isLoaded = true
104  }
105  }
106 
107  StackView {
108  visible: isLoaded
109  id: stackView
110  anchors.fill: parent
111  initialItem: initPage
112  }
113 
114  Units {
115  id: units
116  }
117 
118  //Dialogs
119  FindDialog {
120  id: findDialog
121  }
122 
123  //Details
124  DetailsDialog {
125  id: detailsDialog
126  }
127 
128  DetailsAddLink {
129  id: detailsAddLink
130  }
131 
132  DetailsLinkMenu {
133  id: detailsLinkMenu
134  x: (window.width - width)/2
135  y: (window.height - height)/2
136  }
137 
138  //Location
139  LocationDialog {
140  id: locationDialog
141  }
142 
143  LocationEdit {
144  id: locationEdit
145  }
146 
147  LocationLoading {
148  id: locationLoading
149  }
150 
151  AboutDialog {
152  id: aboutDialog
153  }
154 
155  //Pages
156  INDIControlPanel {
157  id: indiControlPanel
158  }
159 
160  Page {
161  id: initPage
162  title: xi18n("Sky Map")
163  padding: 0
164 
165  Rectangle {
166  anchors.fill: parent
167  color: "black" //Color scheme
168  }
169  }
170 
171  SkyMapLiteWrapper {
172  /*The reason SkyMapLite is a not a child of initPage is that it can't handle properly change of
173  opacity. Each time we go from / to initPage this component is made invisible / visible and
174  skyMapLiteWrapper is anchored to fill null / parent*/
175  id: skyMapLite
176  anchors.fill: parent
177  }
178 
179  //Popups
180  TimePage {
181  id: timePage
182  }
183 
184  ColorSchemePopup {
185  id: colorSchemePopup
186  x: (window.width - width)/2
187  y: (window.height - height)/2
188  }
189 
190  ProjectionsPopup {
191  id: projPopup
192  x: (window.width - width)/2
193  y: (window.height - height)/2
194  }
195 
196  FOVPopup {
197  id: fovPopup
198  x: (window.width - width)/2
199  y: (window.height - height)/2
200  }
201 
202  TutorialPopup {
203  id: tutorialPopup
204  x: (window.width - width)/2
205  y: (window.height - height)/2
206  }
207 
208  TutorialExitPopup {
209  id: tutorialExitPopup
210  x: (window.width - width)/2
211  y: (window.height - height)/2
212  }
213 
214  //Menus
215  ContextMenu {
216  id: contextMenu
217  x: (window.width - width)/2
218  y: (window.height - height)/2
219  }
220 
221  LocationsGeoMenu {
222  id: locationsGeoMenu
223  x: (window.width - width)/2
224  y: (window.height - height)/2
225  }
226 
227  Drawer {
228  id: globalDrawer
229  objectName: "globalDrawer"
230  width: Math.min(window.width, window.height) / 4 * 2
231  height: window.height
232  //Disable drawer while loading
233  dragMargin: isLoaded ? Qt.styleHints.startDragDistance : -Qt.styleHints.startDragDistance
234  background: Rectangle {
235  anchors.fill: parent
236  color: Num.sysPalette.base
237  }
238 
239  onOpened: {
240  contextDrawer.close()
241  }
242 
243  Image {
244  id: drawerBanner
245  source: "images/kstars.png"
246  fillMode: Image.PreserveAspectFit
247 
248  anchors {
249  left: parent.left
250  top: parent.top
251  right: parent.right
252  }
253  }
254 
255  ListView {
256  clip: true
257  id: pagesList
258  anchors {
259  left: parent.left
260  top: drawerBanner.bottom
261  right: parent.right
262  bottom: parent.bottom
263  }
264 
265  delegate: ItemDelegate {
266  id: globalDrawerControl
267  Rectangle {
268  anchors {
269  horizontalCenter: parent.horizontalCenter
270  bottom: parent.bottom
271  }
272  width: parent.width - 10
273  color: "#E8E8E8"
274  height: 1
275  }
276 
277  contentItem: KSText {
278  rightPadding: globalDrawerControl.spacing
279  text: globalDrawerControl.text
280  font: globalDrawerControl.font
281  elide: Text.ElideRight
282  visible: globalDrawerControl.text
283  horizontalAlignment: Text.AlignLeft
284  verticalAlignment: Text.AlignVCenter
285  }
286 
287  width: parent.width
288  text: model.objID.title
289  onClicked: {
290  if(stackView.currentItem != model.objID) {
291  if(model.objID != initPage) {
292  stackView.replace(null, [initPage, model.objID])
293  } else {
294  stackView.replace(null, initPage)
295  }
296  globalDrawer.close()
297  }
298  }
299  }
300 
301  property ListModel drawerModel : ListModel {
302  //Trick to enable storing of object ids
303  Component.onCompleted: {
304  append({objID: initPage});
305  append({objID: indiControlPanel});
306  append({objID: findDialog});
307  append({objID: locationDialog});
308  append({objID: aboutDialog});
309  }
310  }
311 
312  model: drawerModel
313 
314  ScrollIndicator.vertical: ScrollIndicator { }
315  }
316  }
317 
318  //Study mode
319  property bool step1: false
320  property bool step2: false
321  property bool step3: false
322  property bool step4: false
323  property bool step5: false
324 
325  function askExitTutorial() {
326  tutorialExitPopup.open()
327  }
328 
329  function exitTutorial() {
330  KStarsLite.runTutorial = false
331  tutorialPopup.close()
332  step1 = false
333  step2 = false
334  step3 = false
335  step4 = false
336  step5 = false
337  }
338 
339  //Step 1 - Global Drawer
340  TutorialStep1 {
341 
342  }
343 
344  //Step 2 - Context Drawer
345  TutorialStep2 {
346 
347  }
348 
349  //Step 5 - Location
350  TutorialStep5 {
351 
352  }
353 
354  Drawer {
355  id: contextDrawer
356  objectName: "contextDrawer"
357  width: Math.min(window.width, window.height) / 4 * 2
358  height: window.height
359  //Disable drawer while loading and if SkyMapLite is not visible
360  dragMargin: isSkyMapVisible && isLoaded ? Qt.styleHints.startDragDistance + 15 : -Qt.styleHints.startDragDistance
361  edge: Qt.RightEdge
362  background: Rectangle {
363  anchors.fill: parent
364  color: Num.sysPalette.base
365  }
366 
367  onOpened: {
368  globalDrawer.close()
369  }
370 
371  KSLabel {
372  id: contextTitle
373  anchors {
374  top: parent.top
375  left: parent.left
376  margins: 10
377  }
378 
379  font.pointSize: 14
380  text: stackView.currentItem.title
381  }
382 
383  ListView {
384  id: contextList
385  anchors {
386  left: parent.left
387  top: contextTitle.bottom
388  right: parent.right
389  bottom: parent.bottom
390  topMargin: 15
391  }
392  model: drawerModel
393 
394  delegate: ItemDelegate {
395  id: contextDrawerControl
396  Rectangle {
397  anchors {
398  horizontalCenter: parent.horizontalCenter
399  bottom: parent.bottom
400  }
401  width: parent.width - 10
402  color: "#E8E8E8"
403  height: 1
404  }
405 
406  width: parent.width
407  text: model.title
408  onClicked: {
409  if(model.type == "popup") {
410  objID.open()
411  }
412 
413  contextDrawer.close()
414  }
415 
416  contentItem: KSText {
417  rightPadding: contextDrawerControl.spacing
418  text: contextDrawerControl.text
419  font: contextDrawerControl.font
420  elide: Text.ElideRight
421  visible: contextDrawerControl.text
422  horizontalAlignment: Text.AlignLeft
423  verticalAlignment: Text.AlignVCenter
424  }
425  }
426 
427  property ListModel drawerModel : ListModel {
428  //Trick to enable storing of object ids
429  Component.onCompleted: {
430  append({title: xi18n("Projection systems"), objID: projPopup, type: "popup"});
431  append({title: xi18n("Color Schemes"), objID: colorSchemePopup, type: "popup"});
432  append({title: xi18n("FOV Symbols"), objID: fovPopup, type: "popup"});
433  }
434  }
435 
436  ScrollIndicator.vertical: ScrollIndicator { }
437  }
438 
439  ColumnLayout {
440  anchors {
441  left: parent.left
442  right: parent.right
443  bottom: parent.bottom
444  }
445 
446  RowLayout {
447  id: magnitudeRow
448  anchors {
449  leftMargin: 10
450  left: parent.left
451  rightMargin: 10
452  right: parent.right
453  }
454 
455  property color magnitudeColor: colorSchemePopup.currentCScheme == "cs_night" ? "white" : "black"
456 
457  Rectangle {
458  anchors{
459  left: parent.left
460  bottom: smallestMag.bottom
461  }
462 
463  width: 24
464  height: 24
465  radius: width * 0.5
466  color: magnitudeRow.magnitudeColor
467  }
468 
469  Rectangle {
470  anchors{
471  horizontalCenter: parent.horizontalCenter
472  bottom: smallestMag.bottom
473  }
474 
475  width: 16
476  height: 16
477  radius: width * 0.5
478  color: magnitudeRow.magnitudeColor
479  }
480 
481  Rectangle {
482  id: smallestMag
483 
484  anchors {
485  right: parent.right
486  verticalCenter: parent.bottom
487  }
488 
489  width: 8
490  height: 8
491  radius: width * 0.5
492  color: magnitudeRow.magnitudeColor
493  }
494  }
495 
496  Slider {
497  id: magSlider
498  anchors {
499  left: parent.left
500  right: parent.right
501  }
502 
503  from: 1.18778
504  to: 5.75954
505  value: SkyMapLite.magLim
506 
507  onValueChanged: {
508  SkyMapLite.magLim = value
509  }
510  }
511  }
512  }
513 
514  //Handle back button
515  Connections {
516  target: window
517  onClosing: {
518  if (Qt.platform.os == "android") {
519  if(stackView.depth > 1) {
520  close.accepted = false;
521  stackView.pop()
522  }
523  }
524  }
525  }
526 }
Definition: Units.qml:9
QTextStream & right(QTextStream &stream)
This class loads QML files and connects SkyMapLite and KStarsData Unlike KStars class it is not a mai...
Definition: kstarslite.h:46
Type type(const QSqlDatabase &db)
QTextStream & left(QTextStream &stream)
const QList< QKeySequence > & close()
QString xi18n(const char *text, const TYPE &arg...)
double magLim
magnitude limit.
Definition: skymaplite.h:62
QTextStream & left(QTextStream &s)
QTextStream & right(QTextStream &s)
Item for displaying sky objects; also handles user interaction events.
Definition: skymaplite.h:58
KJOBWIDGETS_EXPORT QWidget * window(KJob *job)
QString & fill(QChar ch, int size)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Aug 11 2022 04:00:01 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.