mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-13 07:17:13 -06:00
Theme Editor: paint real colors and HSL values in overlay on right side of editor (instead of behind editor text; previous commit)
This commit is contained in:
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.themeeditor;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLayer;
|
||||||
|
import javax.swing.plaf.LayerUI;
|
||||||
|
import javax.swing.text.BadLocationException;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.Token;
|
||||||
|
import com.formdev.flatlaf.UIDefaultsLoaderAccessor;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.util.HSLColor;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An overlay layer that paints additional information about line content on the right side.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
class FlatThemeEditorOverlay
|
||||||
|
extends LayerUI<FlatSyntaxTextArea>
|
||||||
|
{
|
||||||
|
private static final int COLOR_PREVIEW_WIDTH = 100;
|
||||||
|
|
||||||
|
private Font font;
|
||||||
|
private Font baseFont;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
// paint the syntax text area
|
||||||
|
super.paint( g, c );
|
||||||
|
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
FlatSyntaxTextArea textArea = ((JLayer<FlatSyntaxTextArea>)c).getView();
|
||||||
|
Rectangle clipBounds = g.getClipBounds();
|
||||||
|
|
||||||
|
// determine first and last visible lines
|
||||||
|
int firstVisibleLine;
|
||||||
|
int lastVisibleLine;
|
||||||
|
try {
|
||||||
|
int startOffset = textArea.viewToModel( new Point( 0, clipBounds.y ) );
|
||||||
|
int endOffset = textArea.viewToModel( new Point( 0, clipBounds.y + clipBounds.height ) );
|
||||||
|
firstVisibleLine = textArea.getLineOfOffset( startOffset );
|
||||||
|
lastVisibleLine = textArea.getLineOfOffset( endOffset );
|
||||||
|
} catch( BadLocationException ex ) {
|
||||||
|
// ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute font (and cache it)
|
||||||
|
if( baseFont != textArea.getFont() ) {
|
||||||
|
baseFont = textArea.getFont();
|
||||||
|
int fontSize = Math.max( (int) Math.round( baseFont.getSize() * 0.8 ), 8 );
|
||||||
|
font = baseFont.deriveFont( (float) fontSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
FontMetrics fm = c.getFontMetrics( font );
|
||||||
|
int maxTextWidth = fm.stringWidth( "HSL 360 100 100" );
|
||||||
|
int textHeight = fm.getAscent() - fm.getLeading();
|
||||||
|
|
||||||
|
int width = c.getWidth();
|
||||||
|
int previewWidth = UIScale.scale( COLOR_PREVIEW_WIDTH );
|
||||||
|
int gap = UIScale.scale( 4 );
|
||||||
|
|
||||||
|
// check whether preview is outside of clip bounds
|
||||||
|
if( clipBounds.x + clipBounds.width < width - previewWidth - maxTextWidth - gap )
|
||||||
|
return;
|
||||||
|
|
||||||
|
g.setFont( font );
|
||||||
|
|
||||||
|
// paint additional information
|
||||||
|
for( int line = firstVisibleLine; line <= lastVisibleLine; line++ ) {
|
||||||
|
Color color = getColorInLine( textArea, line );
|
||||||
|
if( color == null )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// paint color preview
|
||||||
|
int lineEndOffset = textArea.getLineEndOffset( line );
|
||||||
|
Rectangle r = textArea.modelToView( lineEndOffset - 1 );
|
||||||
|
int pw = Math.min( width - r.x - gap, previewWidth );
|
||||||
|
int px = width - pw;
|
||||||
|
g.setColor( color );
|
||||||
|
g.fillRect( px, r.y, pw, r.height );
|
||||||
|
|
||||||
|
// paint text
|
||||||
|
int textX = px - maxTextWidth;
|
||||||
|
if( textX > r.x + gap) {
|
||||||
|
float[] hsl = HSLColor.fromRGB( color );
|
||||||
|
String hslStr = String.format( "HSL %d %d %d",
|
||||||
|
Math.round( hsl[0] ), Math.round( hsl[1] ), Math.round( hsl[2] ) );
|
||||||
|
g.setColor( textArea.getForeground() );
|
||||||
|
FlatUIUtils.drawString( textArea, g, hslStr, textX,
|
||||||
|
r.y + ((r.height - textHeight) / 2) + textHeight );
|
||||||
|
}
|
||||||
|
} catch( BadLocationException ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color getColorInLine( FlatSyntaxTextArea textArea, int line ) {
|
||||||
|
Token token = textArea.getTokenListForLine( line );
|
||||||
|
for( Token t = token; t != null && t.isPaintable(); t = t.getNextToken() ) {
|
||||||
|
if( t.getType() == FlatThemeTokenMaker.TOKEN_COLOR ) {
|
||||||
|
try {
|
||||||
|
return new Color( UIDefaultsLoaderAccessor.parseColorRGBA( t.getLexeme() ), true );
|
||||||
|
} catch( IllegalArgumentException ex ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import java.awt.Color;
|
|||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import javax.swing.JLayer;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
|
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
|
||||||
import org.fife.ui.rsyntaxtextarea.FileLocation;
|
import org.fife.ui.rsyntaxtextarea.FileLocation;
|
||||||
@@ -55,7 +56,7 @@ class FlatThemeEditorPane
|
|||||||
textArea.setSyntaxEditingStyle( FLATLAF_STYLE );
|
textArea.setSyntaxEditingStyle( FLATLAF_STYLE );
|
||||||
textArea.setMarkOccurrences( true );
|
textArea.setMarkOccurrences( true );
|
||||||
textArea.addParser( new FlatThemeParser() );
|
textArea.addParser( new FlatThemeParser() );
|
||||||
textArea.setUseColorOfColorTokens( true );
|
// textArea.setUseColorOfColorTokens( true );
|
||||||
|
|
||||||
// theme
|
// theme
|
||||||
try {
|
try {
|
||||||
@@ -71,15 +72,19 @@ class FlatThemeEditorPane
|
|||||||
scheme.getStyle( FlatThemeTokenMaker.TOKEN_COLOR ).background = new Color( 0x0a000000, true );
|
scheme.getStyle( FlatThemeTokenMaker.TOKEN_COLOR ).background = new Color( 0x0a000000, true );
|
||||||
scheme.getStyle( FlatThemeTokenMaker.TOKEN_VARIABLE ).background = new Color( 0x1800cc00, true );
|
scheme.getStyle( FlatThemeTokenMaker.TOKEN_VARIABLE ).background = new Color( 0x1800cc00, true );
|
||||||
|
|
||||||
|
// create overlay layer
|
||||||
|
JLayer<FlatSyntaxTextArea> overlay = new JLayer<>( textArea, new FlatThemeEditorOverlay() );
|
||||||
|
|
||||||
// create scroll pane
|
// create scroll pane
|
||||||
scrollPane = new RTextScrollPane( textArea );
|
scrollPane = new RTextScrollPane( overlay );
|
||||||
scrollPane.setLineNumbersEnabled( true );
|
scrollPane.setLineNumbersEnabled( true );
|
||||||
|
|
||||||
// scale fonts
|
// scale fonts
|
||||||
if( UIScale.getUserScaleFactor() != 1 ) {
|
if( UIScale.getUserScaleFactor() != 1 )
|
||||||
textArea.setFont( scaleFont( textArea.getFont() ) );
|
textArea.setFont( scaleFont( textArea.getFont() ) );
|
||||||
scrollPane.getGutter().setLineNumberFont( scaleFont( scrollPane.getGutter().getLineNumberFont() ) );
|
|
||||||
}
|
// use same font for line numbers as in editor
|
||||||
|
scrollPane.getGutter().setLineNumberFont( textArea.getFont() );
|
||||||
|
|
||||||
add( scrollPane, BorderLayout.CENTER );
|
add( scrollPane, BorderLayout.CENTER );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user