From ebbbd61dba7799dfcc46e3822b5f7080f2bc4d99 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 17 Jul 2015 11:29:53 -0400 Subject: [PATCH] add icons to the tabs on the footer --- app/src/processing/app/ui/Editor.java | 2 +- app/src/processing/app/ui/EditorFooter.java | 102 +++++++++++++++--- core/todo.txt | 6 ++ java/src/processing/mode/java/JavaEditor.java | 2 +- todo.txt | 2 + 5 files changed, 99 insertions(+), 15 deletions(-) diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 7e1d25747..63c41599d 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -434,7 +434,7 @@ public abstract class Editor extends JFrame implements RunnerListener { public EditorFooter createFooter() { EditorFooter ef = new EditorFooter(this); console = new EditorConsole(this); - ef.addPanel(Language.text("editor.footer.console"), console); + ef.addPanel(console, Language.text("editor.footer.console"), "/lib/footer/console"); return ef; /* diff --git a/app/src/processing/app/ui/EditorFooter.java b/app/src/processing/app/ui/EditorFooter.java index 65448584d..84f972ee0 100644 --- a/app/src/processing/app/ui/EditorFooter.java +++ b/app/src/processing/app/ui/EditorFooter.java @@ -3,9 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-15 The Processing Foundation - Copyright (c) 2004-13 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology + Copyright (c) 2015 The Processing Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,7 +55,11 @@ public class EditorFooter extends Box { // amount of extra space between individual tabs static final int TAB_BETWEEN = 3; // amount of margin on the left/right for the text on the tab - static final int TEXT_MARGIN = 16; + static final int MARGIN = 16; + + static final int ICON_WIDTH = 14; + static final int ICON_HEIGHT = 13; + static final int ICON_TOP = 5; Color[] textColor = new Color[2]; Color[] tabColor = new Color[2]; @@ -102,8 +104,20 @@ public class EditorFooter extends Box { } - public void addPanel(String name, Component comp) { - tabs.add(new Tab(name, comp)); + /** Add a panel with no icon. */ + public void addPanel(Component comp, String name) { + addPanel(comp, name, null); + } + + + /** + * Add a panel with a name and icon. + * @param comp Component that will be shown when this tab is selected + * @param name Title to appear on the tab itself + * @param icon Prefix of the file name for the icon + */ + public void addPanel(Component comp, String name, String icon) { + tabs.add(new Tab(comp, name, icon)); cardPanel.add(name, comp); } @@ -237,21 +251,27 @@ public class EditorFooter extends Box { int x = left; for (Tab tab : tabs) { - int state = tab.isCurrent() ? SELECTED : UNSELECTED; tab.left = x; - x += TEXT_MARGIN; - x += tab.textWidth + TEXT_MARGIN; + x += MARGIN; + if (tab.hasIcon()) { + x += ICON_WIDTH + MARGIN; + } + x += tab.textWidth + MARGIN; tab.right = x; // if drawing and not just placing if (g != null) { + tab.draw(g); + /* + int state = tab.isCurrent() ? SELECTED : UNSELECTED; g.setColor(tabColor[state]); if (tab.notification) { g.setColor(errorColor); } - drawTab(g, tab.left, tab.right, tab.isFirst(), tab.isLast()); + //drawTab(g, tab.left, tab.right, tab.isFirst(), tab.isLast()); + tab.draw(g); - int textLeft = tab.left + ((tab.right - tab.left) - tab.textWidth) / 2; + int textLeft = tab.getTextLeft(); if (tab.notification && state == UNSELECTED) { g.setColor(Color.LIGHT_GRAY); } else { @@ -260,12 +280,14 @@ public class EditorFooter extends Box { int tabHeight = TAB_BOTTOM - TAB_TOP; int baseline = TAB_TOP + (tabHeight + fontAscent) / 2; g.drawString(tab.name, textLeft, baseline); + */ } x += TAB_BETWEEN; } } + /* private void drawTab(Graphics g, int left, int right, boolean leftNotch, boolean rightNotch) { Graphics2D g2 = (Graphics2D) g; @@ -273,6 +295,7 @@ public class EditorFooter extends Box { rightNotch ? CURVE_RADIUS : 0, leftNotch ? CURVE_RADIUS : 0)); } + */ public Dimension getPreferredSize() { @@ -299,13 +322,26 @@ public class EditorFooter extends Box { Component comp; boolean notification; + Image enabledIcon; + Image selectedIcon; + int left; int right; int textWidth; - Tab(String name, Component comp) { - this.name = name; + Tab(Component comp, String name, String icon) { this.comp = comp; + this.name = name; + + if (icon != null) { + Mode mode = editor.getMode(); + final int res = Toolkit.highResDisplay() ? 2 : 1; + enabledIcon = mode.loadImage(icon + "-enabled-" + res + "x.png"); + selectedIcon = mode.loadImage(icon + "-selected-" + res + "x.png"); + if (selectedIcon == null) { + selectedIcon = enabledIcon; // use this as the default + } + } } boolean contains(int x) { @@ -323,5 +359,45 @@ public class EditorFooter extends Box { boolean isLast() { return tabs.get(tabs.size() - 1) == this; } + + int getTextLeft() { + int links = left; + if (enabledIcon != null) { + links += ICON_WIDTH; + } + return links + ((right - links) - textWidth) / 2; + } + + boolean hasIcon() { + return enabledIcon != null; + } + + void draw(Graphics g) { + int state = isCurrent() ? SELECTED : UNSELECTED; + g.setColor(tabColor[state]); + if (notification) { + g.setColor(errorColor); + } + + Graphics2D g2 = (Graphics2D) g; + g2.fill(Toolkit.createRoundRect(left, TAB_TOP, right, TAB_BOTTOM, 0, 0, + isLast() ? CURVE_RADIUS : 0, + isFirst() ? CURVE_RADIUS : 0)); + + if (hasIcon()) { + Image icon = isCurrent() ? selectedIcon : enabledIcon; + g.drawImage(icon, left + MARGIN, ICON_TOP, ICON_WIDTH, ICON_HEIGHT, null); + } + + int textLeft = getTextLeft(); + if (notification && state == UNSELECTED) { + g.setColor(Color.LIGHT_GRAY); + } else { + g.setColor(textColor[state]); + } + int tabHeight = TAB_BOTTOM - TAB_TOP; + int baseline = TAB_TOP + (tabHeight + fontAscent) / 2; + g.drawString(name, textLeft, baseline); + } } } diff --git a/core/todo.txt b/core/todo.txt index a0d3fa768..4b4bdd2e2 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,12 @@ 0239 core +opengl +X ArrayIndexOutOfBoundsException error when enabling depth sorting in P3D +X https://github.com/processing/processing/pull/3477 +X https://github.com/processing/processing/issues/3476 + + docs _ note that full screen and present are now different _ on Export to Application, this has an impact diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 482e56191..104208923 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -264,7 +264,7 @@ public class JavaEditor extends Editor { // console = new EditorConsole(this); // footer.addPanel(Language.text("editor.footer.console"), console); - footer.addPanel(Language.text("editor.footer.errors"), errorTableScrollPane); + footer.addPanel(errorTableScrollPane, Language.text("editor.footer.errors"), "/lib/footer/error"); //return consolePanel; return footer; diff --git a/todo.txt b/todo.txt index 57d716d15..2c9350655 100644 --- a/todo.txt +++ b/todo.txt @@ -22,6 +22,8 @@ _ https://github.com/processing/processing/issues/3464 gui _ add new lower console/errors icons +_ fix the red for the console/error stuff +_ also the sidebar, the squiggly line beneath code, and the status bar _ show hover text with 'debug' _ inquire about updated document icon _ don't show breakpoints when debugger is off