Compare commits

...

12 Commits
0.14 ... 0.16

Author SHA1 Message Date
Karl Tauber
6438e890bb release 0.16 2019-10-23 10:46:46 +02:00
Karl Tauber
7d72b13ac9 made JButton, JCheckBox, JRadioButton, JToggleButton and JSlider non-opaque (#20) 2019-10-23 10:36:33 +02:00
Karl Tauber
a2e21cb07b fixed Java 9 module descriptor (broken since 0.14) 2019-10-23 09:55:55 +02:00
Karl Tauber
06766cb4db Demo: missing SwingUtilities.invokeLater() added 2019-10-23 09:03:08 +02:00
Karl Tauber
72e8ab70a3 Demo: tooltips added to toolbar buttons 2019-10-22 12:09:04 +02:00
Karl Tauber
0f38af5922 ComboBox: right-to-left fixes (#18) 2019-10-22 12:07:23 +02:00
Karl Tauber
4181759008 right-to-left fixes:
-Slider: colored track (if ticks and labels are hidden) was on the left side of the thumb
- ToolTip: multi-line text was not aligned to the right

(issue #18)
2019-10-21 22:12:51 +02:00
Karl Tauber
fff0e5e946 fixed FlatTestLaf (broken by commit 342b932f9e) 2019-10-21 20:11:35 +02:00
Karl Tauber
be88eeb343 release 0.15 2019-10-21 18:29:40 +02:00
Karl Tauber
342b932f9e ToolTip:
- Improved styling of dark tooltips (darker background, no border).
- increased top and bottom margins
- use brighter color in light theme
- Fixed colors in tooltips of disabled components. (issue #15)
2019-10-21 18:07:43 +02:00
Karl Tauber
964dc14a8a ComboBox: fixed NPE in combobox with custom renderer after switching to FlatLaf (#16; regression in 0.14) 2019-10-21 17:04:23 +02:00
Karl Tauber
b56f462626 SwingX: added screenshots 2019-10-21 13:42:22 +02:00
29 changed files with 216 additions and 58 deletions

View File

@@ -1,6 +1,23 @@
FlatLaf Change Log
==================
## 0.16
- Made some fixes for right-to-left support in ComboBox, Slider and ToolTip.
(issue #18)
- Fixed Java 9 module descriptor (broken since 0.14).
- Made `JButton`, `JCheckBox`, `JRadioButton`, `JToggleButton` and `JSlider`
non-opaque. (issue #20)
## 0.15
- ToolTip: Improved styling of dark tooltips (darker background, no border).
- ToolTip: Fixed colors in tooltips of disabled components. (issue #15)
- ComboBox: Fixed NPE in combobox with custom renderer after switching to
FlatLaf. (issue #16; regression in 0.14)
## 0.14
- ComboBox: Use small border if used as table editor.

View File

@@ -35,7 +35,7 @@ build script:
groupId: com.formdev
artifactId: flatlaf
version: 0.14
version: 0.16
Otherwise download `flatlaf-<version>.jar` here:

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
version = "0.14"
version = "0.16"
allprojects {
repositories {

View File

@@ -131,6 +131,7 @@ public class FlatButtonUI
defaults_initialized = true;
}
LookAndFeel.installProperty( b, "opaque", false );
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
MigLayoutVisualPadding.install( b, focusWidth );
@@ -169,15 +170,16 @@ public class FlatButtonUI
@Override
public void update( Graphics g, JComponent c ) {
if( isHelpButton( c ) ) {
// fill background if opaque to avoid garbage if user sets opaque to true
if( c.isOpaque() )
FlatUIUtils.paintParentBackground( g, c );
if( isHelpButton( c ) ) {
helpButtonIcon.paintIcon( c, g, 0, 0 );
return;
}
if( c.isOpaque() && isContentAreaFilled( c ) ) {
FlatUIUtils.paintParentBackground( g, c );
if( isContentAreaFilled( c ) ) {
Color background = getBackground( c );
if( background != null ) {
Graphics2D g2 = (Graphics2D) g.create();

View File

@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -213,6 +214,9 @@ public class FlatComboBoxUI
{
// fix editor component colors
updateEditorColors();
} else if( editor != null && source == comboBox && propertyName == "componentOrientation" ) {
ComponentOrientation o = (ComponentOrientation) e.getNewValue();
editor.applyComponentOrientation( o );
}
}
};
@@ -235,6 +239,8 @@ public class FlatComboBoxUI
if( editor instanceof JTextComponent )
((JTextComponent)editor).setBorder( BorderFactory.createEmptyBorder() );
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
updateEditorColors();
}
@@ -315,6 +321,7 @@ public class FlatComboBoxUI
CellPaddingBorder.uninstall( renderer );
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
c.setFont( comboBox.getFont() );
c.applyComponentOrientation( comboBox.getComponentOrientation() );
CellPaddingBorder.uninstall( c );
boolean enabled = comboBox.isEnabled();
@@ -370,10 +377,18 @@ public class FlatComboBoxUI
extends BasicComboPopup
{
private CellPaddingBorder paddingBorder;
private final ListCellRenderer renderer = new PopupListCellRenderer();
FlatComboPopup( JComboBox combo ) {
super( combo );
// BasicComboPopup listens to JComboBox.componentOrientation and updates
// the component orientation of the list, scroller and popup, but when
// switching the LaF and a new combo popup is created, the component
// orientation is not applied.
ComponentOrientation o = comboBox.getComponentOrientation();
list.setComponentOrientation( o );
scroller.setComponentOrientation( o );
setComponentOrientation( o );
}
@Override
@@ -387,7 +402,13 @@ public class FlatComboBoxUI
comboBox.setPrototypeDisplayValue( prototype );
// make popup wider if necessary
pw = Math.max( pw, displaySize.width );
if( displaySize.width > pw ) {
int diff = displaySize.width - pw;
pw = displaySize.width;
if( !comboBox.getComponentOrientation().isLeftToRight() )
px -= diff;
}
return super.computePopupBounds( px, py, pw, ph );
}
@@ -405,7 +426,7 @@ public class FlatComboBoxUI
protected void configureList() {
super.configureList();
list.setCellRenderer( renderer );
list.setCellRenderer( new PopupListCellRenderer() );
}
@Override
@@ -416,7 +437,7 @@ public class FlatComboBoxUI
super.propertyChange( e );
if( e.getPropertyName() == "renderer" )
list.setCellRenderer( renderer );
list.setCellRenderer( new PopupListCellRenderer() );
}
};
}
@@ -434,6 +455,7 @@ public class FlatComboBoxUI
CellPaddingBorder.uninstall( renderer );
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
c.applyComponentOrientation( comboBox.getComponentOrientation() );
if( c instanceof JComponent ) {
if( paddingBorder == null )

View File

@@ -66,6 +66,7 @@ public class FlatRadioButtonUI
defaults_initialized = true;
}
LookAndFeel.installProperty( b, "opaque", false );
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
MigLayoutVisualPadding.install( b, null );

View File

@@ -25,6 +25,7 @@ import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JComponent;
import javax.swing.JSlider;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSliderUI;
@@ -96,6 +97,8 @@ public class FlatSliderUI
protected void installDefaults( JSlider slider ) {
super.installDefaults( slider );
LookAndFeel.installProperty( slider, "opaque", false );
trackWidth = UIManager.getInt( "Slider.trackWidth" );
thumbWidth = UIManager.getInt( "Slider.thumbWidth" );
@@ -170,9 +173,15 @@ public class FlatSliderUI
if( slider.getOrientation() == JSlider.HORIZONTAL ) {
float y = trackRect.y + (trackRect.height - tw) / 2f;
if( enabled && isRoundThumb() ) {
int cw = thumbRect.x + (thumbRect.width / 2) - trackRect.x;
coloredTrack = new RoundRectangle2D.Float( trackRect.x, y, cw, tw, arc, arc );
track = new RoundRectangle2D.Float( trackRect.x + cw, y, trackRect.width - cw, tw, arc, arc );
if( slider.getComponentOrientation().isLeftToRight() ) {
int cw = thumbRect.x + (thumbRect.width / 2) - trackRect.x;
coloredTrack = new RoundRectangle2D.Float( trackRect.x, y, cw, tw, arc, arc );
track = new RoundRectangle2D.Float( trackRect.x + cw, y, trackRect.width - cw, tw, arc, arc );
} else {
int cw = trackRect.x + trackRect.width - thumbRect.x - (thumbRect.width / 2);
coloredTrack = new RoundRectangle2D.Float( trackRect.x + trackRect.width - cw, y, cw, tw, arc, arc );
track = new RoundRectangle2D.Float( trackRect.x, y, trackRect.width - cw, tw, arc, arc );
}
} else
track = new RoundRectangle2D.Float( trackRect.x, y, trackRect.width, tw, arc, arc );
} else {

View File

@@ -74,11 +74,14 @@ public class FlatToolTipUI
List<String> lines = FlatLaf.split( ((JToolTip)c).getTipText(), '\n' );
int x = insets.left;
int x2 = c.getWidth() - insets.right;
int y = insets.top - fm.getDescent();
int lineHeight = fm.getHeight();
JComponent comp = ((JToolTip)c).getComponent();
boolean leftToRight = (comp != null ? comp : c).getComponentOrientation().isLeftToRight();
for( String line : lines ) {
y += lineHeight;
g.drawString( line, x, y );
g.drawString( line, leftToRight ? x : x2 - SwingUtilities.computeStringWidth( fm, line ), y );
}
} else
super.paint( g, c );

View File

@@ -24,4 +24,6 @@ module com.formdev.flatlaf {
exports com.formdev.flatlaf.icons;
exports com.formdev.flatlaf.ui;
exports com.formdev.flatlaf.util;
uses com.formdev.flatlaf.FlatDefaultsAddon;
}

View File

@@ -227,7 +227,8 @@ ToggleButton.toolbar.selectedBackground=5c6164
#---- ToolTip ----
ToolTip.background=4b4d4d
ToolTip.border=4,6,4,6
ToolTip.background=1e2123
#---- Tree ----

View File

@@ -409,7 +409,10 @@ ToolBar.separatorColor=@@Separator.foreground
#---- ToolTip ----
ToolTip.border=2,6,2,6,@@Component.borderColor
ToolTip.border=4,6,4,6,@@Component.borderColor
ToolTip.borderInactive=null
ToolTip.backgroundInactive=@@ToolTip.background
ToolTip.foregroundInactive=@disabledText
#---- Tree ----

View File

@@ -234,7 +234,7 @@ ToggleButton.toolbar.selectedBackground=cfcfcf
#---- ToolTip ----
ToolTip.background=f7f7f7
ToolTip.background=fafafa
#---- Tree ----

View File

@@ -26,8 +26,10 @@ public class FlatChooserTest
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatChooserTest" );
frame.showFrame( new FlatChooserTest() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatChooserTest" );
frame.showFrame( new FlatChooserTest() );
} );
}
FlatChooserTest() {

View File

@@ -27,8 +27,10 @@ public class FlatComponents2Test
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatComponents2Test" );
frame.showFrame( new FlatComponents2Test() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatComponents2Test" );
frame.showFrame( new FlatComponents2Test() );
} );
}
FlatComponents2Test() {

View File

@@ -28,8 +28,10 @@ public class FlatComponentsTest
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatComponentsTest" );
frame.showFrame( new FlatComponentsTest() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatComponentsTest" );
frame.showFrame( new FlatComponentsTest() );
} );
}
FlatComponentsTest() {
@@ -230,17 +232,20 @@ public class FlatComponentsTest
//---- button1 ----
button1.setText("enabled");
button1.setDisplayedMnemonicIndex(0);
button1.setToolTipText("This button is enabled.");
add(button1, "cell 1 1");
//---- button2 ----
button2.setText("disabled");
button2.setDisplayedMnemonicIndex(0);
button2.setEnabled(false);
button2.setToolTipText("This button is disabled.");
add(button2, "cell 2 1");
//---- button5 ----
button5.setText("default");
button5.setDisplayedMnemonicIndex(0);
button5.setToolTipText("Tool tip with\nmultiple\nlines.");
add(button5, "cell 3 1");
//---- button3 ----
@@ -344,7 +349,15 @@ public class FlatComponentsTest
"editable",
"a",
"bb",
"ccc"
"ccc",
"dd",
"e",
"ff",
"ggg",
"hh",
"i",
"jj",
"kkk"
}));
add(comboBox1, "cell 1 5,growx");
@@ -364,7 +377,15 @@ public class FlatComponentsTest
"not editable",
"a",
"bb",
"ccc"
"ccc",
"dd",
"e",
"ff",
"ggg",
"hh",
"i",
"jj",
"kkk"
}));
add(comboBox3, "cell 3 5,growx");

View File

@@ -43,6 +43,7 @@ new FormModel {
name: "button1"
"text": "enabled"
"displayedMnemonicIndex": 0
"toolTipText": "This button is enabled."
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
@@ -51,6 +52,7 @@ new FormModel {
"text": "disabled"
"displayedMnemonicIndex": 0
"enabled": false
"toolTipText": "This button is disabled."
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1"
} )
@@ -58,6 +60,7 @@ new FormModel {
name: "button5"
"text": "default"
"displayedMnemonicIndex": 0
"toolTipText": "Tool tip with\nmultiple\nlines."
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 1"
} )
@@ -203,6 +206,14 @@ new FormModel {
addElement( "a" )
addElement( "bb" )
addElement( "ccc" )
addElement( "dd" )
addElement( "e" )
addElement( "ff" )
addElement( "ggg" )
addElement( "hh" )
addElement( "i" )
addElement( "jj" )
addElement( "kkk" )
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5,growx"
@@ -229,6 +240,14 @@ new FormModel {
addElement( "a" )
addElement( "bb" )
addElement( "ccc" )
addElement( "dd" )
addElement( "e" )
addElement( "ff" )
addElement( "ggg" )
addElement( "hh" )
addElement( "i" )
addElement( "jj" )
addElement( "kkk" )
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 5,growx"

View File

@@ -17,8 +17,10 @@ public class FlatContainerTest
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatContainerTest" );
frame.showFrame( new FlatContainerTest() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatContainerTest" );
frame.showFrame( new FlatContainerTest() );
} );
}
public FlatContainerTest() {

View File

@@ -239,6 +239,7 @@ public class FlatInspector
text += "Enabled: " + c.isEnabled() + '\n';
text += "Opaque: " + c.isOpaque() + '\n';
text += "Focusable: " + c.isFocusable() + '\n';
text += "Left-to-right: " + c.getComponentOrientation().isLeftToRight() + '\n';
text += "Parent: " + c.getParent().getClass().getName();
return text;

View File

@@ -29,8 +29,10 @@ public class FlatMenusTest
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatMenusTest" );
frame.showFrame( new FlatMenusTest() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatMenusTest" );
frame.showFrame( new FlatMenusTest() );
} );
}
FlatMenusTest() {

View File

@@ -30,8 +30,10 @@ public class FlatOptionPaneTest
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatOptionPaneTest" );
frame.showFrame( new FlatOptionPaneTest() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatOptionPaneTest" );
frame.showFrame( new FlatOptionPaneTest() );
} );
}
FlatOptionPaneTest() {

View File

@@ -47,6 +47,8 @@ public class FlatTestFrame
private JComponent content;
private FlatInspector inspector;
public boolean useApplyComponentOrientation;
public static FlatTestFrame create( String[] args, String title ) {
Preferences prefs = Preferences.userRoot().node( PREFS_ROOT_PATH );
@@ -307,9 +309,17 @@ public class FlatTestFrame
}
private void rightToLeftChanged() {
contentPanel.applyComponentOrientation( rightToLeftCheckBox.isSelected()
ComponentOrientation orientation = rightToLeftCheckBox.isSelected()
? ComponentOrientation.RIGHT_TO_LEFT
: ComponentOrientation.LEFT_TO_RIGHT );
: ComponentOrientation.LEFT_TO_RIGHT;
if( useApplyComponentOrientation )
content.applyComponentOrientation( orientation );
else {
updateComponentsRecur( content, (c, type) -> {
c.setComponentOrientation( orientation );
} );
}
contentPanel.revalidate();
contentPanel.repaint();
}

View File

@@ -20,6 +20,7 @@
@selectionBackground=00aa00
@selectionInactiveBackground=888888
@selectionInactiveForeground=ffffff
@disabledText=000088
@textComponentBackground=ffffff
@cellFocusColor=ff0000
@icon=afafaf
@@ -37,8 +38,8 @@
*.selectionBackground=@selectionBackground
*.selectionForeground=ffff00
*.disabledBackground=e0e0e0
*.disabledForeground=000088
*.disabledText=000088
*.disabledForeground=@disabledText
*.disabledText=@disabledText
*.acceleratorForeground=ff8888
*.acceleratorSelectionForeground=ffffff

View File

@@ -205,18 +205,37 @@ class DemoFrame
//======== toolBar1 ========
{
toolBar1.setMargin(new Insets(3, 3, 3, 3));
//---- backButton ----
backButton.setToolTipText("Back");
toolBar1.add(backButton);
//---- forwardButton ----
forwardButton.setToolTipText("Forward");
toolBar1.add(forwardButton);
toolBar1.addSeparator();
//---- cutButton ----
cutButton.setToolTipText("Cut");
toolBar1.add(cutButton);
//---- copyButton ----
copyButton.setToolTipText("Copy");
toolBar1.add(copyButton);
//---- pasteButton ----
pasteButton.setToolTipText("Paste");
toolBar1.add(pasteButton);
toolBar1.addSeparator();
//---- refreshButton ----
refreshButton.setToolTipText("Refresh");
toolBar1.add(refreshButton);
toolBar1.addSeparator();
//---- showToggleButton ----
showToggleButton.setSelected(true);
showToggleButton.setToolTipText("Show Details");
toolBar1.add(showToggleButton);
}
contentPane.add(toolBar1, BorderLayout.NORTH);

View File

@@ -17,27 +17,33 @@ new FormModel {
"margin": new java.awt.Insets( 3, 3, 3, 3 )
add( new FormComponent( "javax.swing.JButton" ) {
name: "backButton"
"toolTipText": "Back"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "forwardButton"
"toolTipText": "Forward"
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator5"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "cutButton"
"toolTipText": "Cut"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "copyButton"
"toolTipText": "Copy"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "pasteButton"
"toolTipText": "Paste"
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator6"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "refreshButton"
"toolTipText": "Refresh"
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator7"
@@ -45,6 +51,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "showToggleButton"
"selected": true
"toolTipText": "Show Details"
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "North"

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.demo;
import java.util.prefs.Preferences;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatLightLaf;
@@ -32,29 +33,31 @@ public class FlatLafDemo
static Preferences prefs;
public static void main( String[] args ) {
prefs = Preferences.userRoot().node( PREFS_ROOT_PATH );
SwingUtilities.invokeLater( () -> {
prefs = Preferences.userRoot().node( PREFS_ROOT_PATH );
// set look and feel
try {
if( args.length > 0 )
UIManager.setLookAndFeel( args[0] );
else {
String lafClassName = prefs.get( KEY_LAF, FlatLightLaf.class.getName() );
UIManager.setLookAndFeel( lafClassName );
// set look and feel
try {
if( args.length > 0 )
UIManager.setLookAndFeel( args[0] );
else {
String lafClassName = prefs.get( KEY_LAF, FlatLightLaf.class.getName() );
UIManager.setLookAndFeel( lafClassName );
}
} catch( Exception ex ) {
ex.printStackTrace();
// fallback
FlatLightLaf.install();
}
} catch( Exception ex ) {
ex.printStackTrace();
// fallback
FlatLightLaf.install();
}
// create frame
DemoFrame frame = new DemoFrame();
// create frame
DemoFrame frame = new DemoFrame();
// show frame
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
// show frame
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
} );
}
}

View File

@@ -17,6 +17,10 @@ addon:
- `JXTaskPaneContainer`
- `JXTaskPane`
![Flat Light SwingX Demo](../images/FlatLightSwingXTest.png)
![Flat Dark SwingX Demo](../images/FlatDarkSwingXTest.png)
Download
--------
@@ -28,7 +32,7 @@ build script:
groupId: com.formdev
artifactId: flatlaf-swingx
version: 0.14
version: 0.16
Otherwise download `flatlaf-swingx-<version>.jar` here:

View File

@@ -31,8 +31,11 @@ public class FlatSwingXTest
extends JPanel
{
public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatSwingXTest" );
frame.showFrame( new FlatSwingXTest() );
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatSwingXTest" );
frame.useApplyComponentOrientation = true;
frame.showFrame( new FlatSwingXTest() );
} );
}
FlatSwingXTest() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB