Skip to content

Commit 3cbcf62

Browse files
committed
Continued work on tutorial
1 parent 4c98c7e commit 3cbcf62

File tree

8 files changed

+137
-58
lines changed

8 files changed

+137
-58
lines changed

src/ngscopeclient/MainWindow.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,12 @@ void MainWindow::ToolbarButtons()
10351035

10361036
//Trigger button group
10371037
if(ImGui::ImageButton("trigger-start", GetTexture("trigger-start"), buttonsize))
1038+
{
10381039
m_session.ArmTrigger(TriggerGroup::TRIGGER_TYPE_NORMAL);
1040+
1041+
if(m_tutorialDialog && (m_tutorialDialog->GetCurrentStep() == TutorialWizard::TUTORIAL_03_ACQUIRE) )
1042+
m_tutorialDialog->AdvanceToNextStep();
1043+
}
10391044
Dialog::Tooltip("Arm the trigger in normal mode");
10401045
if(multigroup)
10411046
{
@@ -1051,8 +1056,7 @@ void MainWindow::ToolbarButtons()
10511056
ImVec2 anchorPos(
10521057
buttonEndPos.x - ImGui::GetFontSize(),
10531058
buttonStartPos.y + 2*ImGui::GetFontSize());
1054-
m_tutorialDialog->DrawSpeechBubble(anchorPos, ImGuiDir_Up, " Arm the trigger");
1055-
//FIXME better handling of going off edge
1059+
m_tutorialDialog->DrawSpeechBubble(anchorPos, ImGuiDir_Up, "Arm the trigger");
10561060
}
10571061

10581062
if(ImGui::ImageButton("trigger-single", GetTexture("trigger-single"), buttonsize))

src/ngscopeclient/TutorialWizard.cpp

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ TutorialWizard::TutorialWizard(Session* session, MainWindow* parent)
5353
m_markdownText.push_back(ReadDataFile("md/tutorial_01_addinstrument.md"));
5454
m_markdownText.push_back(ReadDataFile("md/tutorial_02_connect.md"));
5555
m_markdownText.push_back(ReadDataFile("md/tutorial_03_acquire.md"));
56+
m_markdownText.push_back(ReadDataFile("md/tutorial_04_scrollzoom.md"));
57+
58+
m_markdownText.push_back(ReadDataFile("md/tutorial_99_final.md"));
59+
60+
//DEBUG: autiomatically jump ahead a bit
61+
m_step = TUTORIAL_03_ACQUIRE;
5662
}
5763

5864
TutorialWizard::~TutorialWizard()
@@ -93,16 +99,18 @@ bool TutorialWizard::DoRender()
9399

94100
ImGui::Separator();
95101

96-
//move slightly right of centerline
97-
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x / 2);
102+
//move near the right edge
103+
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.8);
98104

99105
//Show back button unless at first step
106+
//TODO: is this necessary? will it break things? For now turn it off
107+
/*
100108
ImGui::BeginDisabled(m_step == TUTORIAL_00_INTRO);
101109
if(ImGui::Button("<< Back"))
102110
m_step --;
103111
ImGui::EndDisabled();
104-
105112
ImGui::SameLine();
113+
*/
106114

107115
//Show forward button
108116
//If last step, close dialog when pressed
@@ -114,26 +122,32 @@ bool TutorialWizard::DoRender()
114122
}
115123
else
116124
{
117-
//Enable the continue button as needed
118125
ImGui::BeginDisabled(!m_continueEnabled);
119-
120-
//By default, continue is disabled when we move to the next step
121-
if(ImGui::Button("Continue >>"))
122-
{
123-
m_step ++;
124-
m_continueEnabled = false;
125-
}
126-
126+
if(ImGui::Button("Continue >>"))
127+
AdvanceToNextStep();
127128
ImGui::EndDisabled();
128129
}
129130

130-
//If this is the first step, show the first bubble
131-
if(m_step == TUTORIAL_00_INTRO)
131+
//Show hints on continue button for some steps
132+
if(m_continueEnabled)
132133
{
133134
ImVec2 anchorPos(
134135
buttonStartPos.x + 2*ImGui::GetFontSize(),
135136
buttonStartPos.y + 2*ImGui::GetFontSize());
136-
DrawSpeechBubble(anchorPos, ImGuiDir_Up, "Begin the tutorial");
137+
switch(m_step)
138+
{
139+
case TUTORIAL_00_INTRO:
140+
DrawSpeechBubble(anchorPos, ImGuiDir_Up, "Begin the tutorial");
141+
break;
142+
143+
case TUTORIAL_04_SCROLLZOOM:
144+
DrawSpeechBubble(anchorPos, ImGuiDir_Up, "Continue when you are comfortable zooming the plot");
145+
break;
146+
147+
//show nothing otherwise
148+
default:
149+
break;
150+
}
137151
}
138152

139153
return true;
@@ -144,30 +158,52 @@ bool TutorialWizard::DoRender()
144158

