Skip to content

Commit

Permalink
a major ux feature - all actions can be accessed now from menu bar
Browse files Browse the repository at this point in the history
  • Loading branch information
klesun committed Jul 5, 2015
1 parent bc220c3 commit 4520052
Show file tree
Hide file tree
Showing 24 changed files with 324 additions and 267 deletions.
4 changes: 1 addition & 3 deletions src/Gui/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ public Settings(Storyspace storyspace) {
public void setDefaultChannel(int value) { this.defaultChannel = value; }
public int getDefaultChannel() { return this.defaultChannel; }

public ActionResult scale(int sign) {
public void scale(int sign) {
this.scaleKoefficient = sign == 1 ? -1 : -3;
storyspace.getImageStorage().refreshImageSizes();

storyspace.getChildScrollList().stream()
.filter(s -> s.content instanceof StaffPanel)
.forEach(s -> ((StaffPanel)s.content).surfaceCompletelyChanged());

return new ActionResult("defaultly passed to parent");
}

public int getStepWidth() { return getNotaWidth(); } // nota image width (the one OS would display when you click on fil->properties)
Expand Down
43 changes: 43 additions & 0 deletions src/Main/MajesticListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package Main;

import Stuff.Midi.DeviceEbun;
import sun.awt.WindowClosingListener;

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class MajesticListener implements WindowListener {
@Override
public void windowOpened(WindowEvent e) {

}

@Override
public void windowClosing(WindowEvent e) {
DeviceEbun.closeMidiDevices();
}

@Override
public void windowClosed(WindowEvent e) {
}

@Override
public void windowIconified(WindowEvent e) {

}

@Override
public void windowDeiconified(WindowEvent e) {

}

@Override
public void windowActivated(WindowEvent e) {

}

@Override
public void windowDeactivated(WindowEvent e) {

}
}
67 changes: 52 additions & 15 deletions src/Main/MajesticWindow.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package Main;

import Gui.Constants;
import Model.ActionFactory;
import Model.Combo;
import Model.IComponentModel;
import Model.*;
import Storyspace.Staff.StaffPanel;
import Storyspace.Storyspace;
import Stuff.OverridingDefaultClasses.TruMenuItem;
import Stuff.Tools.Logger;

import javax.swing.*;
import javax.swing.Action;

import java.awt.*;
import java.util.Map;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;

public class MajesticWindow extends JFrame {

Expand All @@ -21,6 +25,8 @@ public class MajesticWindow extends JFrame {
public JPanel cards = new JPanel();
private JMenuBar menuBar;

private Component lastFocusedBeforeMenu = null;

public enum cardEnum {
CARDS_STORYSPACE,
CARDS_TERMINAL,
Expand All @@ -31,8 +37,9 @@ public enum cardEnum {

public MajesticWindow() {
super("Да будет такая музыка!"); //Заголовок окна
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setSize(XP_MINWIDTH, XP_MINHEIGHT);
this.addWindowListener(new MajesticListener());

// TODO: maybe just make window have CardLayout ? why having leak container ????
cards.setLayout(new CardLayout());
Expand All @@ -48,11 +55,8 @@ public MajesticWindow() {
// this method should be called only once
public void init() {
cards.add(storyspace = new Storyspace(this), cardEnum.CARDS_STORYSPACE.name());

// addMenuBar();

addMenuBar();
switchTo(cardEnum.CARDS_STORYSPACE);

// for user-friendship there will be one initial staff
storyspace.addMusicBlock().getScroll().switchFullscreen();

Expand All @@ -62,23 +66,40 @@ private void addMenuBar() {
this.menuBar = new JMenuBar();
addMenuItems(new Storyspace(this));
setJMenuBar(menuBar);
getRootPane().addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
lastFocusedBeforeMenu = e.getOppositeComponent();
}
});
}

private void addMenuItems(IComponentModel fakeModelForClassMethods) {

JMenu modelMenu = new JMenu(fakeModelForClassMethods.getClass().getSimpleName());

for (Map.Entry<Combo, ActionFactory> entry: fakeModelForClassMethods.getHandler().getActionMap().entrySet()) {
LinkedHashMap<Combo, ContextAction> actionMap = fakeModelForClassMethods.getHandler().getStaticActionMap();
for (Combo key: actionMap.keySet()) {
ContextAction action = actionMap.get(key);

if (entry.getValue().omitMenuBar()) {
if (action.omitMenuBar()) {
continue;
}

JMenuItem eMenuItem = new JMenuItem("Do Action: " + entry.getKey().toString());
eMenuItem.setFont(Constants.PROJECT_FONT);
eMenuItem.setMnemonic(entry.getKey().getKeyCode());
String caption = action.getCaption() != null ? action.getCaption() : "Do Action:";
JMenuItem eMenuItem = new TruMenuItem(caption);
// eMenuItem.setFont(Constants.PROJECT_FONT);
eMenuItem.setToolTipText("No description");
eMenuItem.addActionListener(event -> entry.getValue().createAction().doDo());
eMenuItem.setAccelerator(key.toKeystroke());

eMenuItem.addActionListener(event -> {
Class<? extends IComponentModel> cls = fakeModelForClassMethods.getClass();
IComponentModel context = findeFocusedByClass(cls);
if (context != null) {
action.redo(context);
} else {
Logger.warning("Cant perform action, " + cls.getSimpleName() + " class instance not focused!");
}
});

modelMenu.add(eMenuItem);
}
Expand All @@ -89,6 +110,22 @@ private void addMenuItems(IComponentModel fakeModelForClassMethods) {
}
}

private IComponentModel findeFocusedByClass(Class<? extends IComponentModel> cls) {
if (cls == Storyspace.class) {
return storyspace;
} else {
IComponentModel result = storyspace.getFocusedChild(lastFocusedBeforeMenu);
while (result != null) {
if (result.getClass() == cls) {
break;
} else {
result = result.getFocusedChild();
}
}
return result;
}
}

// the Great idea behind this is to refresh menu bar each time we change focus
// i.e. when we're pointing Nota we have Menus: [Storyspace, Scroll, Staff, Accord, Nota], when Paragraph - [Storyspace, Scroll, Article, Paragraph] etc
public void updateMenuBar() {
Expand Down
9 changes: 6 additions & 3 deletions src/Model/AbstractHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

abstract public class AbstractHandler implements KeyListener, MouseListener, MouseMotionListener {
Expand Down Expand Up @@ -64,6 +62,11 @@ public AbstractHandler(IComponentModel context) {

// override me, please!
protected void initActionMap() {}
// override me, please!
public LinkedHashMap<Combo, ContextAction> getStaticActionMap() {
return new LinkedHashMap<>();
}

// implemented methods
final public void keyPressed(KeyEvent e) {
getRootHandler().handleKey(new Combo(e));
Expand Down
13 changes: 1 addition & 12 deletions src/Model/AbstractModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,9 @@ public AbstractModel(IComponentModel parent) { // TODO: i'm not sure, that paren

@Override
final public Helper getModelHelper() { return h; }
public IComponentModel getModelParent() { return this.parent; }

public List<String> getFieldList() {
return getModelHelper().getFieldStorage().stream().map(f -> f.getName()).collect(Collectors.toList());
}

public AbstractModel reconstructFromJson(JSONObject jsObject) throws JSONException { return (AbstractModel)h.reconstructFromJson(jsObject); }

public void getJsonRepresentation(JSONObject dict) {
h.getJsonRepresentation(dict);
}

final public JSONObject getJsonRepresentation() { return Helper.getJsonRepresentation(this); }

// field getters

public IComponentModel getModelParent() { return this.parent; }
}
18 changes: 7 additions & 11 deletions src/Model/Combo.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package Model;

import Stuff.OverridingDefaultClasses.TruHashMap;
import Stuff.OverridingDefaultClasses.TruMap;
import Stuff.Tools.Logger;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import javafx.scene.input.KeyCode;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

public class Combo {
Expand All @@ -30,10 +27,6 @@ public Combo(int mod, int keyCode) {
this.keyCode = keyCode;
}

public static Combo makeFake() {
return new Combo(0,0);
}

public Combo changeSign() {
return new Combo(this.mod, anti(this.keyCode));
}
Expand Down Expand Up @@ -119,14 +112,17 @@ public String toString() {
return (this.mod > 0 ? this.getModName() + "+" : "") + this.getKeyName();
}

public KeyStroke toKeystroke() {
return KeyStroke.getKeyStroke(getKeyCode(), mod);
}

private String getModName() {
Map<Integer, String> modMap = new TruHashMap<>().p(KeyEvent.SHIFT_MASK, "Shift").p(KeyEvent.CTRL_MASK, "Ctrl").p(KeyEvent.ALT_MASK, "Alt");
Map<Integer, String> modMap = new TruMap<>().p(KeyEvent.SHIFT_MASK, "Shift").p(KeyEvent.CTRL_MASK, "Ctrl").p(KeyEvent.ALT_MASK, "Alt");
return modMap.get(this.mod);
}

private String getKeyName() {
return Character.toString((char)getKeyCode());
// return Character.getName(getKeyCode());
}

@Override
Expand Down
23 changes: 21 additions & 2 deletions src/Model/ContextAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import java.util.function.Consumer;
import java.util.function.Function;

public class ContextAction<C extends IComponentModel> {
public class ContextAction<C> {


private Boolean isDone = false;
private String name = "Anonymous";
private String caption = null;
private String description = "No description";
private Boolean omitMenuBar = false;

private Function<C, ActionResult> redo;
private Runnable undo = null;
Expand All @@ -20,6 +21,15 @@ public ContextAction<C> setRedo(Function<C, ActionResult> lambda) {
return this;
}

public ContextAction<C> setOmitMenuBar(Boolean value) {
this.omitMenuBar = value;
return this;
}

public Boolean omitMenuBar() {
return this.omitMenuBar;
}

public ContextAction<C> setRedo(Consumer<C> lambda) {
return setRedo(context -> {
lambda.accept(context);
Expand All @@ -32,6 +42,15 @@ public ContextAction<C> setUndo(Runnable lambda) {
return this;
}

public ContextAction<C> setCaption(String caption) {
this.caption = caption;
return this;
}

public String getCaption() {
return this.caption;
}

public ActionResult redo(C context) {
return this.redo.apply(context);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Model/Field/Field.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package Model.Field;

import Model.IModel;
import Stuff.OverridingDefaultClasses.TruHashMap;
import Stuff.OverridingDefaultClasses.TruMap;
import Stuff.Tools.Logger;
import org.apache.commons.math3.fraction.Fraction;
import org.apache.commons.math3.fraction.FractionFormat;
Expand Down Expand Up @@ -112,7 +112,7 @@ public Field setValueFromString(String str) {
}

private static Map<Class, Function<String, Object>> getParserMap() {
TruHashMap<Class, Function<String, Object>> map = new TruHashMap<>();
TruMap<Class, Function<String, Object>> map = new TruMap<>();
map.p(Integer.class, Integer::parseInt)
.p(Boolean.class, Boolean::parseBoolean)
.p(Fraction.class, new FractionFormat()::parse)
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Helper.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public JSONObject getJsonRepresentation() {

public void getJsonRepresentation(JSONObject dict) {
for (Field field : fieldStorage) {
if (field.get().getClass() != Boolean.class || field != field.defaultValue) { // Issue[69]
if (field.get().getClass() != Boolean.class || field.get() != field.defaultValue) { // Issue[69]
dict.put(field.getName(), field.getJsonValue());
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/Model/IModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@
import org.json.JSONObject;

public interface IModel {

IComponentModel getModelParent();
Helper getModelHelper();

void getJsonRepresentation(JSONObject dict);
IModel reconstructFromJson(JSONObject jsObject) throws JSONException;
default void getJsonRepresentation(JSONObject dict) {
getModelHelper().getJsonRepresentation(dict);
}
default JSONObject getJsonRepresentation() {
return Helper.getJsonRepresentation(this);
}
default IModel reconstructFromJson(JSONObject jsObject) throws JSONException {
return getModelHelper().reconstructFromJson(jsObject);
}

default int limit(int value, int min, int max) { return Math.min(Math.max(value, min), max); }
default Fraction limit(Fraction value, Fraction min, Fraction max) {
Expand Down
Loading

0 comments on commit 4520052

Please sign in to comment.