Browse Source

Added loading icons.

Added LoadingIndicator.
pull/170/head
weisj 5 years ago
parent
commit
1a46895b2c
  1. 69
      core/src/main/java/com/github/weisj/darklaf/components/RotatableIconAnimator.java
  2. 127
      core/src/main/java/com/github/weisj/darklaf/components/loading/LoadingIndicator.java
  3. 25
      core/src/main/java/com/github/weisj/darklaf/graphics/Animator.java
  4. 12
      core/src/main/resources/com/github/weisj/darklaf/icons/progress/pause.svg
  5. 9
      core/src/main/resources/com/github/weisj/darklaf/icons/progress/resume.svg
  6. 18
      core/src/main/resources/com/github/weisj/darklaf/icons/progress/step_passive.svg
  7. 18
      core/src/main/resources/com/github/weisj/darklaf/icons/progress/step_working.svg
  8. 26
      core/src/test/java/ui/label/LabelDemo.java
  9. 64
      core/src/test/java/ui/label/LabelDemoBase.java
  10. 61
      core/src/test/java/ui/label/LoadIndicator.java
  11. 12
      property-loader/src/main/java/com/github/weisj/darklaf/icons/DarkSVGIcon.java
  12. 4
      property-loader/src/main/java/com/github/weisj/darklaf/icons/RotatableIcon.java
  13. 41
      property-loader/src/main/java/com/github/weisj/darklaf/icons/RotateIcon.java
  14. 92
      property-loader/src/main/java/com/github/weisj/darklaf/icons/TwoIcon.java
  15. 32
      utils/src/main/java/com/github/weisj/darklaf/util/Alignment.java

69
core/src/main/java/com/github/weisj/darklaf/components/RotatableIconAnimator.java

@ -0,0 +1,69 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.components;
import java.awt.event.ActionEvent;
import javax.swing.*;
import com.github.weisj.darklaf.icons.RotatableIcon;
import com.github.weisj.darklaf.util.Alignment;
public class RotatableIconAnimator extends Timer {
private final RotatableIcon icon;
private final JComponent parent;
private final int frameCount;
private int frame;
public RotatableIconAnimator(final RotatableIcon icon, final JComponent parent) {
this(Alignment.values().length, icon, parent);
}
public RotatableIconAnimator(final int frames, final RotatableIcon icon, final JComponent parent) {
super(100, null);
if (icon == null) throw new IllegalArgumentException("Icon is null");
if (parent == null) throw new IllegalArgumentException("Component is null");
addActionListener(this::onAction);
setRepeats(true);
this.icon = icon;
this.frameCount = frames;
this.parent = parent;
}
public void resume() {
start();
}
public void onAction(final ActionEvent e) {
icon.setRotation(Math.PI * 2 * (((double) frame) / frameCount));
parent.repaint();
frame = (frame + 1) % frameCount;
}
public void suspend() {
stop();
}
}

127
core/src/main/java/com/github/weisj/darklaf/components/loading/LoadingIndicator.java

