changeset 107:e4588b8a8ddc

Started on TabOptions
author Fox
date Sat, 08 Apr 2023 00:14:40 +0200
parents 9ece57b1895d
children 7852a62809ba
files src/junotu/OptionTree.java src/junotu/TabOptions.java src/junotu/TabSimpleSearch.java src/junotu/Window.java
diffstat 4 files changed, 281 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/junotu/OptionTree.java	Sat Apr 08 00:14:40 2023 +0200
@@ -0,0 +1,97 @@
+package junotu;
+
+import java.util.ArrayList;
+
+public class OptionTree {
+
+	public static class Option<T> {
+
+		public String tag;
+		public String brief;
+		public String hint;
+		public T default_value;
+
+		public Option()
+		{
+		}
+
+		public Option( String tag_, String brief_, String hint_, T default_ )
+		{
+			tag = tag_;
+			brief = brief_;
+			hint = hint_;
+			default_value = default_;
+		}
+
+	}
+
+	public static class OptionFolder extends Option<Void> {
+		public ArrayList<Option<?>> options = new ArrayList<Option<?>>();
+
+		public OptionFolder( String brief_, String hint_ )
+		{
+			brief = brief_;
+			hint = hint_;
+		}
+		
+		public <T extends Option> T add( T option )
+		{
+			options.add(option);
+			return option;
+		}
+
+	}
+
+	public static class OptionCategory extends Option<Void> {}
+
+	public static class OptionCheckbox extends Option<Boolean> {}
+	public static class OptionSlider extends Option<Float> {
+
+		public float minimum = 0.0f;
+		public float maximum = 1.0f;
+		
+		public OptionSlider( String tag_, String brief_, String hint_, float default_, float min, float max )
+		{
+			tag = tag_;
+			brief = brief_;
+			hint = hint_;
+			default_value = default_;
+			minimum = min;
+			maximum = max;
+		}
+		
+	}
+	
+	public static class OptionNumberCounter extends Option<Integer> {
+
+		public int minimum = 0;
+		public int maximum = 10;
+		public int step    = 1;
+		
+		public OptionNumberCounter( String tag_, String brief_, String hint_, int default_, int min, int max, int step_ )
+		{
+			tag = tag_;
+			brief = brief_;
+			hint = hint_;
+			default_value = default_;
+			minimum = min;
+			maximum = max;
+			step = step_;
+		}
+		
+	}
+
+	public static class OptionString extends Option<String> {}
+	
+	public static class OptionAction extends Option<Void> {
+		void onClick() {}
+	}
+
+	public OptionFolder root = new OptionFolder( "root", "Root of the options." );
+
+	public <T extends Option> T add( T option )
+	{
+		return root.<T>add(option);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/junotu/TabOptions.java	Sat Apr 08 00:14:40 2023 +0200
@@ -0,0 +1,170 @@
+package junotu;
+
+import java.util.Vector;
+
+import java.awt.Component;
+import javax.swing.JPanel;
+import javax.swing.Box;
+import javax.swing.JScrollPane;
+import javax.swing.JButton;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import javax.swing.BoxLayout;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import junotu.Window.TabInterface;
+import junotu.OptionTree;
+
+public class TabOptions extends JPanel implements ActionListener, TabInterface {
+
+	private static final String ACTION_PATH_BUTTON = "path_button";
+
+	private static class Option extends JPanel implements ActionListener {
+		TabOptions events;
+
+		@Override
+		public void actionPerformed( ActionEvent e )
+		{
+			if( events != null ) {
+				events.actionPerformed( new ActionEvent( this, e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers() ) );
+			}
+		}
+	}
+
+	private static class OptionFolder extends Option {
+	
+		OptionTree.OptionFolder folder;
+		
+		public OptionFolder( TabOptions events_, OptionTree.OptionFolder folder_ )
+		{
+			setLayout( new BoxLayout( this, BoxLayout.X_AXIS ) );
+			events = events_;
+			folder = folder_;
+
+			JButton button = new JButton( folder.brief );
+
+			this.add(button);
+
+			if( folder.hint.length() > 0 ) {
+				button.setToolTipText( folder.hint );
+			}
+
+			button.addActionListener(this);
+		}
+	}
+	private static class OptionCategory extends Option {}
+	private static class OptionCheckbox extends Option {}
+	private static class OptionSlider extends Option {}
+	private static class OptionNumberCounter extends Option {}
+	private static class OptionString extends Option {}
+	private static class OptionAction extends Option {}
+
+	static public final OptionTree OPTION_TREE;
+	static {
+		OPTION_TREE = new OptionTree();
+		OPTION_TREE.root = new OptionTree.OptionFolder( "JUnotu", "JUnotu options." );
+
+		OptionTree.OptionFolder f1 = OPTION_TREE.add( new OptionTree.OptionFolder( "1", "Folder one." ) );
+		OptionTree.OptionFolder f2 = OPTION_TREE.add( new OptionTree.OptionFolder( "2", "Folder two." ) );
+		OptionTree.OptionFolder f3 = OPTION_TREE.add( new OptionTree.OptionFolder( "3", "Folder three." ) );
+
+		f1.add( new OptionTree.OptionFolder( "1.1", "Folder one one." ) );
+		f1.add( new OptionTree.OptionFolder( "1.2", "Folder one two." ) );
+		f1.add( new OptionTree.OptionFolder( "1.3", "Folder one three." ) );
+		
+		f2.add( new OptionTree.OptionFolder( "2.1", "Folder two one." ) );
+		f2.add( new OptionTree.OptionFolder( "2.2", "Folder two two." ) );
+		f2.add( new OptionTree.OptionFolder( "2.3", "Folder two three." ) );
+		
+		f3.add( new OptionTree.OptionFolder( "3.1", "Folder three one." ) );
+		f3.add( new OptionTree.OptionFolder( "3.2", "Folder three two." ) );
+		f3.add( new OptionTree.OptionFolder( "3.3", "Folder three three." ) );
+	}
+
+	public Card card;
+	public Vector<OptionTree.OptionFolder> path = new Vector<OptionTree.OptionFolder>();
+
+	JPanel pathBox;
+	Box optionList;
+
+	public TabOptions()
+	{
+		setLayout( new BorderLayout() );
+		pathBox = new JPanel();
+		optionList = Box.createVerticalBox();
+		JScrollPane scroll = new JScrollPane(optionList);
+		JButton apply = new JButton("Apply");
+
+		pathBox.setLayout( new FlowLayout( FlowLayout.LEFT ) );
+
+		add( pathBox, BorderLayout.NORTH );
+		add( scroll, BorderLayout.CENTER );
+		add( apply, BorderLayout.SOUTH );
+
+		path.add( OPTION_TREE.root );
+
+		scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+		
+	}
+
+	@Override
+	public void onSwitchedTo()
+	{
+		generate();
+	}
+
+	public void generate()
+	{
+		optionList.removeAll();
+		pathBox.removeAll();
+		OptionTree.OptionFolder page = path.get( path.size()-1 );
+		for( int i = 0; i < page.options.size(); i++ ) {
+			OptionTree.Option<?> option = page.options.get(i);
+			if( option instanceof OptionTree.OptionFolder ) {
+				optionList.add( new OptionFolder( this, (OptionTree.OptionFolder)option ) );
+			} else {
+				System.out.print( "TabOptions, generate: Unknown option type '"+option.getClass().getName()+"', cannot create interface.\n" );
+			}
+		}
+		optionList.add( Box.createVerticalGlue() );
+		for( int i = 0; i < path.size(); i++ ) {
+			JButton button = new JButton( path.get(i).brief );
+			pathBox.add( button );
+			button.setActionCommand( ACTION_PATH_BUTTON );
+			button.addActionListener(this);
+		}
+		pathBox.add( Box.createHorizontalGlue() );
+		
+		revalidate();
+		repaint();
+	}
+
+	public void actionPerformed( ActionEvent e )
+	{
+		Object source = e.getSource();
+		String command = e.getActionCommand();
+
+		switch( command ) {
+			case ACTION_PATH_BUTTON: {
+				Component[] buttons = pathBox.getComponents();
+				for( int i = 0; i < buttons.length; i++ ) {
+					if( buttons[i] == source ) {
+						path.setSize( i+1 );
+						generate();
+						return;
+					}
+				}
+			}
+		}
+
+		if( source instanceof OptionFolder ) {
+			OptionFolder clicked = (OptionFolder)source;
+			path.add( clicked.folder );
+			generate();
+		}
+	}
+
+}
--- a/src/junotu/TabSimpleSearch.java	Thu Apr 06 13:06:40 2023 +0200
+++ b/src/junotu/TabSimpleSearch.java	Sat Apr 08 00:14:40 2023 +0200
@@ -46,6 +46,7 @@
 	private Box results;
 	private JScrollPane scroll;
 
+	private JMenuItem menu_options;
 	private JMenuItem menu_calendar;
 	private JMenuItem menu_resaveAll;
 
@@ -64,6 +65,7 @@
 		scroll = new JScrollPane( results );
 
 		menu = new JPopupMenu("Menu");
+		menu_options = menu.add("Options");
 		menu_calendar = menu.add("Calendar board");
 		menu_resaveAll = menu.add("Resave all cards (developer)");
 
@@ -87,6 +89,7 @@
 
 		create.addActionListener(this);
 		context.addActionListener(this);
+		menu_options.addActionListener(this);
 		menu_calendar.addActionListener(this);
 		menu_resaveAll.addActionListener(this);
 
@@ -119,6 +122,7 @@
 		field.setToolTipText("Search query.");
 		create.setToolTipText("Create new card. Shift-click to open it in a new window.");
 		context.setToolTipText("Bring up a menu with more actions.");
+		menu_options.setToolTipText("All "+Main.PROGRAM_NAME+" settings.");
 		menu_calendar.setToolTipText("Open calendar board.");
 		menu_resaveAll.setToolTipText("Resave all cards. Might be useful if you updated program version and database format changed.");
 
@@ -225,6 +229,9 @@
 			buttonClickedCreate( newWindow );
 		} else if( source == context ) {
 			menu.show( (Component)source, 0, 0 );
+		} else if( source == menu_options ) {
+			Window window = (Window)this.getTopLevelAncestor();
+			window.tabSwitch( Tab.OPTIONS );
 		} else if( source == menu_calendar ) {
 			Window window = (Window)this.getTopLevelAncestor();
 			window.tabSwitch( Tab.CALENDAR_BOARD );
--- a/src/junotu/Window.java	Thu Apr 06 13:06:40 2023 +0200
+++ b/src/junotu/Window.java	Sat Apr 08 00:14:40 2023 +0200
@@ -26,6 +26,7 @@
 import junotu.TabSimpleSearch;
 import junotu.TabBoard;
 import junotu.TabCalendarBoard;
+import junotu.TabOptions;
 
 public class Window extends JFrame implements ActionListener {
 
@@ -38,6 +39,7 @@
 		EDIT,
 		BOARD,
 		CALENDAR_BOARD,
+		OPTIONS,
 	};
 
 	private static final String[] TAB_NAMES = {
@@ -45,6 +47,7 @@
 		"Edit",
 		"Board",
 		"Calendar board",
+		"Options",
 	};
 
 	public final String KEY_ACTION_NEW_WINDOW = "new_window";
@@ -53,6 +56,7 @@
 	public TabEdit          tabEdit;
 	public TabBoard         tabBoard;
 	public TabCalendarBoard tabCalendarBoard;
+	public TabOptions       tabOptions;
 
 	private JPanel tabs;
 	private CardLayout tabsLayout;
@@ -124,16 +128,19 @@
 		tabEdit = new TabEdit();
 		tabBoard = new TabBoard();
 		tabCalendarBoard = new TabCalendarBoard();
+		tabOptions = new TabOptions();
 
 		this.add(tabs);
 		tabs.add(tabSearch);
 		tabs.add(tabEdit);
 		tabs.add(tabBoard);
 		tabs.add(tabCalendarBoard);
+		tabs.add(tabOptions);
 		tabsLayout.addLayoutComponent( tabSearch,        TAB_NAMES[Tab.SEARCH.ordinal()] );
 		tabsLayout.addLayoutComponent( tabEdit,          TAB_NAMES[Tab.EDIT.ordinal()] );
 		tabsLayout.addLayoutComponent( tabBoard,         TAB_NAMES[Tab.BOARD.ordinal()] );
 		tabsLayout.addLayoutComponent( tabCalendarBoard, TAB_NAMES[Tab.CALENDAR_BOARD.ordinal()] );
+		tabsLayout.addLayoutComponent( tabOptions,       TAB_NAMES[Tab.OPTIONS.ordinal()] );
 
 		tabs.registerKeyboardAction(
 			this,