diff options
| author | Tannin <Tannin@Serenity> | 2013-02-03 12:49:25 +0100 |
|---|---|---|
| committer | Tannin <Tannin@Serenity> | 2013-02-03 12:49:25 +0100 |
| commit | 981f8b3acf7e76f27c02f4ced80d55b424cc7497 (patch) | |
| tree | 0f504d99d1e5fe197258febff3c147d0725abda4 /src/tutorials | |
initial commit to mercurial repository.
Corresponds to MO version 0.12.6
Diffstat (limited to 'src/tutorials')
| -rw-r--r-- | src/tutorials/Highlight.qml | 19 | ||||
| -rw-r--r-- | src/tutorials/TutorialDescription.qml | 54 | ||||
| -rw-r--r-- | src/tutorials/TutorialOverlay.qml | 53 | ||||
| -rw-r--r-- | src/tutorials/tutorial_basics.js | 2 | ||||
| -rw-r--r-- | src/tutorials/tutorial_conflictresolution_main.js | 164 | ||||
| -rw-r--r-- | src/tutorials/tutorial_conflictresolution_modinfo.js | 21 | ||||
| -rw-r--r-- | src/tutorials/tutorial_firststeps.js | 5 | ||||
| -rw-r--r-- | src/tutorials/tutorial_firststeps_browser.js | 12 | ||||
| -rw-r--r-- | src/tutorials/tutorial_firststeps_main.js | 172 | ||||
| -rw-r--r-- | src/tutorials/tutorial_firststeps_modinfo.js | 24 | ||||
| -rw-r--r-- | src/tutorials/tutorial_firststeps_settings.js | 25 | ||||
| -rw-r--r-- | src/tutorials/tutorial_window_installer.js | 37 | ||||
| -rw-r--r-- | src/tutorials/tutorials.js | 75 | ||||
| -rw-r--r-- | src/tutorials/tutorials_installdialog.qml | 7 | ||||
| -rw-r--r-- | src/tutorials/tutorials_mainwindow.qml | 8 | ||||
| -rw-r--r-- | src/tutorials/tutorials_modinfodialog.qml | 7 | ||||
| -rw-r--r-- | src/tutorials/tutorials_nexusdialog.qml | 8 | ||||
| -rw-r--r-- | src/tutorials/tutorials_settingsdialog.qml | 7 |
18 files changed, 700 insertions, 0 deletions
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("<img src=\":/MO/gui/emblem_conflict_overwrite\" /> indicates that the mod overwrites files that are also available in another mod.")
+ waitForClick()
+ },
+ function() {
+ tutorial.text = qsTr("<img src=\":/MO/gui/emblem_conflict_overwritten\" /> indicates that the mod is <b>partially</b> overwritten by another.")
+ waitForClick()
+ },
+ function() {
+ tutorial.text = qsTr("<img src=\":/MO/gui/emblem_conflict_mixed\" /> indicates that both of the above is true.")
+ waitForClick()
+ },
+ function() {
+ tutorial.text = qsTr("<img src=\":/MO/gui/emblem_conflict_redundant\" /> 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 <i>Information</i>-Dialog of an <b>enabled</b> mod you're interested in by "
+ +"either double-clicking it or selecting <i>Information...</i> 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 <i>what</i> 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 \"<data>\".")
+ 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
+}
|
