From 707e86ac4eed15ed72762d54badb73e7bf9912e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 14 Apr 2015 22:26:07 +0200 Subject: [PATCH] Color skins Basic skin set to new Oceanic Error log Frame now skinned --- build_common.xml | 3 +- .../flash/configuration/Configuration.java | 5 + .../flash/gui/AdvancedSettingsDialog.java | 124 ++++++++- .../decompiler/flash/gui/ErrorLogFrame.java | 4 + .../flash/gui/FolderPreviewPanel.java | 20 +- .../decompiler/flash/gui/HeaderLabel.java | 14 +- .../decompiler/flash/gui/ImagePanel.java | 8 +- src/com/jpexs/decompiler/flash/gui/Main.java | 13 +- .../jpexs/decompiler/flash/gui/MainPanel.java | 4 +- .../decompiler/flash/gui/MyResizableIcon.java | 2 + .../gui/MyRibbonApplicationMenuButtonUI.java | 99 +++++++- .../decompiler/flash/gui/OceanicSkin.java | 240 ++++++++++++++++++ .../decompiler/flash/gui/PreviewPanel.java | 8 +- src/com/jpexs/decompiler/flash/gui/View.java | 36 ++- .../gui/graphics/buttonicon_clear_256.png | Bin 0 -> 17571 bytes .../flash/gui/graphics/oceanic.colorschemes | 210 +++++++++++++++ .../locales/AdvancedSettingsDialog.properties | 4 + .../flash/gui/player/PlayerControls.java | 4 +- 18 files changed, 755 insertions(+), 43 deletions(-) create mode 100644 src/com/jpexs/decompiler/flash/gui/OceanicSkin.java create mode 100644 src/com/jpexs/decompiler/flash/gui/graphics/buttonicon_clear_256.png create mode 100644 src/com/jpexs/decompiler/flash/gui/graphics/oceanic.colorschemes diff --git a/build_common.xml b/build_common.xml index f3e48a6c7..5d4627f31 100644 --- a/build_common.xml +++ b/build_common.xml @@ -6,7 +6,8 @@ - + + diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 6f7ddf493..a66b76c67 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -266,6 +266,11 @@ public class Configuration { @ConfigurationName("gui.splitPane2.dividerLocation") public static final ConfigurationItem guiSplitPane2DividerLocation = null; + @ConfigurationDefaultString("com.jpexs.decompiler.flash.gui.OceanicSkin") + @ConfigurationName("gui.skin") + @ConfigurationCategory("ui") + public static final ConfigurationItem guiSkin = null; + @ConfigurationDefaultInt(3) @ConfigurationCategory("export") public static final ConfigurationItem saveAsExeScaleMode = null; diff --git a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java index 6cb844901..e14f1fc56 100644 --- a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java @@ -21,10 +21,15 @@ import com.jpexs.decompiler.flash.configuration.ConfigurationCategory; import com.jpexs.decompiler.flash.configuration.ConfigurationItem; import com.jpexs.decompiler.flash.gui.helpers.SpringUtilities; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.reflect.Field; @@ -39,17 +44,27 @@ import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.SpringLayout; +import javax.swing.SwingConstants; import javax.swing.table.DefaultTableModel; +import org.pushingpixels.substance.api.ColorSchemeAssociationKind; +import org.pushingpixels.substance.api.ComponentState; +import org.pushingpixels.substance.api.DecorationAreaType; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; +import org.pushingpixels.substance.api.SubstanceSkin; +import org.pushingpixels.substance.api.renderers.SubstanceDefaultListCellRenderer; +import org.pushingpixels.substance.api.skin.SkinInfo; /** * @@ -99,6 +114,27 @@ public class AdvancedSettingsDialog extends AppDialog implements ActionListener } }; } + + private static class SkinSelect { + private String name; + private String className; + + public SkinSelect(String name, String className) { + this.name = name; + this.className = className; + } + + public String getClassName() { + return className; + } + + @Override + public String toString() { + return name; + } + + + } private void initComponents() { okButton = new JButton(); @@ -159,6 +195,65 @@ public class AdvancedSettingsDialog extends AppDialog implements ActionListener JTabbedPane tabPane = new JTabbedPane(); Map tabs = new HashMap<>(); + + JComboBox skinComboBox=new JComboBox<>(); + skinComboBox.setRenderer(new SubstanceDefaultListCellRenderer(){ + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + SubstanceDefaultListCellRenderer cmp= (SubstanceDefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //To change body of generated methods, choose Tools | Templates. + final SkinSelect ss=(SkinSelect)value; + cmp.setIcon(new Icon() { + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + try { + Class act = Class.forName(ss.getClassName()); + SubstanceSkin skin = (SubstanceSkin)act.newInstance(); + Color fill = skin.getColorScheme(DecorationAreaType.GENERAL,ColorSchemeAssociationKind.FILL,ComponentState.ENABLED).getBackgroundFillColor(); + Color hilight=skin.getColorScheme(DecorationAreaType.GENERAL,ColorSchemeAssociationKind.FILL,ComponentState.ROLLOVER_SELECTED).getBackgroundFillColor(); + Color border = skin.getColorScheme(DecorationAreaType.GENERAL,ColorSchemeAssociationKind.BORDER,ComponentState.ENABLED).getDarkColor(); + g2.setColor(fill); + g2.fillOval(0, 0, 16, 16); + g2.setColor(hilight); + g2.fillArc(0, 0, 16, 16, -45, 90); + g2.setColor(border); + g2.drawOval(0, 0, 16, 16); + + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { + //no icon + } + + } + + @Override + public int getIconWidth() { + return 16; + } + + @Override + public int getIconHeight() { + return 16; + } + }); + return cmp; + } + + }); + skinComboBox.addItem(new SkinSelect(OceanicSkin.NAME, OceanicSkin.class.getName())); + Map skins = SubstanceLookAndFeel.getAllSkins(); + for(String skinKey:skins.keySet()){ + SkinInfo skin=skins.get(skinKey); + skinComboBox.addItem(new SkinSelect(skin.getDisplayName(), skin.getClassName())); + if(skin.getClassName().equals(Configuration.guiSkin.get())){ + skinComboBox.setSelectedIndex(skinComboBox.getItemCount()-1); + } + } + for (String cat : categorized.keySet()) { JPanel configPanel = new JPanel(new SpringLayout()); for (String name : categorized.get(cat).keySet()) { @@ -172,23 +267,33 @@ public class AdvancedSettingsDialog extends AppDialog implements ActionListener ParameterizedType listType = (ParameterizedType) field.getGenericType(); Class itemType = (Class) listType.getActualTypeArguments()[0]; - /*String description = Configuration.getDescription(field); - if (description == null) { - description = ""; - }*/ + String description = translate("config.description." + name); Object defaultValue = Configuration.getDefaultValue(field); + if(name.equals("gui.skin")){ + Class c; + try { + c = Class.forName((String)defaultValue); + defaultValue = c.getField("NAME").get(c); + } catch (ClassNotFoundException | NoSuchFieldException | SecurityException ex) { + Logger.getLogger(AdvancedSettingsDialog.class.getName()).log(Level.SEVERE, null, ex); + } + + } if (defaultValue != null) { description += " (" + translate("default") + ": " + defaultValue + ")"; } - //model.addRow(new Object[]{locName, item.get(), description}); - + JLabel l = new JLabel(locName, JLabel.TRAILING); l.setToolTipText(description); configPanel.add(l); Component c = null; - if ((itemType == String.class) || (itemType == Integer.class) || (itemType == Long.class) || (itemType == Double.class) || (itemType == Float.class) || (itemType == Calendar.class)) { + if(name.equals("gui.skin")){ + skinComboBox.setToolTipText(description); + skinComboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, skinComboBox.getPreferredSize().height)); + c = skinComboBox; + } else if ((itemType == String.class) || (itemType == Integer.class) || (itemType == Long.class) || (itemType == Double.class) || (itemType == Float.class) || (itemType == Calendar.class)) { JTextField tf = new JTextField(); Object val = item.get(); if (val == null) { @@ -298,7 +403,10 @@ public class AdvancedSettingsDialog extends AppDialog implements ActionListener ParameterizedType listType = (ParameterizedType) fields.get(name).getGenericType(); Class itemType = (Class) listType.getActualTypeArguments()[0]; - if (itemType == String.class) { + if(name.equals("gui.skin")){ + value = ((SkinSelect)((JComboBox)c).getSelectedItem()).className; + } + else if (itemType == String.class) { value = ((JTextField) c).getText(); } if (itemType == Boolean.class) { diff --git a/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java b/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java index 3138794ec..596e1a5dd 100644 --- a/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java +++ b/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java @@ -78,6 +78,10 @@ public class ErrorLogFrame extends AppFrame { return handler; } + public static boolean hasInstance() { + return instance != null; + } + public static ErrorLogFrame getInstance() { if (instance == null) { instance = new ErrorLogFrame(); diff --git a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java index 84d8fc931..f33601a1e 100644 --- a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java @@ -50,6 +50,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.swing.JLabel; import javax.swing.JPanel; +import org.pushingpixels.substance.api.ColorSchemeAssociationKind; +import org.pushingpixels.substance.api.ComponentState; +import org.pushingpixels.substance.api.DecorationAreaType; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; /** * @@ -188,9 +192,13 @@ public class FolderPreviewPanel extends JPanel { JLabel l = new JLabel(); Font f = l.getFont().deriveFont(AffineTransform.getScaleInstance(0.8, 0.8)); int finish_y = (int) Math.ceil((r.y + r.height) / (float) CELL_HEIGHT); - g.setColor(Color.black); - Color color = new Color(0xd9, 0xe8, 0xfb); - Color selectedColor = new Color(0xfe, 0xca, 0x81); + Color color = SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED).getBackgroundFillColor(); + Color selectedColor = SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).getBackgroundFillColor(); + Color borderColor = SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.BORDER, ComponentState.ROLLOVER_SELECTED).getUltraDarkColor(); + Color textColor = SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).getForegroundColor(); + + //g.setColor(SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED)); + for (int y = start_y; y <= finish_y; y++) { for (int x = 0; x < cols; x++) { int index = y * cols + x; @@ -222,10 +230,12 @@ public class FolderPreviewPanel extends JPanel { s = treeItem.toString(); } g.setFont(f); - g.setColor(Color.black); + g.setColor(borderColor); g.drawLine(x * CELL_WIDTH, y * CELL_HEIGHT + BORDER_SIZE + PREVIEW_SIZE, x * CELL_WIDTH + CELL_WIDTH, y * CELL_HEIGHT + BORDER_SIZE + PREVIEW_SIZE); - g.drawString(s, x * CELL_WIDTH + BORDER_SIZE, y * CELL_HEIGHT + BORDER_SIZE + PREVIEW_SIZE + LABEL_HEIGHT); g.drawRect(x * CELL_WIDTH, y * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT); + g.setColor(textColor); + g.drawString(s, x * CELL_WIDTH + BORDER_SIZE, y * CELL_HEIGHT + BORDER_SIZE + PREVIEW_SIZE + LABEL_HEIGHT); + } } } diff --git a/src/com/jpexs/decompiler/flash/gui/HeaderLabel.java b/src/com/jpexs/decompiler/flash/gui/HeaderLabel.java index 8a8a148fb..66f2aa6f2 100644 --- a/src/com/jpexs/decompiler/flash/gui/HeaderLabel.java +++ b/src/com/jpexs/decompiler/flash/gui/HeaderLabel.java @@ -22,8 +22,12 @@ import java.awt.geom.GeneralPath; import java.util.EnumSet; import java.util.Set; import javax.swing.JLabel; +import org.pushingpixels.substance.api.ColorSchemeAssociationKind; +import org.pushingpixels.substance.api.ComponentState; import org.pushingpixels.substance.api.DecorationAreaType; +import org.pushingpixels.substance.api.SubstanceColorScheme; import org.pushingpixels.substance.api.SubstanceConstants; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; import org.pushingpixels.substance.api.painter.border.StandardBorderPainter; import org.pushingpixels.substance.api.skin.OfficeBlue2007Skin; import org.pushingpixels.substance.internal.utils.SubstanceOutlineUtilities; @@ -65,7 +69,7 @@ public class HeaderLabel extends JLabel { @Override public void paint(Graphics g) { - g.setColor(new Color(217, 232, 251)); + g.setColor(SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.HEADER, ColorSchemeAssociationKind.FILL,ComponentState.ENABLED).getBackgroundFillColor()); g.fillRect(0, 0, getWidth(), getHeight()); StandardBorderPainter borderPainter = new StandardBorderPainter(); @@ -80,12 +84,12 @@ public class HeaderLabel extends JLabel { GeneralPath contour = SubstanceOutlineUtilities.getBaseOutline(getWidth(), getHeight() + dy, cornerRadius, straightSides, borderInsets); + borderPainter.paintBorder(g, this, getWidth(), getHeight() + dy, - contour, contourInner, new OfficeBlue2007Skin().getActiveColorScheme(DecorationAreaType.HEADER)); - g.setColor(Color.black); + contour, contourInner,SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.HEADER, ColorSchemeAssociationKind.BORDER,ComponentState.ENABLED)); + g.setColor(SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.HEADER, ColorSchemeAssociationKind.FILL,ComponentState.ENABLED).getForegroundColor()); JLabel lab = new JLabel(getText(), JLabel.CENTER); lab.setSize(getSize()); - lab.paint(g); - //g.drawString(getText(), getWidth()/2-getFontMetrics(getFont()).stringWidth(getText())/2, getFont().getSize()); + lab.paint(g); } } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index e3a1ebed6..cde4afd42 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -207,7 +207,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis g2d.setPaint(View.transparentPaint); g2d.fill(new Rectangle(0, 0, getWidth(), getHeight())); g2d.setComposite(AlphaComposite.SrcOver); - g2d.setPaint(View.swfBackgroundColor); + g2d.setPaint(View.getSwfBackgroundColor()); g2d.fill(new Rectangle(0, 0, getWidth(), getHeight())); if (img != null) { calcRect(); @@ -342,7 +342,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis super(new BorderLayout()); //iconPanel.setHorizontalAlignment(JLabel.CENTER); setOpaque(true); - setBackground(View.DEFAULT_BACKGROUND_COLOR); + setBackground(View.getDefaultBackgroundColor()); iconPanel = new IconPanel(); //labelPan.add(label, new GridBagConstraints()); @@ -554,7 +554,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis } public synchronized void setImage(SerializableImage image) { - setBackground(View.swfBackgroundColor); + setBackground(View.getSwfBackgroundColor()); clear(); timelined = null; @@ -567,7 +567,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis } public synchronized void setText(TextTag textTag, TextTag newTextTag) { - setBackground(View.swfBackgroundColor); + setBackground(View.getSwfBackgroundColor()); clear(); timelined = null; diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 8293fa018..626c22886 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -791,6 +791,14 @@ public class Main { logger.log(Level.SEVERE, null, ex); } } + View.execInEventDispatch(new Runnable() { + + @Override + public void run() { + ErrorLogFrame.createNewInstance(); + } + }); + autoCheckForUpdates(); offerAssociation(); View.execInEventDispatch(new Runnable() { @@ -867,8 +875,7 @@ public class Main { } } Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get())); - AppStrings.updateLanguage(); - ErrorLogFrame.createNewInstance(); + AppStrings.updateLanguage(); try { Class cl = Class.forName("org.pushingpixels.substance.api.SubstanceLookAndFeel"); @@ -1357,7 +1364,7 @@ public class Main { fileTxt.setFormatter(formatterTxt); logger.addHandler(fileTxt); - if (!GraphicsEnvironment.isHeadless()) { + if (!GraphicsEnvironment.isHeadless() && ErrorLogFrame.hasInstance()) { ErrorLogFrame.getInstance().clearErrorState(); } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index cdb2133c2..40726850e 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -2147,9 +2147,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { case ACTION_SELECT_BKCOLOR: - Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectbkcolor.title"), View.swfBackgroundColor); + Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectbkcolor.title"), View.getSwfBackgroundColor()); if (newColor != null) { - View.swfBackgroundColor = newColor; + View.setSwfBackgroundColor(newColor); reload(true); } break; diff --git a/src/com/jpexs/decompiler/flash/gui/MyResizableIcon.java b/src/com/jpexs/decompiler/flash/gui/MyResizableIcon.java index 773ea78b3..b5cb9ae02 100644 --- a/src/com/jpexs/decompiler/flash/gui/MyResizableIcon.java +++ b/src/com/jpexs/decompiler/flash/gui/MyResizableIcon.java @@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.gui; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.Map; diff --git a/src/com/jpexs/decompiler/flash/gui/MyRibbonApplicationMenuButtonUI.java b/src/com/jpexs/decompiler/flash/gui/MyRibbonApplicationMenuButtonUI.java index c8a7c84c4..f052116f0 100644 --- a/src/com/jpexs/decompiler/flash/gui/MyRibbonApplicationMenuButtonUI.java +++ b/src/com/jpexs/decompiler/flash/gui/MyRibbonApplicationMenuButtonUI.java @@ -16,10 +16,19 @@ */ package com.jpexs.decompiler.flash.gui; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.MultipleGradientPaint; +import java.awt.RadialGradientPaint; +import java.awt.RenderingHints; +import java.awt.Shape; import java.awt.event.MouseEvent; +import java.awt.geom.AffineTransform; +import java.awt.geom.Ellipse2D; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; @@ -27,6 +36,10 @@ import org.pushingpixels.flamingo.api.common.model.PopupButtonModel; import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.BasicRibbonApplicationMenuButtonUI; import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton; import org.pushingpixels.lafwidget.animation.effects.GhostingListener; +import org.pushingpixels.substance.api.ColorSchemeAssociationKind; +import org.pushingpixels.substance.api.ComponentState; +import org.pushingpixels.substance.api.DecorationAreaType; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; import org.pushingpixels.substance.flamingo.common.ui.ActionPopupTransitionAwareUI; import org.pushingpixels.substance.flamingo.utils.CommandButtonVisualStateTracker; import org.pushingpixels.substance.internal.animation.StateTransitionTracker; @@ -49,6 +62,7 @@ public class MyRibbonApplicationMenuButtonUI extends BasicRibbonApplicationMenuB private MyResizableIcon clickIcon = null; private MyResizableIcon normalIcon = null; + private MyResizableIcon clearIcon = null; private final boolean buttonResized = false; @@ -56,11 +70,89 @@ public class MyRibbonApplicationMenuButtonUI extends BasicRibbonApplicationMenuB return clickIcon; } + + public static MyResizableIcon[] getIcons(){ + MyResizableIcon clearIcon = View.getMyResizableIcon("buttonicon_clear_256"); + return new MyResizableIcon[]{ + clearIcon, + //normal + new MyResizableIcon(clearIcon.originalImage) { + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setPaint(new RadialGradientPaint(getIconWidth() / 2, getIconHeight() / 2, getIconWidth() / 2, new float[]{0.32f, 0.84f, 1f}, new Color[]{ + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.HIGHLIGHT, ComponentState.ENABLED).shiftBackground(Color.white, 0.5).getUltraLightColor(), + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED).getMidColor(), + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.BORDER, ComponentState.ENABLED).getUltraDarkColor() + }, MultipleGradientPaint.CycleMethod.NO_CYCLE)); + Shape s = new Ellipse2D.Double(x, y, getIconWidth(), getIconHeight()); + g2.fill(s); + g2.setPaint(SubstanceLookAndFeel.getCurrentSkin().getEnabledColorScheme(DecorationAreaType.PRIMARY_TITLE_PANE).getMidColor()); + super.paintIcon(c, g, x, y); + } + }, + //hover + new MyResizableIcon(clearIcon.originalImage) { + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setPaint(new RadialGradientPaint(getIconWidth() / 2, getIconHeight() / 2, getIconWidth() / 2, new float[]{0.32f, 0.84f, 1f}, new Color[]{ + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.HIGHLIGHT, ComponentState.ROLLOVER_UNSELECTED)/*.shiftBackground(Color.white, 0.8)*/.getUltraLightColor(), + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_UNSELECTED).getMidColor(), + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.BORDER, ComponentState.ROLLOVER_UNSELECTED)/*.shiftBackground(new Color(0x7c, 0x7c, 0x7c), 0.8)*/.getUltraDarkColor() + }, MultipleGradientPaint.CycleMethod.NO_CYCLE)); + Shape s = new Ellipse2D.Double(x, y, getIconWidth(), getIconHeight()); + g2.fill(s); + super.paintIcon(c, g, x, y); + } + }, + //click + new MyResizableIcon(clearIcon.originalImage) { + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setPaint(new RadialGradientPaint(getIconWidth() / 2, getIconHeight() / 2, getIconWidth() / 2, new float[]{0.2f, 0.5f, 0.8f}, new Color[]{ + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).getUltraLightColor(), + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).getMidColor(), + SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).shiftBackground(Color.black, 0.7).getUltraDarkColor() + }, MultipleGradientPaint.CycleMethod.NO_CYCLE)); + Shape s = new Ellipse2D.Double(x, y, getIconWidth(), getIconHeight()); + g2.fill(s); + AffineTransform origt = g2.getTransform(); + AffineTransform t = (AffineTransform) origt.clone(); + t.translate(-getIconWidth() / 2, -getIconHeight() / 2); + t.scale(0.8, 0.8); + t.translate(getIconWidth() / 2 + getIconWidth() / 4, getIconHeight() / 2 + getIconHeight() / 4); + g2.setTransform(t); + g2.setPaint(Color.BLACK); + super.paintIcon(c, g, x, y); + g2.setTransform(origt); + } + } + + }; + } + public MyRibbonApplicationMenuButtonUI() { super(); - hoverIcon = View.getMyResizableIcon("buttonicon_hover_256"); - normalIcon = View.getMyResizableIcon("buttonicon_256"); - clickIcon = View.getMyResizableIcon("buttonicon_down_256"); + MyResizableIcon[] icons=getIcons(); + clearIcon = icons[0]; + normalIcon = icons[1]; + hoverIcon = icons[2]; + clickIcon = icons[3]; + } /** @@ -177,6 +269,7 @@ public class MyRibbonApplicationMenuButtonUI extends BasicRibbonApplicationMenuB if (regular == null) { return; } + //SubstanceLookAndFeel.getCurrentSkin().getActiveColorScheme(DecorationAreaType.GENERAL); Graphics2D g2d = (Graphics2D) g.create(); regular.paintIcon(this.applicationMenuButton, g2d, 0, 0); diff --git a/src/com/jpexs/decompiler/flash/gui/OceanicSkin.java b/src/com/jpexs/decompiler/flash/gui/OceanicSkin.java new file mode 100644 index 000000000..5a2e3d986 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/OceanicSkin.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2015 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +import java.awt.Color; + +import org.pushingpixels.substance.api.*; +import org.pushingpixels.substance.api.painter.border.CompositeBorderPainter; +import org.pushingpixels.substance.api.painter.border.DelegateFractionBasedBorderPainter; +import org.pushingpixels.substance.api.painter.border.FractionBasedBorderPainter; +import org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter; +import org.pushingpixels.substance.api.painter.decoration.FractionBasedDecorationPainter; +import org.pushingpixels.substance.api.painter.fill.FractionBasedFillPainter; +import org.pushingpixels.substance.api.painter.highlight.ClassicHighlightPainter; +import org.pushingpixels.substance.api.painter.overlay.BottomLineOverlayPainter; +import org.pushingpixels.substance.api.shaper.ClassicButtonShaper; + +public class OceanicSkin extends SubstanceSkin { + + /** + * Display name for this skin. + */ + public static final String NAME = "Oceanic"; + + /** + * Creates a new Oceanic skin. + */ + public OceanicSkin() { + SubstanceSkin.ColorSchemes colorSchemes = SubstanceSkin + .getColorSchemes("com/jpexs/decompiler/flash/gui/graphics/oceanic.colorschemes"); + + SubstanceColorScheme activeScheme = colorSchemes + .get("Oceanic Active"); + SubstanceColorScheme enabledScheme = colorSchemes + .get("Oceanic Enabled"); + + SubstanceColorSchemeBundle defaultSchemeBundle = new SubstanceColorSchemeBundle( + activeScheme, enabledScheme, enabledScheme); + defaultSchemeBundle.registerColorScheme(enabledScheme, 0.5f, + ComponentState.DISABLED_UNSELECTED); + defaultSchemeBundle.registerColorScheme(activeScheme, 0.5f, + ComponentState.DISABLED_SELECTED); + + SubstanceColorScheme rolloverScheme = colorSchemes + .get("Oceanic Rollover"); + SubstanceColorScheme rolloverSelectedScheme = colorSchemes + .get("Oceanic Rollover Selected"); + SubstanceColorScheme selectedScheme = colorSchemes + .get("Oceanic Selected"); + SubstanceColorScheme pressedScheme = colorSchemes + .get("Oceanic Pressed"); + SubstanceColorScheme pressedSelectedScheme = colorSchemes + .get("Oceanic Pressed Selected"); + + // register state-specific color schemes on rollovers and selections + defaultSchemeBundle.registerColorScheme(rolloverScheme, + ComponentState.ROLLOVER_UNSELECTED); + defaultSchemeBundle.registerColorScheme(rolloverSelectedScheme, + ComponentState.ROLLOVER_SELECTED); + defaultSchemeBundle.registerColorScheme(selectedScheme, + ComponentState.SELECTED); + defaultSchemeBundle.registerColorScheme(pressedScheme, + ComponentState.PRESSED_UNSELECTED); + defaultSchemeBundle.registerColorScheme(pressedSelectedScheme, + ComponentState.PRESSED_SELECTED); + + // register state-specific highlight color schemes on rollover and + // selections + defaultSchemeBundle.registerHighlightColorScheme(rolloverScheme, 0.8f, + ComponentState.ROLLOVER_UNSELECTED); + defaultSchemeBundle.registerHighlightColorScheme(selectedScheme, 0.8f, + ComponentState.SELECTED); + defaultSchemeBundle.registerHighlightColorScheme( + rolloverSelectedScheme, 0.8f, ComponentState.ROLLOVER_SELECTED); + defaultSchemeBundle.registerHighlightColorScheme(selectedScheme, 0.8f, + ComponentState.ARMED, ComponentState.ROLLOVER_ARMED); + + // borders and marks + SubstanceColorScheme borderEnabledScheme = colorSchemes + .get("Oceanic Border Enabled"); + SubstanceColorScheme borderActiveScheme = colorSchemes + .get("Oceanic Border Active"); + SubstanceColorScheme borderRolloverScheme = colorSchemes + .get("Oceanic Border Rollover"); + SubstanceColorScheme borderRolloverSelectedScheme = colorSchemes + .get("Oceanic Border Rollover Selected"); + SubstanceColorScheme borderSelectedScheme = colorSchemes + .get("Oceanic Border Selected"); + SubstanceColorScheme borderPressedScheme = colorSchemes + .get("Oceanic Border Pressed"); + + defaultSchemeBundle.registerColorScheme(borderEnabledScheme, + ColorSchemeAssociationKind.BORDER, ComponentState.ENABLED); + defaultSchemeBundle.registerColorScheme(borderEnabledScheme, + ColorSchemeAssociationKind.BORDER, + ComponentState.DISABLED_SELECTED, + ComponentState.DISABLED_UNSELECTED); + defaultSchemeBundle.registerColorScheme(borderActiveScheme, + ColorSchemeAssociationKind.BORDER, ComponentState.DEFAULT); + defaultSchemeBundle.registerColorScheme(borderRolloverScheme, + ColorSchemeAssociationKind.BORDER, + ComponentState.ROLLOVER_UNSELECTED); + defaultSchemeBundle.registerColorScheme(borderRolloverSelectedScheme, + ColorSchemeAssociationKind.BORDER, + ComponentState.ROLLOVER_SELECTED, ComponentState.ARMED, + ComponentState.ROLLOVER_ARMED); + defaultSchemeBundle.registerColorScheme(borderSelectedScheme, + ColorSchemeAssociationKind.BORDER, ComponentState.SELECTED); + defaultSchemeBundle.registerColorScheme(borderPressedScheme, + ColorSchemeAssociationKind.BORDER, + ComponentState.PRESSED_SELECTED, + ComponentState.PRESSED_UNSELECTED); + + // tabs and tab borders + SubstanceColorScheme tabSelectedScheme = colorSchemes + .get("Oceanic Tab Selected"); + SubstanceColorScheme tabRolloverScheme = colorSchemes + .get("Oceanic Tab Rollover"); + defaultSchemeBundle.registerColorScheme(tabSelectedScheme, + ColorSchemeAssociationKind.TAB, ComponentState.SELECTED, + ComponentState.ROLLOVER_SELECTED, + ComponentState.PRESSED_SELECTED, + ComponentState.PRESSED_UNSELECTED); + defaultSchemeBundle.registerColorScheme(tabRolloverScheme, + ColorSchemeAssociationKind.TAB, + ComponentState.ROLLOVER_UNSELECTED); + defaultSchemeBundle.registerColorScheme(borderEnabledScheme, + ColorSchemeAssociationKind.TAB_BORDER, ComponentState.SELECTED, + ComponentState.ROLLOVER_UNSELECTED); + defaultSchemeBundle.registerColorScheme(rolloverSelectedScheme, + ColorSchemeAssociationKind.TAB_BORDER, + ComponentState.ROLLOVER_SELECTED); + + // separator + SubstanceColorScheme separatorScheme = colorSchemes + .get("Oceanic Separator"); + defaultSchemeBundle.registerColorScheme(separatorScheme, + ColorSchemeAssociationKind.SEPARATOR); + + this.registerDecorationAreaSchemeBundle(defaultSchemeBundle, + DecorationAreaType.NONE); + + this.watermarkScheme = colorSchemes.get("Oceanic Watermark"); + + SubstanceColorScheme generalWatermarkScheme = colorSchemes + .get("Oceanic Header Watermark"); + + this.registerAsDecorationArea(generalWatermarkScheme, + DecorationAreaType.FOOTER, DecorationAreaType.HEADER, + DecorationAreaType.TOOLBAR); + + SubstanceColorScheme titleWatermarkScheme = colorSchemes + .get("Oceanic Title Watermark"); + + this.registerAsDecorationArea(titleWatermarkScheme, + DecorationAreaType.GENERAL, + DecorationAreaType.PRIMARY_TITLE_PANE, + DecorationAreaType.SECONDARY_TITLE_PANE); + + setSelectedTabFadeStart(0.7); + setSelectedTabFadeEnd(0.9); + + this.addOverlayPainter(new BottomLineOverlayPainter( + new ColorSchemeSingleColorQuery() { + @Override + public Color query(SubstanceColorScheme scheme) { + Color fg = scheme.getForegroundColor(); + return new Color(fg.getRed(), fg.getGreen(), fg + .getBlue(), 72); + } + }), DecorationAreaType.PRIMARY_TITLE_PANE, + DecorationAreaType.SECONDARY_TITLE_PANE); + + this.buttonShaper = new ClassicButtonShaper(); + this.watermark = null; + + this.fillPainter = new FractionBasedFillPainter("Oceanic", + new float[]{0.0f, 0.49999f, 0.5f, 1.0f}, + new ColorSchemeSingleColorQuery[]{ + ColorSchemeSingleColorQuery.ULTRALIGHT, + ColorSchemeSingleColorQuery.LIGHT, + ColorSchemeSingleColorQuery.ULTRADARK, + ColorSchemeSingleColorQuery.EXTRALIGHT}); + + FractionBasedBorderPainter outerBorderPainter = new FractionBasedBorderPainter( + "Oceanic Outer", new float[]{0.0f, 0.5f, 1.0f}, + new ColorSchemeSingleColorQuery[]{ + ColorSchemeSingleColorQuery.EXTRALIGHT, + ColorSchemeSingleColorQuery.DARK, + ColorSchemeSingleColorQuery.MID}); + SubstanceBorderPainter innerBorderPainter = new DelegateFractionBasedBorderPainter( + "Oceanic Inner", outerBorderPainter, new int[]{ + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + new ColorSchemeTransform() { + @Override + public SubstanceColorScheme transform( + SubstanceColorScheme scheme) { + return scheme.tint(0.8f); + } + }); + this.borderPainter = new CompositeBorderPainter("Oceanic", + outerBorderPainter, innerBorderPainter); + + this.decorationPainter = new FractionBasedDecorationPainter( + "Oceanic", new float[]{0.0f, 0.1199999f, 0.12f, + 0.5f, 0.9f, 1.0f}, new ColorSchemeSingleColorQuery[]{ + ColorSchemeSingleColorQuery.LIGHT, + ColorSchemeSingleColorQuery.LIGHT, + ColorSchemeSingleColorQuery.ULTRADARK, + ColorSchemeSingleColorQuery.MID, + ColorSchemeSingleColorQuery.ULTRALIGHT, + ColorSchemeSingleColorQuery.LIGHT}); + this.highlightPainter = new ClassicHighlightPainter(); + } + + /* + * (non-Javadoc) + * + * @see org.pushingpixels.substance.skin.SubstanceSkin#getDisplayName() + */ + @Override + public String getDisplayName() { + return NAME; + } + +} diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index 14650e55c..5af40bfde 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -381,7 +381,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener { } else { JPanel swtPanel = new JPanel(new BorderLayout()); swtPanel.add(new JLabel("
" + mainPanel.translate("notavailonthisplatform") + "
", JLabel.CENTER), BorderLayout.CENTER); - swtPanel.setBackground(View.DEFAULT_BACKGROUND_COLOR); + swtPanel.setBackground(View.getDefaultBackgroundColor()); leftComponent = swtPanel; } @@ -654,10 +654,10 @@ public class PreviewPanel extends JSplitPane implements ActionListener { tempFile = File.createTempFile("ffdec_view_", ".swf"); tempFile.deleteOnExit(); - Color backgroundColor = View.swfBackgroundColor; + Color backgroundColor = View.getSwfBackgroundColor(); if (tagObj instanceof FontTag) { //Fonts are always black on white - backgroundColor = View.DEFAULT_BACKGROUND_COLOR; + backgroundColor = View.getDefaultBackgroundColor(); } if (tagObj instanceof Frame) { @@ -1112,7 +1112,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener { } public void showSwf(SWF swf) { - Color backgroundColor = View.DEFAULT_BACKGROUND_COLOR; + Color backgroundColor = View.getDefaultBackgroundColor(); for (Tag t : swf.tags) { if (t instanceof SetBackgroundColorTag) { backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java index 304c18e93..08c255648 100644 --- a/src/com/jpexs/decompiler/flash/gui/View.java +++ b/src/com/jpexs/decompiler/flash/gui/View.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.ConfigurationItem; import java.awt.BorderLayout; import java.awt.Color; @@ -81,7 +82,9 @@ import javax.swing.text.JTextComponent; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon; +import org.pushingpixels.substance.api.ColorSchemeAssociationKind; import org.pushingpixels.substance.api.ComponentState; +import org.pushingpixels.substance.api.DecorationAreaType; import org.pushingpixels.substance.api.SubstanceColorScheme; import org.pushingpixels.substance.api.SubstanceConstants; import org.pushingpixels.substance.api.SubstanceLookAndFeel; @@ -96,10 +99,25 @@ import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities; * @author JPEXS */ public class View { + + public static Color getDefaultBackgroundColor() { + return SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED).getBackgroundFillColor(); + } + + private static Color swfBackgroundColor = null; - public static final Color DEFAULT_BACKGROUND_COLOR = new Color(217, 231, 250); + public static void setSwfBackgroundColor(Color swfBackgroundColor) { + View.swfBackgroundColor = swfBackgroundColor; + } - public static Color swfBackgroundColor = DEFAULT_BACKGROUND_COLOR; + public static Color getSwfBackgroundColor() { + if(swfBackgroundColor == null){ + return getDefaultBackgroundColor(); + } + return swfBackgroundColor; + } + + private static final BufferedImage transparentTexture; @@ -140,6 +158,7 @@ public class View { try { UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel()); + SubstanceLookAndFeel.setSkin(Configuration.guiSkin.get()); UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, 0.999);//This works for not changing labels color and not changing Dialogs title UIManager.put("Tree.expandedIcon", getIcon("expand16")); UIManager.put("Tree.collapsedIcon", getIcon("collapse16")); @@ -267,10 +286,15 @@ public class View { */ public static void setWindowIcon(Window f) { List images = new ArrayList<>(); - images.add(loadImage("icon16")); - images.add(loadImage("icon32")); - images.add(loadImage("icon48")); - images.add(loadImage("icon256")); + MyResizableIcon[] icons=MyRibbonApplicationMenuButtonUI.getIcons(); + MyResizableIcon icon=icons[1]; + int sizes[] = new int[] {16,32,48,256}; + for(int size:sizes){ + icon.setIconSize(size,size); + BufferedImage bi=new BufferedImage(size, size, BufferedImage.TYPE_4BYTE_ABGR); + icon.paintIcon(f, bi.getGraphics(), 0, 0); + images.add(bi); + } f.setIconImages(images); } diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/buttonicon_clear_256.png b/src/com/jpexs/decompiler/flash/gui/graphics/buttonicon_clear_256.png new file mode 100644 index 0000000000000000000000000000000000000000..3f0d105c2829c6b46b42a13972c007d8394f3015 GIT binary patch literal 17571 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 x=3)>$F2bPHr^(