package org.geogebra.desktop.cas.view; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.ImageIcon; import javax.swing.JToolBar; import org.geogebra.common.awt.GColor; import org.geogebra.common.gui.util.SelectionTable; import org.geogebra.common.kernel.geos.GeoCasCell; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoText; import org.geogebra.common.util.debug.Log; import org.geogebra.desktop.awt.GColorD; import org.geogebra.desktop.gui.GuiManagerD; import org.geogebra.desktop.gui.color.ColorPopupMenuButton; import org.geogebra.desktop.gui.util.GeoGebraIconD; import org.geogebra.desktop.gui.util.MyToggleButtonD; import org.geogebra.desktop.gui.util.PopupMenuButtonD; import org.geogebra.desktop.main.AppD; import org.geogebra.desktop.main.LocalizationD; import org.geogebra.desktop.util.GuiResourcesD; /** * Stylebar for CAS */ public class CASStyleBar extends JToolBar implements ActionListener { /** */ private static final long serialVersionUID = 1L; /** application */ protected AppD app; /** CAS view */ protected CASViewD casView; // buttons and lists of buttons private MyToggleButtonD[] toggleBtnList; private PopupMenuButtonD[] popupBtnList; private ColorPopupMenuButton btnTextColor; private PopupMenuButtonD btnTextSize; /** button for bold text */ protected MyToggleButtonD btnBold; /** button for italic text */ protected MyToggleButtonD btnItalic; /** use as text button */ protected MyToggleButtonD btnUseAsText; /** use as text button */ protected MyToggleButtonD btnShowKeyboard; /** height of buttons */ protected int iconHeight = 18; private Dimension iconDimension = new Dimension(16, iconHeight); private boolean needUndo = false; private ArrayList<GeoElement> selectedRows; private LocalizationD loc; /** * @param view * CAS view * @param app * application */ public CASStyleBar(CASViewD view, AppD app) { this.app = app; this.loc = app.getLocalization(); this.casView = view; selectedRows = new ArrayList<GeoElement>(); setFloatable(false); initGUI(); } /** * * @param targetGeos * list of seleted cells */ public void setSelectedRows(ArrayList<GeoElement> targetGeos) { if (targetGeos != null) { selectedRows = targetGeos; } updateStyleBar(); } /** * * @param geo * selected cell */ public void setSelectedRow(GeoElement geo) { selectedRows.clear(); selectedRows.add(geo); updateStyleBar(); } @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource(); needUndo = false; processSource(source, selectedRows); if (needUndo) { app.storeUndoInfo(); needUndo = false; } // updateGUI(); } /** * @param source * event source * @param targetGeos * cells that need updating */ protected void processSource(Object source, ArrayList<GeoElement> targetGeos) { if (source == btnTextColor) { if (btnTextColor.getSelectedIndex() >= 0) { applyTextColor(targetGeos); // btnTextColor.setFgColor((Color)btnTextColor.getSelectedValue()); // btnItalic.setForeground((Color)btnTextColor.getSelectedValue()); // btnBold.setForeground((Color)btnTextColor.getSelectedValue()); } } else if (source == btnBold) { applyFontStyle(targetGeos); } else if (source == btnItalic) { applyFontStyle(targetGeos); } else if (source == btnTextSize) { applyTextSize(targetGeos); } else if (source == btnUseAsText) { int i = casView.getConsoleTable().getEditingRow(); int pos = ((CASTableCellEditorD) casView.getConsoleTable() .getCellEditor(i, CASTableD.COL_CAS_CELLS)) .getCaretPosition(); applyUseAsText(targetGeos); casView.getConsoleTable().startEditingRow(i); ((CASTableCellEditorD) casView.getConsoleTable().getCellEditor(i, CASTableD.COL_CAS_CELLS)).setCaretPosition(pos); } else if (source == btnShowKeyboard) { if ((app.getGuiManager()) != null) { if (AppD.isVirtualKeyboardActive() && !((GuiManagerD) app.getGuiManager()) .showVirtualKeyboard()) { // if keyboard is active but hidden, just show it ((GuiManagerD) app.getGuiManager()).toggleKeyboard(true); ((GuiManagerD) app.getGuiManager()).getVirtualKeyboard() .toggleNumeric(true); } else { AppD.setVirtualKeyboardActive( !AppD.isVirtualKeyboardActive()); ((GuiManagerD) app.getGuiManager()) .toggleKeyboard(AppD.isVirtualKeyboardActive()); ((GuiManagerD) app.getGuiManager()).getVirtualKeyboard() .toggleNumeric(AppD.isVirtualKeyboardActive()); } } } updateStyleBar(); } /** * Updates the stylebar */ public void updateStyleBar() { for (int i = 0; i < popupBtnList.length; i++) { try { popupBtnList[i].update(selectedRows.toArray()); } catch (Exception e) { // TODO: find problem } } for (int i = 0; i < toggleBtnList.length; i++) { try { toggleBtnList[i].update(selectedRows.toArray()); } catch (Exception e) { e.printStackTrace(); // TODO: find problem } } } private void applyTextColor(ArrayList<GeoElement> geos) { Color color = GColorD.getAwtColor(btnTextColor.getSelectedColor()); for (int i = 0; i < geos.size(); i++) { GeoElement geo = geos.get(i); if (geo instanceof GeoCasCell) { ((GeoCasCell) geo).setFontColor(GColorD.newColor(color)); geo.updateRepaint(); needUndo = true; } } } private void applyUseAsText(ArrayList<GeoElement> geos) { // btnUseAsText for (int i = 0; i < geos.size(); i++) { GeoElement geo = geos.get(i); if (geo instanceof GeoCasCell) { ((GeoCasCell) geo).setUseAsText(btnUseAsText.isSelected()); geo.updateRepaint(); needUndo = true; } } } private void applyFontStyle(ArrayList<GeoElement> geos) { int fontStyle = 0; if (btnBold.isSelected()) { fontStyle += 1; } if (btnItalic.isSelected()) { fontStyle += 2; } for (int i = 0; i < geos.size(); i++) { GeoElement geo = geos.get(i); Log.debug(((GeoCasCell) geo).getGeoText()); if (geo instanceof GeoCasCell && ((GeoCasCell) geo).getGeoText() .getFontStyle() != fontStyle) { ((GeoCasCell) geo).getGeoText().setFontStyle(fontStyle); geo.updateRepaint(); needUndo = true; } } } private void applyTextSize(ArrayList<GeoElement> geos) { double fontSize = GeoText .getRelativeFontSize(btnTextSize.getSelectedIndex()); // transform // indices // to // the // range // -4, // .. , // 4 for (int i = 0; i < geos.size(); i++) { GeoElement geo = geos.get(i); if (geo instanceof GeoCasCell && ((GeoCasCell) geo).getGeoText() .getFontSizeMultiplier() != fontSize) { ((GeoCasCell) geo).setFontSizeMultiplier(fontSize); geo.updateRepaint(); needUndo = true; } } } /** * @return array of popup buttons */ protected PopupMenuButtonD[] newPopupBtnList() { return new PopupMenuButtonD[] { btnTextColor, btnTextSize }; } /** * @return array of toggle buttons */ protected MyToggleButtonD[] newToggleBtnList() { return new MyToggleButtonD[] { btnBold, btnItalic, btnUseAsText }; } public void reinit() { initGUI(); } private void initGUI() { removeAll(); ImageIcon kbdIcon = app.getScaledIcon(GuiResourcesD.CAS_KEYBOARD); iconHeight = kbdIcon.getIconHeight(); iconDimension = new Dimension(iconHeight, iconHeight); btnShowKeyboard = new MyToggleButtonD(kbdIcon, iconHeight); createTextButtons(); add(btnUseAsText); add(btnTextColor); add(btnBold); add(btnItalic); btnShowKeyboard.addActionListener(this); add(btnShowKeyboard); // add(btnTextSize); //TODO: Fix text size popupBtnList = newPopupBtnList(); toggleBtnList = newToggleBtnList(); updateStyleBar(); } // ===================================================== // Text Format Buttons // ===================================================== /** * @param geos * list of selected cells * @return whether all given objects are cells in text mode */ static boolean checkGeoText(Object[] geos) { boolean geosOK = (geos.length > 0); for (int i = 0; i < geos.length; i++) { if (!(geos[i] instanceof GeoCasCell)) { geosOK = false; break; } else if (!((GeoCasCell) geos[i]).isUseAsText()) { geosOK = false; break; } } return geosOK; } private void createTextButtons() { // ======================== // text color button final Dimension textColoriconHeight = new Dimension(iconHeight, iconHeight); btnTextColor = new ColorPopupMenuButton(app, textColoriconHeight, ColorPopupMenuButton.COLORSET_DEFAULT, false) { private static final long serialVersionUID = 1L; private GColor geoColor; @Override public void update(Object[] geos) { boolean geosOK = checkGeoText(geos); setVisible(geosOK); if (geosOK) { GeoElement geo = ((GeoElement) geos[0]) .getGeoElementForPropertiesDialog(); geoColor = ((GeoCasCell) geo).getFontColor(); updateColorTable(); // find the geoColor in the table and select it int index = this.getColorIndex(geoColor); setSelectedIndex(index); // if nothing was selected, set the icon to show the // non-standard color if (index == -1) { this.setIcon(getButtonIcon()); } setFgColor(geoColor); // setFontStyle(((TextProperties) geo).getFontStyle()); } } @Override public ImageIcon getButtonIcon() { return GeoGebraIconD.createTextSymbolIcon("A", app.getPlainFont(), textColoriconHeight, GColorD.getAwtColor(getSelectedColor()), null); } }; btnTextColor.addActionListener(this); // ======================================== // use as text button ImageIcon useAsTextIcon = GeoGebraIconD.createStringIcon( loc.getMenu("Text").substring(0, 1), app.getPlainFont(), true, false, true, iconDimension, Color.black, null); btnUseAsText = new MyToggleButtonD(useAsTextIcon, iconHeight) { private static final long serialVersionUID = 1L; @Override public void update(Object[] geos) { setVisible(true); btnUseAsText.setSelected(checkGeoText(geos)); } }; btnUseAsText.addActionListener(this); // ======================================== // bold text button ImageIcon boldIcon = GeoGebraIconD.createStringIcon( loc.getMenu("Bold").substring(0, 1), app.getPlainFont(), true, false, true, iconDimension, Color.black, null); btnBold = new MyToggleButtonD(boldIcon, iconHeight) { private static final long serialVersionUID = 1L; @Override public void update(Object[] geos) { boolean geosOK = checkGeoText(geos); setVisible(geosOK); if (geosOK) { GeoElement geo = ((GeoElement) geos[0]) .getGeoElementForPropertiesDialog(); int style = ((GeoCasCell) geo).getGeoText().getFontStyle(); btnBold.setSelected(style == Font.BOLD || style == (Font.BOLD + Font.ITALIC)); } } }; btnBold.addActionListener(this); // ======================================== // italic text button ImageIcon italicIcon = GeoGebraIconD.createStringIcon( loc.getMenu("Italic").substring(0, 1), app.getPlainFont(), false, true, true, iconDimension, Color.black, null); btnItalic = new MyToggleButtonD(italicIcon, iconHeight) { private static final long serialVersionUID = 1L; @Override public void update(Object[] geos) { boolean geosOK = checkGeoText(geos); setVisible(geosOK); this.setVisible(geosOK); if (geosOK) { GeoElement geo = ((GeoElement) geos[0]) .getGeoElementForPropertiesDialog(); int style = ((GeoCasCell) geo).getGeoText().getFontStyle(); btnItalic.setSelected(style == Font.ITALIC || style == (Font.BOLD + Font.ITALIC)); } } }; btnItalic.addActionListener(this); // ======================================== // text size button String[] textSizeArray = app.getLocalization().getFontSizeStrings(); btnTextSize = new PopupMenuButtonD(app, textSizeArray, -1, 1, new Dimension(-1, iconHeight), SelectionTable.MODE_TEXT) { private static final long serialVersionUID = 1L; @Override public void update(Object[] geos) { boolean geosOK = checkGeoText(geos); setVisible(geosOK); if (geosOK) { GeoElement geo = ((GeoElement) geos[0]); setSelectedIndex(GeoText.getFontSizeIndex( ((GeoCasCell) geo).getFontSizeMultiplier())); // font // size // ranges // from // -4 to 4, transform // this to 0,1,..,4 } } }; btnTextSize.addActionListener(this); btnTextSize.setKeepVisible(false); } /** * Update localization */ public void setLabels() { initGUI(); btnUseAsText.setToolTipText(loc.getPlainTooltip("stylebar.UseAsText")); btnTextColor.setToolTipText(loc.getPlainTooltip("stylebar.TextColor")); btnTextSize.setToolTipText(loc.getPlainTooltip("stylebar.TextSize")); btnBold.setToolTipText(loc.getPlainTooltip("stylebar.Bold")); btnItalic.setToolTipText(loc.getPlainTooltip("stylebar.Italic")); } }