// This file is part of AceWiki. // Copyright 2008-2013, AceWiki developers. // // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If // not, see http://www.gnu.org/licenses/. package ch.uzh.ifi.attempto.preditor; import java.util.List; import nextapp.echo.app.Alignment; import nextapp.echo.app.ApplicationInstance; import nextapp.echo.app.Border; import nextapp.echo.app.Button; import nextapp.echo.app.Color; import nextapp.echo.app.Column; import nextapp.echo.app.Component; import nextapp.echo.app.Extent; import nextapp.echo.app.Font; import nextapp.echo.app.Insets; import nextapp.echo.app.Row; import nextapp.echo.app.TaskQueueHandle; import nextapp.echo.app.event.ActionEvent; import nextapp.echo.app.event.ActionListener; import ch.uzh.ifi.attempto.echocomp.EchoThread; import ch.uzh.ifi.attempto.echocomp.Style; import echopoint.ContainerEx; import echopoint.able.Scrollable; /** * This class represents a menu block of the predictive editor. A menu block consists of a list of * menu items. * * @author Tobias Kuhn */ class MenuBlock extends Column implements ActionListener { private static final long serialVersionUID = -5856577034761259001L; private PreditorWindow preditor; private MenuBlockContent content; private ContainerEx container; private Column menuColumn = new Column(); private Button label = new Button("..."); private Button enlargeButton = new Button(); private int state = 0; private List<MenuItem> items; private int width, height; private int colorShift; private int progress; private final ApplicationInstance app; private final TaskQueueHandle taskQueue; private final int lazyEvalStep = 25; /** * Creates a new menu block. * * @param actionListener The action listener. */ MenuBlock(int width, int height, int colorShift, PreditorWindow preditor) { this.width = width; this.height = height; this.colorShift = colorShift % 360; this.app = EchoThread.getActiveApplication(); this.taskQueue = app.createTaskQueue(); this.preditor = preditor; setInsets(new Insets(0, 1, 0, 0)); Row labelRow = new Row(); label.setEnabled(false); label.setHeight(new Extent(16)); label.setWidth(new Extent(100)); label.setDisabledBackground(Color.WHITE); label.setDisabledForeground(Color.BLACK); label.setDisabledFont(new Font(Style.fontTypeface, Font.ITALIC, new Extent(11))); label.setRolloverEnabled(false); label.setLineWrap(false); label.setAlignment(new Alignment(Alignment.LEFT, Alignment.BOTTOM)); label.setInsets(new Insets(1, 0, 0, 0)); labelRow.add(label); enlargeButton.setHeight(new Extent(15)); enlargeButton.setWidth(new Extent(10)); enlargeButton.setFont(new Font(Style.fontTypeface, Font.BOLD, new Extent(11))); enlargeButton.setForeground(Style.lightBackground); enlargeButton.setRolloverEnabled(true); enlargeButton.setRolloverForeground(Color.BLACK); enlargeButton.addActionListener(this); setEnlarged(false); labelRow.add(enlargeButton); add(labelRow); container = new ContainerEx(); container.setBorder(new Border(1, Color.BLACK, Border.STYLE_INSET)); container.setBackground(shiftColor(Style.lightBackground)); container.setScrollBarPolicy(Scrollable.AUTO); container.setWidth(new Extent(this.width)); container.setHeight(new Extent(this.height)); add(container); Column menuBaseColumn = new Column(); menuBaseColumn.setBackground(shiftColor(Style.mediumBackground)); menuBaseColumn.add(menuColumn); container.add(menuBaseColumn); } private Color shiftColor(Color color) { return Style.shiftColor(color, colorShift); } /** * Sets the content and the size of this menu block. * * @param content The content to be shown in this menu block. */ public synchronized void setContent(MenuBlockContent content) { this.content = content; state++; label.setText(content.getName()); label.setWidth(new Extent(width - 8)); menuColumn.removeAll(); items = content.getItems(); progress = 0; if (items.size() > height/15) { menuColumn.add(createNextMenuComponent()); calculateRest(state); } else { for (MenuItem m : items) { m.setColorShift(colorShift); menuColumn.add(m); m.setWidth(new Extent(width - 4)); } progress = items.size(); } } /** * Returns the current content of this menu block. * * @return The content. */ public MenuBlockContent getContent() { return content; } /** * Clears the content and removes all menu items. */ public void clear() { state++; content = null; menuColumn.removeAll(); } private synchronized void calculateRest(final int state) { if (progress >= items.size()) return; if (this.state != state) return; EchoThread thread = new EchoThread() { public ApplicationInstance getApplication() { return app; } public void run() { final Component c = createNextMenuComponent(); app.enqueueTask( taskQueue, new Runnable() { public void run() { addMenuComponent(c, state); } } ); } }; thread.start(); } private synchronized void addMenuComponent(Component c, int state) { if (this.state != state) return; menuColumn.add(c); calculateRest(state); } private synchronized Component createNextMenuComponent() { Column c = new Column(); int endPos = progress + lazyEvalStep; if (endPos > items.size()) endPos = items.size(); for (int i = progress ; i < endPos ; i++) { MenuItem m = items.get(i); m.setColorShift(colorShift); m.setWidth(new Extent(width - 24)); c.add(m); } progress = endPos; return c; } public void setVisible(boolean visible) { state++; super.setVisible(visible); } /** * This method is used to switch from normal to enlarged mode and back. * * @param enlarged true to switch to enlarged mode; false to switch back. */ public void setEnlarged(boolean enlarged) { if (enlarged) { enlargeButton.setText("–"); enlargeButton.setToolTipText(preditor.getLocalized("preditor_menublocktooltip_normalsize")); enlargeButton.setActionCommand("downsize"); } else { enlargeButton.setText("+"); enlargeButton.setToolTipText(preditor.getLocalized("preditor_menublocktooltip_enlarge")); enlargeButton.setActionCommand("enlarge"); } } public void actionPerformed(ActionEvent e) { String c = e.getActionCommand(); preditor.actionPerformed(new ActionEvent(this, c)); } }