From 981f8b3acf7e76f27c02f4ced80d55b424cc7497 Mon Sep 17 00:00:00 2001 From: Tannin Date: Sun, 3 Feb 2013 12:49:25 +0100 Subject: initial commit to mercurial repository. Corresponds to MO version 0.12.6 --- src/tutorials/Highlight.qml | 19 +++ src/tutorials/TutorialDescription.qml | 54 +++++++ src/tutorials/TutorialOverlay.qml | 53 +++++++ src/tutorials/tutorial_basics.js | 2 + src/tutorials/tutorial_conflictresolution_main.js | 164 ++++++++++++++++++++ .../tutorial_conflictresolution_modinfo.js | 21 +++ src/tutorials/tutorial_firststeps.js | 5 + src/tutorials/tutorial_firststeps_browser.js | 12 ++ src/tutorials/tutorial_firststeps_main.js | 172 +++++++++++++++++++++ src/tutorials/tutorial_firststeps_modinfo.js | 24 +++ src/tutorials/tutorial_firststeps_settings.js | 25 +++ src/tutorials/tutorial_window_installer.js | 37 +++++ src/tutorials/tutorials.js | 75 +++++++++ src/tutorials/tutorials_installdialog.qml | 7 + src/tutorials/tutorials_mainwindow.qml | 8 + src/tutorials/tutorials_modinfodialog.qml | 7 + src/tutorials/tutorials_nexusdialog.qml | 8 + src/tutorials/tutorials_settingsdialog.qml | 7 + 18 files changed, 700 insertions(+) create mode 100644 src/tutorials/Highlight.qml create mode 100644 src/tutorials/TutorialDescription.qml create mode 100644 src/tutorials/TutorialOverlay.qml create mode 100644 src/tutorials/tutorial_basics.js create mode 100644 src/tutorials/tutorial_conflictresolution_main.js create mode 100644 src/tutorials/tutorial_conflictresolution_modinfo.js create mode 100644 src/tutorials/tutorial_firststeps.js create mode 100644 src/tutorials/tutorial_firststeps_browser.js create mode 100644 src/tutorials/tutorial_firststeps_main.js create mode 100644 src/tutorials/tutorial_firststeps_modinfo.js create mode 100644 src/tutorials/tutorial_firststeps_settings.js create mode 100644 src/tutorials/tutorial_window_installer.js create mode 100644 src/tutorials/tutorials.js create mode 100644 src/tutorials/tutorials_installdialog.qml create mode 100644 src/tutorials/tutorials_mainwindow.qml create mode 100644 src/tutorials/tutorials_modinfodialog.qml create mode 100644 src/tutorials/tutorials_nexusdialog.qml create mode 100644 src/tutorials/tutorials_settingsdialog.qml (limited to 'src/tutorials') diff --git a/src/tutorials/Highlight.qml b/src/tutorials/Highlight.qml new file mode 100644 index 00000000..bb4db78f --- /dev/null +++ b/src/tutorials/Highlight.qml @@ -0,0 +1,19 @@ +// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5 +import QtQuick 1.1 + +Rectangle { + radius: 10 + color: "transparent" + height: 100 + border.color: "black" + border.width: 3 + opacity: 0.9 + smooth: true + + SequentialAnimation on opacity { + loops: Animation.Infinite + + PropertyAnimation { easing.type: Easing.InOutSine; duration: 300; to: 0.1 } + PropertyAnimation { easing.type: Easing.OutInSine; duration: 300; to: 0.7 } + } +} diff --git a/src/tutorials/TutorialDescription.qml b/src/tutorials/TutorialDescription.qml new file mode 100644 index 00000000..b295e477 --- /dev/null +++ b/src/tutorials/TutorialDescription.qml @@ -0,0 +1,54 @@ +import QtQuick 1.1 + +// rectangle for description texts +Rectangle { + property alias text: textBox.text + property alias continueVisible: continueIcon.visible + property int innerWidth; + signal clicked + + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 100 + width: textBox.width + 30 + height: textBox.height + 8 + border.color: "black" + border.width: 3 + smooth: true + opacity: 0.9 + color: "#707070" + + Image { + id: continueIcon + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + anchors.right: parent.right + anchors.rightMargin: 5 + source: "qrc:/MO/gui/next" + + SequentialAnimation on opacity { + loops: Animation.Infinite + + PauseAnimation { duration: 500 } + PropertyAnimation { easing.type: Easing.InOutSine; duration: 400; to: 0.0 } + PropertyAnimation { easing.type: Easing.OutInSine; duration: 400; to: 1.0 } + } + } + + Text { + id: textBox + text: "" + font.pointSize: 12 + font.bold: false + width: innerWidth + font.family: "Courier" + wrapMode: Text.WordWrap + anchors.centerIn: parent + } + + MouseArea { + id: clickArea + anchors.fill: parent + onClicked: parent.clicked(mouse) + } +} diff --git a/src/tutorials/TutorialOverlay.qml b/src/tutorials/TutorialOverlay.qml new file mode 100644 index 00000000..34959d7d --- /dev/null +++ b/src/tutorials/TutorialOverlay.qml @@ -0,0 +1,53 @@ +// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5 +import QtQuick 1.1 +import "tutorials.js" as Logic + +Rectangle { + color: "transparent" + + property int step : 0 + property alias description: tutDescription + property alias highlight: tutHighlight + property alias text: tutDescription.text + property alias boxOpacity: tutDescription.opacity + property int offsetBottom: 50 + property int maxWidth: 400 + + function init() { + Logic.init() + Logic.nextStep() + } + + function enableBackground(enabled) { + disabledBackground.visible = enabled + } + + signal nextStep + + onNextStep: { + if (step == 0) { + Logic.init() + } + + Logic.nextStep() + } + + TutorialDescription { + id: tutDescription + innerWidth: maxWidth + anchors.bottomMargin: offsetBottom + onClicked: { + Logic.clickNext() + } + } + + Rectangle { + id: disabledBackground + anchors.fill: parent + opacity: 0.2 + color: "#808080" + } + + Highlight { id: tutHighlight } + +} diff --git a/src/tutorials/tutorial_basics.js b/src/tutorials/tutorial_basics.js new file mode 100644 index 00000000..c8776b28 --- /dev/null +++ b/src/tutorials/tutorial_basics.js @@ -0,0 +1,2 @@ +function tutorial() { +} diff --git a/src/tutorials/tutorial_conflictresolution_main.js b/src/tutorials/tutorial_conflictresolution_main.js new file mode 100644 index 00000000..3a7160c6 --- /dev/null +++ b/src/tutorials/tutorial_conflictresolution_main.js @@ -0,0 +1,164 @@ +//TL Conflict Resolution#10 +function getTutorialSteps() { + return [ + function() { + tutorial.text = qsTr("There are multiple types of conflicts you may encounter when dealing with Mods. " + +"This tutorial will try to cover and explain how to deal with all of them.") + waitForClick() + }, + function() { + tutorial.text = qsTr("First up are file conflicts. These occur when two mods contain the same file. " + +"Most commonly this happens when several mods replace the same standard asset from " + +"the game, like the texture of an armor.") + waitForClick() + }, + function() { + tutorial.text = qsTr("As an example, say you install \"ModA\" which contains stylish new iron and leather armor. " + +"Then you install \"ModB\" which contains sexy ebony and leather armor. Obviously there is a " + +"conflict now: which leather armor to use?") + waitForClick() + }, + function() { + tutorial.text = qsTr("If you were to install the mods manually, when installing \"ModB\" you would be asked if you want " + +"to overwrite conflicting files. If you choose yes, you get the leather armor from \"ModB\" otherwise " + +"you keep the one from \"ModA\". If you later decide you made the wrong choice, " + +"you have to reinstall one of the mods.") + waitForClick() + }, + function() { + tutorial.text = qsTr("With MO, both ModA and ModB get installed completely (no overwrite dialog) and by default " + +"\"ModB\" gets to provide the leather armor because it's automatically assigned the higher priority.") + waitForClick() + }, + function() { + tutorial.text = qsTr("However, you can change the mod priority at any time using drag&drop on this list. " + +"If you assign \"ModA\" a higher priority, it provides the leather armor, no re-installation required. " + +"Since the priorities of mods in this list are treated as if the mods were installed in that order, " + +"I tend to talk about \"installation order\".") + highlightItem("modList", false) + waitForClick() + }, + function() { + tutorial.text = qsTr("If the \"Flags\"-column is enabled in the mod list, it will show you which mods are involved in a conflict and how...") + waitForClick() + }, + function() { + unhighlight() + tutorial.text = qsTr(" indicates that the mod overwrites files that are also available in another mod.") + waitForClick() + }, + function() { + tutorial.text = qsTr(" indicates that the mod is partially overwritten by another.") + waitForClick() + }, + function() { + tutorial.text = qsTr(" indicates that both of the above is true.") + waitForClick() + }, + function() { + tutorial.text = qsTr(" indicates that the mod is completely overwrtten by another. You could as well disable it."); + waitForClick() + }, + function() { + tutorial.text = qsTr("There are two ways to see the individual files involved in a conflict:") + waitForClick() + }, + function() { + tutorial.text = qsTr("Option A: Switch to the \"Data\"-tab if necessary") + if (!tutorialControl.waitForTabOpen("tabWidget", 2)) { + highlightItem("tabWidget", false) + waitForClick() + } else { + highlightItem("tabWidget", true) + } + }, + function() { + tutorial.text = qsTr("... here, if you mark the highlighted control, the tree will only display files in conflict. " + +"In the right column, it says which mod currently provides the mod (because it has highest priority) " + +"and if you hover your mouse over that info, it will list which other mods contains it.") + highlightItem("conflictsCheckBox", false) + waitForClick() + }, + function() { + tutorial.text = qsTr("Option B: Open the Information-Dialog of an enabled mod you're interested in by " + +"either double-clicking it or selecting Information... from the right-click menu") + highlightItem("modList", true) + manager.activateTutorial("ModInfoDialog", "tutorial_conflictresolution_modinfo.js") + applicationWindow.modInfoDisplayed.connect(nextStep) + }, + function() { + unhighlight() + tutorial.text = qsTr("This was everything to know about file conflicts. The second type of conflict we have to deal with " + +"are \"record conflicts\".") + waitForClick() + }, + function() { + tutorial.text = qsTr("I told you in the \"First Steps\" tutorial how the esp/esm plugins contain changes to the game world " + +"like modifications to the terrain or existing NPCs. Each change like this is stored in a record, hence the " + +"name \"record conflict\". For example when two mods try to change the same location, only one change can become active.") + waitForClick() + }, + function() { + tutorial.text = qsTr("As with file conflicts you can't really fix these conflicts, you have to choose which change you want. " + +"This time around however, if you choose wrong, your game may become unstable because there may be " + +"dependencies between the records of a mod.") + waitForClick() + }, + function() { + tutorial.text = qsTr("Please open the \"ESPs\"-tab...") + highlightItem("tabWidget", true) + if (!tutorialControl.waitForTabOpen("tabWidget", 0)) { + nextStep() + } + }, + function() { + tutorial.text = qsTr("Again you can use drag&drop to change priorities of plugins, thus deciding which plugin takes " + +"precedence in regards to conflicts. This is commonly called the \"load order\". " + +"But how do you know how to order the plugins?") + waitForClick() + }, + function() { + unhighlight() + tutorial.text = qsTr("Unlike with file conflicts, MO does not provide help on finding conflicts. The good news is, there " + +"already is a perfect tool for that called BOSS. BOSS is available on the Nexus and integrates " + +"neatly with MO. Basically, if you don't have BOSS yet, install it once this tutorial is over.") + waitForClick() + }, + function() { + tutorial.text = qsTr("After you installed BOSS in the default location (follow its instructions), start MO again and BOSS should automatically appear as an Executable...") + highlightItem("startGroup", false) + waitForClick() + }, + function() { + tutorial.text = qsTr("When you run BOSS, it will automatically re-organize plugins for best compatibility (overwriting your manual changes). " + +"It will also open a report in your browser that warns about incompatibilities. You should read the report, at least " + +"for new mods.") + waitForClick() + }, + function() { + unhighlight() + tutorial.text = qsTr("The final type of conflicts are also \"record conflicts\". Like the previous type. It's confusing, so " + +"I'll just call them \"lists conflicts\" instead. The difference is the types of " + +"records in conflict. The ones in question here can be merged so you may be able to get all modifications in your game.") + waitForClick() + }, + function() { + tutorial.text = qsTr("One common example of such records are leveled lists that contain all the items that may spawn at a specific " + +"character level. Traditionally, if multiple mods add items to such a list, only one is in effect...") + waitForClick() + }, + function() { + tutorial.text = qsTr("... but there are tools to merge those mods so you can have the effects of all of them. Again, this " + +"functionality is not integrated with MO because there are already great tools. For Oblivion and Skyrim " + +"look for wrye bash, for fallout 3/nv it's wrye flash. For Skyrim there is also " + +"\"SkyBash\". All of these can create a so-called \"bashed patch\" which is a plugin that contains the combined " + +"mergeable records from all your mods.") + waitForClick() + }, + function() { + tutorial.text = qsTr("This completes the tutorial.") + waitForClick() + } + + ] +} diff --git a/src/tutorials/tutorial_conflictresolution_modinfo.js b/src/tutorials/tutorial_conflictresolution_modinfo.js new file mode 100644 index 00000000..b5ef461e --- /dev/null +++ b/src/tutorials/tutorial_conflictresolution_modinfo.js @@ -0,0 +1,21 @@ +function getTutorialSteps() { + return [ + function() { + tutorial.text = qsTr("Please switch to the \"Conflicts\"-Tab.") + highlightItem("tabWidget", true) + if (!tutorialControl.waitForTabOpen("tabWidget", 4)) { + nextStep() + } + }, + function() { + tutorial.text = qsTr("Here you can see a list of files in this mod that out-prioritize others " + +"in a file conflict and one with files where this mod is overridden.") + waitForClick() + }, + function() { + tutorial.text = qsTr("Please close the information dialog again.") + waitForClick() + } + + ] +} diff --git a/src/tutorials/tutorial_firststeps.js b/src/tutorials/tutorial_firststeps.js new file mode 100644 index 00000000..bf3cad38 --- /dev/null +++ b/src/tutorials/tutorial_firststeps.js @@ -0,0 +1,5 @@ +// First Steps +subTutorials = [ + ["MainWindow", "tutorial_firststeps_main.js"], + ["SettingsDialog", "tutorial_firststeps_settings.js"] + ]; diff --git a/src/tutorials/tutorial_firststeps_browser.js b/src/tutorials/tutorial_firststeps_browser.js new file mode 100644 index 00000000..062cc18c --- /dev/null +++ b/src/tutorials/tutorial_firststeps_browser.js @@ -0,0 +1,12 @@ +function getTutorialSteps() +{ + return [ + function() { + tutorial.text = qsTr("This is a fully featured browser that is set up to " + +"open the correct nexus page for your game. You can " + +"download any mod using the \"DOWNLOAD WITH MANAGER\"-button " + +"or the \"manual\"-link and it will be downloaded by MO.") + waitForClick() + } + ] +} diff --git a/src/tutorials/tutorial_firststeps_main.js b/src/tutorials/tutorial_firststeps_main.js new file mode 100644 index 00000000..9785dc42 --- /dev/null +++ b/src/tutorials/tutorial_firststeps_main.js @@ -0,0 +1,172 @@ +//TL First Steps#0 +function getTutorialSteps() +{ + return [ + function() { + tutorial.text = qsTr("Welcome to the ModOrganizer Tutorial! This will guide you through the most important features of the program.") + waitForClick() + }, + + function() { + tutorial.text = qsTr("Before we continue with the step-by-step tutorial, I'd like to tell you about the other ways you can receive help on ModOrganizer.") + waitForClick() + }, + + function() { + tutorial.text = qsTr("The highlighted button provides hints on solving problems MO recognized automatically.") + if (!tutorialControl.waitForAction("actionProblems")) { + highlightAction("actionProblems", false) + waitForClick() + } else { + tutorial.text += qsTr("\nThere IS a problem now but you may want to hold off on fixing it until after completing the tutorial.") + highlightAction("actionProblems", true) + } + }, + + function() { + tutorial.text = qsTr("This button provides multiple sources of information and further tutorials.") + highlightItem("actionHelp", true) + tutorialControl.waitForButton("actionHelp") + }, + + function() { + tutorial.text = qsTr("Finally there are tooltips on almost every part of Mod Organizer. If there is a control " + + "in MO you don't understand, please try hovering over it to get a short description or " + + "use \"Help on UI\" from the help menu to get a longer explanation") + waitForClick() + }, + + function() { + tutorial.text = qsTr("This list displays all mods installed through MO. The first point in our agenda will be adding some stuff to it.") + highlightItem("modList", false) + waitForClick() + }, + + function() { + tutorial.text = qsTr("There are a few ways to get mods into ModOrganizer. The easiest is to use the embedded nexus browser. Click \"Nexus\"") + highlightAction("actionNexus", true) + manager.activateTutorial("NexusDialog", "tutorial_firststeps_browser.js") + tutorialControl.waitForAction("actionNexus") + }, + + function() { + tutorial.text = qsTr("Downloads will appear here. Double click one to install it.") + applicationWindow.modInstalled.connect(nextStep) + highlightItem("downloadView", true) + }, + + function() { + unhighlight() + applicationWindow.modInstalled.disconnect(nextStep) + tutorial.text = qsTr("Great, you just installed your first mod. Please note that the installation procedure may differ based on how a mod was packaged.") + waitForClick() + }, + + function() { + tutorial.text = qsTr("I promised you multiple ways of getting mods into MO. Please open the settings dialog now.") + highlightAction("actionSettings", true) + manager.activateTutorial("SettingsDialog", "tutorial_firststeps_settings.js") + tutorialControl.waitForAction("actionSettings") + }, + + function() { + tutorial.text = qsTr("So far I only showed you how to get mods from Nexus.\n" + + "You can also install mods from disk using the \"Install Mod\" button.") + highlightAction("actionInstallMod", false) + waitForClick() + }, + + function() { + unhighlight() + tutorial.text = qsTr("Now you know all about downloading and installing mods but they are not enabled yet...") + waitForClick() + }, + + function() { + tutorial.text = qsTr("Install a few more mods if you want, then enable mods by checking them in the left pane. " + + "Mods that aren't enabled have no effect on the game whatsoever. ") + highlightItem("modList", true) + modList.modlist_changed.connect(nextStep) + }, + + function() { + modList.modlist_changed.disconnect(nextStep) + unhighlight() + tutorial.text = qsTr("For some mods, enabling it on the left pane is all you have to do...") + waitForClick() + }, + + function() { + tutorial.text = qsTr("...but most contain plugins. These are plugins for the game and are required " + +"to add stuff to the game (new weapons, armors, quests, areas, ...). " + +"Please open the \"ESPs\"-tab to get a list of plugins.") + if (tutorialControl.waitForTabOpen("tabWidget", 0)) { + highlightItem("tabWidget", true) + } else { + waitForClick() + } + }, + + function() { + tutorial.text = qsTr("You will notice some plugins are grayed out. These are part of the main game and can't be " + +"disabled.") + waitForClick() + }, + + function() { + tutorial.text = qsTr("A single mod may contain zero, one or multiple esps. Some or all may be optional. " + + "If in doubt, please consult the documentation of the indiviual mod. " + + "To do so, right-click the mod and select \"Information\".") + highlightItem("modList", true) + manager.activateTutorial("ModInfoDialog", "tutorial_firststeps_modinfo.js") + applicationWindow.modInfoDisplayed.connect(nextStep) + }, + + function() { + tutorial.text = qsTr("Another special type of files are BSAs. These are bundles of game resources. " + + "Please open the \"BSAs\"-tab.") + if (tutorialControl.waitForTabOpen("tabWidget", 1)) { + highlightItem("tabWidget", true) + } else { + waitForClick() + } + }, + + function() { + tutorial.text = qsTr("These archives can be a real headache because the way bsas interact " + + "with non-bundled resources is complicated. The game can even crash if required " + + "archives are not loaded or ordered incorrectly.") + waitForClick() + }, + + function() { + tutorial.text = qsTr("MO applies some \"magic\" to make all BSAs that are checked in this list load in " + + "the correct order interleaved with the non-bundled resources. Usually it's best " + + "to check all bsas that have an exclamation mark at the side.") + waitForClick() + }, + + function() { + tutorial.text = qsTr("Now you know how to download, install and enable mods.\n" + + "It's important you always start the game from inside MO, otherwise " + + "the mods you installed here won't work.") + highlightItem("startGroup", false) + waitForClick() + }, + + function() { + tutorial.text = qsTr("This combobox lets you choose what to start. This way you can start the game, Launcher, " + + "Script Extender, the Creation Kit or other tools. If you miss a tool you can also configure this list " + + "but that is an advanced topic.") + highlightItem("executablesListBox", false) + waitForClick() + }, + + function() { + tutorial.text = qsTr("This completes the basic tutorial. As homework go play a bit! After you " + + "have installed more mods you may want to read the tutorial on conflict resolution.") + highlightItem("startButton", false) + waitForClick() + } + ] +} diff --git a/src/tutorials/tutorial_firststeps_modinfo.js b/src/tutorials/tutorial_firststeps_modinfo.js new file mode 100644 index 00000000..3c56d1f4 --- /dev/null +++ b/src/tutorials/tutorial_firststeps_modinfo.js @@ -0,0 +1,24 @@ +function getTutorialSteps() +{ + return [ + function() { + tutorial.text = qsTr("This dialog tries to expose as much information about a mod as possible. " + +"Depending on the mod this may include readmes, screenshots, optional plugins and so on. " + +"If a certain type of information was not found in a mod, the corresponding tab " + +"is grayed out.") + highlightItem("tabWidget", false) + waitForClick() + }, + function() { + tutorial.text = qsTr("If you installed the mod from Nexus, the corresponding tab should give you direct " + +"access to the mod page. That tab can also be used to download optional packages " + +"or updates for the mod.") + waitForClick() + }, + function() { + unhighlight() + tutorial.text = qsTr("We may re-visit this screen in later tutorials.") + waitForClick() + } + ] +} diff --git a/src/tutorials/tutorial_firststeps_settings.js b/src/tutorials/tutorial_firststeps_settings.js new file mode 100644 index 00000000..2bff4251 --- /dev/null +++ b/src/tutorials/tutorial_firststeps_settings.js @@ -0,0 +1,25 @@ +function getTutorialSteps() +{ + return [ + function() { + highlightItem("tabWidget", true) + tutorial.text = qsTr("You can use your regular browser to download from Nexus.\nPlease open the \"Nexus\"-tab") + tutorialControl.waitForTabOpen("tabWidget", 2) + }, + + function() { + highlightItem("handleNXMBox", false) + tutorial.text = qsTr("If this box is checked the \"DOWNLOAD WITH MANAGER\"-buttons " + +"in your regular browser will also download with Mod Organizer.") + waitForClick() + }, + + function() { + highlightItem("nexusBox", false) + tutorial.text = qsTr("You can also store your Nexus-credentials " + +"here for automatic login. The password is " + +"stored unencrypted on your disk!") + waitForClick() + } + ] +} diff --git a/src/tutorials/tutorial_window_installer.js b/src/tutorials/tutorial_window_installer.js new file mode 100644 index 00000000..a2779234 --- /dev/null +++ b/src/tutorials/tutorial_window_installer.js @@ -0,0 +1,37 @@ +//WIN InstallDialog +function getTutorialSteps() +{ + return [ + function() { + tutorial.text = qsTr("This mod has been packaged in a way that Mod Organizer did not automatically " + + "recognize...") + waitForClick() + }, + function() { + tutorial.text = qsTr("You can use drag&drop on this list to fix the structure of the mod.") + highlightItem("treeContent", false) + waitForClick() + }, + function() { + tutorial.text = qsTr("The correct structure replicates the data-directory of the game. That means " + + "esps, the \"meshes\"- or \"textures\"-directory and so on should be directly " + + "below \"\".") + waitForClick() + }, + function() { + tutorial.text = qsTr("You can also disable files and directories that you don't want to unpack.") + waitForClick() + }, + function() { + tutorial.text = qsTr("From the context menu (right-click) you can open textfiles, in case " + + "you want to access a readme.") + waitForClick() + }, + function() { + tutorial.text = qsTr("This text will turn green if MO thinks the structure looks good.") + highlightItem("problemLabel", false) + manager.finishWindowTutorial("InstallDialog") + waitForClick() + } + ] +} diff --git a/src/tutorials/tutorials.js b/src/tutorials/tutorials.js new file mode 100644 index 00000000..f2b18856 --- /dev/null +++ b/src/tutorials/tutorials.js @@ -0,0 +1,75 @@ +var tutorialSteps = [] +var waitingForClick = false + + +function highlightItem(widgetName, click) { + var rect = tutorialControl.getRect(widgetName) + highlight.x = rect.x - 1 + highlight.y = rect.y - 1 + highlight.width = rect.width + 2 + highlight.height = rect.height + 2 + if (click) { + highlight.border.color = "green" + } else { + highlight.border.color = "blue" + } + highlight.visible = true +} + +function highlightAction(actionName, click) { + var rect = tutorialControl.getActionRect(actionName) + highlight.x = rect.x - 1 + highlight.y = rect.y - 1 + highlight.width = rect.width + 2 + highlight.height = rect.height + 2 + if (click) { + highlight.border.color = "green" + } else { + highlight.border.color = "blue" + } + highlight.visible = true +} + +function unhighlight() +{ + highlight.visible = false +} + +function waitForClick() +{ + waitingForClick = true; + description.continueVisible = true + // ui needs to be locked, otherwise the tutorial-view does not receive mouse-events! + tutorialControl.lockUI(true) +} + +function clickNext() +{ + if (waitingForClick) { + nextStep() + } +} + +function nextStep() +{ + waitingForClick = false; + description.continueVisible = false + if (step < tutorialSteps.length) { + tutorialControl.lockUI(false) + step++ + tutorialSteps[step - 1]() + } else { + tutorialControl.finish() + } +} + +function init() +{ + var res = Qt.include("file:///" + scriptName) + if (res.status !== 0) { + console.log("failed to load " + scriptName + ": " + res.status) + return + } + + tutorialSteps = getTutorialSteps() +} diff --git a/src/tutorials/tutorials_installdialog.qml b/src/tutorials/tutorials_installdialog.qml new file mode 100644 index 00000000..33f0a660 --- /dev/null +++ b/src/tutorials/tutorials_installdialog.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TutorialOverlay { + id: tutorial + offsetBottom: 65 + maxWidth: 420 +} diff --git a/src/tutorials/tutorials_mainwindow.qml b/src/tutorials/tutorials_mainwindow.qml new file mode 100644 index 00000000..6b4e6b30 --- /dev/null +++ b/src/tutorials/tutorials_mainwindow.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + + +TutorialOverlay { + id: tutorial + offsetBottom: 50 + maxWidth: 400 +} diff --git a/src/tutorials/tutorials_modinfodialog.qml b/src/tutorials/tutorials_modinfodialog.qml new file mode 100644 index 00000000..e9a56cb3 --- /dev/null +++ b/src/tutorials/tutorials_modinfodialog.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TutorialOverlay { + id: tutorial + offsetBottom: 60 + maxWidth: 420 +} diff --git a/src/tutorials/tutorials_nexusdialog.qml b/src/tutorials/tutorials_nexusdialog.qml new file mode 100644 index 00000000..6a7af6d6 --- /dev/null +++ b/src/tutorials/tutorials_nexusdialog.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TutorialOverlay { + id: tutorial + offsetBottom: 40 + maxWidth: 600 + boxOpacity: 0.95 +} diff --git a/src/tutorials/tutorials_settingsdialog.qml b/src/tutorials/tutorials_settingsdialog.qml new file mode 100644 index 00000000..e9a56cb3 --- /dev/null +++ b/src/tutorials/tutorials_settingsdialog.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TutorialOverlay { + id: tutorial + offsetBottom: 60 + maxWidth: 420 +} -- cgit v1.3.1