GitOrigin-RevId: 9e3a941071cfbf0f86f36da4be4b7d8c333b3d17
This commit is contained in:
Gregory.Shrago
2023-12-16 19:21:38 +04:00
committed by intellij-monorepo-bot
parent 0feb6d8fcf
commit cc5beecbce
37 changed files with 2192 additions and 2177 deletions

View File

@@ -28,33 +28,33 @@ import org.jetbrains.annotations.NotNull;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class ShowThumbnailsAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
if (project != null && file != null && file.isDirectory()) {
ThumbnailManager thumbnailManager = ThumbnailManager.getManager(project);
ThumbnailView thumbnailView = thumbnailManager.getThumbnailView();
thumbnailView.setRoot(file);
thumbnailView.setVisible(true);
thumbnailView.activate();
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
if (project != null && file != null && file.isDirectory()) {
ThumbnailManager thumbnailManager = ThumbnailManager.getManager(project);
ThumbnailView thumbnailView = thumbnailManager.getThumbnailView();
thumbnailView.setRoot(file);
thumbnailView.setVisible(true);
thumbnailView.activate();
}
}
@Override
public void update(@NotNull AnActionEvent e) {
VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
boolean enabled = file != null && file.isDirectory();
if (ActionPlaces.isPopupPlace(e.getPlace())) {
e.getPresentation().setEnabledAndVisible(enabled);
}
else {
e.getPresentation().setEnabled(enabled);
}
@Override
public void update(@NotNull AnActionEvent e) {
VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
boolean enabled = file != null && file.isDirectory();
if (ActionPlaces.isPopupPlace(e.getPlace())) {
e.getPresentation().setEnabledAndVisible(enabled);
}
else {
e.getPresentation().setEnabled(enabled);
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
}

View File

@@ -29,90 +29,91 @@ import java.util.function.BiFunction;
* @author tav
*/
public interface ImageDocument {
/**
* A scaled image provider.
*/
interface ScaledImageProvider extends BiFunction<Double/* scale */, Component, BufferedImage> {}
/**
* A scaled image provider.
*/
interface ScaledImageProvider extends BiFunction<Double/* scale */, Component, BufferedImage> {
}
/**
* A scaled image provider with caching strategy.
*/
interface CachedScaledImageProvider extends ScaledImageProvider {
default void clearCache() {}
}
/**
* A scaled image provider with caching strategy.
*/
interface CachedScaledImageProvider extends ScaledImageProvider {
default void clearCache() { }
}
/**
* Return image for rendering
*
* @return Image renderer
*/
Image getRenderer();
/**
* Return image for rendering
*
* @return Image renderer
*/
Image getRenderer();
/**
* Returns an image in the provided scale for rendering
*
* @return Image renderer
*/
Image getRenderer(double scale);
/**
* Returns an image in the provided scale for rendering
*
* @return Image renderer
*/
Image getRenderer(double scale);
/**
* Return current image.
*
* @return Return current buffered image
*/
BufferedImage getValue();
/**
* Return current image.
*
* @return Return current buffered image
*/
BufferedImage getValue();
/**
* Returns an image represented in the provided scale.
*/
BufferedImage getValue(double scale);
/**
* Returns an image represented in the provided scale.
*/
BufferedImage getValue(double scale);
/**
* Returns the bounds of the current image.
*/
@Nullable
default Rectangle getBounds() {
return getBounds(1d);
}
/**
* Returns the bounds of the current image.
*/
@Nullable
default Rectangle getBounds() {
return getBounds(1d);
}
/**
* Returns the bounds of the image represented in the provided scale.
*/
@Nullable
default Rectangle getBounds(double scale) {
BufferedImage image = getValue(scale);
return image != null ? new Rectangle(image.getWidth(), image.getHeight()) : null;
}
/**
* Returns the bounds of the image represented in the provided scale.
*/
@Nullable
default Rectangle getBounds(double scale) {
BufferedImage image = getValue(scale);
return image != null ? new Rectangle(image.getWidth(), image.getHeight()) : null;
}
/**
* Set image value
*
* @param image Value
*/
void setValue(BufferedImage image);
/**
* Set image value
*
* @param image Value
*/
void setValue(BufferedImage image);
/**
* Sets the scaled image provider.
*
* @param imageProvider the image provider
*/
void setValue(ScaledImageProvider imageProvider);
/**
* Sets the scaled image provider.
*
* @param imageProvider the image provider
*/
void setValue(ScaledImageProvider imageProvider);
/**
* Return image format.
*
* @return Format name
*/
String getFormat();
/**
* Return image format.
*
* @return Format name
*/
String getFormat();
/**
* Set image format.
*
* @param format Format from ImageIO (GIF, PNG, JPEG etc)
*/
void setFormat(String format);
/**
* Set image format.
*
* @param format Format from ImageIO (GIF, PNG, JPEG etc)
*/
void setFormat(String format);
void addChangeListener(ChangeListener listener);
void addChangeListener(ChangeListener listener);
void removeChangeListener(ChangeListener listener);
void removeChangeListener(ChangeListener listener);
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright 2004-2005 Alexey Efimov
*
* 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
*
* http://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.
*/
* Copyright 2004-2005 Alexey Efimov
*
* 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
*
* http://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 org.intellij.images.editor;
import com.intellij.openapi.Disposable;
@@ -30,35 +30,34 @@ import javax.swing.*;
*/
public interface ImageEditor extends Disposable, ImageComponentDecorator {
@NotNull
VirtualFile getFile();
@NotNull
VirtualFile getFile();
Project getProject();
Project getProject();
ImageDocument getDocument();
ImageDocument getDocument();
JComponent getComponent();
JComponent getComponent();
/**
* Return the target of image editing area within entire component,
* returned by {@link #getComponent()}.
*
* @return Content component
*/
JComponent getContentComponent();
/**
* Return the target of image editing area within entire component,
* returned by {@link #getComponent()}.
*
* @return Content component
*/
JComponent getContentComponent();
/**
* Return {@code true} if editor show valid image.
*
* @return {@code true} if editor show valid image.
*/
boolean isValid();
/**
* Return {@code true} if editor is already disposed.
*
* @return {@code true} if editor is already disposed.
*/
boolean isDisposed();
/**
* Return {@code true} if editor show valid image.
*
* @return {@code true} if editor show valid image.
*/
boolean isValid();
/**
* Return {@code true} if editor is already disposed.
*
* @return {@code true} if editor is already disposed.
*/
boolean isDisposed();
}

View File

@@ -18,5 +18,5 @@ package org.intellij.images.editor;
import com.intellij.openapi.fileEditor.FileEditor;
public interface ImageFileEditor extends FileEditor {
ImageEditor getImageEditor();
ImageEditor getImageEditor();
}

View File

@@ -25,78 +25,78 @@ import org.jetbrains.annotations.Nullable;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface ImageZoomModel {
int MACRO_ZOOM_POWER_LIMIT = 5;
int MICRO_ZOOM_POWER_LIMIT = 8;
double MACRO_ZOOM_RATIO = 2.0d;
double MICRO_ZOOM_RATIO = 1.5d;
double MACRO_ZOOM_LIMIT = Math.pow(MACRO_ZOOM_RATIO, MACRO_ZOOM_POWER_LIMIT);
double MICRO_ZOOM_LIMIT = Math.pow(1 / MICRO_ZOOM_RATIO, MICRO_ZOOM_POWER_LIMIT);
int MACRO_ZOOM_POWER_LIMIT = 5;
int MICRO_ZOOM_POWER_LIMIT = 8;
double MACRO_ZOOM_RATIO = 2.0d;
double MICRO_ZOOM_RATIO = 1.5d;
double MACRO_ZOOM_LIMIT = Math.pow(MACRO_ZOOM_RATIO, MACRO_ZOOM_POWER_LIMIT);
double MICRO_ZOOM_LIMIT = Math.pow(1 / MICRO_ZOOM_RATIO, MICRO_ZOOM_POWER_LIMIT);
double getZoomFactor();
double getZoomFactor();
void setZoomFactor(double zoomFactor);
void setZoomFactor(double zoomFactor);
void fitZoomToWindow();
void fitZoomToWindow();
void zoomOut();
void zoomOut();
void zoomIn();
void zoomIn();
void setZoomLevelChanged(boolean value);
void setZoomLevelChanged(boolean value);
boolean canZoomOut();
boolean canZoomOut();
boolean canZoomIn();
boolean canZoomIn();
boolean isZoomLevelChanged();
boolean isZoomLevelChanged();
default @Nullable ZoomOptions getCustomZoomOptions() {
return null;
default @Nullable ZoomOptions getCustomZoomOptions() {
return null;
}
default void setCustomZoomOptions(@Nullable ZoomOptions zoomOptions) {
// Nothing.
}
ImageZoomModel STUB = new ImageZoomModel() {
@Override
public double getZoomFactor() {
return 1;
}
default void setCustomZoomOptions(@Nullable ZoomOptions zoomOptions) {
// Nothing.
@Override
public void setZoomFactor(double zoomFactor) {
}
ImageZoomModel STUB = new ImageZoomModel() {
@Override
public double getZoomFactor() {
return 1;
}
@Override
public void zoomOut() {
}
@Override
public void setZoomFactor(double zoomFactor) {
}
@Override
public void zoomIn() {
}
@Override
public void zoomOut() {
}
@Override
public void setZoomLevelChanged(boolean value) {
}
@Override
public void zoomIn() {
}
@Override
public void fitZoomToWindow() {
}
@Override
public void setZoomLevelChanged(boolean value) {
}
@Override
public boolean canZoomOut() {
return false;
}
@Override
public void fitZoomToWindow() {
}
@Override
public boolean canZoomIn() {
return false;
}
@Override
public boolean canZoomOut() {
return false;
}
@Override
public boolean canZoomIn() {
return false;
}
@Override
public boolean isZoomLevelChanged() {
return false;
}
};
@Override
public boolean isZoomLevelChanged() {
return false;
}
};
}

View File

@@ -18,7 +18,6 @@ package org.intellij.images.editor.actionSystem;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import org.intellij.images.editor.ImageEditor;
import org.intellij.images.ui.ImageComponentDecorator;
import org.jetbrains.annotations.NotNull;
@@ -28,38 +27,24 @@ import org.jetbrains.annotations.NotNull;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class ImageEditorActionUtil {
private ImageEditorActionUtil() {
}
private ImageEditorActionUtil() {
}
/**
* Extract current editor from event context.
*
* @param e Action event
* @return Current {@link ImageEditor} or {@code null}
*/
//public static ImageEditor getValidEditor(AnActionEvent e) {
// ImageEditor editor = getEditor(e);
// if (editor != null && editor.isValid()) {
// return editor;
// }
// return null;
//}
public static ImageComponentDecorator getImageComponentDecorator(@NotNull AnActionEvent e) {
DataContext dataContext = e.getDataContext();
return ImageComponentDecorator.DATA_KEY.getData(dataContext);
}
public static ImageComponentDecorator getImageComponentDecorator(@NotNull AnActionEvent e) {
DataContext dataContext = e.getDataContext();
return ImageComponentDecorator.DATA_KEY.getData(dataContext);
}
/**
* Enable or disable current action from event.
*
* @param e Action event
* @return Enabled value
*/
public static boolean setEnabled(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = getImageComponentDecorator(e);
Presentation presentation = e.getPresentation();
presentation.setEnabled(decorator != null);
return presentation.isEnabled();
}
/**
* Enable or disable current action from event.
*
* @param e Action event
* @return Enabled value
*/
public static boolean setEnabled(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = getImageComponentDecorator(e);
Presentation presentation = e.getPresentation();
presentation.setEnabled(decorator != null);
return presentation.isEnabled();
}
}

View File

@@ -23,10 +23,7 @@ import org.jetbrains.annotations.NonNls;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface ImageEditorActions {
@NonNls
String GROUP_TOOLBAR = "Images.EditorToolbar";
@NonNls
String GROUP_POPUP = "Images.EditorPopupMenu";
@NonNls
String ACTION_PLACE = "Images.Editor";
@NonNls String GROUP_TOOLBAR = "Images.EditorToolbar";
@NonNls String GROUP_POPUP = "Images.EditorPopupMenu";
@NonNls String ACTION_PLACE = "Images.Editor";
}

View File

@@ -33,27 +33,27 @@ import org.jetbrains.annotations.NotNull;
* @see ImageZoomModel#setZoomFactor
*/
public final class ActualSizeAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
if (decorator != null) {
ImageZoomModel zoomModel = decorator.getZoomModel();
zoomModel.setZoomFactor(1.0d);
zoomModel.setZoomLevelChanged(true);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
if (decorator != null) {
ImageZoomModel zoomModel = decorator.getZoomModel();
zoomModel.setZoomFactor(1.0d);
zoomModel.setZoomLevelChanged(true);
}
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ImageEditorActionUtil.setEnabled(e)) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
ImageZoomModel zoomModel = decorator.getZoomModel();
e.getPresentation().setEnabled(zoomModel.getZoomFactor() != 1.0d);
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ImageEditorActionUtil.setEnabled(e)) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
ImageZoomModel zoomModel = decorator.getZoomModel();
e.getPresentation().setEnabled(zoomModel.getZoomFactor() != 1.0d);
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
}

View File

@@ -32,26 +32,26 @@ import org.jetbrains.annotations.NotNull;
* @see ImageEditor#getZoomModel
*/
public final class ZoomInAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
if (decorator != null) {
ImageZoomModel zoomModel = decorator.getZoomModel();
zoomModel.zoomIn();
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
if (decorator != null) {
ImageZoomModel zoomModel = decorator.getZoomModel();
zoomModel.zoomIn();
}
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ImageEditorActionUtil.setEnabled(e)) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
ImageZoomModel zoomModel = decorator.getZoomModel();
e.getPresentation().setEnabled(zoomModel.canZoomIn());
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ImageEditorActionUtil.setEnabled(e)) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
ImageZoomModel zoomModel = decorator.getZoomModel();
e.getPresentation().setEnabled(zoomModel.canZoomIn());
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
}

View File

@@ -32,26 +32,26 @@ import org.jetbrains.annotations.NotNull;
* @see ImageEditor#getZoomModel
*/
public final class ZoomOutAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
if (decorator != null) {
ImageZoomModel zoomModel = decorator.getZoomModel();
zoomModel.zoomOut();
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
if (decorator != null) {
ImageZoomModel zoomModel = decorator.getZoomModel();
zoomModel.zoomOut();
}
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ImageEditorActionUtil.setEnabled(e)) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
ImageZoomModel zoomModel = decorator.getZoomModel();
e.getPresentation().setEnabled(zoomModel.canZoomOut());
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ImageEditorActionUtil.setEnabled(e)) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
ImageZoomModel zoomModel = decorator.getZoomModel();
e.getPresentation().setEnabled(zoomModel.canZoomOut());
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
}