145159
void TutorialWizard::DrawSpeechBubble(
146160
ImVec2 anchorPos,
147-
ImGuiDir dirTip,
148-
const string& str)
161+
[[maybe_unused]] ImGuiDir dirTip,
162+
string str)
149163
{
150164
auto& prefs = m_session->GetPreferences();
151165
auto outlineColor = prefs.GetColor("Appearance.Help.bubble_outline_color");
152166
auto fillColor = prefs.GetColor("Appearance.Help.bubble_fill_color");
153167
auto list = ImGui::GetForegroundDrawList();
154168

155169
auto textsize = ImGui::CalcTextSize(str.c_str(), nullptr);
156-
157-
//Anchor position is the tip of the speech bubble, centered on the menu
158170
auto size = ImGui::GetFontSize();
159-
float tailLength = size;
171+
172+
//Default is for the arrow to be 1/4 of the way across
173+
auto leftOverhang = textsize.x / 4;
160174
float radius = 0.5 * size;
175+
176+
//Update overhang if the button would go off the start of the window
177+
//For now, we only care about the left side
178+
auto viewport = ImGui::GetWindowViewport();
179+
auto wpos = viewport->Pos;
180+
float farleft = anchorPos.x - (leftOverhang + radius);
181+
float offLeftEdge = farleft - wpos.x;
182+
if(offLeftEdge < 0)
183+
{
184+
//for now just clamp the anchor
185+
//but this breaks things we can't make it too small
186+
//anchorPos.x += fabs(offLeftEdge) + size;
187+
leftOverhang = 2*size;
188+
189+
//Make the text a bit wider and recalculate the size
190+
//Quick hack, but it keeps it visible!
191+
str = " " + str;
192+
textsize = ImGui::CalcTextSize(str.c_str(), nullptr);
193+
}
194+
195+
//Anchor position is the tip of the speech bubble
196+
float tailLength = size;
161197
ImVec2 textPos(
162-
anchorPos.x - textsize.x/4,
198+
anchorPos.x - leftOverhang,
163199
anchorPos.y + tailLength + radius);
164200

165201
//Fill
166-
MakePathSpeechBubble(list, dirTip, anchorPos, textsize, tailLength, radius);
202+
MakePathSpeechBubble(list, dirTip, anchorPos, textsize, tailLength, radius, leftOverhang);
167203
list->PathFillConcave(fillColor);
168204

169205
//Outline
170-
MakePathSpeechBubble(list, dirTip, anchorPos, textsize, tailLength, radius);
206+
MakePathSpeechBubble(list, dirTip, anchorPos, textsize, tailLength, radius, leftOverhang);
171207
list->PathStroke(outlineColor, 0, 0.25 * size);
172208

173209
//Text
@@ -181,24 +217,11 @@ void TutorialWizard::MakePathSpeechBubble(
181217
ImVec2 anchorPos,
182218
ImVec2 textsize,
183219
float tailLength,
184-
float radius)
220+
float radius,
221+
float leftOverhang)
185222
{
186223
auto size = ImGui::GetFontSize();
187224
auto tailWidth = size;
188-
189-
//Default is for the arrow to be 1/4 of the way across
190-
auto leftOverhang = textsize.x / 4;
191-
192-
//Update overhang if the button would go off the start of the window
193-
auto wpos = ImGui::GetWindowPos();
194-
float minleft = wpos.x;
195-
float farleft = anchorPos.x - (leftOverhang + radius);
196-
float offLeftEdge = farleft - minleft;
197-
if(offLeftEdge < 0)
198-
{
199-
//leftOverhang = 0.5*size;
200-
}
201-
202225
auto rightOverhang = textsize.x - leftOverhang;
203226

204227
//ImGui wants clockwise winding. Starting from the tip of the speech bubble go down, then across

src/ngscopeclient/TutorialWizard.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,34 +51,49 @@ class TutorialWizard : public Dialog
5151
TUTORIAL_00_INTRO,
5252
TUTORIAL_01_ADDINSTRUMENT,
5353
TUTORIAL_02_CONNECT,
54-
TUTORIAL_03_ACQUIRE
54+
TUTORIAL_03_ACQUIRE,
55+
TUTORIAL_04_SCROLLZOOM,
56+
57+
TUTORIAL_99_FINAL
5558
};
5659

5760
TutorialStep GetCurrentStep()
5861
{ return static_cast<TutorialStep>(m_step); }
5962

6063
///@brief Move the tutorial to the next step
6164
void AdvanceToNextStep()
62-
{ m_step ++; }
65+
{
66+
m_step ++;
67+
m_continueEnabled = false;
68+
}
69+
70+
///@brief Enable the next step but do not advance to it
71+
void EnableNextStep()
72+
{ m_continueEnabled = true; }
73+
74+
void DrawSpeechBubble(
75+
ImVec2 anchorPos,
76+
ImGuiDir dirTip,
77+
std::string str);
78+
79+
protected:
6380

6481
void MakePathSpeechBubble(
6582
ImDrawList* list,
6683
ImGuiDir dirTip,
6784
ImVec2 anchorPos,
6885
ImVec2 textsize,
6986
float tailLength,
70-
float radius);
87+
float radius,
88+
float leftOverhang);
7189

