diff --git a/app/src/processing/app/EditorHeader.java b/app/src/processing/app/EditorHeader.java index 68e474eaf..c85cc7d29 100644 --- a/app/src/processing/app/EditorHeader.java +++ b/app/src/processing/app/EditorHeader.java @@ -37,27 +37,31 @@ import javax.swing.*; */ public class EditorHeader extends JComponent { // height of this tab bar - static final int HIGH = 30; + static final int HIGH = 29; // standard UI sizing (OS-specific, but generally consistent) // static final int SCROLLBAR_WIDTH = 16; // amount of space on the left edge before the tabs start - static final int MARGIN_WIDTH = Editor.LEFT_GUTTER; +// static final int MARGIN_WIDTH = Editor.LEFT_GUTTER; - static final int ARROW_TAB_WIDTH = 23; + static final int ARROW_TAB_WIDTH = 18; // distance from the righthand side of a tab to the drop-down arrow // static final int ARROW_GAP_WIDTH = 8; // indent x/y for notch on the tab - static final int ARROW_TOP = 12; - static final int ARROW_BOTTOM = 20; - static final int ARROW_WIDTH = 9; + static final int ARROW_TOP = 11; + static final int ARROW_BOTTOM = 18; + static final int ARROW_WIDTH = 6; + + static final int CURVE_RADIUS = 6; // static final int NOTCH = 0; // how far to raise the tab from the bottom of this Component - static final int TAB_HEIGHT = HIGH; +// static final int TAB_HEIGHT = HIGH; + static final int TAB_TOP = 0; + static final int TAB_BOTTOM = 27; // // line that continues across all of the tabs for the current one // static final int TAB_STRETCH = 3; // amount of extra space between individual tabs - static final int TAB_BETWEEN = 4; + 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; // width of the tab when no text visible @@ -201,12 +205,9 @@ public class EditorHeader extends JComponent { public void paintComponent(Graphics screen) { - setOpaque(false); - if (screen == null) return; - Sketch sketch = editor.getSketch(); - if (sketch == null) return; // ?? + if (sketch == null) return; // possible? Dimension size = getSize(); if ((size.width != sizeW) || (size.height != sizeH)) { @@ -274,7 +275,7 @@ public class EditorHeader extends JComponent { font.getStringBounds(tab.text, g2.getFontRenderContext()).getWidth(); } // make sure everything can fit - if (!placeTabs(MARGIN_WIDTH, tabMax, null)) { + if (!placeTabs(Editor.LEFT_GUTTER, tabMax, null)) { //System.arraycopy(tabs, 0, visitOrder, 0, tabs.length); // always show the tab with the sketch's name // System.arraycopy(tabs, 1, visitOrder, 0, tabs.length - 1); @@ -292,14 +293,14 @@ public class EditorHeader extends JComponent { // Keep shrinking the tabs one-by-one until things fit properly for (int i = 0; i < visitOrder.length; i++) { tabs[visitOrder[i].index].textVisible = false; - if (placeTabs(MARGIN_WIDTH, tabMax, null)) { + if (placeTabs(Editor.LEFT_GUTTER, tabMax, null)) { break; } } } // now actually draw the tabs - if(!placeTabs(MARGIN_WIDTH, tabMax - ARROW_TAB_WIDTH, g2)){ + if (!placeTabs(Editor.LEFT_GUTTER, tabMax - ARROW_TAB_WIDTH, g2)){ // draw the dropdown menu target at the right of the window menuRight = tabMax; menuLeft = menuRight - ARROW_TAB_WIDTH; @@ -310,12 +311,18 @@ public class EditorHeader extends JComponent { } g.setColor(tabColor[UNSELECTED]); - drawTab(g, menuLeft, menuRight); + drawTab(g, menuLeft, menuRight, false, true); // int arrowY = (getHeight() - TAB_HEIGHT - TAB_STRETCH) + (TAB_HEIGHT - ARROW_HEIGHT)/2; // g.drawImage(tabArrow, menuLeft, arrowY, // ARROW_WIDTH, ARROW_HEIGHT, null); // TODO draw arrow here + g.setColor(tabColor[SELECTED]); + + // can't be done with lines, b/c retina leaves tiny hairlines + g.fillRect(Editor.LEFT_GUTTER, TAB_BOTTOM, + editor.getWidth(), 2); + g.setColor(arrowColor); GeneralPath trianglePath = new GeneralPath(); float x1 = menuLeft + (ARROW_TAB_WIDTH - ARROW_WIDTH) / 2f; @@ -334,8 +341,8 @@ public class EditorHeader extends JComponent { Sketch sketch = editor.getSketch(); int x = left; - final int bottom = getHeight(); // - TAB_STRETCH; - final int top = bottom - TAB_HEIGHT; +// final int bottom = getHeight(); // - TAB_STRETCH; +// final int top = bottom - TAB_HEIGHT; // GeneralPath path = null; for (int i = 0; i < sketch.getCodeCount(); i++) { @@ -376,7 +383,7 @@ public class EditorHeader extends JComponent { if (g != null && tab.right < right) { g.setColor(tabColor[state]); - drawTab(g, tab.left, tab.right); + drawTab(g, tab.left, tab.right, i == 0, false); // path.lineTo(x - NOTCH, top); // path.lineTo(x, top + NOTCH); // path.lineTo(x, bottom); @@ -392,8 +399,8 @@ public class EditorHeader extends JComponent { g.setColor(textColor[state]); // int baseline = (int) Math.ceil((sizeH + fontAscent) / 2.0); //int baseline = bottom - (TAB_HEIGHT - fontAscent)/2; - int tabHeight = TAB_HEIGHT; //bottom - top; - int baseline = top + (tabHeight + fontAscent) / 2; + int tabHeight = TAB_BOTTOM - TAB_TOP; + int baseline = TAB_TOP + (tabHeight + fontAscent) / 2; //g.drawString(sketch.code[i].name, textLeft, baseline); g.drawString(tab.text, textLeft, baseline); // g.drawLine(tab.left, baseline-fontAscent, tab.right, baseline-fontAscent); @@ -403,7 +410,7 @@ public class EditorHeader extends JComponent { if (code.isModified()) { g.setColor(modifiedColor); //g.drawLine(tab.left + NOTCH, top, tab.right - NOTCH, top); - g.drawLine(tab.left, top, tab.right, top); + g.drawLine(tab.left, TAB_TOP, tab.right, TAB_TOP); } } @@ -425,10 +432,59 @@ public class EditorHeader extends JComponent { } - private void drawTab(Graphics g, int left, int right) { - final int bottom = getHeight(); // - TAB_STRETCH; - final int top = bottom - TAB_HEIGHT; - g.fillRect(left, top, right - left, bottom - top); + private void drawTab(Graphics g, int left, int right, + boolean leftNotch, boolean rightNotch) { +// final int bottom = getHeight(); // - TAB_STRETCH; +// final int top = bottom - TAB_HEIGHT; +// g.fillRect(left, top, right - left, bottom - top); + + Graphics2D g2 = (Graphics2D) g; +// GeneralPath path = new GeneralPath(); + roundRect(g2, left, TAB_TOP, right, TAB_BOTTOM, + leftNotch ? CURVE_RADIUS : 0, + rightNotch ? CURVE_RADIUS : 0, + 0, 0); + +// path.moveTo(left, TAB_BOTTOM); +// if (left == MARGIN_WIDTH) { // first tab on the left +// path.lineTo(left, TAB_TOP - CURVE_RADIUS); +// } + + } + + + private void roundRect(Graphics2D g2, + float x1, float y1, float x2, float y2, + float tl, float tr, float br, float bl) { + GeneralPath path = new GeneralPath(); +// vertex(x1+tl, y1); + + if (tr != 0) { + path.moveTo(x2-tr, y1); + path.quadTo(x2, y1, x2, y1+tr); + } else { + path.moveTo(x2, y1); + } + if (br != 0) { + path.lineTo(x2, y2-br); + path.quadTo(x2, y2, x2-br, y2); + } else { + path.lineTo(x2, y2); + } + if (bl != 0) { + path.lineTo(x1+bl, y2); + path.quadTo(x1, y2, x1, y2-bl); + } else { + path.lineTo(x1, y2); + } + if (tl != 0) { + path.lineTo(x1, y1+tl); + path.quadTo(x1, y1, x1+tl, y1); + } else { + path.lineTo(x1, y1); + } + path.closePath(); + g2.fill(path); } diff --git a/app/src/processing/app/Toolkit.java b/app/src/processing/app/Toolkit.java index 4dfa3ab5b..fa44aa61d 100644 --- a/app/src/processing/app/Toolkit.java +++ b/app/src/processing/app/Toolkit.java @@ -722,7 +722,7 @@ public class Toolkit { monoFont = createFont("SourceCodePro-Regular.ttf", size); //monoBoldFont = createFont("SourceCodePro-Semibold.ttf", size); monoBoldFont = createFont("SourceCodePro-Bold.ttf", size); - + // additional language constraints if ("el".equals(Language.getLanguage())) { if (!monoFont.canDisplay(GREEK_SMALL_LETTER_ALPHA) || @@ -758,7 +758,7 @@ public class Toolkit { try { sansFont = createFont("SourceSansPro-Regular.ttf", size); sansBoldFont = createFont("SourceSansPro-Semibold.ttf", size); - + // additional language constraints if ("el".equals(Language.getLanguage())) { if (!sansFont.canDisplay(GREEK_SMALL_LETTER_ALPHA) || diff --git a/build/shared/lib/theme.txt b/build/shared/lib/theme.txt index a625626e3..cc5ffc476 100644 --- a/build/shared/lib/theme.txt +++ b/build/shared/lib/theme.txt @@ -10,14 +10,19 @@ status.font = processing.sans,plain,14 # TABS # Settings for the tab area at the top. -header.text.font = processing.sans,bold,15 +header.text.font = processing.sans,bold,13 header.text.selected.color = #000000 header.text.unselected.color = #ffffff -header.tab.selected.color = #ffffff -header.tab.unselected.color = #657d87 -header.tab.arrow.color = #000000 +#header.tab.arrow.color = #000000 +header.tab.arrow.color = #ffffff header.gradient.top = #132638 header.gradient.bottom = #122535 +#header.tab.selected.color = #ffffff +#header.tab.unselected.color = #657d87 + +# r11-002 +header.tab.selected.color = #e0fffd +header.tab.unselected.color = #2d4251 # CONSOLE # The font is handled by preferences, so its size/etc are modifiable. @@ -51,7 +56,7 @@ divider.dot.color = #505050 #toolbar.sketch.color = #ffffff toolbar.rollover.font = processing.sans,plain,12 toolbar.rollover.color = #ffffff -toolbar.gradient.top = #142c40 +toolbar.gradient.top = #142a3e toolbar.gradient.bottom = #132638 # MODE SELECTOR diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 198f4037a..48bbb5d22 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -211,6 +211,8 @@ public class JavaEditor extends Editor { JTabbedPane tabPane = new JTabbedPane(JTabbedPane.BOTTOM); // tabPane.setUI(new BasicTabbedPaneUI()); tabPane.setUI(new SimpleTabbedPaneUI()); +// tabPane.setUI(new SillyTabbedPaneUI()); +// tabPane.setUI(new PlasticTabbedPaneUI()); // tabPane.setBorder(BorderFactory.createEmptyBorder()); // tabPane.setBackground(Color.RED); diff --git a/java/src/processing/mode/java/SillyTabbedPaneUI.java b/java/src/processing/mode/java/SillyTabbedPaneUI.java new file mode 100644 index 000000000..adc30c520 --- /dev/null +++ b/java/src/processing/mode/java/SillyTabbedPaneUI.java @@ -0,0 +1,179 @@ +package processing.mode.java; + + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicTabbedPaneUI; +import java.awt.*; + +public class SillyTabbedPaneUI extends BasicTabbedPaneUI { + static final int HIGH = 30; + + // controls the ugly extra amount at the top + static private final Insets NO_INSETS = new Insets(0, 0, 0, 0); + +// private Font selectedFont; +// private FontMetrics selectedMetrics; + +// /** +// * The color to use to fill in the background +// */ +// private Color fillColor; + + + static public ComponentUI createUI(JComponent c) { + return new SillyTabbedPaneUI(); + } + + + protected void installDefaults() { + super.installDefaults(); + + tabAreaInsets.left = 4; + selectedTabPadInsets = new Insets(0, 0, 0, 0); + tabInsets = selectedTabPadInsets; + +// tabPane.setBackground(Color.CYAN); +// Color background = tabPane.getBackground(); +// fillColor = background.darker(); + +// selectedFont = tabPane.getFont().deriveFont(Font.BOLD); +// selectedMetrics = tabPane.getFontMetrics(selectedFont); + } + + + public int getTabRunCount(JTabbedPane pane) { + return 1; + } + + + protected Insets getContentBorderInsets(int tabPlacement) { + return NO_INSETS; + } + + + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { + return HIGH; +// int vHeight = fontHeight; +// if (vHeight % 2 > 0) { +// vHeight++; +// } +// return vHeight; + } + + + protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { + return super.calculateTabWidth(tabPlacement, tabIndex, metrics) + metrics.getHeight(); + } + + + protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, + int x, int y, int w, int h, boolean isSelected) { + g.setColor(isSelected ? Color.RED : Color.ORANGE); + g.fillRect(x, y, w, h); + /* + Polygon shape = new Polygon(); + + shape.addPoint(x, y + h); + shape.addPoint(x, y); + shape.addPoint(x + w - (h / 2), y); + + if (isSelected || (tabIndex == (rects.length - 1))) + { + shape.addPoint(x + w + (h / 2), y + h); + } + else + { + shape.addPoint(x + w, y + (h / 2)); + shape.addPoint(x + w, y + h); + } + + g.setColor(tabPane.getBackground()); + g.fillPolygon(shape); + */ + } + + + /** Paint the border of an individual tab */ + protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, + int x, int y, int w, int h, boolean isSelected) { + } + + + protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, int selectedIndex, + int x, int y, int w, int h) { + /* + Rectangle selectedRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect); + + selectedRect.width = selectedRect.width + (selectedRect.height / 2) - 1; + + g.setColor(Color.BLACK); + + g.drawLine(x, y, selectedRect.x, y); + g.drawLine(selectedRect.x + selectedRect.width + 1, y, x + w, y); + + g.setColor(Color.WHITE); + + g.drawLine(x, y + 1, selectedRect.x, y + 1); + g.drawLine(selectedRect.x + 1, y + 1, selectedRect.x + 1, y); + g.drawLine(selectedRect.x + selectedRect.width + 2, y + 1, x + w, y + 1); + + g.setColor(shadow); + g.drawLine(selectedRect.x + selectedRect.width, y, selectedRect.x + selectedRect.width + 1, y + 1); + */ + } + + + protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, + int x, int y, int w, int h) { + } + + + protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, int selectedIndex, + int x, int y, int w, int h) { + } + + + protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, + int x, int y, int w, int h) { + } + + + protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, + int tabIndex, Rectangle iconRect, + Rectangle textRect, boolean isSelected) { + } + + + protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { + int tw = tabPane.getBounds().width; + +// g.setColor(fillColor); + g.setColor(Color.YELLOW); + g.fillRect(0, 0, tw, rects[0].height + 3); + + super.paintTabArea(g, tabPlacement, selectedIndex); + } + + + /* + protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) + { + if (isSelected) + { + int vDifference = (int)(selectedMetrics.getStringBounds(title,g).getWidth()) - textRect.width; + textRect.x -= (vDifference / 2); + super.paintText(g, tabPlacement, selectedFont, selectedMetrics, tabIndex, title, textRect, isSelected); + } + else + { + super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); + } + } + */ + + protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) + { + return 0; + } +} diff --git a/java/src/processing/mode/java/SimpleTabbedPaneUI.java b/java/src/processing/mode/java/SimpleTabbedPaneUI.java index ec825ff96..5696f5bd3 100644 --- a/java/src/processing/mode/java/SimpleTabbedPaneUI.java +++ b/java/src/processing/mode/java/SimpleTabbedPaneUI.java @@ -197,6 +197,10 @@ public class SimpleTabbedPaneUI extends BasicTabbedPaneUI { 0, 21, colorSet.bottomGradColor2)); g2d.fillRect(xpos, 10, width, 11); +// System.out.println("drawing orange"); +// g2d.setColor(Color.ORANGE); +// g2d.fillRect(xpos, 0, width, 21); + if (contentTopBorderDrawn) { g2d.setColor(lineColor); g2d.drawLine(rect.x, 20, rect.x + rect.width - 1, 20);