@ -0,0 +1,127 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.components.loading;
import javax.swing.*;
import com.github.weisj.darklaf.components.RotatableIconAnimator;
import com.github.weisj.darklaf.icons.EmptyIcon;
import com.github.weisj.darklaf.icons.RotatableIcon;
import com.github.weisj.darklaf.icons.TwoIcon;
import com.github.weisj.darklaf.util.DarkUIUtil;
/**
* Label that functions as an loading indicator.
*/
public class LoadingIndicator extends JLabel {
private final RotatableIcon loadIcon = new RotatableIcon(DarkUIUtil.ICON_LOADER.getIcon("progress/step_working.svg"));
private final Icon pausedIcon = DarkUIUtil.ICON_LOADER.getIcon("progress/step_passive.svg");
private final Icon emptyIcon = EmptyIcon.create(loadIcon.getIconWidth(), loadIcon.getIconHeight());
private final TwoIcon displayIcon = new TwoIcon(loadIcon, null);
private final RotatableIconAnimator animator = new RotatableIconAnimator(8, loadIcon, this);
private boolean running;
public LoadingIndicator(final String text, final Icon icon, final int horizontalAlignment) {
super(text, icon, horizontalAlignment);
displayIcon.setIconGap(getIconTextGap());
}
public LoadingIndicator(final String text, final int horizontalAlignment) {
this(text, null, horizontalAlignment);
}
public LoadingIndicator(final String text) {
this(text, null, LEADING);
}
public LoadingIndicator(final Icon image, final int horizontalAlignment) {
this(null, image, horizontalAlignment);
}
public LoadingIndicator(final Icon image) {
this(null, image, CENTER);
}
public LoadingIndicator() {
this("", null, LEADING);
}
/**
* Sets whether the icon should be animated.
*
* @param running true if animated.
*/
public void setRunning(final boolean running) {
this.running = running;
setAnimatorState(running);
}
private void setAnimatorState(final boolean running) {
if (running == animator.isRunning()) return;
if (running) {
animator.resume();
} else {
animator.suspend();
}
repaint();
}
@Override
public void setEnabled(final boolean enabled) {
super.setEnabled(enabled);
setAnimatorState(isRunning());
}
/**
* Returns whether the loading icon is animated and visible.
*
* @see #setRunning(boolean)
* @return true if animated and visible.
*/
public boolean isRunning() {
return running && isEnabled();
}
@Override
public void setIconTextGap(final int iconTextGap) {
super.setIconTextGap(iconTextGap);
displayIcon.setIconGap(getIconTextGap());
}
@Override
public Icon getIcon() {
displayIcon.setLeftIcon(running ? loadIcon : pausedIcon);
displayIcon.setRightIcon(super.getIcon());
return displayIcon;
}
@Override
public Icon getDisabledIcon() {
displayIcon.setLeftIcon(emptyIcon);
displayIcon.setRightIcon(super.getDisabledIcon());
return displayIcon;
}
}

25
core/src/main/java/com/github/weisj/darklaf/graphics/Animator.java

@ -66,18 +66,22 @@ public abstract class Animator {
this.repeatable = repeatable; this.repeatable = repeatable;
this.forward = forward; this.forward = forward;
currentFrame = forward ? 0 : totalFrames; currentFrame = forward ? 0 : totalFrames;
resetTime();
reset(); reset();
} }
public void reset() { private void resetTime() {
currentFrame = 0;
startTime = -1; startTime = -1;
} }
public void reset() {
currentFrame %= totalFrames;
if (!forward) currentFrame = totalFrames - currentFrame;
}
private static ScheduledExecutorService createScheduler() { private static ScheduledExecutorService createScheduler() {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, r -> { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, r -> {
final Thread thread = new Thread(r, "Darcula Animations"); final Thread thread = new Thread(r, "Animations Thread");
thread.setDaemon(true); thread.setDaemon(true);
thread.setPriority(Thread.MAX_PRIORITY); thread.setPriority(Thread.MAX_PRIORITY);
return thread; return thread;
@ -89,7 +93,8 @@ public abstract class Animator {
} }
public void suspend() { public void suspend() {
startTime = -1; resetTime();
reset();
stopTicker(); stopTicker();
} }
@ -119,10 +124,11 @@ public abstract class Animator {
@Override @Override
public void run() { public void run() {
if (isScheduled.compareAndSet(false, true) && !isDisposed()) { if (!isScheduled.get() && !isDisposed()) {
isScheduled.set(true);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
isScheduled.set(false);
onTick(); onTick();
isScheduled.set(false);
}); });
} }
} }
@ -136,7 +142,6 @@ public abstract class Animator {
private void animationDone() { private void animationDone() {
stopTicker(); stopTicker();
SwingUtilities.invokeLater(this::paintCycleEnd); SwingUtilities.invokeLater(this::paintCycleEnd);
} }
@ -145,11 +150,11 @@ public abstract class Animator {
} }
private void onTick() { private void onTick() {
if (isDisposed()) return; if (isDisposed() || ticker == null) return;
if (startTime == -1) { if (startTime == -1) {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
stopTime = startTime + cycleDuration * (totalFrames - currentFrame) / totalFrames; stopTime = startTime + (cycleDuration * (totalFrames - currentFrame)) / totalFrames;
} }
final double passedTime = System.currentTimeMillis() - startTime; final double passedTime = System.currentTimeMillis() - startTime;

12
core/src/main/resources/com/github/weisj/darklaf/icons/progress/pause.svg

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
<defs id="colors">
<linearGradient id="Icons.pause.color">
<stop offset="0" stop-color="#AFB1B3"/>
<stop offset="1" stop-color="#AFB1B3"/>
</linearGradient>
</defs>
<g fill="url(#Icons.pause.color)" fill-rule="evenodd" transform="translate(2)">
<rect width="3.5" height="14"/>
<rect width="3.5" height="14" x="6.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 473 B

9
core/src/main/resources/com/github/weisj/darklaf/icons/progress/resume.svg

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
<defs id="colors">
<linearGradient id="Icons.resume.color">
<stop offset="0" stop-color="#AFB1B3"/>
<stop offset="1" stop-color="#AFB1B3"/>
</linearGradient>
</defs>
<polygon fill="url(#Icons.resume.color)" fill-rule="evenodd" points="7 1 14 13 0 13" transform="rotate(90 7 7)"/>
</svg>

After

Width:  |  Height:  |  Size: 423 B

18
core/src/main/resources/com/github/weisj/darklaf/icons/progress/step_passive.svg

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<defs id="colors">
<linearGradient id="Icons.step.passive.color">
<stop offset="0" stop-color="#AFB1B3"/>
<stop offset="1" stop-color="#AFB1B3"/>
</linearGradient>
</defs>
<g fill="url(#Icons.step.passive.color)" fill-opacity=".5" fill-rule="evenodd" transform="translate(1 1)">
<rect width="2" height="4" x="2.471" y="1.471" transform="rotate(-45 3.471 3.471)"/>
<rect width="4" height="2" y="6"/>
<rect width="2" height="4" x="2.471" y="8.531" transform="rotate(45 3.471 10.531)"/>
<rect width="2" height="4" x="6" y="10"/>
<rect width="2" height="4" x="9.531" y="8.531" transform="rotate(-45 10.531 10.531)"/>
<rect width="4" height="2" x="10" y="6"/>
<rect width="2" height="4" x="9.531" y="1.471" transform="rotate(45 10.531 3.471)"/>
<rect width="2" height="4" x="6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 991 B

18
core/src/main/resources/com/github/weisj/darklaf/icons/progress/step_working.svg

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<defs id="colors">
<linearGradient id="Icons.step.working.color">
<stop offset="0" stop-color="#AFB1B3"/>
<stop offset="1" stop-color="#AFB1B3"/>
</linearGradient>
</defs>
<g fill="url(#Icons.step.working.color)" fill-rule="evenodd" transform="translate(1 1)">
<rect width="2" height="4" x="2.471" y="1.471" opacity=".93" transform="rotate(-45 3.471 3.471)"/>
<rect width="4" height="2" y="6" opacity=".78"/>
<rect width="2" height="4" x="2.471" y="8.531" opacity=".69" transform="rotate(45 3.471 10.531)"/>
<rect width="2" height="4" x="6" y="10" opacity=".62"/>
<rect width="2" height="4" x="9.531" y="8.531" opacity=".48" transform="rotate(-45 10.531 10.531)"/>
<rect width="4" height="2" x="10" y="6" opacity=".38"/>
<rect width="2" height="4" x="9.531" y="1.471" opacity=".3" transform="rotate(45 10.531 3.471)"/>
<rect width="2" height="4" x="6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

26
core/src/test/java/ui/label/LabelDemo.java

@ -29,36 +29,16 @@ import java.awt.*;
import javax.swing.*; import javax.swing.*;
import ui.ComponentDemo; import ui.ComponentDemo;
import ui.DemoPanel;
import ui.DemoResources; import ui.DemoResources;
public class LabelDemo implements ComponentDemo { public class LabelDemo extends LabelDemoBase<JLabel> {
public static void main(final String[] args) { public static void main(final String[] args) {
ComponentDemo.showDemo(new LabelDemo()); ComponentDemo.showDemo(new LabelDemo());
} }
@Override protected JLabel createLabel() {
public JComponent createComponent() { return new JLabel("Test Label", DemoResources.FOLDER_ICON, JLabel.LEFT);
Icon icon = DemoResources.FOLDER_ICON;
JLabel label = new JLabel("Test Label", icon, JLabel.LEFT);
DemoPanel panel = new DemoPanel(label);
JPanel controlPanel = panel.addControls();
controlPanel.add(new JCheckBox("enabled") {
{
setSelected(label.isEnabled());
addActionListener(e -> label.setEnabled(isSelected()));
}
});
controlPanel.add(new JCheckBox("LeftToRight") {
{
setSelected(label.getComponentOrientation().isLeftToRight());
addActionListener(e -> label.setComponentOrientation(isSelected() ? ComponentOrientation.LEFT_TO_RIGHT
: ComponentOrientation.RIGHT_TO_LEFT));
}
});
return panel;
} }
@Override @Override

64
core/src/test/java/ui/label/LabelDemoBase.java

@ -0,0 +1,64 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ui.label;
import java.awt.*;
import javax.swing.*;
import ui.ComponentDemo;
import ui.DemoPanel;
public abstract class LabelDemoBase<T extends JLabel> implements ComponentDemo {
@Override
public JComponent createComponent() {
T label = createLabel();
DemoPanel panel = new DemoPanel(label);
JPanel controlPanel = createControlPanel(panel, label);
return panel;
}
protected JPanel createControlPanel(final DemoPanel panel, final T label) {
JPanel controlPanel = panel.addControls();
controlPanel.add(new JCheckBox("enabled") {
{
setSelected(label.isEnabled());
addActionListener(e -> label.setEnabled(isSelected()));
}
});
controlPanel.add(new JCheckBox("LeftToRight") {
{
setSelected(label.getComponentOrientation().isLeftToRight());
addActionListener(e -> label.setComponentOrientation(isSelected() ? ComponentOrientation.LEFT_TO_RIGHT
: ComponentOrientation.RIGHT_TO_LEFT));
}
});
return controlPanel;
}
protected abstract T createLabel();
}

61
core/src/test/java/ui/label/LoadIndicator.java

@ -0,0 +1,61 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ui.label;
import javax.swing.*;
import ui.ComponentDemo;
import ui.DemoPanel;
import ui.DemoResources;
import com.github.weisj.darklaf.components.loading.LoadingIndicator;
public class LoadIndicator extends LabelDemoBase<LoadingIndicator> {
public static void main(final String[] args) {
ComponentDemo.showDemo(new LoadIndicator());
}
@Override
protected JPanel createControlPanel(final DemoPanel panel, final LoadingIndicator label) {
JPanel controls = super.createControlPanel(panel, label);
controls.add(new JCheckBox("running") {
{
setSelected(label.isRunning());
addActionListener(e -> label.setRunning(isSelected()));
}
});
return controls;
}
protected LoadingIndicator createLabel() {
return new LoadingIndicator("Load Indicator", DemoResources.FOLDER_ICON, JLabel.LEFT);
}
@Override
public String getTitle() {
return "Load Indicator Demo";
}
}

12
property-loader/src/main/java/com/github/weisj/darklaf/icons/DarkSVGIcon.java

@ -41,7 +41,7 @@ import com.kitfox.svg.app.beans.SVGIcon;
* @author Jannis Weis * @author Jannis Weis
* @since 2019 * @since 2019
*/ */
public class DarkSVGIcon implements DerivableIcon<DarkSVGIcon>, Serializable { public class DarkSVGIcon implements DerivableIcon<DarkSVGIcon>, RotateIcon, Serializable {
private static final Logger LOGGER = LogUtil.getLogger(DarkSVGIcon.class); private static final Logger LOGGER = LogUtil.getLogger(DarkSVGIcon.class);
private final Dimension size; private final Dimension size;
@ -99,15 +99,7 @@ public class DarkSVGIcon implements DerivableIcon<DarkSVGIcon>, Serializable {
return new SVGIcon(); return new SVGIcon();
} }
/** @Override
* Paint the icon with rotation.
*
* @param c the parent component.
* @param g the graphics object.
* @param x the x coordinate
* @param y the y coordinate
* @param rotation the rotation in radians.
*/
public void paintIcon(final Component c, final Graphics g, final int x, final int y, public void paintIcon(final Component c, final Graphics g, final int x, final int y,
final double rotation) { final double rotation) {
ensureLoaded(); ensureLoaded();

4
property-loader/src/main/java/com/github/weisj/darklaf/icons/RotatableIcon.java

@ -51,8 +51,8 @@ public class RotatableIcon implements Icon {
@Override @Override
public void paintIcon(final Component c, final Graphics g, final int x, final int y) { public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
if (icon instanceof DarkSVGIcon) { if (icon instanceof RotateIcon) {
((DarkSVGIcon) icon).paintIcon(c, g, x, y, getAngle()); ((RotateIcon) icon).paintIcon(c, g, x, y, getAngle());
} else if (icon != null) { } else if (icon != null) {
Graphics2D g2 = (Graphics2D) g.create(); Graphics2D g2 = (Graphics2D) g.create();
AffineTransform transform = new AffineTransform(); AffineTransform transform = new AffineTransform();

41
property-loader/src/main/java/com/github/weisj/darklaf/icons/RotateIcon.java

@ -0,0 +1,41 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.icons;
import java.awt.*;
public interface RotateIcon {
/**
* Paint the icon with rotation.
*
* @param c the parent component.
* @param g the graphics object.
* @param x the x coordinate
* @param y the y coordinate
* @param rotation the rotation in radians.
*/
void paintIcon(Component c, Graphics g, int x, int y, double rotation);
}

92
property-loader/src/main/java/com/github/weisj/darklaf/icons/TwoIcon.java

@ -0,0 +1,92 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.icons;
import java.awt.*;
import javax.swing.*;
public class TwoIcon implements Icon {
private int iconGap = 2;
private Icon leftIcon;
private Icon rightIcon;
public TwoIcon(final Icon leftIcon, final Icon rightIcon) {
this(leftIcon, rightIcon, 2);
}
public TwoIcon(final Icon leftIcon, final Icon rightIcon, final int iconGap) {
setLeftIcon(leftIcon);
setRightIcon(rightIcon);
this.iconGap = iconGap;
}
public void setIconGap(final int iconGap) {
this.iconGap = iconGap;
}
public void setLeftIcon(final Icon leftIcon) {
this.leftIcon = leftIcon != null ? leftIcon : EmptyIcon.create(0);
}
public void setRightIcon(final Icon rightIcon) {
this.rightIcon = rightIcon != null ? rightIcon : EmptyIcon.create(0);
}
public Icon getLeftIcon() {
return leftIcon;
}
public Icon getRightIcon() {
return rightIcon;
}
@Override
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
int mid = getIconHeight() / 2;
boolean ltr = c.getComponentOrientation().isLeftToRight();
Icon left = ltr ? leftIcon : rightIcon;
Icon right = ltr ? rightIcon : leftIcon;
int y1 = y + mid - left.getIconHeight() / 2;
int y2 = y + mid - right.getIconHeight() / 2;
leftIcon.paintIcon(c, g, x, y1);
rightIcon.paintIcon(c, g, x + left.getIconWidth() + iconGap, y2);
}
@Override
public int getIconWidth() {
int l = leftIcon.getIconWidth();
int r = rightIcon.getIconWidth();
int gap = 0;
if (l != 0 && r != 0) gap = iconGap;
return l + r + gap;
}
@Override
public int getIconHeight() {
return Math.max(leftIcon.getIconHeight(), rightIcon.getIconHeight());
}
}

32
utils/src/main/java/com/github/weisj/darklaf/util/Alignment.java

@ -304,4 +304,36 @@ public enum Alignment {
public boolean isWest(final boolean includePure) { public boolean isWest(final boolean includePure) {
return (this == Alignment.WEST && includePure) || this == Alignment.NORTH_WEST || this == Alignment.SOUTH_WEST; return (this == Alignment.WEST && includePure) || this == Alignment.NORTH_WEST || this == Alignment.SOUTH_WEST;
} }
public double getAngle() {
double angle = 0.0;
switch (this) {
case NORTH :
case CENTER :
angle = 0.0;
break;
case SOUTH :
angle = 180.0;
break;
case EAST :
angle = 90.0;
break;
case WEST :
angle = 270.0;
break;
case NORTH_EAST :
angle = 45.0;
break;
case NORTH_WEST :
angle = 315.0;
break;
case SOUTH_EAST :
angle = 135.0;
break;
case SOUTH_WEST :
angle = 225.0;
break;
}
return Math.toRadians(angle);
}
} }

Loading…
Cancel
Save