Skip to content

Commit

Permalink
Tutorial updates
Browse files Browse the repository at this point in the history
- Add ability to exit tutorial early
- Update and clarify many of the tutorials
  • Loading branch information
Silarn committed Sep 25, 2023
1 parent 7050927 commit 523ea04
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 174 deletions.
14 changes: 4 additions & 10 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@ MainWindow::MainWindow(Settings& settings, OrganizerCore& organizerCore,

if (organizerCore.managedGame()->sortMechanism() ==
MOBase::IPluginGame::SortMechanism::NONE) {
ui->bossButton->setDisabled(true);
ui->bossButton->setToolTip(tr("There is no supported sort mechanism for this game. "
ui->sortButton->setDisabled(true);
ui->sortButton->setToolTip(tr("There is no supported sort mechanism for this game. "
"You will probably have to use a third-party tool."));
}

Expand Down Expand Up @@ -2265,14 +2265,8 @@ void MainWindow::tutorialTriggered()
{
QAction* tutorialAction = qobject_cast<QAction*>(sender());
if (tutorialAction != nullptr) {
if (QMessageBox::question(this, tr("Start Tutorial?"),
tr("You're about to start a tutorial. For technical "
"reasons it's not possible to end "
"the tutorial early. Continue?"),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
TutorialManager::instance().activateTutorial("MainWindow",
tutorialAction->data().toString());
}
TutorialManager::instance().activateTutorial("MainWindow",
tutorialAction->data().toString());
}
}

Expand Down
99 changes: 54 additions & 45 deletions src/mainwindow.ui

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/pluginlistview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void PluginListView::setup(OrganizerCore& core, MainWindow* mw, Ui::MainWindow*
});

// sort
connect(mwui->bossButton, &QPushButton::clicked, [=] {
connect(mwui->sortButton, &QPushButton::clicked, [=] {
onSortButtonClicked();
});

Expand Down
55 changes: 55 additions & 0 deletions src/tutorials/TutorialCanceller.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import QtQuick 2.7

// rectangle for description texts
Rectangle {
property alias text: textBox.text
property alias cancelVisible: cancelIcon.visible
property int innerWidth;
signal clicked

anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 70
width: textBox.width + 30
height: textBox.height + 8
border.color: "black"
border.width: 3
smooth: true
//opacity: 0.9
z: 10000
color: "#FF707070"

Image {
id: cancelIcon
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
anchors.right: parent.right
anchors.rightMargin: 5
source: "qrc:/MO/gui/multiply_red"

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: "Exit Tutorial"
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()
}
}
9 changes: 9 additions & 0 deletions src/tutorials/TutorialOverlay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ Rectangle {
}
}

TutorialCanceller {
id: tutorialCanceller
innerWidth: 200
anchors.bottomMargin: offsetBottom - 30
onClicked: {
Logic.cancelTutorial()
}
}

Rectangle {
id: disabledBackground
anchors.fill: parent
Expand Down
144 changes: 89 additions & 55 deletions src/tutorials/tutorial_conflictresolution_main.js

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions src/tutorials/tutorial_conflictresolution_modinfo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function getTutorialSteps() {
tutorialCanceller.visible = false
return [
function() {
tutorial.text = qsTr("Please switch to the \"Conflicts\"-Tab.")
Expand All @@ -8,12 +9,13 @@ function getTutorialSteps() {
}
},
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.")
tutorial.text = qsTr("Here you can see two lists: a list of files that this mod overwrites that are also "
+ "provided by other mods, and a list of files in this mod which are overwritten by "
+ "one or more other mods.")
waitForClick()
},
function() {
tutorial.text = qsTr("Please close the information dialog again.")
tutorial.text = qsTr("Please close the information dialog.")
waitForClick()
}

Expand Down
71 changes: 41 additions & 30 deletions src/tutorials/tutorial_firststeps_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ function getTutorialSteps()
{
return [
function() {
tutorial.text = qsTr("Welcome to the ModOrganizer Tutorial! This will guide you through the most common features of MO."
+ "\nPlease go along with the tutorial because some things can't be demonstrated if you skip something.")
tutorial.text = qsTr("Welcome to the Mod Organizer Tutorial! This will guide you through the most common "
+ "features of MO2.\n\n"
+ "It is highly recommended for first-time users to complete the tutorial from beginning "
+ "to end to properly demonstrate key components of the tool.")
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.")
tutorial.text = qsTr("Before we continue with the step-by-step tutorial, here are a few ways you can receive "
+ "help with Mod Organizer.")
waitForClick()
},

function() {
tutorial.text = qsTr("The highlighted button provides hints on solving potential problems MO recognized automatically.")
tutorial.text = qsTr("The highlighted button will display potential problems detected with your setup and may "
+ "suggest solutions. (Click it and then close the window to proceed.)")
if (tutorialControl.waitForAction("actionNotifications")) {
tutorial.text += qsTr("\nThere IS a notification now but you may want to hold off on clearing it until after completing the tutorial.")
tutorial.text += qsTr("\n\nIt appears you have one now, however you can hold off on clearing it until after "
+ "completing the tutorial.")
highlightAction("actionNotifications", true)
} else {
highlightAction("actionNotifications", false)
Expand All @@ -26,7 +31,8 @@ function getTutorialSteps()

function() {
console.log("next")
tutorial.text = qsTr("This button provides multiple sources of information and further tutorials.")
tutorial.text = qsTr("This button contains additional information about the application, links to other sources "
+ "of help, and further tutorials. (Open the menu to proceed.)")
if (tutorialControl.waitForAction("actionHelp")) {
highlightAction("actionHelp", true)
} else {
Expand All @@ -37,21 +43,23 @@ function getTutorialSteps()

function() {
unhighlight()
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")
tutorial.text = qsTr("Finally, there are tooltips and extra information available all across Mod Organizer. If "
+ "there is a control you don't understand, please try hovering over it for a short "
+ "description. Alternatively, you can use \"Help on UI\" from the Help menu to click on "
+ "some controls and get a comprehensive explanation.")
waitForClick()
},

function() {
tutorial.text = qsTr("This list displays all mods installed through MO. It also displays installed DLCs and some mods "
+ "installed outside MO but you have limited control over those in MO.")
tutorial.text = qsTr("This list displays all mods installed through MO2. It also displays installed DLCs and "
+ "any 'unmanaged' mods installed outside MO2. You have limited control over those.")
highlightItem("modList", false)
waitForClick()
},

function() {
tutorial.text = qsTr("Before we start installing mods, let's have a quick look at the settings.")
tutorial.text = qsTr("Before we start installing mods, let's have a quick look at the settings. (Open the "
+ "settings dialog to proceed via the highlighted button.)")
manager.activateTutorial("SettingsDialog", "tutorial_firststeps_settings.js")
if (tutorialControl.waitForAction("actionSettings")) {
highlightAction("actionSettings", true)
Expand All @@ -63,13 +71,13 @@ function getTutorialSteps()

function() {
unhighlight()
tutorial.text = qsTr("Now it's time to install a few mods!"
+ "Please go along with this because we need a few mods installed to demonstrate other features")
tutorial.text = qsTr("Now it's time to install a mod!\n\n"
+ "(This will be a requirement in order to demonstrate other features later.)")
waitForClick()
},

function() {
tutorial.text = qsTr("There are a few ways to get mods into ModOrganizer. "
tutorial.text = qsTr("There are a few ways to get mods into Mod Organizer. "
+ "If you associated MO with NXM links in the settings you can now use your regular browser to send downloads from Nexus to MO. "
+ "Click on \"Nexus\" to open nexus, find a mod and click the green download buttons on Nexus saying \"Download with Manager\".")
if (tutorialControl.waitForAction("actionNexus") &&
Expand All @@ -89,26 +97,28 @@ function getTutorialSteps()
},

function() {
tutorial.text = qsTr("Downloads will appear on the \"Downloads\"-tab here. You have to download and install at least one mod to proceed.")
tutorial.text = qsTr("Downloads will appear on the \"Downloads\" tab here. You have to download and install at "
+ "least one mod to proceed.")
organizer.modInstalled.connect(nextStep)
highlightItem("tabWidget", true)
},

function() {
unhighlight()
organizer.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.")
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() {
unhighlight()
tutorial.text = qsTr("Now you know all about downloading and installing mods but they are not enabled yet...")
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. "
tutorial.text = qsTr("Install a few more mods if you want, then enable them by checking them in the left pane. "
+ "Mods that aren't enabled have no effect on the game whatsoever. ")
highlightItem("modList", true)
modList.tutorialModlistUpdate.connect(nextStep)
Expand All @@ -122,9 +132,9 @@ function getTutorialSteps()
},

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 \"Plugins\"-tab to get a list of plugins.")
tutorial.text = qsTr("...but for some games they may contain plugins. These are files the game must load and "
+ "are required to change or add aspects of the game (new weapons, armors, quests, areas, ...).\n\n"
+ "Please open the \"Plugins\" tab to get a list of plugins.")
if (tutorialControl.waitForTabOpen("tabWidget", "espTab")) {
highlightItem("tabWidget", true)
} else {
Expand All @@ -133,13 +143,13 @@ function getTutorialSteps()
},

function() {
tutorial.text = qsTr("You will notice some plugins are grayed out. These are part of the main game and can't be "
tutorial.text = qsTr("You may 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. "
tutorial.text = qsTr("A single mod may contain zero, one, or multiple plugin files. Some or all may be optional. "
+ "If in doubt, please consult the documentation of the individual mod. "
+ "To do so, right-click the mod and select \"Information\".")
highlightItem("modList", true)
Expand All @@ -148,24 +158,25 @@ function getTutorialSteps()
},

function() {
tutorial.text = qsTr("Now you know how to download, install and enable mods.\n"
tutorial.text = qsTr("Now you know how to download, install, and enable mods.\n\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.")
tutorial.text = qsTr("This combobox lets you choose <i>what</i> to start. This is how you will launch the game "
+ "or any other tool which must access the game's mod directories. If a tool is not "
+ "listed here, you can also configure these options, 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.")
tutorial.text = qsTr("This completes the basic tutorial. Feel free to play the game and try out your new mods! "
+ "Once you have installed a larger number, you may want to continue with the tutorial "
+ "on conflict resolution.")
highlightItem("startButton", false)
waitForClick()
}
Expand Down
5 changes: 3 additions & 2 deletions src/tutorials/tutorial_firststeps_modinfo.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
function getTutorialSteps()
{
tutorialCanceller.visible = false
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. "
+"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.")
+"access to the mod page description, which can be refreshed directly from Nexus.")
waitForClick()
},
function() {
Expand Down
8 changes: 5 additions & 3 deletions src/tutorials/tutorial_firststeps_settings.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
function getTutorialSteps()
{
tutorialCanceller.visible = false
return [
function() {
highlightItem("tabWidget", true)
tutorial.text = qsTr("You can use your regular browser to download from Nexus.\nPlease open the \"Nexus\"-tab")
tutorial.text = qsTr("It is possible to download files directly from Nexus.\n\n"
+ "Please open the \"Nexus\" tab.")
tutorialControl.waitForTabOpen("tabWidget", "nexusTab")
},

function() {
highlightItem("associateButton", false)
tutorial.text = qsTr("Click this button so that \"DOWNLOAD WITH MANAGER\"-buttons "
+"are download with Mod Organizer.")
tutorial.text = qsTr("Clicking on this button should register Nexus \"Download with Manager\" buttons "
+"to download with Mod Organizer.")
waitForClick()
},

Expand Down
1 change: 1 addition & 0 deletions src/tutorials/tutorial_primer_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ function setupTooptips() {
}

function getTutorialSteps() {
tutorialCanceller.visible = false
return [
function() {
tutorial.text = qsTr("Click to quit")
Expand Down
Loading

0 comments on commit 523ea04

Please sign in to comment.