View File

@@ -31,9 +31,10 @@ public final class ImageEditorManagerImpl {
}
@NotNull
public static ImageEditorUI createImageEditorUI(BufferedImage image){
public static ImageEditorUI createImageEditorUI(BufferedImage image) {
return createImageEditorUI(image, null);
}
@NotNull
public static ImageEditorUI createImageEditorUI(BufferedImage image, @Nullable String format) {
ImageEditorUI ui = new ImageEditorUI(null);

View File

@@ -214,7 +214,8 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
String format = document.getFormat();
if (format == null) {
format = editor != null ? ImagesBundle.message("unknown.format") : "";
} else {
}
else {
format = StringUtil.toUpperCase(format);
}
VirtualFile file = editor != null ? editor.getFile() : null;
@@ -222,7 +223,8 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
ImagesBundle.message("image.info",
image.getWidth(), image.getHeight(), format,
colorModel.getPixelSize(), file != null ? StringUtil.formatFileSize(file.getLength()) : ""));
} else {
}
else {
infoLabel.setText(null);
}
}
@@ -243,6 +245,7 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
removeAll();
}
@Override
public void setTransparencyChessboardVisible(boolean visible) {
imageComponent.setTransparencyChessboardVisible(visible);
@@ -585,7 +588,8 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
private class FocusRequester extends MouseAdapter {
@Override
public void mousePressed(@NotNull MouseEvent e) {
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus(ImageEditorUI.this, true));
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(
() -> IdeFocusManager.getGlobalInstance().requestFocus(ImageEditorUI.this, true));
}
}
@@ -670,7 +674,7 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { DataFlavor.imageFlavor };
return new DataFlavor[]{DataFlavor.imageFlavor};
}
@Override
@@ -690,7 +694,7 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
private class OptionsChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Options options = (Options) evt.getSource();
Options options = (Options)evt.getSource();
EditorOptions editorOptions = options.getEditorOptions();
TransparencyChessboardOptions chessboardOptions = editorOptions.getTransparencyChessboardOptions();
GridOptions gridOptions = editorOptions.getGridOptions();
@@ -703,5 +707,4 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
imageComponent.setGridLineColor(gridOptions.getLineColor());
}
}
}

View File

@@ -56,16 +56,19 @@ final class ImageFileEditorProvider implements FileEditorProvider, DumbAware {
if (IfsUtil.isSVG(file)) {
TextEditor editor = (TextEditor)TextEditorProvider.getInstance().createEditor(project, file);
if (JBCefApp.isSupported() && RegistryManager.getInstance().is("ide.browser.jcef.svg-viewer.enabled")) {
return new TextEditorWithPreview(editor, new JCefImageViewer(file, "image/svg+xml") , "SvgEditor");
} else {
return new TextEditorWithPreview(editor, new JCefImageViewer(file, "image/svg+xml"), "SvgEditor");
}
else {
ImageFileEditorImpl viewer = new ImageFileEditorImpl(project, file);
editor.getEditor().getDocument().addDocumentListener(new DocumentListener() {
final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, editor);
@Override
public void documentChanged(@NotNull DocumentEvent event) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(() -> ((ImageEditorImpl)viewer.getImageEditor()).setValue(new LightVirtualFile("preview.svg", file.getFileType(), event.getDocument().getText())),
500);
myAlarm.addRequest(
() -> ((ImageEditorImpl)viewer.getImageEditor())
.setValue(new LightVirtualFile("preview.svg", file.getFileType(), event.getDocument().getText())), 500);
}
}, editor);
return new TextEditorWithPreview(editor, viewer, "SvgEditor");

View File

@@ -21,21 +21,21 @@ package org.intellij.images.options;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface EditorOptions extends Cloneable {
GridOptions getGridOptions();
GridOptions getGridOptions();
TransparencyChessboardOptions getTransparencyChessboardOptions();
TransparencyChessboardOptions getTransparencyChessboardOptions();
ZoomOptions getZoomOptions();
ZoomOptions getZoomOptions();
void inject(EditorOptions options);
void inject(EditorOptions options);
boolean setOption(String name, Object value);
boolean setOption(String name, Object value);
boolean isFileNameVisible();
boolean isFileNameVisible();
void setFileNameVisible(boolean fileNameVisible);
void setFileNameVisible(boolean fileNameVisible);
void setFileSizeVisible(boolean fileSizeVisible);
void setFileSizeVisible(boolean fileSizeVisible);
boolean isFileSizeVisible();
boolean isFileSizeVisible();
}

View File

@@ -23,14 +23,12 @@ import org.jetbrains.annotations.NonNls;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface ExternalEditorOptions extends Cloneable {
@NonNls
String ATTR_PREFIX = "ExternalEditor.";
@NonNls
String ATTR_EXECUTABLE_PATH = ATTR_PREFIX + "executablePath";
@NonNls String ATTR_PREFIX = "ExternalEditor.";
@NonNls String ATTR_EXECUTABLE_PATH = ATTR_PREFIX + "executablePath";
String getExecutablePath();
String getExecutablePath();
void inject(ExternalEditorOptions options);
void inject(ExternalEditorOptions options);
boolean setOption(String name, Object value);
boolean setOption(String name, Object value);
}

View File

@@ -26,30 +26,25 @@ import java.awt.*;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface GridOptions extends Cloneable {
@NonNls
String ATTR_PREFIX = "Editor.Grid.";
@NonNls
String ATTR_SHOW_DEFAULT = ATTR_PREFIX + "showDefault";
@NonNls
String ATTR_LINE_ZOOM_FACTOR = ATTR_PREFIX + "lineZoomFactor";
@NonNls
String ATTR_LINE_SPAN = ATTR_PREFIX + "lineSpan";
@NonNls
String ATTR_LINE_COLOR = ATTR_PREFIX + "lineColor";
@NonNls String ATTR_PREFIX = "Editor.Grid.";
@NonNls String ATTR_SHOW_DEFAULT = ATTR_PREFIX + "showDefault";
@NonNls String ATTR_LINE_ZOOM_FACTOR = ATTR_PREFIX + "lineZoomFactor";
@NonNls String ATTR_LINE_SPAN = ATTR_PREFIX + "lineSpan";
@NonNls String ATTR_LINE_COLOR = ATTR_PREFIX + "lineColor";
int DEFAULT_LINE_ZOOM_FACTOR = 3;
int DEFAULT_LINE_SPAN = 1;
Color DEFAULT_LINE_COLOR = JBColor.DARK_GRAY;
int DEFAULT_LINE_ZOOM_FACTOR = 3;
int DEFAULT_LINE_SPAN = 1;
Color DEFAULT_LINE_COLOR = JBColor.DARK_GRAY;
boolean isShowDefault();
boolean isShowDefault();
int getLineZoomFactor();
int getLineZoomFactor();
int getLineSpan();
int getLineSpan();
Color getLineColor();
Color getLineColor();
void inject(GridOptions options);
void inject(GridOptions options);
boolean setOption(String name, Object value);
boolean setOption(String name, Object value);
}

View File

@@ -26,27 +26,27 @@ import java.beans.PropertyChangeListener;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface Options extends Cloneable {
@NotNull
EditorOptions getEditorOptions();
@NotNull
EditorOptions getEditorOptions();
@NotNull
ExternalEditorOptions getExternalEditorOptions();
@NotNull
ExternalEditorOptions getExternalEditorOptions();
/**
* Option injection from other options.
*
* @param options Other options
*/
void inject(@NotNull Options options);
/**
* Option injection from other options.
*
* @param options Other options
*/
void inject(@NotNull Options options);
void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parent);
void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parent);
/**
* Set option by string representation.
*
* @param name Name of option
* @param value Value
* @return {@code true} if option is matched and setted.
*/
boolean setOption(@NotNull String name, Object value);
/**
* Set option by string representation.
*
* @param name Name of option
* @param value Value
* @return {@code true} if option is matched and setted.
*/
boolean setOption(@NotNull String name, Object value);
}

View File

@@ -23,14 +23,14 @@ import com.intellij.openapi.application.ApplicationManager;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public abstract class OptionsManager {
/**
* Return current options.
*
* @return Options
*/
public abstract Options getOptions();
/**
* Return current options.
*
* @return Options
*/
public abstract Options getOptions();
public static OptionsManager getInstance() {
return ApplicationManager.getApplication().getService(OptionsManager.class);
}
public static OptionsManager getInstance() {
return ApplicationManager.getApplication().getService(OptionsManager.class);
}
}

View File

@@ -25,30 +25,25 @@ import java.awt.*;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface TransparencyChessboardOptions extends Cloneable {
@NonNls
String ATTR_PREFIX = "Editor.TransparencyChessboard.";
@NonNls
String ATTR_SHOW_DEFAULT = ATTR_PREFIX + "showDefault";
@NonNls
String ATTR_CELL_SIZE = ATTR_PREFIX + "cellSize";
@NonNls
String ATTR_WHITE_COLOR = ATTR_PREFIX + "whiteColor";
@NonNls
String ATTR_BLACK_COLOR = ATTR_PREFIX + "blackColor";
@NonNls String ATTR_PREFIX = "Editor.TransparencyChessboard.";
@NonNls String ATTR_SHOW_DEFAULT = ATTR_PREFIX + "showDefault";
@NonNls String ATTR_CELL_SIZE = ATTR_PREFIX + "cellSize";
@NonNls String ATTR_WHITE_COLOR = ATTR_PREFIX + "whiteColor";
@NonNls String ATTR_BLACK_COLOR = ATTR_PREFIX + "blackColor";
int DEFAULT_CELL_SIZE = 5;
Color DEFAULT_WHITE_COLOR = Color.WHITE;
Color DEFAULT_BLACK_COLOR = Color.LIGHT_GRAY;
int DEFAULT_CELL_SIZE = 5;
Color DEFAULT_WHITE_COLOR = Color.WHITE;
Color DEFAULT_BLACK_COLOR = Color.LIGHT_GRAY;
boolean isShowDefault();
boolean isShowDefault();
int getCellSize();
int getCellSize();
Color getWhiteColor();
Color getWhiteColor();
Color getBlackColor();
Color getBlackColor();
void inject(TransparencyChessboardOptions options);
void inject(TransparencyChessboardOptions options);
boolean setOption(String name, Object value);
boolean setOption(String name, Object value);
}

View File

