diff --git a/modules/decima-ui/src/main/java/com/shade/decima/ui/Application.java b/modules/decima-ui/src/main/java/com/shade/decima/ui/Application.java index 4023addef..15bd07850 100644 --- a/modules/decima-ui/src/main/java/com/shade/decima/ui/Application.java +++ b/modules/decima-ui/src/main/java/com/shade/decima/ui/Application.java @@ -43,6 +43,7 @@ import com.shade.platform.ui.editors.lazy.UnloadableEditorInput; import com.shade.platform.ui.menus.MenuManager; import com.shade.platform.ui.views.ViewManager; +import com.shade.platform.ui.wm.StatusBar; import com.shade.util.NotNull; import com.shade.util.Nullable; import org.slf4j.Logger; @@ -70,6 +71,7 @@ public class Application implements com.shade.platform.model.app.Application { private final Preferences preferences; private final ServiceManager serviceManager; + private MessageBusConnection connection; private JFrame frame; static { @@ -103,6 +105,8 @@ public void start(@NotNull String[] args) { ApplicationCLI.execute(args); } + connection = MessageBus.getInstance().connect(); + configureUI(); frame = new JFrame(); configureFrame(frame); @@ -125,10 +129,23 @@ public void start(@NotNull String[] args) { return null; }); - final JToolBar statusBar = new JToolBar(); + MenuSelectionManager.defaultManager().addChangeListener(e -> { + final MenuSelectionManager manager = (MenuSelectionManager) e.getSource(); + final MenuElement[] path = manager.getSelectedPath(); + + if (path.length > 0) { + final MenuElement element = path[path.length - 1]; + final JComponent component = (JComponent) element.getComponent(); + final String description = (String) component.getClientProperty(MenuManager.DESCRIPTION_KEY); + StatusBar.set(description); + } else { + StatusBar.set(null); + } + }); + + final StatusBarImpl statusBar = new StatusBarImpl(); statusBar.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIColor.SHADOW)); - statusBar.add(Box.createHorizontalGlue()); - statusBar.add(new MemoryIndicator()); + connection.subscribe(StatusBar.TOPIC, statusBar); final JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); @@ -192,7 +209,6 @@ private void configureFrame(@NotNull JFrame frame) { JOptionPane.setRootFrame(frame); - final MessageBusConnection connection = MessageBus.getInstance().connect(); connection.subscribe(ApplicationSettings.SETTINGS, new ApplicationSettingsChangeListener() { @Override public void fontChanged(@Nullable String fontFamily, int fontSize) { @@ -469,4 +485,29 @@ private static Path getConfigPath() { return modernPath; } + + private static class StatusBarImpl extends JToolBar implements StatusBar { + private final JLabel infoLabel; + + public StatusBarImpl() { + infoLabel = new JLabel((String) null); + infoLabel.setVerticalAlignment(SwingConstants.CENTER); + + add(Box.createHorizontalStrut(10)); + add(infoLabel); + add(Box.createHorizontalGlue()); + add(new MemoryIndicator()); + } + + @Nullable + @Override + public String getInfo() { + return infoLabel.getText(); + } + + @Override + public void setInfo(@Nullable String text) { + infoLabel.setText(text); + } + } } diff --git a/modules/decima-ui/src/main/java/com/shade/decima/ui/editor/impl/DefaultEditorOnboardingProvider.java b/modules/decima-ui/src/main/java/com/shade/decima/ui/editor/impl/DefaultEditorOnboardingProvider.java index 06efa39ae..cecd8ce58 100644 --- a/modules/decima-ui/src/main/java/com/shade/decima/ui/editor/impl/DefaultEditorOnboardingProvider.java +++ b/modules/decima-ui/src/main/java/com/shade/decima/ui/editor/impl/DefaultEditorOnboardingProvider.java @@ -16,7 +16,7 @@ public Iterable getOnboardings() { return List.of( new EditorOnboarding.Action(FileMenu.NewProjectItem.ID, "Create new project"), new EditorOnboarding.Action(EditMenu.FindFilesItem.ID, "Find files"), - new EditorOnboarding.Action(ViewMenu.RecentFilesItem.ID, "Show recent files"), + new EditorOnboarding.Action(ViewMenu.RecentEditorsItem.ID, "Show recent files"), new EditorOnboarding.Text("Drop files here to open them") ); } diff --git a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/EditMenu.java b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/EditMenu.java index ba0323fa5..32186fffc 100644 --- a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/EditMenu.java +++ b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/EditMenu.java @@ -14,7 +14,7 @@ @MenuRegistration(id = APP_MENU_EDIT_ID, name = "&Edit", order = 2000) public final class EditMenu extends Menu { - @MenuItemRegistration(parent = APP_MENU_EDIT_ID, icon = "Action.undoIcon", keystroke = "ctrl Z", group = APP_MENU_EDIT_GROUP_UNDO, order = 1000) + @MenuItemRegistration(parent = APP_MENU_EDIT_ID, icon = "Action.undoIcon", description = "Undo last redone operation", keystroke = "ctrl Z", group = APP_MENU_EDIT_GROUP_UNDO, order = 1000) public static class UndoItem extends MenuItem { @Override public void perform(@NotNull MenuItemContext ctx) { @@ -47,7 +47,7 @@ public String getName(@NotNull MenuItemContext ctx) { } } - @MenuItemRegistration(parent = APP_MENU_EDIT_ID, icon = "Action.redoIcon", keystroke = "ctrl shift Z", group = APP_MENU_EDIT_GROUP_UNDO, order = 2000) + @MenuItemRegistration(parent = APP_MENU_EDIT_ID, icon = "Action.redoIcon", description = "Redo last undone operation", keystroke = "ctrl shift Z", group = APP_MENU_EDIT_GROUP_UNDO, order = 2000) public static class RedoItem extends MenuItem { @Override public void perform(@NotNull MenuItemContext ctx) { @@ -80,7 +80,7 @@ public String getName(@NotNull MenuItemContext ctx) { } } - @MenuItemRegistration(id = FindFilesItem.ID, parent = APP_MENU_EDIT_ID, name = "Find &Files\u2026", icon = "Action.searchIcon", keystroke = "ctrl shift F", group = APP_MENU_EDIT_GROUP_GENERAL, order = 1000) + @MenuItemRegistration(id = FindFilesItem.ID, parent = APP_MENU_EDIT_ID, name = "Find &Files\u2026", description = "Find files in the active project", icon = "Action.searchIcon", keystroke = "ctrl shift F", group = APP_MENU_EDIT_GROUP_GENERAL, order = 1000) public static class FindFilesItem extends MenuItem { public static final String ID = APP_MENU_EDIT_ID + ".findFiles"; diff --git a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/FileMenu.java b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/FileMenu.java index a80c1c53b..1c9942d4f 100644 --- a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/FileMenu.java +++ b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/FileMenu.java @@ -36,7 +36,7 @@ public final class FileMenu extends Menu { @MenuItemRegistration(id = APP_MENU_FILE_NEW_ID, parent = APP_MENU_FILE_ID, name = "&New", group = APP_MENU_FILE_GROUP_OPEN, order = 1000) public static class NewItem extends MenuItem {} - @MenuItemRegistration(id = NewProjectItem.ID, parent = APP_MENU_FILE_NEW_ID, name = "&Project\u2026", keystroke = "ctrl N", group = APP_MENU_FILE_GROUP_OPEN, order = 1000) + @MenuItemRegistration(id = NewProjectItem.ID, parent = APP_MENU_FILE_NEW_ID, name = "&Project\u2026", description = "Create a new project", keystroke = "ctrl N", group = APP_MENU_FILE_GROUP_OPEN, order = 1000) public static class NewProjectItem extends MenuItem { public static final String ID = APP_MENU_FILE_NEW_ID + ".project"; @@ -54,7 +54,7 @@ public void perform(@NotNull MenuItemContext ctx) { } } - @MenuItemRegistration(parent = APP_MENU_FILE_ID, name = "&Open\u2026", icon = "Tree.openIcon", group = APP_MENU_FILE_GROUP_OPEN, order = 2000) + @MenuItemRegistration(parent = APP_MENU_FILE_ID, name = "&Open\u2026", description = "Open a file in editor", icon = "Tree.openIcon", group = APP_MENU_FILE_GROUP_OPEN, order = 2000) public static class OpenItem extends MenuItem { @Override public void perform(@NotNull MenuItemContext ctx) { @@ -127,7 +127,7 @@ private static SaveableEditor findSaveableEditor() { } } - @MenuItemRegistration(parent = APP_MENU_FILE_ID, name = "Se&ttings\u2026", group = APP_MENU_FILE_GROUP_SETTINGS, keystroke = "ctrl alt S", order = 1000) + @MenuItemRegistration(parent = APP_MENU_FILE_ID, name = "Se&ttings\u2026", description = "Edit application settings", group = APP_MENU_FILE_GROUP_SETTINGS, keystroke = "ctrl alt S", order = 1000) public static class SettingsItem extends MenuItem { @Override public void perform(@NotNull MenuItemContext ctx) { @@ -156,7 +156,7 @@ public boolean isEnabled(@NotNull MenuItemContext ctx) { } } - @MenuItemRegistration(parent = APP_MENU_FILE_ID, name = "E&xit", keystroke = "ctrl Q", group = APP_MENU_FILE_GROUP_EXIT, order = 1000) + @MenuItemRegistration(parent = APP_MENU_FILE_ID, name = "E&xit", description = "Exit the application :(", group = APP_MENU_FILE_GROUP_EXIT, order = 1000) public static class ExitItem extends MenuItem { @Override public void perform(@NotNull MenuItemContext ctx) { diff --git a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ToolsMenu.java b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ToolsMenu.java index e54784403..aab137942 100644 --- a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ToolsMenu.java +++ b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ToolsMenu.java @@ -10,7 +10,7 @@ @MenuRegistration(id = APP_MENU_TOOLS_ID, name = "&Tools", order = 3500) public class ToolsMenu extends Menu { - @MenuItemRegistration(parent = APP_MENU_TOOLS_ID, name = "&Hash Tool", group = APP_MENU_TOOLS_GROUP_GENERAL, order = 1000) + @MenuItemRegistration(parent = APP_MENU_TOOLS_ID, name = "&Hash Tool", description = "Open a tool for computing hashes of a string", group = APP_MENU_TOOLS_GROUP_GENERAL, order = 1000) public static class HashToolItem extends MenuItem { @Override public void perform(@NotNull MenuItemContext ctx) { diff --git a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ViewMenu.java b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ViewMenu.java index 6532f9520..bcb75325c 100644 --- a/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ViewMenu.java +++ b/modules/decima-ui/src/main/java/com/shade/decima/ui/menu/menus/ViewMenu.java @@ -57,8 +57,8 @@ public void perform(@NotNull MenuItemContext ctx) { } } - @MenuItemRegistration(id = RecentFilesItem.ID, parent = APP_MENU_VIEW_ID, name = "Rec&ent Editors", keystroke = "ctrl E", group = APP_MENU_VIEW_GROUP_GENERAL, order = 1000) - public static class RecentFilesItem extends MenuItem { + @MenuItemRegistration(id = RecentEditorsItem.ID, parent = APP_MENU_VIEW_ID, name = "Rec&ent Editors", description = "Show a list of recently viewed editors among opened ones", keystroke = "ctrl E", group = APP_MENU_VIEW_GROUP_GENERAL, order = 1000) + public static class RecentEditorsItem extends MenuItem { public static final String ID = APP_MENU_VIEW_ID + ".recentEditors"; @Override diff --git a/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/MenuManager.java b/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/MenuManager.java index d2eb3f101..388544e5d 100644 --- a/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/MenuManager.java +++ b/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/MenuManager.java @@ -10,6 +10,7 @@ public interface MenuManager { DataKey CONTEXT_KEY = new DataKey<>("context", DataContext.class); + DataKey DESCRIPTION_KEY = new DataKey<>("description", String.class); String CTX_MENU_ID = "menu.ctx"; String APP_MENU_ID = "menu.app"; diff --git a/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/impl/MenuManagerImpl.java b/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/impl/MenuManagerImpl.java index 66ecd0666..d9afa3f2f 100644 --- a/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/impl/MenuManagerImpl.java +++ b/modules/platform-ui/src/main/java/com/shade/platform/ui/menus/impl/MenuManagerImpl.java @@ -258,6 +258,10 @@ private JMenuItem createMenuItem(@NotNull MenuItem item, @NotNull MenuItemRegist menuItem.setAccelerator(KeyStroke.getKeyStroke(metadata.keystroke())); } + if (!metadata.description().isEmpty()) { + menuItem.putClientProperty(DESCRIPTION_KEY, metadata.description()); + } + if (!item.isEnabled(context)) { menuItem.setEnabled(false); } diff --git a/modules/platform-ui/src/main/java/com/shade/platform/ui/settings/impl/SettingsDialog.java b/modules/platform-ui/src/main/java/com/shade/platform/ui/settings/impl/SettingsDialog.java index b6cb606aa..343f5fba5 100644 --- a/modules/platform-ui/src/main/java/com/shade/platform/ui/settings/impl/SettingsDialog.java +++ b/modules/platform-ui/src/main/java/com/shade/platform/ui/settings/impl/SettingsDialog.java @@ -98,13 +98,8 @@ public void mouseClicked(MouseEvent e) { pageHeader.add(activePageTitleLabel); pageHeader.add(activePageRevertLabel); - final JPanel contentPane = new JPanel() { - @Override - public void updateUI() { - super.updateUI(); - setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, UIColor.SHADOW)); - } - }; + final JPanel contentPane = new JPanel(); + contentPane.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, UIColor.SHADOW)); contentPane.setLayout(new BorderLayout(0, 0)); contentPane.add(pageHeader, BorderLayout.NORTH); contentPane.add(activePagePanel, BorderLayout.CENTER); diff --git a/modules/platform-ui/src/main/java/com/shade/platform/ui/wm/StatusBar.java b/modules/platform-ui/src/main/java/com/shade/platform/ui/wm/StatusBar.java new file mode 100644 index 000000000..d3d60880f --- /dev/null +++ b/modules/platform-ui/src/main/java/com/shade/platform/ui/wm/StatusBar.java @@ -0,0 +1,13 @@ +package com.shade.platform.ui.wm; + +import com.shade.platform.model.messages.MessageBus; +import com.shade.platform.model.messages.Topic; +import com.shade.util.Nullable; + +public interface StatusBar extends StatusBarInfo { + Topic TOPIC = Topic.create("StatusBarInfo", StatusBarInfo.class); + + static void set(@Nullable String text) { + MessageBus.getInstance().publisher(TOPIC).setInfo(text); + } +} diff --git a/modules/platform-ui/src/main/java/com/shade/platform/ui/wm/StatusBarInfo.java b/modules/platform-ui/src/main/java/com/shade/platform/ui/wm/StatusBarInfo.java new file mode 100644 index 000000000..d787949e7 --- /dev/null +++ b/modules/platform-ui/src/main/java/com/shade/platform/ui/wm/StatusBarInfo.java @@ -0,0 +1,10 @@ +package com.shade.platform.ui.wm; + +import com.shade.util.Nullable; + +public interface StatusBarInfo { + @Nullable + String getInfo(); + + void setInfo(@Nullable String text); +}