3737 */
3838public class EditorHeader extends JComponent {
3939 // height of this tab bar
40- static final int HIGH = 30 ;
40+ static final int HIGH = 29 ;
4141 // standard UI sizing (OS-specific, but generally consistent)
4242// static final int SCROLLBAR_WIDTH = 16;
4343 // amount of space on the left edge before the tabs start
44- static final int MARGIN_WIDTH = Editor .LEFT_GUTTER ;
44+ // static final int MARGIN_WIDTH = Editor.LEFT_GUTTER;
4545
46- static final int ARROW_TAB_WIDTH = 23 ;
46+ static final int ARROW_TAB_WIDTH = 18 ;
4747 // distance from the righthand side of a tab to the drop-down arrow
4848// static final int ARROW_GAP_WIDTH = 8;
4949 // indent x/y for notch on the tab
50- static final int ARROW_TOP = 12 ;
51- static final int ARROW_BOTTOM = 20 ;
52- static final int ARROW_WIDTH = 9 ;
50+ static final int ARROW_TOP = 11 ;
51+ static final int ARROW_BOTTOM = 18 ;
52+ static final int ARROW_WIDTH = 6 ;
53+
54+ static final int CURVE_RADIUS = 6 ;
5355
5456// static final int NOTCH = 0;
5557 // how far to raise the tab from the bottom of this Component
56- static final int TAB_HEIGHT = HIGH ;
58+ // static final int TAB_HEIGHT = HIGH;
59+ static final int TAB_TOP = 0 ;
60+ static final int TAB_BOTTOM = 27 ;
5761// // line that continues across all of the tabs for the current one
5862// static final int TAB_STRETCH = 3;
5963 // amount of extra space between individual tabs
60- static final int TAB_BETWEEN = 4 ;
64+ static final int TAB_BETWEEN = 3 ;
6165 // amount of margin on the left/right for the text on the tab
6266 static final int TEXT_MARGIN = 16 ;
6367 // width of the tab when no text visible
@@ -201,12 +205,9 @@ public void updateMode() {
201205
202206
203207 public void paintComponent (Graphics screen ) {
204- setOpaque (false );
205-
206208 if (screen == null ) return ;
207-
208209 Sketch sketch = editor .getSketch ();
209- if (sketch == null ) return ; // ? ?
210+ if (sketch == null ) return ; // possible ?
210211
211212 Dimension size = getSize ();
212213 if ((size .width != sizeW ) || (size .height != sizeH )) {
@@ -274,7 +275,7 @@ public void paintComponent(Graphics screen) {
274275 font .getStringBounds (tab .text , g2 .getFontRenderContext ()).getWidth ();
275276 }
276277 // make sure everything can fit
277- if (!placeTabs (MARGIN_WIDTH , tabMax , null )) {
278+ if (!placeTabs (Editor . LEFT_GUTTER , tabMax , null )) {
278279 //System.arraycopy(tabs, 0, visitOrder, 0, tabs.length);
279280 // always show the tab with the sketch's name
280281// System.arraycopy(tabs, 1, visitOrder, 0, tabs.length - 1);
@@ -292,14 +293,14 @@ public void paintComponent(Graphics screen) {
292293 // Keep shrinking the tabs one-by-one until things fit properly
293294 for (int i = 0 ; i < visitOrder .length ; i ++) {
294295 tabs [visitOrder [i ].index ].textVisible = false ;
295- if (placeTabs (MARGIN_WIDTH , tabMax , null )) {
296+ if (placeTabs (Editor . LEFT_GUTTER , tabMax , null )) {
296297 break ;
297298 }
298299 }
299300 }
300301
301302 // now actually draw the tabs
302- if (!placeTabs (MARGIN_WIDTH , tabMax - ARROW_TAB_WIDTH , g2 )){
303+ if (!placeTabs (Editor . LEFT_GUTTER , tabMax - ARROW_TAB_WIDTH , g2 )){
303304 // draw the dropdown menu target at the right of the window
304305 menuRight = tabMax ;
305306 menuLeft = menuRight - ARROW_TAB_WIDTH ;
@@ -310,12 +311,18 @@ public void paintComponent(Graphics screen) {
310311 }
311312
312313 g .setColor (tabColor [UNSELECTED ]);
313- drawTab (g , menuLeft , menuRight );
314+ drawTab (g , menuLeft , menuRight , false , true );
314315// int arrowY = (getHeight() - TAB_HEIGHT - TAB_STRETCH) + (TAB_HEIGHT - ARROW_HEIGHT)/2;
315316// g.drawImage(tabArrow, menuLeft, arrowY,
316317// ARROW_WIDTH, ARROW_HEIGHT, null);
317318 // TODO draw arrow here
318319
320+ g .setColor (tabColor [SELECTED ]);
321+
322+ // can't be done with lines, b/c retina leaves tiny hairlines
323+ g .fillRect (Editor .LEFT_GUTTER , TAB_BOTTOM ,
324+ editor .getWidth (), 2 );
325+
319326 g .setColor (arrowColor );
320327 GeneralPath trianglePath = new GeneralPath ();
321328 float x1 = menuLeft + (ARROW_TAB_WIDTH - ARROW_WIDTH ) / 2f ;
@@ -334,8 +341,8 @@ private boolean placeTabs(int left, int right, Graphics2D g) {
334341 Sketch sketch = editor .getSketch ();
335342 int x = left ;
336343
337- final int bottom = getHeight (); // - TAB_STRETCH;
338- final int top = bottom - TAB_HEIGHT ;
344+ // final int bottom = getHeight(); // - TAB_STRETCH;
345+ // final int top = bottom - TAB_HEIGHT;
339346// GeneralPath path = null;
340347
341348 for (int i = 0 ; i < sketch .getCodeCount (); i ++) {
@@ -376,7 +383,7 @@ private boolean placeTabs(int left, int right, Graphics2D g) {
376383
377384 if (g != null && tab .right < right ) {
378385 g .setColor (tabColor [state ]);
379- drawTab (g , tab .left , tab .right );
386+ drawTab (g , tab .left , tab .right , i == 0 , false );
380387// path.lineTo(x - NOTCH, top);
381388// path.lineTo(x, top + NOTCH);
382389// path.lineTo(x, bottom);
@@ -392,8 +399,8 @@ private boolean placeTabs(int left, int right, Graphics2D g) {
392399 g .setColor (textColor [state ]);
393400// int baseline = (int) Math.ceil((sizeH + fontAscent) / 2.0);
394401 //int baseline = bottom - (TAB_HEIGHT - fontAscent)/2;
395- int tabHeight = TAB_HEIGHT ; //bottom - top ;
396- int baseline = top + (tabHeight + fontAscent ) / 2 ;
402+ int tabHeight = TAB_BOTTOM - TAB_TOP ;
403+ int baseline = TAB_TOP + (tabHeight + fontAscent ) / 2 ;
397404 //g.drawString(sketch.code[i].name, textLeft, baseline);
398405 g .drawString (tab .text , textLeft , baseline );
399406// g.drawLine(tab.left, baseline-fontAscent, tab.right, baseline-fontAscent);
@@ -403,7 +410,7 @@ private boolean placeTabs(int left, int right, Graphics2D g) {
403410 if (code .isModified ()) {
404411 g .setColor (modifiedColor );
405412 //g.drawLine(tab.left + NOTCH, top, tab.right - NOTCH, top);
406- g .drawLine (tab .left , top , tab .right , top );
413+ g .drawLine (tab .left , TAB_TOP , tab .right , TAB_TOP );
407414 }
408415 }
409416
@@ -425,10 +432,59 @@ private boolean placeTabs(int left, int right, Graphics2D g) {
425432 }
426433
427434
428- private void drawTab (Graphics g , int left , int right ) {
429- final int bottom = getHeight (); // - TAB_STRETCH;
430- final int top = bottom - TAB_HEIGHT ;
431- g .fillRect (left , top , right - left , bottom - top );
435+ private void drawTab (Graphics g , int left , int right ,
436+ boolean leftNotch , boolean rightNotch ) {
437+ // final int bottom = getHeight(); // - TAB_STRETCH;
438+ // final int top = bottom - TAB_HEIGHT;
439+ // g.fillRect(left, top, right - left, bottom - top);
440+
441+ Graphics2D g2 = (Graphics2D ) g ;
442+ // GeneralPath path = new GeneralPath();
443+ roundRect (g2 , left , TAB_TOP , right , TAB_BOTTOM ,
444+ leftNotch ? CURVE_RADIUS : 0 ,
445+ rightNotch ? CURVE_RADIUS : 0 ,
446+ 0 , 0 );
447+
448+ // path.moveTo(left, TAB_BOTTOM);
449+ // if (left == MARGIN_WIDTH) { // first tab on the left
450+ // path.lineTo(left, TAB_TOP - CURVE_RADIUS);
451+ // }
452+
453+ }
454+
455+
456+ private void roundRect (Graphics2D g2 ,
457+ float x1 , float y1 , float x2 , float y2 ,
458+ float tl , float tr , float br , float bl ) {
459+ GeneralPath path = new GeneralPath ();
460+ // vertex(x1+tl, y1);
461+
462+ if (tr != 0 ) {
463+ path .moveTo (x2 -tr , y1 );
464+ path .quadTo (x2 , y1 , x2 , y1 +tr );
465+ } else {
466+ path .moveTo (x2 , y1 );
467+ }
468+ if (br != 0 ) {
469+ path .lineTo (x2 , y2 -br );
470+ path .quadTo (x2 , y2 , x2 -br , y2 );
471+ } else {
472+ path .lineTo (x2 , y2 );
473+ }
474+ if (bl != 0 ) {
475+ path .lineTo (x1 +bl , y2 );
476+ path .quadTo (x1 , y2 , x1 , y2 -bl );
477+ } else {
478+ path .lineTo (x1 , y2 );
479+ }
480+ if (tl != 0 ) {
481+ path .lineTo (x1 , y1 +tl );
482+ path .quadTo (x1 , y1 , x1 +tl , y1 );
483+ } else {
484+ path .lineTo (x1 , y1 );
485+ }
486+ path .closePath ();
487+ g2 .fill (path );
432488 }
433489
434490
0 commit comments