72-
void DrawSpeechBubble(
73-
ImVec2 anchorPos,
74-
ImGuiDir dirTip,
75-
const std::string& str);
76-
77-
protected:
90+
///@brief Text for each tutorial page
7891
std::vector<std::string> m_markdownText;
7992

93+
///@brief Current step of the tutorial
8094
size_t m_step;
8195

96+
///@brief True if the "continue" button is active
8297
bool m_continueEnabled;
8398
};
8499

src/ngscopeclient/WaveformArea.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,14 +4273,32 @@ void WaveformArea::OnMouseWheelPlotArea(float delta, float delta_h)
42734273

42744274
int64_t target = m_group->XPositionToXAxisUnits(ImGui::GetIO().MousePos.x);
42754275

4276-
//Zoom in
4277-
if(delta > 0)
4278-
m_group->OnZoomInHorizontal(target, pow(1.5, delta));
4279-
else if (delta < 0)
4280-
m_group->OnZoomOutHorizontal(target, pow(1.5, -delta));
4276+
//If we have both X and Y deltas, use the larger one and ignore incidental movement in the other axis
4277+
if(fabs(delta) > fabs(delta_h) )
4278+
{
4279+
//Zoom in
4280+
if(delta > 0)
4281+
{
4282+
m_group->OnZoomInHorizontal(target, pow(1.5, delta));
4283+
4284+
//If in the tutorial, ungate the wizard
4285+
auto tutorial = m_parent->GetTutorialWizard();
4286+
if(tutorial && (tutorial->GetCurrentStep() == TutorialWizard::TUTORIAL_04_SCROLLZOOM) )
4287+
tutorial->EnableNextStep();
4288+
}
4289+
else if (delta < 0)
4290+
{
4291+
m_group->OnZoomOutHorizontal(target, pow(1.5, -delta));
4292+
4293+
//If in the tutorial, ungate the wizard
4294+
auto tutorial = m_parent->GetTutorialWizard();
4295+
if(tutorial && (tutorial->GetCurrentStep() == TutorialWizard::TUTORIAL_04_SCROLLZOOM) )
4296+
tutorial->EnableNextStep();
4297+
}
4298+
}
42814299

42824300
//Pan horizontally
4283-
if (delta_h != 0)
4301+
else if (delta_h != 0)
42844302
m_group->OnPanHorizontal(delta_h);
42854303
}
42864304

src/ngscopeclient/WaveformGroup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,11 @@ void WaveformGroup::OnMouseWheel(float delta)
11951195
OnZoomInHorizontal(target, pow(1.5, delta));
11961196
else
11971197
OnZoomOutHorizontal(target, pow(1.5, -delta));
1198+
1199+
//If in the tutorial, ungate the wizard
1200+
auto tutorial = m_parent->GetTutorialWizard();
1201+
if(tutorial && (tutorial->GetCurrentStep() == TutorialWizard::TUTORIAL_04_SCROLLZOOM) )
1202+
tutorial->EnableNextStep();
11981203
}
11991204

12001205
/**

src/ngscopeclient/md/tutorial_00_intro.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
Thanks for trying ngscopeclient! If this is your first time using the tool, we suggest you go through this tutorial to learn your way around.
44

5-
The tutorial will only be automatically displayed once. If you wish to return to the tutorial at any point, simply select "Tutorial" from the Help menu.
5+
You can drag this tutorial window by the title bar to reposition it, or dock it by dragging it to the edge of the window, as needed.
66

7-
You can drag this tutorial window by the title bar to reposition it, or dock it by dragging it to the edge of the window, as needed. To end the tutorial at any time, just press the close button in the title bar of this window.
7+
The tutorial will only be automatically displayed once. To end the tutorial at any time, just press the close button in the title bar of this window. If you wish to return to the tutorial at any point, simply select "Tutorial" from the Help menu.
88

9-
Press the "Continue" button to begin the tutorial.
9+
Press the "Continue" button to begin the tutorial. We suggest maximizing the application so you can see the entire user interface without the tutorial obscuring your view.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Horizontal Zoom
2+
3+
In conventional digital oscilloscopes, the display zoom setting and the sample rate / record length are locked so that changing one changes the other.
4+
5+
Since ngscopeclient allows you to have many views displaying the same waveform data, the horizontal zoom on a plot is independent of the timebase settings. The default record length for the demo scope is 1M samples which is much longer than the visible area of the plot.
6+
7+
Try using your mouse wheel (or touchpad vertical scroll axis) over the timeline or plot to zoom in and out. Zoom centers on the mouse position, so you can focus on different parts of the waveform.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Done
2+
3+
You've completed the tutorial! We hope you enjoy using ngscopeclient.
4+
5+
This tutorial has only scratched the surface of the feature set. Please refer to the PDF or HTML versions of the user manual for a more complete reference.
6+
7+
If you have questions, comments, or problems please reach out via the IRC/Discord channels or file a GitHub ticket.

0 commit comments

Comments
 (0)