mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Theme Editor: added "Pick Color from Screen" action to "Edit" menu that allows picking a color from anywhere on screen and insert/change it at caret position
This commit is contained in:
@@ -0,0 +1,268 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2021 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# base theme (light, dark, intellij or darcula); only used by theme editor
|
||||||
|
@baseTheme = dark
|
||||||
|
|
||||||
|
#---- variables ----
|
||||||
|
|
||||||
|
# general background and foreground (text color)
|
||||||
|
@background = #21252b
|
||||||
|
@foreground = #abb2bf
|
||||||
|
@selectionBackground = #323844
|
||||||
|
@selectionForeground = #d7dae0
|
||||||
|
@selectionInactiveBackground = #2c313a
|
||||||
|
#@selectionInactiveForeground = @foreground
|
||||||
|
#@disabledText = #888
|
||||||
|
@textComponentBackground = #282c34
|
||||||
|
#@menuBackground = darken(@background,5%)
|
||||||
|
#@menuHoverBackground = lighten(@menuBackground,10%,derived)
|
||||||
|
#@menuCheckBackground = darken(@selectionBackground,10%,derived noAutoInverse)
|
||||||
|
#@menuAcceleratorForeground = darken(@foreground,15%)
|
||||||
|
#@menuAcceleratorSelectionForeground = @selectionForeground
|
||||||
|
#@cellFocusColor = #000
|
||||||
|
#@icon = #adadad
|
||||||
|
|
||||||
|
# accent colors (blueish)
|
||||||
|
@accentColor = #568AF2
|
||||||
|
#@accentFocusColor = shade(spin(@accentColor,-8),20%)
|
||||||
|
#@accentLinkColor = lighten(saturate(spin(@accentColor,-5),50%),16%)
|
||||||
|
#@accentSelectionBackground = @accentColor
|
||||||
|
#@accentSliderColor = @accentUnderlineColor
|
||||||
|
#@accentUnderlineColor = lighten(saturate(spin(@accentColor,-8),13%),5%)
|
||||||
|
#@accentButtonDefaultBackground = darken(spin(@accentColor,-8),13%)
|
||||||
|
#
|
||||||
|
## for buttons within components (e.g. combobox or spinner)
|
||||||
|
#@buttonArrowColor = #9A9DA1
|
||||||
|
#@buttonDisabledArrowColor = darken(@buttonArrowColor,25%)
|
||||||
|
#@buttonHoverArrowColor = lighten(@buttonArrowColor,10%,derived noAutoInverse)
|
||||||
|
#@buttonPressedArrowColor = lighten(@buttonArrowColor,20%,derived noAutoInverse)
|
||||||
|
#
|
||||||
|
## Drop (use lazy colors for IntelliJ platform themes, which usually do not specify these colors)
|
||||||
|
#@dropCellBackground = darken(List.selectionBackground,10%,lazy)
|
||||||
|
#@dropCellForeground = lazy(List.selectionForeground)
|
||||||
|
#@dropLineColor = lighten(List.selectionBackground,10%,lazy)
|
||||||
|
#@dropLineShortColor = lighten(List.selectionBackground,30%,lazy)
|
||||||
|
|
||||||
|
|
||||||
|
Button.borderColor = #464c55
|
||||||
|
Button.disabledBorderColor = #2d3137
|
||||||
|
|
||||||
|
#---- CheckBox ----
|
||||||
|
|
||||||
|
CheckBox.icon.style = filled
|
||||||
|
#CheckBox.icon.checkmarkColor = @accentColor
|
||||||
|
#CheckBox.icon.background = @background
|
||||||
|
|
||||||
|
CheckBox.icon[filled].selectedBorderColor = @accentColor
|
||||||
|
CheckBox.icon[filled].selectedBackground = @accentColor
|
||||||
|
CheckBox.icon[filled].checkmarkColor = #001133
|
||||||
|
CheckBox.icon[filled].focusedBackground = #f00
|
||||||
|
|
||||||
|
|
||||||
|
a=hsl(220,24%,20%)
|
||||||
|
#---- Component ----
|
||||||
|
|
||||||
|
Component.borderColor = #333841
|
||||||
|
|
||||||
|
"colors": {
|
||||||
|
"accentColor": "",
|
||||||
|
"backgroundColor": "",
|
||||||
|
# "borderColor": "#333841",
|
||||||
|
"infoForeground": "#7e8491"
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"*": {
|
||||||
|
|
||||||
|
"infoForeground": "#5c6370",
|
||||||
|
|
||||||
|
|
||||||
|
"disabledBackground": "backgroundColor",
|
||||||
|
"inactiveBackground": "backgroundColor",
|
||||||
|
|
||||||
|
"acceleratorForeground": "#E6E6E6",
|
||||||
|
"acceleratorSelectionForeground": "#E6E6E6",
|
||||||
|
|
||||||
|
"errorForeground": "#cd3359",
|
||||||
|
|
||||||
|
"focusColor": "backgroundColor",
|
||||||
|
"focusedBorderColor": "accentColor",
|
||||||
|
|
||||||
|
"separatorColor": "#32363c"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Button": {
|
||||||
|
"foreground": "#a0a7b4",
|
||||||
|
"startBackground": "#3d424b",
|
||||||
|
"endBackground": "#3d424b",
|
||||||
|
"shadowColor": "backgroundColor",
|
||||||
|
"focusedBorderColor": "#646a73",
|
||||||
|
|
||||||
|
"default": {
|
||||||
|
"foreground": "#ffffff",
|
||||||
|
"startBackground": "accentColor",
|
||||||
|
"endBackground": "accentColor",
|
||||||
|
"startBorderColor": "accentColor",
|
||||||
|
"endBorderColor": "accentColor",
|
||||||
|
"focusedBorderColor": "#4269b9",
|
||||||
|
"focusColor": "#4269b9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ComboBox": {
|
||||||
|
"nonEditableBackground": "#333841",
|
||||||
|
"background": "#333841",
|
||||||
|
"selectionBackground": "#4d78cc",
|
||||||
|
"ArrowButton": {
|
||||||
|
"iconColor": "#abb2bf",
|
||||||
|
"disabledIconColor": "#2c313a",
|
||||||
|
"nonEditableBackground": "#333841"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ComboPopup.border": "1,1,1,1,#2d3137",
|
||||||
|
|
||||||
|
"CompletionPopup": {
|
||||||
|
"matchForeground": "accentColor"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Component": {
|
||||||
|
"errorFocusColor": "#802d43",
|
||||||
|
"inactiveErrorFocusColor": "#522530",
|
||||||
|
"warningFocusColor": "#8c812b",
|
||||||
|
"inactiveWarningFocusColor": "#47441f"
|
||||||
|
},
|
||||||
|
|
||||||
|
"DefaultTabs": {
|
||||||
|
"underlineColor": "accentColor",
|
||||||
|
"inactiveUnderlineColor": "#4269b9",
|
||||||
|
"hoverBackground": "#323844"
|
||||||
|
},
|
||||||
|
|
||||||
|
"DragAndDrop": {
|
||||||
|
"areaForeground": "#abb2bf",
|
||||||
|
"areaBackground": "#323844",
|
||||||
|
"areaBorderColor": "#333841"
|
||||||
|
},
|
||||||
|
|
||||||
|
"EditorPane.inactiveBackground": "#282c34",
|
||||||
|
|
||||||
|
"FileColor": {
|
||||||
|
"Yellow": "#3d3026",
|
||||||
|
"Green": "#293a24",
|
||||||
|
"Blue": "#24354f",
|
||||||
|
"Violet": "#2d1942",
|
||||||
|
"Orange": "#3d3026",
|
||||||
|
"Rose": "#3d1e2b"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Label": {
|
||||||
|
"infoForeground": "infoForeground"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Link": {
|
||||||
|
"activeForeground": "#6494ed",
|
||||||
|
"hoverForeground": "#6494ed",
|
||||||
|
"pressedForeground": "#6494ed",
|
||||||
|
"visitedForeground": "#6494ed"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Popup": {
|
||||||
|
"paintBorder": false,
|
||||||
|
"Toolbar.borderColor": "#3d424b",
|
||||||
|
"Header.activeBackground": "#414855",
|
||||||
|
"Header.inactiveBackground": "#2c313a",
|
||||||
|
"Advertiser": {
|
||||||
|
"foreground": "#5c6370",
|
||||||
|
"borderColor": "#2d3137"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ProgressBar": {
|
||||||
|
"trackColor": "#1D1D26",
|
||||||
|
"progressColor": "accentColor",
|
||||||
|
"indeterminateStartColor": "accentColor",
|
||||||
|
"indeterminateEndColor": "#313469",
|
||||||
|
"failedColor": "#bd3c5f",
|
||||||
|
"failedEndColor": "#472c33",
|
||||||
|
"passedColor": "#239E62",
|
||||||
|
"passedEndColor": "#2b4242"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"TabbedPane": {
|
||||||
|
"underlineColor": "accentColor",
|
||||||
|
"contentAreaColor": "#323844",
|
||||||
|
"hoverColor": "#323844"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Table": {
|
||||||
|
"selectionForeground": "#ffffff",
|
||||||
|
"dropLineColor": "#abb2bf",
|
||||||
|
"focusCellForeground": "#abb2bf",
|
||||||
|
"gridColor": "#5c6370",
|
||||||
|
"lightSelectionInactiveForeground": "#abb2bf",
|
||||||
|
"lightSelectionForeground": "#abb2bf",
|
||||||
|
"selectionBackground": "#3d424b",
|
||||||
|
"selectionInactiveForeground": "#abb2bf",
|
||||||
|
"lightSelectionBackground": "#414855",
|
||||||
|
"lightSelectionInactiveBackground": "#323844"
|
||||||
|
},
|
||||||
|
|
||||||
|
"TextArea": {
|
||||||
|
"selectionBackground": "#414855"
|
||||||
|
},
|
||||||
|
|
||||||
|
"TextField": {
|
||||||
|
"selectionBackground": "#414855"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ToggleButton": {
|
||||||
|
"onForeground": "#ffffff",
|
||||||
|
"onBackground": "accentColor",
|
||||||
|
"offForeground": "#9f9fa6",
|
||||||
|
"offBackground": "#3d424b",
|
||||||
|
"borderColor": "#3d424b",
|
||||||
|
"buttonColor": "#5c6370"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ToolTip": {
|
||||||
|
"background": "#3d424b"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"Tree": {
|
||||||
|
"selectionBackground": "#4d78cc",
|
||||||
|
"modifiedItemForeground": "accentColor",
|
||||||
|
"rowHeight": 20
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"icons": {
|
||||||
|
"ColorPalette": {
|
||||||
|
"Checkbox.Background.Default.Dark": "#282c34",
|
||||||
|
"Checkbox.Border.Default.Dark": "#414855",
|
||||||
|
"Checkbox.Foreground.Selected.Dark": "#abb2bf",
|
||||||
|
"Checkbox.Focus.Wide.Dark": "#568AF2",
|
||||||
|
"Checkbox.Focus.Thin.Default.Dark": "#568AF2",
|
||||||
|
"Checkbox.Focus.Thin.Selected.Dark": "#568AF2",
|
||||||
|
"Checkbox.Background.Disabled.Dark": "#21252b",
|
||||||
|
"Checkbox.Border.Disabled.Dark": "#2c313a",
|
||||||
|
"Checkbox.Foreground.Disabled.Dark": "#5c6370"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.AWTException;
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Robot;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JWindow;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import com.formdev.flatlaf.icons.FlatAbstractIcon;
|
||||||
|
import com.formdev.flatlaf.ui.FlatEmptyBorder;
|
||||||
|
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||||
|
import com.formdev.flatlaf.util.HSLColor;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
class FlatColorPipette
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @throws AWTException if platform does not allow using robot (e.g. if headless)
|
||||||
|
* @throws UnsupportedOperationException if platform does not support translucent window
|
||||||
|
*/
|
||||||
|
static void pick( Window owner, boolean modal,
|
||||||
|
Consumer<Color> hoverCallback, Consumer<Color> pickCallback )
|
||||||
|
throws AWTException, UnsupportedOperationException
|
||||||
|
{
|
||||||
|
InvisiblePickWindow pickWindow = new InvisiblePickWindow( owner, modal, hoverCallback, pickCallback );
|
||||||
|
pickWindow.setVisible( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class InvisiblePickWindow ------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An invisible window used to receive mouse and keyboard events for the whole screen.
|
||||||
|
*/
|
||||||
|
private static class InvisiblePickWindow
|
||||||
|
extends JDialog
|
||||||
|
{
|
||||||
|
private final Consumer<Color> hoverCallback;
|
||||||
|
private final Consumer<Color> pickCallback;
|
||||||
|
|
||||||
|
private final Robot robot;
|
||||||
|
private final Magnifier magnifier;
|
||||||
|
|
||||||
|
private int lastX;
|
||||||
|
private int lastY;
|
||||||
|
private Color lastHoverColor;
|
||||||
|
|
||||||
|
InvisiblePickWindow( Window owner, boolean modal,
|
||||||
|
Consumer<Color> hoverCallback, Consumer<Color> pickCallback )
|
||||||
|
throws AWTException, UnsupportedOperationException
|
||||||
|
{
|
||||||
|
super( owner, modal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS );
|
||||||
|
this.hoverCallback = hoverCallback;
|
||||||
|
this.pickCallback = pickCallback;
|
||||||
|
|
||||||
|
setAlwaysOnTop( true );
|
||||||
|
setUndecorated( true );
|
||||||
|
setOpacity( 0.005f );
|
||||||
|
setBounds( owner.getGraphicsConfiguration().getBounds() );
|
||||||
|
|
||||||
|
robot = new Robot( owner.getGraphicsConfiguration().getDevice() );
|
||||||
|
magnifier = new Magnifier( this, robot );
|
||||||
|
|
||||||
|
MouseAdapter mouseListener = new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseMoved( MouseEvent e ) {
|
||||||
|
lastX = e.getX();
|
||||||
|
lastY = e.getY();
|
||||||
|
|
||||||
|
// get color at mouse location
|
||||||
|
// (temporary change opacity to zero to get correct color from robot)
|
||||||
|
float oldOpacity = getOpacity();
|
||||||
|
setOpacity( 0 );
|
||||||
|
Color color = robot.getPixelColor( lastX, lastY );
|
||||||
|
setOpacity( oldOpacity );
|
||||||
|
|
||||||
|
hover( color );
|
||||||
|
magnifier.update( lastX, lastY, color );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked( MouseEvent e ) {
|
||||||
|
dispose();
|
||||||
|
|
||||||
|
if( SwingUtilities.isLeftMouseButton( e ) )
|
||||||
|
pick( robot.getPixelColor( e.getX(), e.getY() ) );
|
||||||
|
else
|
||||||
|
pick( null );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyAdapter keyListener = new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed( KeyEvent e ) {
|
||||||
|
switch( e.getKeyCode() ) {
|
||||||
|
case KeyEvent.VK_ESCAPE: dispose(); pick( null ); break;
|
||||||
|
|
||||||
|
// move mouse one pixel using arrow keys
|
||||||
|
case KeyEvent.VK_LEFT: robot.mouseMove( lastX - 1, lastY ); break;
|
||||||
|
case KeyEvent.VK_RIGHT: robot.mouseMove( lastX + 1, lastY ); break;
|
||||||
|
case KeyEvent.VK_UP: robot.mouseMove( lastX, lastY - 1 ); break;
|
||||||
|
case KeyEvent.VK_DOWN: robot.mouseMove( lastX, lastY + 1 ); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addMouseListener( mouseListener );
|
||||||
|
addMouseMotionListener( mouseListener );
|
||||||
|
addKeyListener( keyListener );
|
||||||
|
|
||||||
|
magnifier.addMouseListener( mouseListener );
|
||||||
|
magnifier.addMouseMotionListener( mouseListener );
|
||||||
|
magnifier.addKeyListener( keyListener );
|
||||||
|
|
||||||
|
magnifier.pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hover( Color color ) {
|
||||||
|
if( hoverCallback == null || color == null || color.equals( lastHoverColor ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastHoverColor = color;
|
||||||
|
|
||||||
|
EventQueue.invokeLater( () -> {
|
||||||
|
hoverCallback.accept( color );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pick( Color color ) {
|
||||||
|
EventQueue.invokeLater( () -> {
|
||||||
|
pickCallback.accept( color );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Magnifier ----------------------------------------------------
|
||||||
|
|
||||||
|
private static class Magnifier
|
||||||
|
extends JWindow
|
||||||
|
{
|
||||||
|
private final Window owner;
|
||||||
|
private final Robot robot;
|
||||||
|
|
||||||
|
private final MagnifierView view;
|
||||||
|
private final JLabel infoLabel;
|
||||||
|
|
||||||
|
private final int zoom;
|
||||||
|
private final int pixels = 16;
|
||||||
|
private Color colorAtMouse;
|
||||||
|
private BufferedImage image;
|
||||||
|
|
||||||
|
public Magnifier( Window owner, Robot robot ) {
|
||||||
|
super( owner );
|
||||||
|
this.owner = owner;
|
||||||
|
this.robot = robot;
|
||||||
|
|
||||||
|
zoom = UIScale.scale( 16 );
|
||||||
|
|
||||||
|
getRootPane().setBorder( new FlatLineBorder( new Insets( 2, 2, 2, 2 ), Color.red, 2 ) );
|
||||||
|
|
||||||
|
view = new MagnifierView();
|
||||||
|
view.setPreferredSize( new Dimension( pixels * zoom, pixels * zoom ) );
|
||||||
|
|
||||||
|
infoLabel = new JLabel( "#" );
|
||||||
|
infoLabel.setIcon( new ColorIcon() );
|
||||||
|
infoLabel.setBorder( new FlatEmptyBorder( 4, 4, 4, 4 ) );
|
||||||
|
|
||||||
|
add( view, BorderLayout.CENTER );
|
||||||
|
add( infoLabel, BorderLayout.SOUTH );
|
||||||
|
}
|
||||||
|
|
||||||
|
void update( int x, int y, Color colorAtXY ) {
|
||||||
|
colorAtMouse = colorAtXY;
|
||||||
|
|
||||||
|
// capture screen at mouse location
|
||||||
|
image = robot.createScreenCapture( new Rectangle( x - (pixels / 2), y - (pixels / 2), pixels, pixels ) );
|
||||||
|
|
||||||
|
// update color in info label
|
||||||
|
HSLColor hslColor = new HSLColor( colorAtMouse );
|
||||||
|
int hue = Math.round( hslColor.getHue() );
|
||||||
|
int saturation = Math.round( hslColor.getSaturation() );
|
||||||
|
int luminance = Math.round( hslColor.getLuminance() );
|
||||||
|
infoLabel.setText( String.format( "#%06x HSL %d %d %d",
|
||||||
|
colorAtMouse.getRGB() & 0xffffff, hue, saturation, luminance ) );
|
||||||
|
|
||||||
|
// place bottom-right to mouse location
|
||||||
|
int mx = x + UIScale.scale( 32 );
|
||||||
|
int my = y + UIScale.scale( 32 );
|
||||||
|
|
||||||
|
// make sure that it is within screen
|
||||||
|
if( mx + getWidth() > owner.getX() + owner.getWidth() )
|
||||||
|
mx = x - getWidth() - UIScale.scale( 32 );
|
||||||
|
if( my + getHeight() > owner.getY() + owner.getHeight() )
|
||||||
|
my = y - getHeight() - UIScale.scale( 32 );
|
||||||
|
|
||||||
|
setLocation( mx, my );
|
||||||
|
setVisible( true );
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class MagnifierView ----
|
||||||
|
|
||||||
|
private class MagnifierView
|
||||||
|
extends JComponent
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g ) {
|
||||||
|
int width = getWidth();
|
||||||
|
int height = getHeight();
|
||||||
|
|
||||||
|
if( image != null )
|
||||||
|
g.drawImage( image, 0, 0, width, height, null );
|
||||||
|
|
||||||
|
int xy = (pixels / 2) * zoom;
|
||||||
|
g.setColor( Color.red );
|
||||||
|
((Graphics2D)g).setStroke( new BasicStroke( 2 ) );
|
||||||
|
g.drawRect( xy - 1, xy - 1, zoom + 2, zoom + 2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class ColorIcon ----
|
||||||
|
|
||||||
|
private class ColorIcon
|
||||||
|
extends FlatAbstractIcon
|
||||||
|
{
|
||||||
|
private static final int WIDTH = 64;
|
||||||
|
private static final int HEIGHT = 16;
|
||||||
|
|
||||||
|
public ColorIcon() {
|
||||||
|
super( WIDTH, HEIGHT, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
g.setColor( colorAtMouse );
|
||||||
|
g.fillRect( 0, 0, WIDTH, HEIGHT );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ import org.fife.ui.rtextarea.RTextAreaUI;
|
|||||||
import org.fife.ui.rtextarea.RUndoManager;
|
import org.fife.ui.rtextarea.RUndoManager;
|
||||||
import com.formdev.flatlaf.UIDefaultsLoaderAccessor;
|
import com.formdev.flatlaf.UIDefaultsLoaderAccessor;
|
||||||
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.InsertColorAction;
|
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.InsertColorAction;
|
||||||
|
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.PickColorAction;
|
||||||
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.DuplicateLinesAction;
|
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.DuplicateLinesAction;
|
||||||
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.IncrementNumberAction;
|
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.IncrementNumberAction;
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ class FlatSyntaxTextArea
|
|||||||
actionMap.put( FlatSyntaxTextAreaActions.incrementNumberAction, new IncrementNumberAction( FlatSyntaxTextAreaActions.incrementNumberAction, true ) );
|
actionMap.put( FlatSyntaxTextAreaActions.incrementNumberAction, new IncrementNumberAction( FlatSyntaxTextAreaActions.incrementNumberAction, true ) );
|
||||||
actionMap.put( FlatSyntaxTextAreaActions.decrementNumberAction, new IncrementNumberAction( FlatSyntaxTextAreaActions.decrementNumberAction, false ) );
|
actionMap.put( FlatSyntaxTextAreaActions.decrementNumberAction, new IncrementNumberAction( FlatSyntaxTextAreaActions.decrementNumberAction, false ) );
|
||||||
actionMap.put( FlatSyntaxTextAreaActions.insertColorAction, new InsertColorAction( FlatSyntaxTextAreaActions.insertColorAction ) );
|
actionMap.put( FlatSyntaxTextAreaActions.insertColorAction, new InsertColorAction( FlatSyntaxTextAreaActions.insertColorAction ) );
|
||||||
|
actionMap.put( FlatSyntaxTextAreaActions.pickColorAction, new PickColorAction( FlatSyntaxTextAreaActions.pickColorAction ) );
|
||||||
|
|
||||||
// add editor key strokes
|
// add editor key strokes
|
||||||
InputMap inputMap = getInputMap();
|
InputMap inputMap = getInputMap();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.themeeditor;
|
package com.formdev.flatlaf.themeeditor;
|
||||||
|
|
||||||
|
import java.awt.AWTException;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
@@ -43,6 +44,7 @@ class FlatSyntaxTextAreaActions
|
|||||||
static final String incrementNumberAction = "FlatLaf.IncrementNumberAction";
|
static final String incrementNumberAction = "FlatLaf.IncrementNumberAction";
|
||||||
static final String decrementNumberAction = "FlatLaf.DecrementNumberAction";
|
static final String decrementNumberAction = "FlatLaf.DecrementNumberAction";
|
||||||
static final String insertColorAction = "FlatLaf.InsertColorAction";
|
static final String insertColorAction = "FlatLaf.InsertColorAction";
|
||||||
|
static final String pickColorAction = "FlatLaf.PickColorAction";
|
||||||
|
|
||||||
static int[] findColorAt( RTextArea textArea, int position ) {
|
static int[] findColorAt( RTextArea textArea, int position ) {
|
||||||
try {
|
try {
|
||||||
@@ -384,4 +386,76 @@ class FlatSyntaxTextAreaActions
|
|||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class PickColorAction ----------------------------------------------
|
||||||
|
|
||||||
|
static class PickColorAction
|
||||||
|
extends RecordableTextAction
|
||||||
|
{
|
||||||
|
PickColorAction( String name ) {
|
||||||
|
super( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformedImpl( ActionEvent e, RTextArea textArea ) {
|
||||||
|
try {
|
||||||
|
// find current color at caret
|
||||||
|
int caretPosition = textArea.getCaretPosition();
|
||||||
|
int start;
|
||||||
|
int len = 0;
|
||||||
|
String oldStr;
|
||||||
|
int[] result = findColorAt( textArea, caretPosition );
|
||||||
|
if( result != null ) {
|
||||||
|
start = result[0];
|
||||||
|
len = result[1];
|
||||||
|
|
||||||
|
oldStr = textArea.getText( start, len );
|
||||||
|
} else {
|
||||||
|
start = caretPosition;
|
||||||
|
oldStr = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicInteger length = new AtomicInteger( len );
|
||||||
|
AtomicBoolean changed = new AtomicBoolean();
|
||||||
|
|
||||||
|
// show pipette color picker
|
||||||
|
Window window = SwingUtilities.windowForComponent( textArea );
|
||||||
|
FlatColorPipette.pick( window, true,
|
||||||
|
color -> {
|
||||||
|
// update editor immediately for live preview
|
||||||
|
String str = colorToString( color );
|
||||||
|
((FlatSyntaxTextArea)textArea).runWithoutUndo( () -> {
|
||||||
|
textArea.replaceRange( str, start, start + length.get() );
|
||||||
|
} );
|
||||||
|
length.set( str.length() );
|
||||||
|
changed.set( true );
|
||||||
|
},
|
||||||
|
color -> {
|
||||||
|
// restore original string
|
||||||
|
((FlatSyntaxTextArea)textArea).runWithoutUndo( () -> {
|
||||||
|
textArea.replaceRange( oldStr, start, start + length.get() );
|
||||||
|
} );
|
||||||
|
length.set( oldStr.length() );
|
||||||
|
|
||||||
|
// update editor
|
||||||
|
if( color != null ) {
|
||||||
|
String newStr = colorToString( color );
|
||||||
|
try {
|
||||||
|
if( !newStr.equals( textArea.getText( start, length.get() ) ) )
|
||||||
|
textArea.replaceRange( newStr, start, start + length.get() );
|
||||||
|
} catch( BadLocationException ex ) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
} catch( BadLocationException | IndexOutOfBoundsException | NumberFormatException | UnsupportedOperationException | AWTException ex ) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMacroID() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -657,6 +657,12 @@ class FlatThemeFileEditor
|
|||||||
themeEditorPane.notifyTextAreaAction( FlatSyntaxTextAreaActions.insertColorAction );
|
themeEditorPane.notifyTextAreaAction( FlatSyntaxTextAreaActions.insertColorAction );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void pickColor() {
|
||||||
|
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
|
||||||
|
if( themeEditorPane != null )
|
||||||
|
themeEditorPane.notifyTextAreaAction( FlatSyntaxTextAreaActions.pickColorAction );
|
||||||
|
}
|
||||||
|
|
||||||
private void showHidePreview() {
|
private void showHidePreview() {
|
||||||
boolean show = previewMenuItem.isSelected();
|
boolean show = previewMenuItem.isSelected();
|
||||||
for( FlatThemeEditorPane themeEditorPane : getThemeEditorPanes() )
|
for( FlatThemeEditorPane themeEditorPane : getThemeEditorPanes() )
|
||||||
@@ -888,6 +894,7 @@ class FlatThemeFileEditor
|
|||||||
editMenu = new JMenu();
|
editMenu = new JMenu();
|
||||||
findMenuItem = new JMenuItem();
|
findMenuItem = new JMenuItem();
|
||||||
insertColorMenuItem = new JMenuItem();
|
insertColorMenuItem = new JMenuItem();
|
||||||
|
pickColorMenuItem = new JMenuItem();
|
||||||
viewMenu = new JMenu();
|
viewMenu = new JMenu();
|
||||||
previewMenuItem = new JCheckBoxMenuItem();
|
previewMenuItem = new JCheckBoxMenuItem();
|
||||||
lightLafMenuItem = new JRadioButtonMenuItem();
|
lightLafMenuItem = new JRadioButtonMenuItem();
|
||||||
@@ -986,6 +993,12 @@ class FlatThemeFileEditor
|
|||||||
insertColorMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK));
|
insertColorMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK));
|
||||||
insertColorMenuItem.addActionListener(e -> insertColor());
|
insertColorMenuItem.addActionListener(e -> insertColor());
|
||||||
editMenu.add(insertColorMenuItem);
|
editMenu.add(insertColorMenuItem);
|
||||||
|
|
||||||
|
//---- pickColorMenuItem ----
|
||||||
|
pickColorMenuItem.setText("Pick Color from Screen");
|
||||||
|
pickColorMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK));
|
||||||
|
pickColorMenuItem.addActionListener(e -> pickColor());
|
||||||
|
editMenu.add(pickColorMenuItem);
|
||||||
}
|
}
|
||||||
menuBar.add(editMenu);
|
menuBar.add(editMenu);
|
||||||
|
|
||||||
@@ -1150,6 +1163,7 @@ class FlatThemeFileEditor
|
|||||||
private JMenu editMenu;
|
private JMenu editMenu;
|
||||||
private JMenuItem findMenuItem;
|
private JMenuItem findMenuItem;
|
||||||
private JMenuItem insertColorMenuItem;
|
private JMenuItem insertColorMenuItem;
|
||||||
|
private JMenuItem pickColorMenuItem;
|
||||||
private JMenu viewMenu;
|
private JMenu viewMenu;
|
||||||
private JCheckBoxMenuItem previewMenuItem;
|
private JCheckBoxMenuItem previewMenuItem;
|
||||||
private JRadioButtonMenuItem lightLafMenuItem;
|
private JRadioButtonMenuItem lightLafMenuItem;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
|
JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -112,6 +112,12 @@ new FormModel {
|
|||||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 71, 130, false )
|
"accelerator": static javax.swing.KeyStroke getKeyStroke( 71, 130, false )
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "insertColor", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "insertColor", false ) )
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "pickColorMenuItem"
|
||||||
|
"text": "Pick Color from Screen"
|
||||||
|
"accelerator": &KeyStroke0 static javax.swing.KeyStroke getKeyStroke( 71, 195, false )
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "pickColor", false ) )
|
||||||
|
} )
|
||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||||
name: "viewMenu"
|
name: "viewMenu"
|
||||||
|
|||||||
Reference in New Issue
Block a user