Skip to content

Commit

Permalink
v0.1.27
Browse files Browse the repository at this point in the history
- Added package `msmEditingTools` with class `MsmEditingTools` to create context menu popups when right-clicking the MSM tree.
- Right now there is only one such context menu for the MSM root node that offers to apply every `sequencingMap` to the affected MSM and MPM maps.
  - The `sequencingMaps` are then deleted from the MSM as they are no longer valid.
  - It is recommended to operate this functionality BEFORE making any entries in the graphical score as they will get lost in the process.
  • Loading branch information
axelberndt committed Nov 20, 2024
1 parent 36ebed9 commit f36c396
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 47 deletions.
7 changes: 7 additions & 0 deletions history.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
### Version History


#### v0.1.27
- Added package `msmEditingTools` with class `MsmEditingTools` to create context menu popups when right-clicking the MSM tree.
- Right now there is only one such context menu for the MSM root node that offers to apply every `sequencingMap` to the affected MSM and MPM maps.
- The `sequencingMaps` are then deleted from the MSM as they are no longer valid.
- It is recommended to operate this functionality BEFORE making any entries in the graphical score as they will get lost in the process.


#### v0.1.26
- Dependency updates
- WebLaF Core v1.2.13 to v1.2.14
Expand Down
2 changes: 1 addition & 1 deletion src/mpmToolbox/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* @author Axel Berndt
*/
public class Main {
public static final String version = "0.1.26";
public static final String version = "0.1.27";

public static void main(String[] args) {
// read the application settings from file
Expand Down
18 changes: 0 additions & 18 deletions src/mpmToolbox/gui/mpmEditingTools/MpmEditingTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import mpmToolbox.gui.mpmTree.MpmStyleCollection;
import mpmToolbox.gui.mpmTree.MpmTree;
import mpmToolbox.gui.mpmTree.MpmTreeNode;
import mpmToolbox.gui.msmTree.MsmTree;
import mpmToolbox.gui.msmTree.MsmTreeNode;
import mpmToolbox.projectData.score.Score;
import mpmToolbox.projectData.score.ScoreNode;
import mpmToolbox.projectData.score.ScorePage;
Expand Down Expand Up @@ -878,22 +876,6 @@ public static WebPopupMenu makeScoreContextMenu(@NotNull MpmTreeNode mpmTreeNode
return menu;
}

/**
* This creates the context menu in the ScoreDisplayPanel when an MSM object is right-clicked.
* @return
*/
public static WebPopupMenu makeScoreContextMenu(@NotNull MsmTreeNode msmTreeNode, @NotNull MsmTree msmTree, @NotNull ScorePage scorePage) {
WebMenuItem deleteFromScore = new WebMenuItem("Remove from Score");
deleteFromScore.addActionListener(actionEvent -> {
scorePage.removeEntry((Element) msmTreeNode.getUserObject()); // remove the note from the score page graph structure
msmTree.updateNode(msmTreeNode); // update the MsmTree
});

WebPopupMenu menu = new WebPopupMenu();
menu.add(deleteFromScore);
return menu;
}

/**
* changes in the performance should also be visible in the alignment that is currently shown in the audio frame
* @param performance the performance where the changes were made
Expand Down
4 changes: 0 additions & 4 deletions src/mpmToolbox/gui/mpmTree/MpmTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ public void mouseClicked(MouseEvent mouseEvent) {
*/
@Override
public void mousePressed(MouseEvent mouseEvent) {

}

/**
Expand All @@ -222,7 +221,6 @@ public void mousePressed(MouseEvent mouseEvent) {
*/
@Override
public void mouseReleased(MouseEvent mouseEvent) {

}

/**
Expand All @@ -231,7 +229,6 @@ public void mouseReleased(MouseEvent mouseEvent) {
*/
@Override
public void mouseEntered(MouseEvent mouseEvent) {

}

/**
Expand All @@ -240,7 +237,6 @@ public void mouseEntered(MouseEvent mouseEvent) {
*/
@Override
public void mouseExited(MouseEvent mouseEvent) {

}

@Override
Expand Down
167 changes: 167 additions & 0 deletions src/mpmToolbox/gui/msmEditingTools/MsmEditingTools.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package mpmToolbox.gui.msmEditingTools;

import com.alee.api.annotations.NotNull;
import com.alee.laf.menu.WebMenuItem;
import com.alee.laf.menu.WebPopupMenu;
import meico.mei.Helper;
import meico.mpm.elements.Part;
import meico.mpm.elements.Performance;
import meico.mpm.elements.maps.ArticulationMap;
import meico.mpm.elements.maps.GenericMap;
import meico.msm.Msm;
import mpmToolbox.gui.mpmTree.MpmTree;
import mpmToolbox.gui.msmTree.MsmTree;
import mpmToolbox.gui.msmTree.MsmTreeNode;
import mpmToolbox.projectData.score.ScorePage;
import nu.xom.Element;
import nu.xom.Elements;

import java.util.ArrayList;
import java.util.HashMap;

/**
* Helper class for MsmTreeNode. It generates the context menu that appears when right clicking
* in the MSM tree and all functionality required for it.
* @author Axel Berndt
*/public class MsmEditingTools {
public static WebPopupMenu makeMsmTreeContextMenu(@NotNull MsmTreeNode forThisNode, @NotNull MsmTree inThisMsmTree) {
MsmTreeNode self = forThisNode;
MsmTree msmTree = inThisMsmTree;

// System.out.println("Creating popup menu for " + self.name);
WebPopupMenu menu = new WebPopupMenu();

switch (self.getType()) {
case msm:
// resolve all sequencingMaps
WebMenuItem expandRepetitions = new WebMenuItem("Resolve all sequencingMaps");
expandRepetitions.setToolTipText("<html>Creates \"through-composed\" MSM and performances.<br>Deletes all sequencingMaps afterwards. If you plan to use<br>this functionality, do it before making entries in the score!</html>");
expandRepetitions.addActionListener(actionEvent -> MsmEditingTools.resolveAllSequencingMaps(msmTree));
menu.add(expandRepetitions);
break;

case attribute:
break;

case global:
break;

case part:
break;

case header:
break;

case dated:
break;

case score:
break;

case sequencingMap:
break;

case note:
break;

case rest:
break;

case lyrics:
break;

case element:
default:
break;
}

return menu;

}

/**
* Invoke this method to immediately open the editor dialog of MSM nodes ... at least those that have
* an editor dialog and are leaf nodes in the MSM tree. Non-leaf nodes expand on double click and that
* is what this method is meant to be used for, open the editor on double click.
* @param forThisNode
* @param inThisMsmTree
*/
public static void quickOpenEditor(@NotNull MsmTreeNode forThisNode, @NotNull MsmTree inThisMsmTree) {
MsmTreeNode self = forThisNode;
MsmTree msmTree = inThisMsmTree;

switch (self.getType()) {
// TODO: any editing of the MSM data?
default:
break;
}
}

/**
* This creates the context menu in the ScoreDisplayPanel when an MSM object is right-clicked.
* @return
*/
public static WebPopupMenu makeScoreContextMenu(@NotNull MsmTreeNode msmTreeNode, @NotNull MsmTree msmTree, @NotNull ScorePage scorePage) {
WebMenuItem deleteFromScore = new WebMenuItem("Remove from Score");
deleteFromScore.addActionListener(actionEvent -> {
scorePage.removeEntry((Element) msmTreeNode.getUserObject()); // remove the note from the score page graph structure
msmTree.updateNode(msmTreeNode); // update the MsmTree
});

WebPopupMenu menu = new WebPopupMenu();
menu.add(deleteFromScore);
return menu;
}

/**
* apply all sequencingMaps to the MSM tree and the MPM performances, remove the sequencingMaps from the MSM
* @param msmTree
*/
private static void resolveAllSequencingMaps(@NotNull MsmTree msmTree) {
Msm msm = msmTree.getProjectPane().getMsm();
MpmTree mpmTree = msmTree.getProjectPane().getMpmTree();

ArrayList<GenericMap> articulationMaps = new ArrayList<>();

// apply the sequencingMaps to MPM data first
Element globalSequencingMap = msm.getRootElement().getFirstChildElement("global").getFirstChildElement("dated").getFirstChildElement("sequencingMap");
for (Performance performance : mpmTree.getProjectPane().getMpm().getAllPerformances()) {
if (globalSequencingMap != null) {
HashMap<String, GenericMap> maps = performance.getGlobal().getDated().getAllMaps();
for (GenericMap map : maps.values()) {
map.applySequencingMap(globalSequencingMap);
if (map instanceof ArticulationMap) // in articulationMaps the elements have notid attribute that has to be updated after resolving the sequencingmaps in MSM
articulationMaps.add(map); // so keep the articulationMaps for later reference
}
}
Elements msmParts = msm.getParts();
ArrayList<Part> mpmParts = performance.getAllParts();
for (int pa=0; pa < performance.size(); ++pa) {
Element msmPart = msmParts.get(pa);
Element sequencingMap = msmPart.getFirstChildElement("dated").getFirstChildElement("sequencingMap");
if (sequencingMap == null) {
sequencingMap = globalSequencingMap;
if (sequencingMap == null)
continue;
}
for (GenericMap map : mpmParts.get(pa).getDated().getAllMaps().values()) {
map.applySequencingMap(sequencingMap);
if (map instanceof ArticulationMap) // in articulationMaps the elements have notid attribute that has to be updated after resolving the sequencingmaps in MSM
articulationMaps.add(map); // so keep the articulationMaps for later reference
}
}
}

// apply the sequencingMaps to MSM data, this will also delete the sequencingMaps
HashMap<String, String> repetitionIDs = msm.resolveSequencingMaps();

// update the articulationMap's elements' noteid attributes
for (GenericMap map : articulationMaps)
Helper.updateMpmNoteidsAfterResolvingRepetitions(map, repetitionIDs);

// reload the nodes whose content changed
msmTree.reloadNode(msmTree.getRootNode());
mpmTree.reloadNode(mpmTree.getRootNode());
msmTree.getProjectPane().getScore().cleanupDeadNodes();
}
}
83 changes: 81 additions & 2 deletions src/mpmToolbox/gui/msmTree/MsmTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,23 @@
import nu.xom.Element;
import nu.xom.Node;

import javax.swing.*;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Enumeration;

/**
* A custom WebAsncTree for MSM data.
* @author Axel Berndt
*/
public class MsmTree extends WebExTree<MsmTreeNode> implements TreeSelectionListener/*, MouseListener*/ {
public class MsmTree extends WebExTree<MsmTreeNode> implements MouseListener, TreeSelectionListener, TreeModelListener {
@NotNull private final ProjectPane projectPane; // a link to the parent project pane to access its data, midi player etc.
private WebDockableFrame dockableFrame = null; // a WebDockableFrame instance that displays this MSM tree, to be used in class ProjectPane

Expand All @@ -44,8 +49,9 @@ public MsmTree(@NotNull ProjectPane projectPane) {
// msmTree.setCellEditor(new MsmTreeCellEditor());
// msmTree.setStyleId(StyleId.treeTransparent);

this.addMouseListener(this);
this.addTreeSelectionListener(this);
// this.addMouseListener(this);
this.treeModel.addTreeModelListener(this);
}

// /**
Expand Down Expand Up @@ -206,4 +212,77 @@ public WebDockableFrame getDockableFrame() {

return this.dockableFrame;
}

/**
* When the user clicked in the tree, perform this action.
* @param mouseEvent
*/
@Override
public void mouseClicked(MouseEvent mouseEvent) {
// right click opens the context menu of the clicked node
if (SwingUtilities.isRightMouseButton(mouseEvent)) { // if right click
MsmTreeNode node = this.getNodeForRow(this.getClosestRowForLocation(mouseEvent.getX(), mouseEvent.getY())); // get the node that has been clicked
node.getContextMenu(this).show(this, mouseEvent.getX() - 25, mouseEvent.getY()); // trigger its context menu
return;
}
if (SwingUtilities.isLeftMouseButton(mouseEvent)) { // if left click
if (mouseEvent.getClickCount() > 1) { // if double (or more) click -> open editor dialog
MsmTreeNode node = this.getSelectedNode(); // get the node that has been double-clicked
node.openEditorDialog(this);
}
}
}

/**
* Perform this action when mouse button is pressed.
* @param mouseEvent
*/
@Override
public void mousePressed(MouseEvent mouseEvent) {
}

/**
* Perform this action when mouse button is released.
* @param mouseEvent
*/
@Override
public void mouseReleased(MouseEvent mouseEvent) {
}

/**
* Perform this action when the mouse cursor enters the MpmTree widget.
* @param mouseEvent
*/
@Override
public void mouseEntered(MouseEvent mouseEvent) {
}

/**
* perform this action when the mouse cursor exits the MpmTree widget.
* @param mouseEvent
*/
@Override
public void mouseExited(MouseEvent mouseEvent) {
}

@Override
public void treeNodesChanged(TreeModelEvent treeModelEvent) {
}

@Override
public void treeNodesInserted(TreeModelEvent treeModelEvent) {
}

@Override
public void treeNodesRemoved(TreeModelEvent treeModelEvent) {
}

/**
* if anything in the tree structure changed the score display gets updated
* @param treeModelEvent
*/
@Override
public void treeStructureChanged(TreeModelEvent treeModelEvent) {
this.projectPane.repaintScoreDisplay(); // repaint the score display so a selected MpmTreeNode gets highlighted and when switching to another performance we get to see its overlay
}
}
Loading

0 comments on commit f36c396

Please sign in to comment.