introduction tour
30
datafiles-src/tours/convert-images.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# A script to batch-convert all source image files into suitable
|
||||
# slideset image files. It converts all *.png, *.jpg and *.xcf.gz
|
||||
# files into the suitably sized jpg images in the datafiles directory.
|
||||
#
|
||||
|
||||
DEST=../../datafiles/tours
|
||||
|
||||
CONVERSION="-background #ececec -flatten -geometry 600x400 -quality 85"
|
||||
|
||||
|
||||
# Convert all xcf files
|
||||
find -iname "*.xcf.gz" | grep -v MANUAL | while read FILE; do
|
||||
|
||||
echo Converting $FILE
|
||||
BASE="$(echo $FILE | sed 's/\.xcf\.gz$//')"
|
||||
xcf2png "$FILE" | convert $CONVERSION - $DEST/$BASE.jpg
|
||||
|
||||
done
|
||||
|
||||
# Convert all png and jpg files
|
||||
find -iname "*.png" -o -iname "*.jpg" | grep -v MANUAL | while read FILE; do
|
||||
|
||||
echo Converting $FILE
|
||||
BASE="$(echo $FILE | sed 's/\.png$//' | sed 's/\.jpg$//')"
|
||||
convert $CONVERSION $FILE $DEST/$BASE.jpg
|
||||
|
||||
done
|
BIN
datafiles-src/tours/introduction/advanced_features.xcf.gz
Normal file
BIN
datafiles-src/tours/introduction/flight_simulations.xcf.gz
Normal file
BIN
datafiles-src/tours/introduction/logo-MANUAL.xcf.gz
Normal file
BIN
datafiles-src/tours/introduction/main_window.png
Normal file
After Width: | Height: | Size: 112 KiB |
BIN
datafiles-src/tours/introduction/main_window_bottom.xcf.gz
Normal file
BIN
datafiles-src/tours/introduction/main_window_top.xcf.gz
Normal file
Before Width: | Height: | Size: 50 KiB |
BIN
datafiles/tours/introduction/advanced_features.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
datafiles/tours/introduction/flight_simulations.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
84
datafiles/tours/introduction/introduction.tour
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
Introduction
|
||||
|
||||
<p>This first tour provides a quick overview of OpenRocket screens and
|
||||
features.
|
||||
|
||||
|
||||
[logo.png]
|
||||
# TODO: Add "Welcome to OpenRocket" text to image.
|
||||
|
||||
<p><b>OpenRocket</b> is a versatile application for designing,
|
||||
simulating and optimizing model rockets. This first tour provides an
|
||||
overview of the OpenRocket screens and features.
|
||||
|
||||
<p>You can browse through the tour using the <b>Next</b> and
|
||||
<b>Previous</b> buttons, or using the <em>left</em> and <em>right
|
||||
arrows</em> on your keyboard.
|
||||
|
||||
|
||||
[none]
|
||||
|
||||
<p>This is the startup screen from which you can create a new rocket
|
||||
design or open existing designs.
|
||||
|
||||
<p>For this tour, let's open an example design called <em>A simple model
|
||||
rocket</em>.
|
||||
|
||||
|
||||
[main_window.jpg]
|
||||
|
||||
<p>This is the main screen of OpenRocket. It is divided horizontally
|
||||
into two parts: the rocket design / flight simulation section and the
|
||||
rocket design view.
|
||||
|
||||
|
||||
[main_window_top.jpg]
|
||||
|
||||
<p>On the top left is the component tree of the rocket design.
|
||||
It displays which components are attached to what components.
|
||||
|
||||
<p>Next to it are buttons which allow adding new components to the
|
||||
rocket.
|
||||
|
||||
|
||||
[main_window_bottom.jpg]
|
||||
|
||||
<p>The bottom half of the window contains a diagram of the current
|
||||
rocket design.
|
||||
|
||||
<p>The different viewing options are described in detail in the
|
||||
<a href="FIXME">Viewing options</a> tour.
|
||||
|
||||
|
||||
[flight_simulations.jpg]
|
||||
|
||||
<p>When you select the <b>Flight simulations</b> tab, the top part of
|
||||
the window changes to show the simulations that have been defined for
|
||||
the rocket.
|
||||
|
||||
<p>You can define various simulations with different motor
|
||||
configurations and differing launch conditions, such as wind and
|
||||
launch rod angle.
|
||||
|
||||
|
||||
[simulation_edit.png]
|
||||
|
||||
<p>By double-clicking on a simulation you open the <em>Simulation edit
|
||||
dialog</em>. On the first two tabs you can define simulation options,
|
||||
on the last two tabs you can plot or export the results.
|
||||
|
||||
<p>Simulating a rocket is described in detail in the
|
||||
<a href="FIXME">Simulating a flight</a> tour.
|
||||
|
||||
|
||||
[advanced_features.jpg]
|
||||
|
||||
<p>Other advanced features include component analysis and automatic
|
||||
design optimization, which are covered by separate tours.
|
||||
|
||||
<p>Next you can take a tour on <a href="FIXME">Creating a rocket
|
||||
design</a>, browse other tours or start experimenting with the
|
||||
software.
|
||||
|
||||
|
BIN
datafiles/tours/introduction/logo.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
datafiles/tours/introduction/main_window.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
datafiles/tours/introduction/main_window_bottom.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
datafiles/tours/introduction/main_window_top.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
datafiles/tours/introduction/simulation_edit.png
Normal file
After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 17 KiB |
@ -11,10 +11,14 @@ div.base {
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 5px;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0000dd;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italics;
|
||||
}
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
@ -11,7 +11,8 @@ This is the <i>description</i>.
|
||||
<p>This is the first slide — the left_design file.
|
||||
|
||||
<p>It's nifty. It can also contain <a href="foobar">links</a> (though they don't work yet).
|
||||
|
||||
<p>Tour2: <a href="test2/test2.tour">Test2</a>
|
||||
<p>Hyperlink: <a href="http://www.google.com">google</a>
|
||||
|
||||
|
||||
[main_window.png]
|
BIN
datafiles/tours/test2/left_design.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
datafiles/tours/test2/main_window.png
Normal file
After Width: | Height: | Size: 59 KiB |
@ -1,6 +1,9 @@
|
||||
|
||||
# This file lists all the available tours.
|
||||
|
||||
test.tour
|
||||
test2.tour
|
||||
introduction/introduction.tour
|
||||
|
||||
|
||||
test1/test.tour
|
||||
test2/test2.tour
|
||||
|
||||
|
@ -5,8 +5,6 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractListModel;
|
||||
@ -29,16 +27,14 @@ import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Named;
|
||||
|
||||
public class GuidedTourSelectionDialog extends JDialog {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private static final String TOURS_BASE_DIR = "datafiles/tours";
|
||||
|
||||
|
||||
|
||||
private final SlideSetManager slideSetManager;
|
||||
private final List<String> tourNames;
|
||||
|
||||
@ -52,21 +48,9 @@ public class GuidedTourSelectionDialog extends JDialog {
|
||||
public GuidedTourSelectionDialog(Window parent) {
|
||||
super(parent, trans.get("title"), ModalityType.MODELESS);
|
||||
|
||||
try {
|
||||
|
||||
slideSetManager = new SlideSetManager(TOURS_BASE_DIR);
|
||||
slideSetManager.load();
|
||||
|
||||
tourNames = slideSetManager.getSlideSetNames();
|
||||
if (tourNames.isEmpty()) {
|
||||
throw new FileNotFoundException("No tours found.");
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new BugException(e);
|
||||
}
|
||||
slideSetManager = SlideSetManager.getSlideSetManager();
|
||||
tourNames = slideSetManager.getSlideSetNames();
|
||||
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
panel.add(new StyledLabel(trans.get("lbl.selectTour"), Style.BOLD), "spanx, wrap rel");
|
||||
@ -87,10 +71,10 @@ public class GuidedTourSelectionDialog extends JDialog {
|
||||
}
|
||||
}
|
||||
});
|
||||
panel.add(new JScrollPane(tourList), "grow, gapright unrel, w 200lp, h 150lp");
|
||||
panel.add(new JScrollPane(tourList), "grow, gapright unrel, w 200lp, h 250lp");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Sub-panel containing description and start button
|
||||
JPanel sub = new JPanel(new MigLayout("fill, ins 0"));
|
||||
sub.add(new StyledLabel(trans.get("lbl.description"), -1), "wrap rel");
|
||||
@ -113,10 +97,10 @@ public class GuidedTourSelectionDialog extends JDialog {
|
||||
});
|
||||
sub.add(start, "growx");
|
||||
|
||||
panel.add(sub, "grow, wrap para, w 200lp, h 150lp");
|
||||
panel.add(sub, "grow, wrap para, w 350lp, h 250lp");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
JButton close = new JButton(trans.get("button.close"));
|
||||
close.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -128,6 +112,7 @@ public class GuidedTourSelectionDialog extends JDialog {
|
||||
|
||||
this.add(panel);
|
||||
GUIUtil.setDisposableDialogOptions(this, close);
|
||||
GUIUtil.rememberWindowPosition(this);
|
||||
tourList.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
@ -192,6 +177,6 @@ public class GuidedTourSelectionDialog extends JDialog {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import javax.imageio.ImageIO;
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class Slide {
|
||||
private static final String NO_IMAGE = "none";
|
||||
|
||||
private final String imageFile;
|
||||
private SoftReference<BufferedImage> imageReference = null;
|
||||
@ -21,16 +22,20 @@ public class Slide {
|
||||
private final String text;
|
||||
|
||||
|
||||
|
||||
|
||||
public Slide(String imageFile, String text) {
|
||||
this.imageFile = imageFile;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public BufferedImage getImage() {
|
||||
|
||||
if (imageFile.equals(NO_IMAGE)) {
|
||||
return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
|
||||
// Check the cache
|
||||
if (imageReference != null) {
|
||||
BufferedImage image = imageReference.get();
|
||||
@ -51,7 +56,7 @@ public class Slide {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private BufferedImage loadImage() {
|
||||
BufferedImage img;
|
||||
|
||||
|
@ -11,6 +11,8 @@ import java.util.Map;
|
||||
|
||||
import javax.swing.text.html.StyleSheet;
|
||||
|
||||
import net.sf.openrocket.util.BugException;
|
||||
|
||||
/**
|
||||
* A manager that loads a number of slide sets from a defined base directory
|
||||
* and provides access to them.
|
||||
@ -18,11 +20,14 @@ import javax.swing.text.html.StyleSheet;
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class SlideSetManager {
|
||||
private static final String TOURS_BASE_DIR = "datafiles/tours";
|
||||
|
||||
private static final String TOURS_FILE = "tours.txt";
|
||||
private static final String STYLESHEET_FILE = "style.css";
|
||||
|
||||
|
||||
private static SlideSetManager slideSetManager = null;
|
||||
|
||||
|
||||
private final String baseDir;
|
||||
private final Map<String, SlideSet> slideSets = new LinkedHashMap<String, SlideSet>();
|
||||
|
||||
@ -49,20 +54,24 @@ public class SlideSetManager {
|
||||
List<String> tours = loadTourList();
|
||||
StyleSheet styleSheet = loadStyleSheet();
|
||||
|
||||
for (String file : tours) {
|
||||
for (String fileAndDir : tours) {
|
||||
String base;
|
||||
String file;
|
||||
|
||||
String base = baseDir + file;
|
||||
int index = base.lastIndexOf('/');
|
||||
String fullFileAndDir = baseDir + fileAndDir;
|
||||
int index = fullFileAndDir.lastIndexOf('/');
|
||||
if (index >= 0) {
|
||||
base = base.substring(0, index);
|
||||
base = fullFileAndDir.substring(0, index);
|
||||
file = fullFileAndDir.substring(index + 1);
|
||||
} else {
|
||||
base = "";
|
||||
file = "";
|
||||
}
|
||||
|
||||
SlideSetLoader loader = new SlideSetLoader(base);
|
||||
SlideSet set = loader.load(file);
|
||||
set.setStyleSheet(styleSheet);
|
||||
slideSets.put(file, set);
|
||||
slideSets.put(fileAndDir, set);
|
||||
}
|
||||
|
||||
}
|
||||
@ -131,4 +140,26 @@ public class SlideSetManager {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a singleton implementation that has loaded the default tours.
|
||||
*/
|
||||
public static SlideSetManager getSlideSetManager() {
|
||||
if (slideSetManager == null) {
|
||||
try {
|
||||
SlideSetManager ssm = new SlideSetManager(TOURS_BASE_DIR);
|
||||
ssm.load();
|
||||
|
||||
if (ssm.getSlideSetNames().isEmpty()) {
|
||||
throw new FileNotFoundException("No tours found.");
|
||||
}
|
||||
|
||||
slideSetManager = ssm;
|
||||
} catch (IOException e) {
|
||||
throw new BugException(e);
|
||||
}
|
||||
}
|
||||
return slideSetManager;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,10 @@ import net.sf.openrocket.gui.components.ImageDisplayComponent;
|
||||
*/
|
||||
public class SlideShowComponent extends JSplitPane {
|
||||
|
||||
private final int WIDTH = 600;
|
||||
private final int HEIGHT_IMAGE = 400;
|
||||
private final int HEIGHT_TEXT = 100;
|
||||
|
||||
private final ImageDisplayComponent imageDisplay;
|
||||
private final JEditorPane textPane;
|
||||
|
||||
@ -27,21 +31,21 @@ public class SlideShowComponent extends JSplitPane {
|
||||
super(VERTICAL_SPLIT);
|
||||
|
||||
imageDisplay = new ImageDisplayComponent();
|
||||
imageDisplay.setPreferredSize(new Dimension(600, 350));
|
||||
imageDisplay.setPreferredSize(new Dimension(WIDTH, HEIGHT_IMAGE));
|
||||
this.setLeftComponent(imageDisplay);
|
||||
|
||||
textPane = new JEditorPane("text/html", "");
|
||||
textPane.setEditable(false);
|
||||
textPane.setPreferredSize(new Dimension(600, 100));
|
||||
textPane.setPreferredSize(new Dimension(WIDTH, HEIGHT_TEXT));
|
||||
|
||||
JScrollPane scrollPanel = new JScrollPane(textPane);
|
||||
this.setRightComponent(scrollPanel);
|
||||
|
||||
this.setResizeWeight(0.7);
|
||||
this.setResizeWeight(((double) HEIGHT_IMAGE) / (HEIGHT_IMAGE + HEIGHT_TEXT));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void setSlide(Slide slide) {
|
||||
this.imageDisplay.setImage(slide.getImage());
|
||||
this.textPane.setText(slide.getText());
|
||||
|
@ -3,24 +3,28 @@ package net.sf.openrocket.gui.help.tours;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Locale;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Chars;
|
||||
|
||||
public class SlideShowDialog extends JDialog {
|
||||
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private SlideShowComponent slideShowComponent;
|
||||
@ -38,35 +42,38 @@ public class SlideShowDialog extends JDialog {
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
slideShowComponent = new SlideShowComponent();
|
||||
slideShowComponent.addHyperlinkListener(new SlideShowLinkListener(parent));
|
||||
panel.add(slideShowComponent, "spanx, grow, wrap para");
|
||||
|
||||
|
||||
|
||||
JPanel sub = new JPanel(new MigLayout("ins 0, fill"));
|
||||
|
||||
prevButton = new JButton(Chars.LEFT_ARROW + " " + trans.get("btn.prev"));
|
||||
prevButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.user("Clicked previous button");
|
||||
setPosition(position - 1);
|
||||
}
|
||||
});
|
||||
sub.add(prevButton, "left");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
nextButton = new JButton(trans.get("btn.next") + " " + Chars.RIGHT_ARROW);
|
||||
nextButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.user("Clicked next button");
|
||||
setPosition(position + 1);
|
||||
}
|
||||
});
|
||||
sub.add(nextButton, "left, gapleft para");
|
||||
|
||||
|
||||
|
||||
sub.add(new JPanel(), "growx");
|
||||
|
||||
|
||||
|
||||
closeButton = new JButton(trans.get("button.close"));
|
||||
closeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -76,12 +83,16 @@ public class SlideShowDialog extends JDialog {
|
||||
});
|
||||
sub.add(closeButton, "right");
|
||||
|
||||
|
||||
|
||||
panel.add(sub, "growx");
|
||||
|
||||
this.add(panel);
|
||||
updateEnabled();
|
||||
addKeyActions();
|
||||
GUIUtil.setDisposableDialogOptions(this, nextButton);
|
||||
nextButton.grabFocus();
|
||||
GUIUtil.rememberWindowPosition(this);
|
||||
GUIUtil.rememberWindowSize(this);
|
||||
this.setAlwaysOnTop(true);
|
||||
}
|
||||
|
||||
@ -120,41 +131,43 @@ public class SlideShowDialog extends JDialog {
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Locale.setDefault(new Locale("de", "DE", ""));
|
||||
|
||||
SlideSetManager manager = new SlideSetManager("datafiles/tours");
|
||||
manager.load();
|
||||
|
||||
final SlideSet set = manager.getSlideSet("test.tour");
|
||||
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
|
||||
|
||||
|
||||
private void addKeyActions() {
|
||||
Action next = new AbstractAction() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
SlideShowDialog ssd = new SlideShowDialog(null);
|
||||
|
||||
ssd.slideShowComponent.addHyperlinkListener(new HyperlinkListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
System.out.println("Hyperlink event: " + e);
|
||||
System.out.println("Event type: " + e.getEventType());
|
||||
System.out.println("Description: " + e.getDescription());
|
||||
System.out.println("URL: " + e.getURL());
|
||||
System.out.println("Source element: " + e.getSourceElement());
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
ssd.setSize(500, 500);
|
||||
ssd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
ssd.setVisible(true);
|
||||
|
||||
ssd.setSlideSet(set, 0);
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
log.user("Key action for next slide");
|
||||
if (position < slideSet.getSlideCount() - 1) {
|
||||
setPosition(position + 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Action previous = new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
log.user("Key action for previous slide");
|
||||
if (position > 0) {
|
||||
setPosition(position - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
String nextKey = "slide:next";
|
||||
String prevKey = "slide:previous";
|
||||
|
||||
JRootPane root = this.getRootPane();
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), nextKey);
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0), nextKey);
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), prevKey);
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0), prevKey);
|
||||
|
||||
root.getActionMap().put(nextKey, next);
|
||||
root.getActionMap().put(prevKey, previous);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
package net.sf.openrocket.gui.help.tours;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Window;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkEvent.EventType;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
public class SlideShowLinkListener implements HyperlinkListener {
|
||||
|
||||
private final Window parent;
|
||||
|
||||
public SlideShowLinkListener(Window parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent event) {
|
||||
|
||||
if (event.getEventType() != EventType.ACTIVATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
URL url = event.getURL();
|
||||
if (url != null && (url.getProtocol().equalsIgnoreCase("http") || url.getProtocol().equals("https"))) {
|
||||
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(url.toURI());
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
String name = event.getDescription();
|
||||
try {
|
||||
SlideSet ss = SlideSetManager.getSlideSetManager().getSlideSet(name);
|
||||
|
||||
SlideShowDialog dialog = new SlideShowDialog(parent);
|
||||
dialog.setSlideSet(ss, 0);
|
||||
dialog.setVisible(true);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Application.getExceptionHandler().handleErrorCondition("Guided tour '" + name + "' not found.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -127,8 +127,8 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set suitable options for a single-use disposable dialog. This includes
|
||||
* setting ESC to close the dialog, adding the appropriate window icons and
|
||||
@ -153,7 +153,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add the correct action to close a JDialog when the ESC key is pressed.
|
||||
* The dialog is closed by sending is a WINDOW_CLOSING event.
|
||||
@ -192,7 +192,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Change the behavior of a component so that TAB and Shift-TAB cycles the focus of
|
||||
* the components. This is necessary for e.g. <code>JTextArea</code>.
|
||||
@ -207,7 +207,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the OpenRocket icons to the window icons.
|
||||
*
|
||||
@ -236,7 +236,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the best available look-and-feel into use.
|
||||
*/
|
||||
@ -294,7 +294,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Automatically remember the size of a window. This stores the window size in the user
|
||||
* preferences when resizing/maximizing the window and sets the state on the first call.
|
||||
@ -377,7 +377,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Traverses recursively the component tree, and sets all applicable component
|
||||
* models to null, so as to remove the listener connections. After calling this
|
||||
@ -519,7 +519,7 @@ public class GUIUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A mouse listener that toggles the state of a boolean value in a table model
|
||||
* when clicked on another column of the table.
|
||||
|