@@ -26,22 +26,22 @@ import java.awt.*;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface ZoomOptions extends Cloneable {
@NonNls
String ATTR_PREFIX = "Editor.Zoom.";
@NonNls
String ATTR_PREFFERED_WIDTH = ATTR_PREFIX + "prefferedWidth";
@NonNls
String ATTR_PREFFERED_HEIGHT = ATTR_PREFIX + "prefferedHeight";
@NonNls
String ATTR_PREFIX = "Editor.Zoom.";
@NonNls
String ATTR_PREFFERED_WIDTH = ATTR_PREFIX + "prefferedWidth";
@NonNls
String ATTR_PREFFERED_HEIGHT = ATTR_PREFIX + "prefferedHeight";
Dimension DEFAULT_PREFFERED_SIZE = new Dimension(128, 128);
Dimension DEFAULT_PREFFERED_SIZE = new Dimension(128, 128);
default boolean isWheelZooming() {
return Registry.is("ide.images.wheel.zooming", true);
}
default boolean isWheelZooming() {
return Registry.is("ide.images.wheel.zooming", true);
}
default boolean isSmartZooming() {
return isWheelZooming();
}
default boolean isSmartZooming() {
return isWheelZooming();
}
default Double getSmartZoomFactor(Rectangle imageSize, Dimension viewPort, int inset) {
if (imageSize == null) return null;
@@ -69,9 +69,9 @@ public interface ZoomOptions extends Cloneable {
return 1.0d;
}
Dimension getPrefferedSize();
Dimension getPrefferedSize();
void inject(ZoomOptions options);
void inject(ZoomOptions options);
boolean setOption(String name, Object value);
boolean setOption(String name, Object value);
}

View File

@@ -32,89 +32,89 @@ import java.beans.PropertyChangeSupport;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
final class EditorOptionsImpl implements EditorOptions, JDOMExternalizable {
private final GridOptions gridOptions;
private final TransparencyChessboardOptions transparencyChessboardOptions;
private final ZoomOptions zoomOptions;
private boolean fileNameVisible = true;
private boolean fileSizeVisible = true;
private final GridOptions gridOptions;
private final TransparencyChessboardOptions transparencyChessboardOptions;
private final ZoomOptions zoomOptions;
private boolean fileNameVisible = true;
private boolean fileSizeVisible = true;
EditorOptionsImpl(PropertyChangeSupport propertyChangeSupport) {
gridOptions = new GridOptionsImpl(propertyChangeSupport);
transparencyChessboardOptions = new TransparencyChessboardOptionsImpl(propertyChangeSupport);
zoomOptions = new ZoomOptionsImpl(propertyChangeSupport);
}
EditorOptionsImpl(PropertyChangeSupport propertyChangeSupport) {
gridOptions = new GridOptionsImpl(propertyChangeSupport);
transparencyChessboardOptions = new TransparencyChessboardOptionsImpl(propertyChangeSupport);
zoomOptions = new ZoomOptionsImpl(propertyChangeSupport);
}
@Override
public GridOptions getGridOptions() {
return gridOptions;
}
@Override
public GridOptions getGridOptions() {
return gridOptions;
}
@Override
public TransparencyChessboardOptions getTransparencyChessboardOptions() {
return transparencyChessboardOptions;
}
@Override
public TransparencyChessboardOptions getTransparencyChessboardOptions() {
return transparencyChessboardOptions;
}
@Override
public ZoomOptions getZoomOptions() {
return zoomOptions;
}
@Override
public ZoomOptions getZoomOptions() {
return zoomOptions;
}
@Override
public EditorOptions clone() throws CloneNotSupportedException {
return (EditorOptions)super.clone();
}
@Override
public EditorOptions clone() throws CloneNotSupportedException {
return (EditorOptions)super.clone();
}
@Override
public void inject(EditorOptions options) {
gridOptions.inject(options.getGridOptions());
transparencyChessboardOptions.inject(options.getTransparencyChessboardOptions());
zoomOptions.inject(options.getZoomOptions());
}
@Override
public void inject(EditorOptions options) {
gridOptions.inject(options.getGridOptions());
transparencyChessboardOptions.inject(options.getTransparencyChessboardOptions());
zoomOptions.inject(options.getZoomOptions());
}
@Override
public boolean setOption(String name, Object value) {
return gridOptions.setOption(name, value) ||
transparencyChessboardOptions.setOption(name, value) ||
zoomOptions.setOption(name, value);
}
@Override
public boolean setOption(String name, Object value) {
return gridOptions.setOption(name, value) ||
transparencyChessboardOptions.setOption(name, value) ||
zoomOptions.setOption(name, value);
}
@Override
public boolean isFileNameVisible() {
return fileNameVisible;
}
@Override
public boolean isFileNameVisible() {
return fileNameVisible;
}
@Override
public void setFileNameVisible(boolean fileNameVisible) {
this.fileNameVisible = fileNameVisible;
}
@Override
public void setFileNameVisible(boolean fileNameVisible) {
this.fileNameVisible = fileNameVisible;
}
@Override
public void setFileSizeVisible(boolean fileSizeVisible) {
this.fileSizeVisible = fileSizeVisible;
}
@Override
public void setFileSizeVisible(boolean fileSizeVisible) {
this.fileSizeVisible = fileSizeVisible;
}
@Override
public boolean isFileSizeVisible() {
return fileSizeVisible;
}
@Override
public boolean isFileSizeVisible() {
return fileSizeVisible;
}
@Override
public void readExternal(Element element) throws InvalidDataException {
((JDOMExternalizable)transparencyChessboardOptions).readExternal(element);
String fileNameVisibleAttr = element.getAttributeValue("fileNameVisible");
fileNameVisible = fileNameVisibleAttr == null || Boolean.parseBoolean(fileNameVisibleAttr);
String fileSizeVisibleAttr = element.getAttributeValue("fileSizeVisible");
fileSizeVisible = fileNameVisibleAttr == null || Boolean.parseBoolean(fileSizeVisibleAttr);
}
@Override
public void readExternal(Element element) throws InvalidDataException {
((JDOMExternalizable)transparencyChessboardOptions).readExternal(element);
String fileNameVisibleAttr = element.getAttributeValue("fileNameVisible");
fileNameVisible = fileNameVisibleAttr == null || Boolean.parseBoolean(fileNameVisibleAttr);
String fileSizeVisibleAttr = element.getAttributeValue("fileSizeVisible");
fileSizeVisible = fileNameVisibleAttr == null || Boolean.parseBoolean(fileSizeVisibleAttr);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
((JDOMExternalizable)transparencyChessboardOptions).writeExternal(element);
if (!fileNameVisible) {
element.setAttribute("fileNameVisible", "false");
}
if (!fileSizeVisible) {
element.setAttribute("fileSizeVisible", "false");
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
((JDOMExternalizable)transparencyChessboardOptions).writeExternal(element);
if (!fileNameVisible) {
element.setAttribute("fileNameVisible", "false");
}
if (!fileSizeVisible) {
element.setAttribute("fileSizeVisible", "false");
}
}
}

View File

@@ -36,5 +36,4 @@ public abstract class ThumbnailManager {
*/
@NotNull
public abstract ThumbnailView getThumbnailView();
}

View File

@@ -12,37 +12,37 @@ import org.jetbrains.annotations.NotNull;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class ThumbnailViewActionUtil {
private ThumbnailViewActionUtil() {
}
private ThumbnailViewActionUtil() {
}
/**
* Extract current thumbnail view from event context.
*
* @param e Action event
* @return Current {@link ThumbnailView} or {@code null}
*/
public static ThumbnailView getVisibleThumbnailView(@NotNull AnActionEvent e) {
ThumbnailView thumbnailView = getThumbnailView(e);
if (thumbnailView != null && thumbnailView.isVisible()) {
return thumbnailView;
}
return null;
/**
* Extract current thumbnail view from event context.
*
* @param e Action event
* @return Current {@link ThumbnailView} or {@code null}
*/
public static ThumbnailView getVisibleThumbnailView(@NotNull AnActionEvent e) {
ThumbnailView thumbnailView = getThumbnailView(e);
if (thumbnailView != null && thumbnailView.isVisible()) {
return thumbnailView;
}
return null;
}
public static ThumbnailView getThumbnailView(@NotNull AnActionEvent e) {
return e.getData(ThumbnailView.DATA_KEY);
}
public static ThumbnailView getThumbnailView(@NotNull AnActionEvent e) {
return e.getData(ThumbnailView.DATA_KEY);
}
/**
* Enable or disable current action from event.
*
* @param e Action event
* @return Enabled value
*/
public static boolean setEnabled(@NotNull AnActionEvent e) {
ThumbnailView thumbnailView = getVisibleThumbnailView(e);
Presentation presentation = e.getPresentation();
presentation.setEnabled(thumbnailView != null);
return presentation.isEnabled();
}
/**
* Enable or disable current action from event.
*
* @param e Action event
* @return Enabled value
*/
public static boolean setEnabled(@NotNull AnActionEvent e) {
ThumbnailView thumbnailView = getVisibleThumbnailView(e);
Presentation presentation = e.getPresentation();
presentation.setEnabled(thumbnailView != null);
return presentation.isEnabled();
}
}

View File

@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NonNls;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public interface ThumbnailViewActions {
@NonNls String GROUP_POPUP = "Images.ThumbnailsPopupMenu";
@NonNls String GROUP_TOOLBAR = "Images.ThumbnailsToolbar";
@NonNls String ACTION_PLACE = "Images.Thumbnails";
@NonNls String GROUP_POPUP = "Images.ThumbnailsPopupMenu";
@NonNls String GROUP_TOOLBAR = "Images.ThumbnailsToolbar";
@NonNls String ACTION_PLACE = "Images.Thumbnails";
}

View File

@@ -18,48 +18,51 @@ import org.jetbrains.annotations.NotNull;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class EnterAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
if (view != null) {
VirtualFile[] selection = view.getSelection();
if (selection.length == 1 && selection[0].isDirectory()) {
view.setRoot(selection[0]);
} else if (selection.length > 0) {
FileEditorManager fileEditorManager = FileEditorManager.getInstance(view.getProject());
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : selection) {
if (typeManager.isImage(file)) {
fileEditorManager.openFile(file, false);
}
}
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
if (view != null) {
VirtualFile[] selection = view.getSelection();
if (selection.length == 1 && selection[0].isDirectory()) {
view.setRoot(selection[0]);
}
else if (selection.length > 0) {
FileEditorManager fileEditorManager = FileEditorManager.getInstance(view.getProject());
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : selection) {
if (typeManager.isImage(file)) {
fileEditorManager.openFile(file, false);
}
}
}
}
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ThumbnailViewActionUtil.setEnabled(e)) {
Presentation presentation = e.getPresentation();
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
VirtualFile[] selection = view.getSelection();
if (selection.length > 0) {
if (selection.length == 1 && selection[0].isDirectory()) {
presentation.setVisible(true);
} else {
boolean notImages = false;
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : selection) {
notImages |= !typeManager.isImage(file);
}
presentation.setEnabled(!notImages);
presentation.setVisible(false);
}
} else {
presentation.setEnabledAndVisible(false);
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ThumbnailViewActionUtil.setEnabled(e)) {
Presentation presentation = e.getPresentation();
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
VirtualFile[] selection = view.getSelection();
if (selection.length > 0) {
if (selection.length == 1 && selection[0].isDirectory()) {
presentation.setVisible(true);
}
else {
boolean notImages = false;
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : selection) {
notImages |= !typeManager.isImage(file);
}
presentation.setEnabled(!notImages);
presentation.setVisible(false);
}
}
else {
presentation.setEnabledAndVisible(false);
}
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {

View File

@@ -35,87 +35,87 @@ import java.util.List;
public final class FilterByTagActionGroup extends ActionGroup implements PopupAction {
public FilterByTagActionGroup() {
setPopup(true);
public FilterByTagActionGroup() {
setPopup(true);
}
@Override
public void update(@NotNull final AnActionEvent e) {
Project project = e.getProject();
if (project == null) {
e.getPresentation().setEnabledAndVisible(false);
return;
}
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
ImageTagManager tagManager = ImageTagManager.getInstance(project);
e.getPresentation().setVisible(view != null && !tagManager.getAllTags().isEmpty());
TagFilter[] filters = view != null ? view.getTagFilters() : null;
e.getPresentation().setText(filters == null ? CommonBundle.message("action.text.all")
: StringUtil.join(filters, filter -> filter.getDisplayName(), ","));
e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheRight);
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
@Override
public AnAction @NotNull [] getChildren(@Nullable AnActionEvent e) {
if (e == null) return AnAction.EMPTY_ARRAY;
DefaultActionGroup group = new DefaultActionGroup();
Project project = e.getProject();
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
if (view == null) return AnAction.EMPTY_ARRAY;
ImageTagManager tagManager = ImageTagManager.getInstance(project);
List<MyToggleAction> tagActions =
ContainerUtil.map(tagManager.getAllTags(), (@NlsSafe var tag) -> new MyToggleAction(view, new TagFilter(tag, tagManager)));
group.add(new AnAction(IdeBundle.messagePointer("action.Anonymous.text.all")) {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
for (MyToggleAction tagAction : tagActions) {
tagAction.setSelected(e, false);
}
}
});
group.add(Separator.getInstance());
group.addAll(tagActions);
return group.getChildren(e);
}
private static class MyToggleAction extends ToggleAction {
private final ThumbnailView myView;
private final TagFilter myFilter;
MyToggleAction(ThumbnailView view, TagFilter filter) {
super(filter.getDisplayName());
myView = view;
myFilter = filter;
}
@Override
public void update(@NotNull final AnActionEvent e) {
Project project = e.getProject();
if (project == null) {
e.getPresentation().setEnabledAndVisible(false);
return;
}
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
ImageTagManager tagManager = ImageTagManager.getInstance(project);
e.getPresentation().setVisible(view != null && !tagManager.getAllTags().isEmpty());
TagFilter[] filters = view != null ? view.getTagFilters() : null;
e.getPresentation().setText(filters == null ? CommonBundle.message("action.text.all")
: StringUtil.join(filters, filter -> filter.getDisplayName(), ","));
e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheRight);
public boolean isSelected(@NotNull AnActionEvent e) {
TagFilter[] filters = myView.getTagFilters();
return filters != null && ContainerUtil.exists(filters, f -> myFilter.getDisplayName().equals(f.getDisplayName()));
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
return ActionUpdateThread.BGT;
}
@Override
public AnAction @NotNull [] getChildren(@Nullable AnActionEvent e) {
if (e == null) return AnAction.EMPTY_ARRAY;
DefaultActionGroup group = new DefaultActionGroup();
Project project = e.getProject();
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
if (view == null) return AnAction.EMPTY_ARRAY;
ImageTagManager tagManager = ImageTagManager.getInstance(project);
List<MyToggleAction> tagActions =
ContainerUtil.map(tagManager.getAllTags(), (@NlsSafe var tag) -> new MyToggleAction(view, new TagFilter(tag, tagManager)));
group.add(new AnAction(IdeBundle.messagePointer("action.Anonymous.text.all")) {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
for (MyToggleAction tagAction : tagActions) {
tagAction.setSelected(e, false);
}
}
});
group.add(Separator.getInstance());
group.addAll(tagActions);
return group.getChildren(e);
}
private static class MyToggleAction extends ToggleAction {
private final ThumbnailView myView;
private final TagFilter myFilter;
MyToggleAction(ThumbnailView view, TagFilter filter) {
super(filter.getDisplayName());
myView = view;
myFilter = filter;
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
TagFilter[] filters = myView.getTagFilters();
return filters != null && ContainerUtil.exists(filters, f -> myFilter.getDisplayName().equals(f.getDisplayName()));
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
if (state) {
myFilter.setFilter(myView);
}
else {
myFilter.clearFilter(myView);
}
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
if (state) {
myFilter.setFilter(myView);
}
else {
myFilter.clearFilter(myView);
}
}
}
}

View File

@@ -27,45 +27,45 @@ public final class FilterByThemeComboBoxAction extends ComboBoxAction {
@Override
public void update(@NotNull final AnActionEvent e) {
Project project = e.getProject();
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
boolean hasApplicableExtension =
ContainerUtil.and(ThemeFilter.EP_NAME.getExtensionList(), filter -> project != null && filter.isApplicableToProject(project));
e.getPresentation().setVisible(view != null && hasApplicableExtension);
ThemeFilter filter = view != null ? view.getFilter() : null;
e.getPresentation().setText(filter == null ? CommonBundle.message("action.text.all") : filter.getDisplayName());
public void update(@NotNull final AnActionEvent e) {
Project project = e.getProject();
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
boolean hasApplicableExtension =
ContainerUtil.and(ThemeFilter.EP_NAME.getExtensionList(), filter -> project != null && filter.isApplicableToProject(project));
e.getPresentation().setVisible(view != null && hasApplicableExtension);
ThemeFilter filter = view != null ? view.getFilter() : null;
e.getPresentation().setText(filter == null ? CommonBundle.message("action.text.all") : filter.getDisplayName());
}
@NotNull
@Override
protected DefaultActionGroup createPopupActionGroup(@NotNull JComponent button, @NotNull DataContext context) {
DefaultActionGroup group = new DefaultActionGroup();
group.add(new FilterImagesAction(new ThemeFilter() {
@Override
public String getDisplayName() {
return ImagesBundle.message("action.all.text");
}
@Override
public boolean accepts(VirtualFile file) {
return true;
}
@Override
public boolean isApplicableToProject(Project project) {
return true;
}
@Override
public void setFilter(ThumbnailView view) {
view.setFilter(this);
}
}));
for (ThemeFilter filter : ThemeFilter.EP_NAME.getExtensionList()) {
group.add(new FilterImagesAction(filter));
}
@NotNull
@Override
protected DefaultActionGroup createPopupActionGroup(@NotNull JComponent button, @NotNull DataContext context) {
DefaultActionGroup group = new DefaultActionGroup();
group.add(new FilterImagesAction(new ThemeFilter() {
@Override
public String getDisplayName() {
return ImagesBundle.message("action.all.text");
}
@Override
public boolean accepts(VirtualFile file) {
return true;
}
@Override
public boolean isApplicableToProject(Project project) {
return true;
}
@Override
public void setFilter(ThumbnailView view) {
view.setFilter(this);
}
}));
for (ThemeFilter filter : ThemeFilter.EP_NAME.getExtensionList()) {
group.add(new FilterImagesAction(filter));
}
return group;
}
return group;
}
}

View File

@@ -14,28 +14,28 @@ import org.jetbrains.annotations.NotNull;
* @author Konstantin Bulenkov
*/
public class ShowBorderAction extends ToggleAction implements DumbAware {
public static final String PROP_NAME = "ImagePlugin.borderVisible";
public static final String PROP_NAME = "ImagePlugin.borderVisible";
public static boolean isBorderVisible() {
return PropertiesComponent.getInstance().getBoolean(PROP_NAME, false);
}
public static boolean isBorderVisible() {
return PropertiesComponent.getInstance().getBoolean(PROP_NAME, false);
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
return isBorderVisible();
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
return isBorderVisible();
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
PropertiesComponent.getInstance().setValue(PROP_NAME, state);
if (decorator != null) {
decorator.setBorderVisible(state);
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
ImageComponentDecorator decorator = ImageEditorActionUtil.getImageComponentDecorator(e);
PropertiesComponent.getInstance().setValue(PROP_NAME, state);
if (decorator != null) {
decorator.setBorderVisible(state);
}
}
}

View File

@@ -11,28 +11,29 @@ import org.intellij.images.ui.ImageComponentDecorator;
import org.jetbrains.annotations.NotNull;
public final class ToggleFileNameAction extends ToggleAction {
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
return decorator != null && decorator.isEnabledForActionPlace(e.getPlace()) && decorator.isFileNameVisible();
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
return decorator != null && decorator.isEnabledForActionPlace(e.getPlace()) && decorator.isFileNameVisible();
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
if (decorator != null && decorator.isEnabledForActionPlace(e.getPlace())) {
decorator.setFileNameVisible(state);
OptionsManager.getInstance().getOptions().getEditorOptions().setFileNameVisible(state);
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
if (decorator != null && decorator.isEnabledForActionPlace(e.getPlace())) {
decorator.setFileNameVisible(state);
OptionsManager.getInstance().getOptions().getEditorOptions().setFileNameVisible(state);
}
}
@Override
public void update(@NotNull final AnActionEvent e) {
super.update(e);
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
e.getPresentation().setEnabled(decorator != null && decorator.isEnabledForActionPlace(e.getPlace()));
e.getPresentation().setText(isSelected(e) ? IdeBundle.message("action.text.hide.file.name") : IdeBundle.message("action.text.show.file.name"));
}
@Override
public void update(@NotNull final AnActionEvent e) {
super.update(e);
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
e.getPresentation().setEnabled(decorator != null && decorator.isEnabledForActionPlace(e.getPlace()));
e.getPresentation().setText(isSelected(e) ? IdeBundle.message("action.text.hide.file.name") :
IdeBundle.message("action.text.show.file.name"));
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {

View File

@@ -11,28 +11,29 @@ import org.intellij.images.ui.ImageComponentDecorator;
import org.jetbrains.annotations.NotNull;
public final class ToggleFileSizeAction extends ToggleAction {
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
return decorator != null && decorator.isEnabledForActionPlace(e.getPlace()) && decorator.isFileSizeVisible();
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
return decorator != null && decorator.isEnabledForActionPlace(e.getPlace()) && decorator.isFileSizeVisible();
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
if (decorator != null && decorator.isEnabledForActionPlace(e.getPlace())) {
decorator.setFileSizeVisible(state);
OptionsManager.getInstance().getOptions().getEditorOptions().setFileSizeVisible(state);
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
if (decorator != null && decorator.isEnabledForActionPlace(e.getPlace())) {
decorator.setFileSizeVisible(state);
OptionsManager.getInstance().getOptions().getEditorOptions().setFileSizeVisible(state);
}
}
@Override
public void update(@NotNull final AnActionEvent e) {
super.update(e);
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
e.getPresentation().setEnabled(decorator != null && decorator.isEnabledForActionPlace(e.getPlace()));
e.getPresentation().setText(isSelected(e) ? IdeBundle.message("action.text.hide.file.size") : IdeBundle.message("action.text.show.file.size"));
}
@Override
public void update(@NotNull final AnActionEvent e) {
super.update(e);
ImageComponentDecorator decorator = e.getData(ImageComponentDecorator.DATA_KEY);
e.getPresentation().setEnabled(decorator != null && decorator.isEnabledForActionPlace(e.getPlace()));
e.getPresentation().setText(isSelected(e) ? IdeBundle.message("action.text.hide.file.size") :
IdeBundle.message("action.text.show.file.size"));
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {

View File

@@ -27,32 +27,34 @@ import org.intellij.images.thumbnail.actionSystem.ThumbnailViewActionUtil;
import org.jetbrains.annotations.NotNull;
public final class ToggleTagsPanelAction extends ToggleAction {
public static final String TAGS_PANEL_VISIBLE = "tags.panel.visible";
public static final String TAGS_PANEL_PROPORTION = "tags.panel.proportion";
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
Project project = e.getProject();
return project != null && PropertiesComponent.getInstance(project).getBoolean(TAGS_PANEL_VISIBLE, false);
}
public static final String TAGS_PANEL_VISIBLE = "tags.panel.visible";
public static final String TAGS_PANEL_PROPORTION = "tags.panel.proportion";
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
PropertiesComponent.getInstance(e.getProject()).setValue(TAGS_PANEL_VISIBLE, state);
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
assert view != null;
view.refresh();
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
Project project = e.getProject();
return project != null && PropertiesComponent.getInstance(project).getBoolean(TAGS_PANEL_VISIBLE, false);
}
@Override
public void update(@NotNull final AnActionEvent e) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
e.getPresentation().setEnabledAndVisible(view != null);
e.getPresentation().setText(isSelected(e) ? IdeBundle.message("action.text.hide.tags.panel") : IdeBundle.message("action.text.show.tags.panel"));
super.update(e);
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
PropertiesComponent.getInstance(e.getProject()).setValue(TAGS_PANEL_VISIBLE, state);
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
assert view != null;
view.refresh();
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
@Override
public void update(@NotNull final AnActionEvent e) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
e.getPresentation().setEnabledAndVisible(view != null);
e.getPresentation().setText(isSelected(e) ? IdeBundle.message("action.text.hide.tags.panel") :
IdeBundle.message("action.text.show.tags.panel"));
super.update(e);
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
}

View File

@@ -15,31 +15,31 @@ import org.jetbrains.annotations.NotNull;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class UpFolderAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
if (view != null) {
VirtualFile root = view.getRoot();
if (root != null) {
VirtualFile parent = root.getParent();
if (parent != null) {
view.setRoot(parent);
}
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
if (view != null) {
VirtualFile root = view.getRoot();
if (root != null) {
VirtualFile parent = root.getParent();
if (parent != null) {
view.setRoot(parent);
}
}
}
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ThumbnailViewActionUtil.setEnabled(e)) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
VirtualFile root = view.getRoot();
e.getPresentation().setEnabled(root != null && root.getParent() != null && !view.isRecursive());
}
@Override
public void update(@NotNull AnActionEvent e) {
if (ThumbnailViewActionUtil.setEnabled(e)) {
ThumbnailView view = ThumbnailViewActionUtil.getVisibleThumbnailView(e);
VirtualFile root = view.getRoot();
e.getPresentation().setEnabled(root != null && root.getParent() != null && !view.isRecursive());
}
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.EDT;
}
}

View File

@@ -32,393 +32,394 @@ import static com.intellij.ui.scale.ScaleType.OBJ_SCALE;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public class ImageComponent extends JComponent {
public static final int IMAGE_INSETS = 2;
public static final int IMAGE_INSETS = 2;
@NonNls
public static final String TRANSPARENCY_CHESSBOARD_CELL_SIZE_PROP = "TransparencyChessboard.cellSize";
@NonNls
public static final String TRANSPARENCY_CHESSBOARD_WHITE_COLOR_PROP = "TransparencyChessboard.whiteColor";
@NonNls
public static final String TRANSPARENCY_CHESSBOARD_BLACK_COLOR_PROP = "TransparencyChessboard.blackColor";
@NonNls
private static final String TRANSPARENCY_CHESSBOARD_VISIBLE_PROP = "TransparencyChessboard.visible";
@NonNls
private static final String GRID_LINE_ZOOM_FACTOR_PROP = "Grid.lineZoomFactor";
@NonNls
private static final String GRID_LINE_SPAN_PROP = "Grid.lineSpan";
@NonNls
private static final String GRID_LINE_COLOR_PROP = "Grid.lineColor";
@NonNls
private static final String GRID_VISIBLE_PROP = "Grid.visible";
@NonNls
private static final String FILE_SIZE_VISIBLE_PROP = "FileSize.visible";
@NonNls
private static final String FILE_NAME_VISIBLE_PROP = "FileName.visible";
@NonNls
public static final String TRANSPARENCY_CHESSBOARD_CELL_SIZE_PROP = "TransparencyChessboard.cellSize";
@NonNls
public static final String TRANSPARENCY_CHESSBOARD_WHITE_COLOR_PROP = "TransparencyChessboard.whiteColor";
@NonNls
public static final String TRANSPARENCY_CHESSBOARD_BLACK_COLOR_PROP = "TransparencyChessboard.blackColor";
@NonNls
private static final String TRANSPARENCY_CHESSBOARD_VISIBLE_PROP = "TransparencyChessboard.visible";
@NonNls
private static final String GRID_LINE_ZOOM_FACTOR_PROP = "Grid.lineZoomFactor";
@NonNls
private static final String GRID_LINE_SPAN_PROP = "Grid.lineSpan";
@NonNls
private static final String GRID_LINE_COLOR_PROP = "Grid.lineColor";
@NonNls
private static final String GRID_VISIBLE_PROP = "Grid.visible";
@NonNls
private static final String FILE_SIZE_VISIBLE_PROP = "FileSize.visible";
@NonNls
private static final String FILE_NAME_VISIBLE_PROP = "FileName.visible";
/**
* @see #getUIClassID
* @see #readObject
*/
@NonNls
private static final String uiClassID = "ImageComponentUI";
/**
* @see #getUIClassID
* @see #readObject
*/
@NonNls
private static final String uiClassID = "ImageComponentUI";
private final ImageDocument document = new ImageDocumentImpl(this);
private final Grid grid = new Grid();
private final Chessboard chessboard = new Chessboard();
private boolean myFileSizeVisible = true;
private boolean myFileNameVisible = true;
private double zoomFactor = 1d;
private boolean myBorderVisible = true;
private final ImageDocument document = new ImageDocumentImpl(this);
private final Grid grid = new Grid();
private final Chessboard chessboard = new Chessboard();
private boolean myFileSizeVisible = true;
private boolean myFileNameVisible = true;
private double zoomFactor = 1d;
private boolean myBorderVisible = true;
public ImageComponent() {
updateUI();
public ImageComponent() {
updateUI();
}
public ImageDocument getDocument() {
return document;
}
public double getZoomFactor() {
return zoomFactor;
}
public void setZoomFactor(double zoomFactor) {
this.zoomFactor = zoomFactor;
}
public void setTransparencyChessboardCellSize(int cellSize) {
int oldValue = chessboard.getCellSize();
if (oldValue != cellSize) {
chessboard.setCellSize(cellSize);
firePropertyChange(TRANSPARENCY_CHESSBOARD_CELL_SIZE_PROP, oldValue, cellSize);
}
}
public ImageDocument getDocument() {
return document;
public void setTransparencyChessboardWhiteColor(Color color) {
Color oldValue = chessboard.getWhiteColor();
if (oldValue != null && !oldValue.equals(color) || oldValue == null && color != null) {
chessboard.setWhiteColor(color);
firePropertyChange(TRANSPARENCY_CHESSBOARD_WHITE_COLOR_PROP, oldValue, color);
}
}
public double getZoomFactor() {
return zoomFactor;
public void setTransparencyChessboardBlankColor(Color color) {
Color oldValue = chessboard.getBlackColor();
if (oldValue != null && !oldValue.equals(color) || oldValue == null && color != null) {
chessboard.setBlackColor(color);
firePropertyChange(TRANSPARENCY_CHESSBOARD_BLACK_COLOR_PROP, oldValue, color);
}
}
public void setZoomFactor(double zoomFactor) {
this.zoomFactor = zoomFactor;
public void setTransparencyChessboardVisible(boolean visible) {
boolean oldValue = chessboard.isVisible();
if (oldValue != visible) {
chessboard.setVisible(visible);
firePropertyChange(TRANSPARENCY_CHESSBOARD_VISIBLE_PROP, oldValue, visible);
}
}
public void setTransparencyChessboardCellSize(int cellSize) {
int oldValue = chessboard.getCellSize();
if (oldValue != cellSize) {
chessboard.setCellSize(cellSize);
firePropertyChange(TRANSPARENCY_CHESSBOARD_CELL_SIZE_PROP, oldValue, cellSize);
public int getTransparencyChessboardCellSize() {
return chessboard.getCellSize();
}
public Color getTransparencyChessboardWhiteColor() {
return chessboard.getWhiteColor();
}
public Color getTransparencyChessboardBlackColor() {
return chessboard.getBlackColor();
}
public boolean isTransparencyChessboardVisible() {
return chessboard.isVisible();
}
public boolean isFileSizeVisible() {
return myFileSizeVisible;
}
public void setFileSizeVisible(boolean fileSizeVisible) {
boolean oldValue = myFileSizeVisible;
myFileSizeVisible = fileSizeVisible;
firePropertyChange(FILE_SIZE_VISIBLE_PROP, oldValue, fileSizeVisible);
}
public boolean isFileNameVisible() {
return myFileNameVisible;
}
public void setFileNameVisible(boolean fileNameVisible) {
boolean oldValue = myFileNameVisible;
myFileNameVisible = fileNameVisible;
firePropertyChange(FILE_NAME_VISIBLE_PROP, oldValue, fileNameVisible);
}
public boolean isBorderVisible() {
return myBorderVisible;
}
public void setBorderVisible(boolean borderVisible) {
boolean oldValue = myBorderVisible;
myBorderVisible = borderVisible;
firePropertyChange("Border.visible", oldValue, myBorderVisible);
}
public void setGridLineZoomFactor(int lineZoomFactor) {
int oldValue = grid.getLineZoomFactor();
if (oldValue != lineZoomFactor) {
grid.setLineZoomFactor(lineZoomFactor);
firePropertyChange(GRID_LINE_ZOOM_FACTOR_PROP, oldValue, lineZoomFactor);
}
}
public void setGridLineSpan(int lineSpan) {
int oldValue = grid.getLineSpan();
if (oldValue != lineSpan) {
grid.setLineSpan(lineSpan);
firePropertyChange(GRID_LINE_SPAN_PROP, oldValue, lineSpan);
}
}
public void setGridLineColor(Color color) {
Color oldValue = grid.getLineColor();
if (oldValue != null && !oldValue.equals(color) || oldValue == null && color != null) {
grid.setLineColor(color);
firePropertyChange(GRID_LINE_COLOR_PROP, oldValue, color);
}
}
public void setGridVisible(boolean visible) {
boolean oldValue = grid.isVisible();
if (oldValue != visible) {
grid.setVisible(visible);
firePropertyChange(GRID_VISIBLE_PROP, oldValue, visible);
}
}
public int getGridLineZoomFactor() {
return grid.getLineZoomFactor();
}
public int getGridLineSpan() {
return grid.getLineSpan();
}
public Color getGridLineColor() {
return grid.getLineColor();
}
public boolean isGridVisible() {
return grid.isVisible();
}
@Nullable
public String getDescription() {
BufferedImage image = getDocument().getValue();
if (image != null) {
return ImagesBundle.message("icon.dimensions", image.getWidth(), image.getHeight(), image.getColorModel().getPixelSize());
}
return null;
}
public void setCanvasSize(int width, int height) {
setSize(width + IMAGE_INSETS * 2, height + IMAGE_INSETS * 2);
}
public void setCanvasSize(Dimension dimension) {
setCanvasSize(dimension.width, dimension.height);
}
public Dimension getCanvasSize() {
Dimension size = getSize();
return new Dimension(size.width - IMAGE_INSETS * 2, size.height - IMAGE_INSETS * 2);
}
@Override
public String getUIClassID() {
return uiClassID;
}
@Override
public void updateUI() {
boolean customUI = UIManager.getDefaults().get(uiClassID) != null;
setUI(customUI ? UIManager.getUI(this) : new ImageComponentUI(this));
}
private static class ImageDocumentImpl implements ImageDocument {
private final List<ChangeListener> listeners = ContainerUtil.createLockFreeCopyOnWriteList();
private CachedScaledImageProvider imageProvider;
private String format;
private Image renderer;
private final Component myComponent;
private final ScaleContextCache<Rectangle> cachedBounds = new ScaleContextCache<>((ctx) -> {
BufferedImage image = getValue(ctx.getScale(OBJ_SCALE));
return image != null ? new Rectangle(image.getWidth(), image.getHeight()) : null;
});
ImageDocumentImpl(Component component) {
myComponent = component;
myComponent.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals("ancestor") && e.getNewValue() == null && imageProvider != null) {
imageProvider.clearCache();
}
}
});
}
public void setTransparencyChessboardWhiteColor(Color color) {
Color oldValue = chessboard.getWhiteColor();
if (oldValue != null && !oldValue.equals(color) || oldValue == null && color != null) {
chessboard.setWhiteColor(color);
firePropertyChange(TRANSPARENCY_CHESSBOARD_WHITE_COLOR_PROP, oldValue, color);
}
@Override
public Image getRenderer() {
return renderer;
}
public void setTransparencyChessboardBlankColor(Color color) {
Color oldValue = chessboard.getBlackColor();
if (oldValue != null && !oldValue.equals(color) || oldValue == null && color != null) {
chessboard.setBlackColor(color);
firePropertyChange(TRANSPARENCY_CHESSBOARD_BLACK_COLOR_PROP, oldValue, color);
}
}
public void setTransparencyChessboardVisible(boolean visible) {
boolean oldValue = chessboard.isVisible();
if (oldValue != visible) {
chessboard.setVisible(visible);
firePropertyChange(TRANSPARENCY_CHESSBOARD_VISIBLE_PROP, oldValue, visible);
}
}
public int getTransparencyChessboardCellSize() {
return chessboard.getCellSize();
}
public Color getTransparencyChessboardWhiteColor() {
return chessboard.getWhiteColor();
}
public Color getTransparencyChessboardBlackColor() {
return chessboard.getBlackColor();
}
public boolean isTransparencyChessboardVisible() {
return chessboard.isVisible();
}
public boolean isFileSizeVisible() {
return myFileSizeVisible;
}
public void setFileSizeVisible(boolean fileSizeVisible) {
boolean oldValue = myFileSizeVisible;
myFileSizeVisible = fileSizeVisible;
firePropertyChange(FILE_SIZE_VISIBLE_PROP, oldValue, fileSizeVisible);
}
public boolean isFileNameVisible() {
return myFileNameVisible;
}
public void setFileNameVisible(boolean fileNameVisible) {
boolean oldValue = myFileNameVisible;
myFileNameVisible = fileNameVisible;
firePropertyChange(FILE_NAME_VISIBLE_PROP, oldValue, fileNameVisible);
}
public boolean isBorderVisible() {
return myBorderVisible;
}
public void setBorderVisible(boolean borderVisible) {
boolean oldValue = myBorderVisible;
myBorderVisible = borderVisible;
firePropertyChange("Border.visible", oldValue, myBorderVisible);
}
public void setGridLineZoomFactor(int lineZoomFactor) {
int oldValue = grid.getLineZoomFactor();
if (oldValue != lineZoomFactor) {
grid.setLineZoomFactor(lineZoomFactor);
firePropertyChange(GRID_LINE_ZOOM_FACTOR_PROP, oldValue, lineZoomFactor);
}
}
public void setGridLineSpan(int lineSpan) {
int oldValue = grid.getLineSpan();
if (oldValue != lineSpan) {
grid.setLineSpan(lineSpan);
firePropertyChange(GRID_LINE_SPAN_PROP, oldValue, lineSpan);
}
}
public void setGridLineColor(Color color) {
Color oldValue = grid.getLineColor();
if (oldValue != null && !oldValue.equals(color) || oldValue == null && color != null) {
grid.setLineColor(color);
firePropertyChange(GRID_LINE_COLOR_PROP, oldValue, color);
}
}
public void setGridVisible(boolean visible) {
boolean oldValue = grid.isVisible();
if (oldValue != visible) {
grid.setVisible(visible);
firePropertyChange(GRID_VISIBLE_PROP, oldValue, visible);
}
}
public int getGridLineZoomFactor() {
return grid.getLineZoomFactor();
}
public int getGridLineSpan() {
return grid.getLineSpan();
}
public Color getGridLineColor() {
return grid.getLineColor();
}
public boolean isGridVisible() {
return grid.isVisible();
@Override
public Image getRenderer(double scale) {
return getValue(scale);
}
@Nullable
public String getDescription() {
BufferedImage image = getDocument().getValue();
if (image != null) {
return ImagesBundle.message("icon.dimensions", image.getWidth(), image.getHeight(), image.getColorModel().getPixelSize());
}
return null;
}
public void setCanvasSize(int width, int height) {
setSize(width + IMAGE_INSETS * 2, height + IMAGE_INSETS * 2);
}
public void setCanvasSize(Dimension dimension) {
setCanvasSize(dimension.width, dimension.height);
}
public Dimension getCanvasSize() {
Dimension size = getSize();
return new Dimension(size.width - IMAGE_INSETS * 2, size.height - IMAGE_INSETS * 2);
@Override
public Rectangle getBounds(double scale) {
ScaleContext ctx = ScaleContext.create(myComponent);
ctx.setScale(OBJ_SCALE.of(scale));
return cachedBounds.getOrProvide(ctx);
}
@Override
public String getUIClassID() {
return uiClassID;
public BufferedImage getValue() {
return getValue(1d);
}
@Override
public void updateUI() {
boolean customUI = UIManager.getDefaults().get(uiClassID) != null;
setUI(customUI ? UIManager.getUI(this) : new ImageComponentUI(this));
public BufferedImage getValue(double scale) {
return imageProvider != null ? imageProvider.apply(scale, myComponent) : null;
}
private static class ImageDocumentImpl implements ImageDocument {
private final List<ChangeListener> listeners = ContainerUtil.createLockFreeCopyOnWriteList();
private CachedScaledImageProvider imageProvider;
private String format;
private Image renderer;
private final Component myComponent;
private final ScaleContextCache<Rectangle> cachedBounds = new ScaleContextCache<>((ctx) -> {
BufferedImage image = getValue(ctx.getScale(OBJ_SCALE));
return image != null ? new Rectangle(image.getWidth(), image.getHeight()) : null;
});
ImageDocumentImpl(Component component) {
myComponent = component;
myComponent.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals("ancestor") && e.getNewValue() == null && imageProvider != null) {
imageProvider.clearCache();
}
}
});
}
@Override
public Image getRenderer() {
return renderer;
}
@Override
public Image getRenderer(double scale) {
return getValue(scale);
}
@Nullable
@Override
public Rectangle getBounds(double scale) {
ScaleContext ctx = ScaleContext.create(myComponent);
ctx.setScale(OBJ_SCALE.of(scale));
return cachedBounds.getOrProvide(ctx);
}
@Override
public BufferedImage getValue() {
return getValue(1d);
}
@Override
public BufferedImage getValue(double scale) {
return imageProvider != null ? imageProvider.apply(scale, myComponent) : null;
}
@Override
public void setValue(BufferedImage image) {
this.renderer = image != null ? Toolkit.getDefaultToolkit().createImage(image.getSource()) : null;
setValue(image != null ? (scale, anchor) -> image : null);
}
@Override
public void setValue(ScaledImageProvider imageProvider) {
this.imageProvider = imageProvider instanceof CachedScaledImageProvider ?
(CachedScaledImageProvider)imageProvider :
imageProvider != null ? (zoom, ancestor) -> imageProvider.apply(zoom, ancestor) :
null;
cachedBounds.clear();
fireChangeEvent(new ChangeEvent(this));
}
@Override
public String getFormat() {
return format;
}
@Override
public void setFormat(String format) {
this.format = format;
fireChangeEvent(new ChangeEvent(this));
}
private void fireChangeEvent(ChangeEvent e) {
for (ChangeListener listener : listeners) {
listener.stateChanged(e);
}
}
@Override
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
@Override
public void setValue(BufferedImage image) {
this.renderer = image != null ? Toolkit.getDefaultToolkit().createImage(image.getSource()) : null;
setValue(image != null ? (scale, anchor) -> image : null);
}
private static final class Chessboard {
private int cellSize = TransparencyChessboardOptions.DEFAULT_CELL_SIZE;
private Color whiteColor = TransparencyChessboardOptions.DEFAULT_WHITE_COLOR;
private Color blackColor = TransparencyChessboardOptions.DEFAULT_BLACK_COLOR;
private boolean visible = false;
@Override
public void setValue(ScaledImageProvider imageProvider) {
this.imageProvider =
imageProvider instanceof CachedScaledImageProvider ?
(CachedScaledImageProvider)imageProvider :
imageProvider != null ? (zoom, ancestor) -> imageProvider.apply(zoom, ancestor) :
null;
public int getCellSize() {
return cellSize;
}
public void setCellSize(int cellSize) {
this.cellSize = cellSize;
}
public Color getWhiteColor() {
return whiteColor;
}
public void setWhiteColor(Color whiteColor) {
this.whiteColor = whiteColor;
}
public Color getBlackColor() {
return blackColor;
}
public void setBlackColor(Color blackColor) {
this.blackColor = blackColor;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
cachedBounds.clear();
fireChangeEvent(new ChangeEvent(this));
}
private static final class Grid {
private int lineZoomFactor = GridOptions.DEFAULT_LINE_ZOOM_FACTOR;
private int lineSpan = GridOptions.DEFAULT_LINE_SPAN;
private Color lineColor = GridOptions.DEFAULT_LINE_COLOR;
private boolean visible = false;
public int getLineZoomFactor() {
return lineZoomFactor;
}
public void setLineZoomFactor(int lineZoomFactor) {
this.lineZoomFactor = lineZoomFactor;
}
public int getLineSpan() {
return lineSpan;
}
public void setLineSpan(int lineSpan) {
this.lineSpan = lineSpan;
}
public Color getLineColor() {
EditorColorsScheme editorScheme = EditorColorsManager.getInstance().getGlobalScheme();
Color color = editorScheme.getColor(ImageEditorColorSchemeSettingsKt.getGRID_LINE_COLOR_KEY());
return color != null ? color : JBColor.DARK_GRAY;
}
public void setLineColor(Color lineColor) {
this.lineColor = lineColor;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
@Override
public String getFormat() {
return format;
}
@Override
public void setFormat(String format) {
this.format = format;
fireChangeEvent(new ChangeEvent(this));
}
private void fireChangeEvent(ChangeEvent e) {
for (ChangeListener listener : listeners) {
listener.stateChanged(e);
}
}
@Override
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
}
private static final class Chessboard {
private int cellSize = TransparencyChessboardOptions.DEFAULT_CELL_SIZE;
private Color whiteColor = TransparencyChessboardOptions.DEFAULT_WHITE_COLOR;
private Color blackColor = TransparencyChessboardOptions.DEFAULT_BLACK_COLOR;
private boolean visible = false;
public int getCellSize() {
return cellSize;
}
public void setCellSize(int cellSize) {
this.cellSize = cellSize;
}
public Color getWhiteColor() {
return whiteColor;
}
public void setWhiteColor(Color whiteColor) {
this.whiteColor = whiteColor;
}
public Color getBlackColor() {
return blackColor;
}
public void setBlackColor(Color blackColor) {
this.blackColor = blackColor;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
}
private static final class Grid {
private int lineZoomFactor = GridOptions.DEFAULT_LINE_ZOOM_FACTOR;
private int lineSpan = GridOptions.DEFAULT_LINE_SPAN;
private Color lineColor = GridOptions.DEFAULT_LINE_COLOR;
private boolean visible = false;
public int getLineZoomFactor() {
return lineZoomFactor;
}
public void setLineZoomFactor(int lineZoomFactor) {
this.lineZoomFactor = lineZoomFactor;
}
public int getLineSpan() {
return lineSpan;
}
public void setLineSpan(int lineSpan) {
this.lineSpan = lineSpan;
}
public Color getLineColor() {
EditorColorsScheme editorScheme = EditorColorsManager.getInstance().getGlobalScheme();
Color color = editorScheme.getColor(ImageEditorColorSchemeSettingsKt.getGRID_LINE_COLOR_KEY());
return color != null ? color : JBColor.DARK_GRAY;
}
public void setLineColor(Color lineColor) {
this.lineColor = lineColor;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
}
}

View File

@@ -17,119 +17,120 @@ import java.awt.image.BufferedImage;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public class ImageComponentUI extends ComponentUI {
private BufferedImage pattern;
private BufferedImage pattern;
public ImageComponentUI(JComponent c) {
c.addPropertyChangeListener(evt -> {
String name = evt.getPropertyName();
if (ImageComponent.TRANSPARENCY_CHESSBOARD_BLACK_COLOR_PROP.equals(name) ||
ImageComponent.TRANSPARENCY_CHESSBOARD_WHITE_COLOR_PROP.equals(name) ||
ImageComponent.TRANSPARENCY_CHESSBOARD_CELL_SIZE_PROP.equals(name)) {
pattern = null;
}
});
}
public ImageComponentUI(JComponent c) {
c.addPropertyChangeListener(evt -> {
String name = evt.getPropertyName();
if (ImageComponent.TRANSPARENCY_CHESSBOARD_BLACK_COLOR_PROP.equals(name) ||
ImageComponent.TRANSPARENCY_CHESSBOARD_WHITE_COLOR_PROP.equals(name) ||
ImageComponent.TRANSPARENCY_CHESSBOARD_CELL_SIZE_PROP.equals(name)) {
pattern = null;
}
});
}
@Override
public void paint(Graphics g, JComponent c) {
ImageComponent ic = (ImageComponent)c;
if (ic != null) {
ImageDocument document = ic.getDocument();
BufferedImage image = document.getValue(ic.getZoomFactor());
if (image != null) {
if (ic.isFileSizeVisible() && ic.isBorderVisible()) paintBorder(g, ic);
@Override
public void paint(Graphics g, JComponent c) {
ImageComponent ic = (ImageComponent)c;
if (ic != null) {
ImageDocument document = ic.getDocument();
BufferedImage image = document.getValue(ic.getZoomFactor());
if (image != null) {
if (ic.isFileSizeVisible() && ic.isBorderVisible()) paintBorder(g, ic);
Dimension size = ic.getCanvasSize();
Graphics igc = g.create(ImageComponent.IMAGE_INSETS, ImageComponent.IMAGE_INSETS, size.width, size.height);
// Transparency chessboard
if (ic.isTransparencyChessboardVisible() && image.getTransparency() != Transparency.OPAQUE) {
paintChessboard(igc, ic);
}
paintImage(igc, ic);
// Grid
if (ic.isGridVisible()) {
paintGrid(igc, ic);
}
igc.dispose();
}
}
}
private static void paintBorder(Graphics g, ImageComponent ic) {
Dimension size = ic.getSize();
g.setColor(ic.getTransparencyChessboardBlackColor());
g.drawRect(0, 0, size.width - 1, size.height - 1);
}
private void paintChessboard(Graphics g, ImageComponent ic) {
Dimension size = ic.getCanvasSize();
// Create pattern
int cellSize = ic.getTransparencyChessboardCellSize();
int patternSize = 2 * cellSize;
Graphics igc = g.create(ImageComponent.IMAGE_INSETS, ImageComponent.IMAGE_INSETS, size.width, size.height);
if (pattern == null) {
pattern = ImageUtil.createImage(g, patternSize, patternSize, BufferedImage.TYPE_INT_ARGB);
Graphics imageGraphics = pattern.getGraphics();
imageGraphics.setColor(ic.getTransparencyChessboardWhiteColor());
imageGraphics.fillRect(0, 0, patternSize, patternSize);
imageGraphics.setColor(ic.getTransparencyChessboardBlackColor());
imageGraphics.fillRect(0, cellSize, cellSize, cellSize);
imageGraphics.fillRect(cellSize, 0, cellSize, cellSize);
// Transparency chessboard
if (ic.isTransparencyChessboardVisible() && image.getTransparency() != Transparency.OPAQUE) {
paintChessboard(igc, ic);
}
((Graphics2D)g).setPaint(new TexturePaint(pattern, new Rectangle(0, 0, patternSize, patternSize)));
g.fillRect(0, 0, size.width, size.height);
}
paintImage(igc, ic);
private static void paintImage(Graphics g, ImageComponent ic) {
ImageDocument document = ic.getDocument();
Dimension size = ic.getCanvasSize();
Graphics2D g2d = (Graphics2D)g;
RenderingHints oldHints = g2d.getRenderingHints();
BufferedImage image = document.getValue(ic.getZoomFactor());
if (image == null) return;
if (size.width > image.getWidth() && size.height > image.getHeight()) {
// disable any kind of source image manipulation when resizing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
} else {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// Grid
if (ic.isGridVisible()) {
paintGrid(igc, ic);
}
StartupUiUtil.drawImage(g, image, new Rectangle(0, 0, size.width, size.height), ic);
g2d.setRenderingHints(oldHints);
igc.dispose();
}
}
}
private static void paintBorder(Graphics g, ImageComponent ic) {
Dimension size = ic.getSize();
g.setColor(ic.getTransparencyChessboardBlackColor());
g.drawRect(0, 0, size.width - 1, size.height - 1);
}
private void paintChessboard(Graphics g, ImageComponent ic) {
Dimension size = ic.getCanvasSize();
// Create pattern
int cellSize = ic.getTransparencyChessboardCellSize();
int patternSize = 2 * cellSize;
if (pattern == null) {
pattern = ImageUtil.createImage(g, patternSize, patternSize, BufferedImage.TYPE_INT_ARGB);
Graphics imageGraphics = pattern.getGraphics();
imageGraphics.setColor(ic.getTransparencyChessboardWhiteColor());
imageGraphics.fillRect(0, 0, patternSize, patternSize);
imageGraphics.setColor(ic.getTransparencyChessboardBlackColor());
imageGraphics.fillRect(0, cellSize, cellSize, cellSize);
imageGraphics.fillRect(cellSize, 0, cellSize, cellSize);
}
private static void paintGrid(Graphics g, ImageComponent ic) {
Dimension size = ic.getCanvasSize();
BufferedImage image = ic.getDocument().getValue();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double zoomX = (double)size.width / (double)imageWidth;
double zoomY = (double)size.height / (double)imageHeight;
double zoomFactor = (zoomX + zoomY) / 2.0d;
if (zoomFactor >= ic.getGridLineZoomFactor()) {
g.setColor(ic.getGridLineColor());
int ls = ic.getGridLineSpan();
for (int dx = ls; dx < imageWidth; dx += ls) {
LinePainter2D.paint((Graphics2D)g, (int)((double)dx * zoomX), 0, (int)((double)dx * zoomX), size.height);
}
for (int dy = ls; dy < imageHeight; dy += ls) {
LinePainter2D.paint((Graphics2D)g, 0, (int)((double)dy * zoomY), size.width, (int)((double)dy * zoomY));
}
}
}
((Graphics2D)g).setPaint(new TexturePaint(pattern, new Rectangle(0, 0, patternSize, patternSize)));
g.fillRect(0, 0, size.width, size.height);
}
@SuppressWarnings({"UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new ImageComponentUI(c);
private static void paintImage(Graphics g, ImageComponent ic) {
ImageDocument document = ic.getDocument();
Dimension size = ic.getCanvasSize();
Graphics2D g2d = (Graphics2D)g;
RenderingHints oldHints = g2d.getRenderingHints();
BufferedImage image = document.getValue(ic.getZoomFactor());
if (image == null) return;
if (size.width > image.getWidth() && size.height > image.getHeight()) {
// disable any kind of source image manipulation when resizing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
}
else {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}
StartupUiUtil.drawImage(g, image, new Rectangle(0, 0, size.width, size.height), ic);
g2d.setRenderingHints(oldHints);
}
private static void paintGrid(Graphics g, ImageComponent ic) {
Dimension size = ic.getCanvasSize();
BufferedImage image = ic.getDocument().getValue();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double zoomX = (double)size.width / (double)imageWidth;
double zoomY = (double)size.height / (double)imageHeight;
double zoomFactor = (zoomX + zoomY) / 2.0d;
if (zoomFactor >= ic.getGridLineZoomFactor()) {
g.setColor(ic.getGridLineColor());
int ls = ic.getGridLineSpan();
for (int dx = ls; dx < imageWidth; dx += ls) {
LinePainter2D.paint((Graphics2D)g, (int)((double)dx * zoomX), 0, (int)((double)dx * zoomX), size.height);
}
for (int dy = ls; dy < imageHeight; dy += ls) {
LinePainter2D.paint((Graphics2D)g, 0, (int)((double)dy * zoomY), size.width, (int)((double)dy * zoomY));
}
}
}
@SuppressWarnings({"UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new ImageComponentUI(c);
}
}

View File

@@ -26,118 +26,118 @@ import javax.swing.*;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public class ThumbnailComponent extends JComponent {
@NonNls
private static final String FORMAT_PROP = "format";
@NonNls
private static final String FILE_SIZE_PROP = "fileSize";
@NonNls
private static final String FILE_NAME_PROP = "fileName";
@NonNls
private static final String DIRECTORY_PROP = "directory";
@NonNls
private static final String IMAGES_COUNT_PROP = "imagesCount";
@NonNls
private static final String FORMAT_PROP = "format";
@NonNls
private static final String FILE_SIZE_PROP = "fileSize";
@NonNls
private static final String FILE_NAME_PROP = "fileName";
@NonNls
private static final String DIRECTORY_PROP = "directory";
@NonNls
private static final String IMAGES_COUNT_PROP = "imagesCount";
/**
* @see #getUIClassID
* @see #readObject
*/
@NonNls
private static final String uiClassID = "ThumbnailComponentUI";
/**
* @see #getUIClassID
* @see #readObject
*/
@NonNls
private static final String uiClassID = "ThumbnailComponentUI";
static {
UIManager.getDefaults().put(uiClassID, ThumbnailComponentUI.class.getName());
static {
UIManager.getDefaults().put(uiClassID, ThumbnailComponentUI.class.getName());
}
/**
* Image component for rendering thumbnail image.
*/
private final ImageComponent imageComponent = new ImageComponent();
private String format;
private long fileSize;
private String fileName;
private boolean directory;
private int imagesCount;
public ThumbnailComponent() {
updateUI();
}
public ImageComponent getImageComponent() {
return imageComponent;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
String oldValue = this.format;
if (oldValue != null && !oldValue.equals(format) || oldValue == null && format != null) {
this.format = format;
firePropertyChange(FORMAT_PROP, oldValue, this.format);
}
}
/**
* Image component for rendering thumbnail image.
*/
private final ImageComponent imageComponent = new ImageComponent();
public long getFileSize() {
return fileSize;
}
private String format;
private long fileSize;
private String fileName;
private boolean directory;
private int imagesCount;
public ThumbnailComponent() {
updateUI();
public void setFileSize(long fileSize) {
long oldValue = this.fileSize;
if (oldValue != fileSize) {
this.fileSize = fileSize;
firePropertyChange(FILE_SIZE_PROP, Long.valueOf(oldValue), Long.valueOf(this.fileSize));
}
}
public ImageComponent getImageComponent() {
return imageComponent;
}
public String getFileName() {
return fileName;
}
public String getFormat() {
return format;
public void setFileName(String fileName) {
String oldValue = this.fileName;
if (oldValue != null && !oldValue.equals(fileName) || oldValue == null && fileName != null) {
this.fileName = fileName;
firePropertyChange(FILE_NAME_PROP, oldValue, this.fileName);
}
}
public void setFormat(String format) {
String oldValue = this.format;
if (oldValue != null && !oldValue.equals(format) || oldValue == null && format != null) {
this.format = format;
firePropertyChange(FORMAT_PROP, oldValue, this.format);
}
}
public boolean isDirectory() {
return directory;
}
public long getFileSize() {
return fileSize;
public void setDirectory(boolean directory) {
boolean oldValue = this.directory;
if (oldValue != directory) {
this.directory = directory;
firePropertyChange(DIRECTORY_PROP, oldValue, this.directory);
}
}
public void setFileSize(long fileSize) {
long oldValue = this.fileSize;
if (oldValue != fileSize) {
this.fileSize = fileSize;
firePropertyChange(FILE_SIZE_PROP, Long.valueOf(oldValue), Long.valueOf(this.fileSize));
}
}
public int getImagesCount() {
return imagesCount;
}
public String getFileName() {
return fileName;
public void setImagesCount(int imagesCount) {
int oldValue = this.imagesCount;
if (oldValue != imagesCount) {
this.imagesCount = imagesCount;
firePropertyChange(IMAGES_COUNT_PROP, oldValue, this.imagesCount);
}
}
public void setFileName(String fileName) {
String oldValue = this.fileName;
if (oldValue != null && !oldValue.equals(fileName) || oldValue == null && fileName != null) {
this.fileName = fileName;
firePropertyChange(FILE_NAME_PROP, oldValue, this.fileName);
}
}
public String getFileSizeText() {
return StringUtil.formatFileSize(fileSize);
}
public boolean isDirectory() {
return directory;
}
@Override
public void updateUI() {
setUI(UIManager.getUI(this));
}
public void setDirectory(boolean directory) {
boolean oldValue = this.directory;
if (oldValue != directory) {
this.directory = directory;
firePropertyChange(DIRECTORY_PROP, oldValue, this.directory);
}
}
public int getImagesCount() {
return imagesCount;
}
public void setImagesCount(int imagesCount) {
int oldValue = this.imagesCount;
if (oldValue != imagesCount) {
this.imagesCount = imagesCount;
firePropertyChange(IMAGES_COUNT_PROP, oldValue, this.imagesCount);
}
}
public String getFileSizeText() {
return StringUtil.formatFileSize(fileSize);
}
@Override
public void updateUI() {
setUI(UIManager.getUI(this));
}
@Override
public String getUIClassID() {
return uiClassID;
}
@Override
public String getUIClassID() {
return uiClassID;
}
}

View File

@@ -22,249 +22,257 @@ import java.awt.image.BufferedImage;
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public class ThumbnailComponentUI extends ComponentUI {
@NonNls
private static final String DOTS = "...";
@NonNls
private static final String DOTS = "...";
private static final Color LINE_COLOR = new Color(0x8E, 0xA8, 0xCE);
private static final Color PNG_COLOR = new Color(0x80, 0x00, 0x80);
private static final Color GIF_COLOR = new Color(0x00, 0x80, 0x00);
private static final Color JPG_COLOR = new Color(0x80, 0x80, 0x00);
private static final Color BMP_COLOR = new Color(0x00, 0x00, 0x80);
private static final Color LINE_COLOR = new Color(0x8E, 0xA8, 0xCE);
private static final Color PNG_COLOR = new Color(0x80, 0x00, 0x80);
private static final Color GIF_COLOR = new Color(0x00, 0x80, 0x00);
private static final Color JPG_COLOR = new Color(0x80, 0x80, 0x00);
private static final Color BMP_COLOR = new Color(0x00, 0x00, 0x80);
private static final ThumbnailComponentUI ui = new ThumbnailComponentUI();
private static final ThumbnailComponentUI ui = new ThumbnailComponentUI();
@Override
public void paint(Graphics g, JComponent c) {
ThumbnailComponent tc = (ThumbnailComponent) c;
if (tc != null) {
UISettings.setupAntialiasing(g);
paintBackground(g, tc);
@Override
public void paint(Graphics g, JComponent c) {
ThumbnailComponent tc = (ThumbnailComponent)c;
if (tc != null) {
UISettings.setupAntialiasing(g);
paintBackground(g, tc);
if (tc.isDirectory()) {
paintDirectory(g, tc);
} else {
paintImageThumbnail(g, tc);
}
if (tc.isDirectory()) {
paintDirectory(g, tc);
}
else {
paintImageThumbnail(g, tc);
}
// File name
if (tc.isDirectory() || tc.getImageComponent().isFileNameVisible()) paintFileName(g, tc);
}
// File name
if (tc.isDirectory() || tc.getImageComponent().isFileNameVisible()) paintFileName(g, tc);
}
}
private static void paintDirectory(Graphics g, ThumbnailComponent tc) {
// Paint directory icon
ImagesIcons.ThumbnailDirectory.paintIcon(tc, g, 5, 5);
int imagesCount = tc.getImagesCount();
if (imagesCount > 0) {
final String title = ImagesBundle.message("icons.count", imagesCount);
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(title, 5 + (ImagesIcons.ThumbnailDirectory.getIconWidth() - fontMetrics.stringWidth(title)) / 2,
ImagesIcons.ThumbnailDirectory
.getIconHeight() / 2 + fontMetrics.getAscent());
}
}
private static void paintImageThumbnail(Graphics g, ThumbnailComponent tc) {
ImageComponent imageComponent = tc.getImageComponent();
// Paint blank
if (imageComponent.isFileSizeVisible()) ImagesIcons.ThumbnailBlank.paintIcon(tc, g, 5, 5);
ImageDocument document = imageComponent.getDocument();
BufferedImage image = document.getValue();
if (image != null) {
paintImage(g, tc);
}
else {
paintError(g, tc);
}
private static void paintDirectory(Graphics g, ThumbnailComponent tc) {
// Paint directory icon
ImagesIcons.ThumbnailDirectory.paintIcon(tc, g, 5, 5);
if (imageComponent.isFileSizeVisible()) paintFileSize(g, tc);
}
int imagesCount = tc.getImagesCount();
if (imagesCount > 0) {
final String title = ImagesBundle.message("icons.count", imagesCount);
private static void paintBackground(Graphics g, ThumbnailComponent tc) {
Dimension size = tc.getSize();
g.setColor(tc.getBackground());
g.fillRect(0, 0, size.width, size.height);
}
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(title, 5 + (ImagesIcons.ThumbnailDirectory.getIconWidth() - fontMetrics.stringWidth(title)) / 2, ImagesIcons.ThumbnailDirectory
.getIconHeight() / 2 + fontMetrics.getAscent());
}
private static void paintImage(Graphics g, ThumbnailComponent tc) {
ImageComponent imageComponent = tc.getImageComponent();
int blankHeight = ImagesIcons.ThumbnailBlank.getIconHeight();
if (imageComponent.isFileSizeVisible()) {
// Paint image info (and reduce height of text from available height)
blankHeight -= paintImageCaps(g, imageComponent);
// Paint image format (and reduce height of text from available height)
blankHeight -= paintFormatText(tc, g);
}
private static void paintImageThumbnail(Graphics g, ThumbnailComponent tc) {
ImageComponent imageComponent = tc.getImageComponent();
// Paint blank
if (imageComponent.isFileSizeVisible()) ImagesIcons.ThumbnailBlank.paintIcon(tc, g, 5, 5);
// Paint image
paintThumbnail(g, imageComponent, blankHeight);
}
ImageDocument document = imageComponent.getDocument();
BufferedImage image = document.getValue();
if (image != null) {
paintImage(g, tc);
} else {
paintError(g, tc);
}
private static int paintImageCaps(Graphics g, ImageComponent imageComponent) {
String description = imageComponent.getDescription();
if (imageComponent.isFileSizeVisible()) paintFileSize(g, tc);
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(description, 8, 7 + fontMetrics.getAscent());
return fontMetrics.getHeight();
}
private static int paintFormatText(ThumbnailComponent tc, Graphics g) {
Font font = getSmallFont().deriveFont(Font.BOLD);
FontMetrics fontMetrics = g.getFontMetrics(font);
String format = StringUtil.toUpperCase(tc.getFormat());
int stringWidth = fontMetrics.stringWidth(format);
int x = ImagesIcons.ThumbnailBlank.getIconWidth() - stringWidth + 2;
int y = ImagesIcons.ThumbnailBlank.getIconHeight() - fontMetrics.getHeight() + 4;
g.setColor(LINE_COLOR);
g.drawLine(x - 3, y - 1, x + stringWidth + 1, y - 1);
g.drawLine(x - 4, y, x - 4, y + fontMetrics.getHeight() - 1);
g.setColor(getFormatColor(format));
g.setFont(font);
g.drawString(
format,
x,
y + fontMetrics.getAscent()
);
return fontMetrics.getHeight();
}
private static Color getFormatColor(String format) {
if ("PNG".equals(format)) {
return PNG_COLOR;
}
else if ("GIF".equals(format)) {
return GIF_COLOR;
}
else if ("JPG".equals(format) || "JPEG".equals(format)) {
return JPG_COLOR;
}
else if ("BMP".equals(format) || "WBMP".equals(format)) {
return BMP_COLOR;
}
return Color.BLACK;
}
private static void paintThumbnail(Graphics g, ImageComponent imageComponent, int blankHeight) {
// Zoom image by available size
int maxWidth = ImagesIcons.ThumbnailBlank.getIconWidth() - 10;
int maxHeight = blankHeight - 10;
BufferedImage image = imageComponent.getDocument().getValue();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
if (imageWidth > maxWidth || imageHeight > maxHeight) {
if (imageWidth > maxWidth) {
double proportion = (double)maxWidth / (double)imageWidth;
imageWidth = maxWidth;
imageHeight = (int)((double)imageHeight * proportion);
}
if (imageHeight > maxHeight) {
double proportion = (double)maxHeight / (double)imageHeight;
imageHeight = maxHeight;
imageWidth = (int)((double)imageWidth * proportion);
}
}
private static void paintBackground(Graphics g, ThumbnailComponent tc) {
Dimension size = tc.getSize();
g.setColor(tc.getBackground());
g.fillRect(0, 0, size.width, size.height);
imageComponent.setCanvasSize(imageWidth, imageHeight);
Dimension size = imageComponent.getSize();
int x = 5 + (ImagesIcons.ThumbnailBlank.getIconWidth() - size.width) / 2;
int y = 5 + (ImagesIcons.ThumbnailBlank.getIconHeight() - size.height) / 2;
imageComponent.paint(g.create(x, y, size.width, size.height));
}
private static void paintFileName(Graphics g, ThumbnailComponent tc) {
Font font = StartupUiUtil.getLabelFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setFont(font);
g.setColor(tc.getForeground());
String fileName = tc.getFileName();
String title = fileName;
while (fontMetrics.stringWidth(title) > ImagesIcons.ThumbnailBlank.getIconWidth() - 8) {
title = title.substring(0, title.length() - 1);
}
private static void paintImage(Graphics g, ThumbnailComponent tc) {
ImageComponent imageComponent = tc.getImageComponent();
int blankHeight = ImagesIcons.ThumbnailBlank.getIconHeight();
if (imageComponent.isFileSizeVisible()) {
// Paint image info (and reduce height of text from available height)
blankHeight -= paintImageCaps(g, imageComponent);
// Paint image format (and reduce height of text from available height)
blankHeight -= paintFormatText(tc, g);
}
// Paint image
paintThumbnail(g, imageComponent, blankHeight);
if (fileName.equals(title)) {
// Center
g.drawString(fileName, 6 + (ImagesIcons.ThumbnailBlank.getIconWidth() - 2 - fontMetrics.stringWidth(title)) / 2,
ImagesIcons.ThumbnailBlank
.getIconHeight() + 8 + fontMetrics.getAscent());
}
private static int paintImageCaps(Graphics g, ImageComponent imageComponent) {
String description = imageComponent.getDescription();
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(description, 8, 7 + fontMetrics.getAscent());
return fontMetrics.getHeight();
else {
int dotsWidth = fontMetrics.stringWidth(DOTS);
while (fontMetrics.stringWidth(title) > ImagesIcons.ThumbnailBlank.getIconWidth() - 8 - dotsWidth) {
title = title.substring(0, title.length() - 1);
}
g.drawString(title + DOTS, 6, ImagesIcons.ThumbnailBlank.getIconHeight() + 8 + fontMetrics.getAscent());
}
}
private static int paintFormatText(ThumbnailComponent tc, Graphics g) {
Font font = getSmallFont().deriveFont(Font.BOLD);
FontMetrics fontMetrics = g.getFontMetrics(font);
private static void paintFileSize(Graphics g, ThumbnailComponent tc) {
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(
tc.getFileSizeText(),
8,
ImagesIcons.ThumbnailBlank.getIconHeight() + 4 - fontMetrics.getHeight() + fontMetrics.getAscent()
);
}
String format = StringUtil.toUpperCase(tc.getFormat());
int stringWidth = fontMetrics.stringWidth(format);
int x = ImagesIcons.ThumbnailBlank.getIconWidth() - stringWidth + 2;
int y = ImagesIcons.ThumbnailBlank.getIconHeight() - fontMetrics.getHeight() + 4;
g.setColor(LINE_COLOR);
g.drawLine(x - 3, y - 1, x + stringWidth + 1, y - 1);
g.drawLine(x - 4, y, x - 4, y + fontMetrics.getHeight() - 1);
g.setColor(getFormatColor(format));
g.setFont(font);
g.drawString(
format,
x,
y + fontMetrics.getAscent()
);
private static void paintError(Graphics g, ThumbnailComponent tc) {
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
return fontMetrics.getHeight();
}
Messages.getErrorIcon().paintIcon(
tc,
g,
5 + (ImagesIcons.ThumbnailBlank.getIconWidth() - Messages.getErrorIcon().getIconWidth()) / 2,
5 + (ImagesIcons.ThumbnailBlank.getIconHeight() - Messages.getErrorIcon().getIconHeight()) / 2
);
private static Color getFormatColor(String format) {
if ("PNG".equals(format)) {
return PNG_COLOR;
} else if ("GIF".equals(format)) {
return GIF_COLOR;
} else if ("JPG".equals(format) || "JPEG".equals(format)) {
return JPG_COLOR;
} else if ("BMP".equals(format) || "WBMP".equals(format)) {
return BMP_COLOR;
}
return Color.BLACK;
}
// Error
String error = getSubmnailComponentErrorString();
g.setColor(JBColor.RED);
g.setFont(font);
g.drawString(error, 8, 8 + fontMetrics.getAscent());
}
private static void paintThumbnail(Graphics g, ImageComponent imageComponent, int blankHeight) {
private static String getSubmnailComponentErrorString() {
return ImagesBundle.message("thumbnails.component.error.text");
}
// Zoom image by available size
int maxWidth = ImagesIcons.ThumbnailBlank.getIconWidth() - 10;
int maxHeight = blankHeight - 10;
private static Font getSmallFont() {
Font labelFont = StartupUiUtil.getLabelFont();
return labelFont.deriveFont(labelFont.getSize2D() - 2.0f);
}
BufferedImage image = imageComponent.getDocument().getValue();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
@Override
public Dimension getPreferredSize(JComponent c) {
Font labelFont = StartupUiUtil.getLabelFont();
FontMetrics fontMetrics = c.getFontMetrics(labelFont);
return new Dimension(
ImagesIcons.ThumbnailBlank.getIconWidth() + 10,
ImagesIcons.ThumbnailBlank.getIconHeight() + fontMetrics.getHeight() + 15
);
}
if (imageWidth > maxWidth || imageHeight > maxHeight) {
if (imageWidth > maxWidth) {
double proportion = (double) maxWidth / (double) imageWidth;
imageWidth = maxWidth;
imageHeight = (int) ((double) imageHeight * proportion);
}
if (imageHeight > maxHeight) {
double proportion = (double) maxHeight / (double) imageHeight;
imageHeight = maxHeight;
imageWidth = (int) ((double) imageWidth * proportion);
}
}
imageComponent.setCanvasSize(imageWidth, imageHeight);
Dimension size = imageComponent.getSize();
int x = 5 + (ImagesIcons.ThumbnailBlank.getIconWidth() - size.width) / 2;
int y = 5 + (ImagesIcons.ThumbnailBlank.getIconHeight() - size.height) / 2;
imageComponent.paint(g.create(x, y, size.width, size.height));
}
private static void paintFileName(Graphics g, ThumbnailComponent tc) {
Font font = StartupUiUtil.getLabelFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setFont(font);
g.setColor(tc.getForeground());
String fileName = tc.getFileName();
String title = fileName;
while (fontMetrics.stringWidth(title) > ImagesIcons.ThumbnailBlank.getIconWidth() - 8) {
title = title.substring(0, title.length() - 1);
}
if (fileName.equals(title)) {
// Center
g.drawString(fileName, 6 + (ImagesIcons.ThumbnailBlank.getIconWidth() - 2 - fontMetrics.stringWidth(title)) / 2, ImagesIcons.ThumbnailBlank
.getIconHeight() + 8 + fontMetrics.getAscent());
} else {
int dotsWidth = fontMetrics.stringWidth(DOTS);
while (fontMetrics.stringWidth(title) > ImagesIcons.ThumbnailBlank.getIconWidth() - 8 - dotsWidth) {
title = title.substring(0, title.length() - 1);
}
g.drawString(title + DOTS, 6, ImagesIcons.ThumbnailBlank.getIconHeight() + 8 + fontMetrics.getAscent());
}
}
private static void paintFileSize(Graphics g, ThumbnailComponent tc) {
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(
tc.getFileSizeText(),
8,
ImagesIcons.ThumbnailBlank.getIconHeight() + 4 - fontMetrics.getHeight() + fontMetrics.getAscent()
);
}
private static void paintError(Graphics g, ThumbnailComponent tc) {
Font font = getSmallFont();
FontMetrics fontMetrics = g.getFontMetrics(font);
Messages.getErrorIcon().paintIcon(
tc,
g,
5 + (ImagesIcons.ThumbnailBlank.getIconWidth() - Messages.getErrorIcon().getIconWidth()) / 2,
5 + (ImagesIcons.ThumbnailBlank.getIconHeight() - Messages.getErrorIcon().getIconHeight()) / 2
);
// Error
String error = getSubmnailComponentErrorString();
g.setColor(JBColor.RED);
g.setFont(font);
g.drawString(error, 8, 8 + fontMetrics.getAscent());
}
private static String getSubmnailComponentErrorString() {
return ImagesBundle.message("thumbnails.component.error.text");
}
private static Font getSmallFont() {
Font labelFont = StartupUiUtil.getLabelFont();
return labelFont.deriveFont(labelFont.getSize2D() - 2.0f);
}
@Override
public Dimension getPreferredSize(JComponent c) {
Font labelFont = StartupUiUtil.getLabelFont();
FontMetrics fontMetrics = c.getFontMetrics(labelFont);
return new Dimension(
ImagesIcons.ThumbnailBlank.getIconWidth() + 10,
ImagesIcons.ThumbnailBlank.getIconHeight() + fontMetrics.getHeight() + 15
);
}
@SuppressWarnings({"UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return ui;
}
@SuppressWarnings({"UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return ui;
}
}