- make button-like FLabels act more like buttons

- can tab focus
  - space/enter to select
  - brighten on hover
- use previous "hover" border for focus indicator
- fix various layout and style bugs (e.g. too-short widths and missing hoverable properties)
This commit is contained in:
myk
2013-02-07 21:31:42 +00:00
parent ead67174e2
commit b08eaf18f5
13 changed files with 81 additions and 47 deletions

View File

@@ -68,7 +68,7 @@ public class PlayerOutcome {
switch(lossState){
case Conceded: return "conceded";
case Milled: return "lost trying to draw cards from empty library";
case LifeReachedZero: return "lost because ran out of lives";
case LifeReachedZero: return "lost because life total reached 0";
case Poisoned: return "lost because of obtaining 10 poison counters";
case OpponentWon: return "lost because an opponent has won by spell '" + loseConditionSpell + "'";
case SpellEffect: return "lost due to effect of spell '" + loseConditionSpell + "'";

View File

@@ -107,6 +107,11 @@ public enum CDeckEditorUI implements CardContainer {
private void moveSelectedCards(
EditorTableView<InventoryItem> table, _MoveAction moveAction, int maxQty) {
List<InventoryItem> items = table.getSelectedCards();
if (items.isEmpty()) {
return;
}
for (InventoryItem item : items) {
moveAction.move(item, Math.min(maxQty, table.getCardCount(item)));
}

View File

@@ -45,7 +45,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, ITableContainer {
.fontSize(14)
.tooltip("Save (in default directory)")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVE))
.text(" ").hoverable(true).build();
@@ -53,7 +53,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, ITableContainer {
.fontSize(14)
.tooltip("Save As")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVEAS))
.text(" ").hoverable(true).build();
@@ -61,7 +61,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, ITableContainer {
.fontSize(14)
.tooltip("Load")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_OPEN))
.text(" ").hoverable(true).build();
@@ -69,7 +69,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, ITableContainer {
.fontSize(14)
.tooltip("New Deck")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_NEW))
.text(" ").hoverable(true).build();
@@ -77,7 +77,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, ITableContainer {
.fontSize(14)
.tooltip("Print Proxies")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PRINT))
.text(" ").hoverable(true).build();
@@ -89,21 +89,21 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, ITableContainer {
.text("Remove card")
.tooltip("Remove selected card from current deck (or double click the row or hit the spacebar)")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS))
.iconScaleAuto(false).hoverable(true).build();
.iconScaleAuto(false).hoverable().build();
private final FLabel btnRemove4 = new FLabel.Builder()
.fontSize(14)
.text("Remove 4 of card")
.tooltip("Remove up to 4 of selected card to current deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS))
.iconScaleAuto(false).hoverable(true).build();
.iconScaleAuto(false).hoverable().build();
private final JLabel btnDoSideboard = new FLabel.Builder()
.fontSize(14)
.text("Deck/Sideboard")
.tooltip("Edit the sideboard for this deck")
.tooltip("Toggle between editing the deck and the sideboard for this deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT))
.iconScaleAuto(false).hoverable(true).build();
.iconScaleAuto(false).hoverable().build();
private final JTextField txfTitle = new FTextField.Builder().text("[New Deck]").build();

View File

@@ -108,7 +108,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
.fontSize(14)
.tooltip("Save this gauntlet")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVE))
.text(" ").hoverable(true).build();
@@ -116,7 +116,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
.fontSize(14)
.tooltip("Build a new gauntlet")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_NEW))
.text(" ").hoverable(true).build();
@@ -124,7 +124,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
.fontSize(14)
.tooltip("Load a gauntlet")
.iconInBackground(true)
.iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f)
.iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_OPEN))
.text(" ").hoverable(true).build();

View File

@@ -50,7 +50,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
final String strCheckboxConstraints = "w 200px!, h 30px!, gap 0 20px 0 0";
final String strCheckboxConstraints = "h 30px!, gap 0 20px 0 0";
pnlStart.setOpaque(false);
pnlStart.add(cbSingletons, strCheckboxConstraints);
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");

View File

@@ -151,7 +151,7 @@ public enum VSubmenuAvatars implements IVSubmenu<CSubmenuAvatars> {
@SuppressWarnings("serial")
private FLabel makeAvatarLabel(final Image img0, final int index0) {
final FLabel lbl = new FLabel.Builder().icon(new ImageIcon(img0)).iconScaleFactor(1.0)
.iconAlpha(0.7f).iconInBackground(true).hoverable(true).build();
.iconInBackground(true).hoverable(true).build();
final Dimension size = new Dimension(100, 100);
lbl.setPreferredSize(size);

View File

@@ -165,7 +165,7 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
}
}
final String strCheckboxConstraints = "w 200px!, h 30px!, gap 0 20px 0 0";
final String strCheckboxConstraints = "h 30px!, gap 0 20px 0 0";
pnlStart.setOpaque(false);
pnlStart.add(cbSingletons, strCheckboxConstraints);
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");

View File

@@ -161,7 +161,7 @@ public enum VSubmenuPlanechase implements IVSubmenu<CSubmenuPlanechase> {
}
}
final String strCheckboxConstraints = "w 200px!, h 30px!, gap 0 20px 0 0";
final String strCheckboxConstraints = "h 30px!, gap 0 20px 0 0";
pnlStart.setOpaque(false);
pnlStart.add(cbSingletons, strCheckboxConstraints);
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");

View File

@@ -203,7 +203,7 @@ public enum VSubmenuVanguard implements IVSubmenu<CSubmenuVanguard> {
}
}
final String strCheckboxConstraints = "w 200px!, h 30px!, gap 0 20px 0 0";
final String strCheckboxConstraints = "h 30px!, gap 0 20px 0 0";
pnlStart.setOpaque(false);
pnlStart.add(cbSingletons, strCheckboxConstraints);
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");

View File

@@ -120,7 +120,6 @@ public class ControlWinLose {
for (Player p : Singletons.getModel().getGame().getRegisteredPlayers()) {
if (!p.getName().equals(lastGame.getWinner().getName())) {
continue; // not a loser
}

View File

@@ -192,7 +192,12 @@ public class CField implements ICDoc {
((FLabel) this.view.getLblExile()).setHoverable(true);
this.view.getLblExile().addMouseListener(madExiled);
if (Preferences.DEV_MODE) {
((FLabel) this.view.getLblLibrary()).setHoverable(true);
}
this.view.getLblLibrary().addMouseListener(madLibrary);
((FLabel) this.view.getLblHand()).setHoverable(true);
this.view.getLblHand().addMouseListener(madHand);
((FLabel) this.view.getLblFlashback()).setHoverable(true);
@@ -208,11 +213,9 @@ public class CField implements ICDoc {
this.view.getLblGreen().addMouseListener(madGreen);
((FLabel) this.view.getLblRed()).setHoverable(true);
this.view.getLblRed().removeMouseListener(madRed);
this.view.getLblRed().addMouseListener(madRed);
((FLabel) this.view.getLblWhite()).setHoverable(true);
this.view.getLblWhite().removeMouseListener(madWhite);
this.view.getLblWhite().addMouseListener(madWhite);
((FLabel) this.view.getLblColorless()).setHoverable(true);

View File

@@ -313,7 +313,7 @@ public class VField implements IVDoc<CField> {
private FLabel getBuiltFLabel(SkinProp p0, String s0, String s1) {
return new FLabel.Builder().icon(new ImageIcon(FSkin.getImage(p0)))
.opaque(false).fontSize(14)
.fontStyle(Font.BOLD).iconAlpha(0.6f).iconInBackground(true)
.fontStyle(Font.BOLD).iconInBackground()
.text(s0).tooltip(s1).fontAlign(SwingConstants.RIGHT).build();
}

View File

@@ -14,6 +14,10 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -57,7 +61,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
private double bldIconScaleFactor = 0.8;
private int bldFontStyle = Font.PLAIN;
private int bldFontSize = 14;
private float bldIconAlpha = 1.0f;
private float bldUnhoveredAlpha = 0.7f;
private int bldIconAlignX = SwingConstants.LEFT;
private Point bldIconInsets = new Point(0, 0);
@@ -143,10 +147,11 @@ public class FLabel extends JLabel implements ILocalRepaint {
/**@param b0 &emsp; boolean, icon will be drawn independent of text
* @return {@link forge.gui.toolbox.Builder} */
public Builder iconInBackground(final boolean b0) { this.bldIconInBackground = b0; return this; }
public Builder iconInBackground() { iconInBackground(true); return this; }
/**@param f0 &emsp; 0.0f - 1.0f. If icon is in background, this alpha is applied.
/**@param f0 &emsp; 0.0f - 1.0f. alpha factor applied when label is hoverable but not currently hovered.
* @return {@link forge.gui.toolbox.Builder} */
public Builder iconAlpha(final float f0) { this.bldIconAlpha = f0; return this; }
public Builder unhoveredAlpha(final float f0) { this.bldUnhoveredAlpha = f0; return this; }
/**@param i0 &emsp; Int. Only available for background icon.
* SwingConstants.HORIZONTAL .VERTICAL or .CENTER
@@ -188,7 +193,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
this.setFontStyle(b0.bldFontStyle);
this.setFontSize(b0.bldFontSize);
this.setIconAlpha(b0.bldIconAlpha);
this.setUnhoveredAlpha(b0.bldUnhoveredAlpha);
this.setCommand(b0.bldCmd);
this.setReactOnMouseDown(b0.reactOnMouseDown);
this.setFontAlign(b0.bldFontAlign);
@@ -198,6 +203,23 @@ public class FLabel extends JLabel implements ILocalRepaint {
// Call this last; to allow the properties which affect icons to already be in place.
this.setIcon(b0.bldIcon);
// If the label has button-like properties, interpret keypresses like a button
if (b0.bldSelectable || b0.bldHoverable) {
this.setFocusable(true);
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(final KeyEvent e) {
if (e.getKeyChar() == ' ' || e.getKeyCode() == 10) { _doMouseAction(); }
}
});
this.addFocusListener(new FocusListener() {
@Override public void focusLost(FocusEvent arg0) { repaintSelf(); }
@Override public void focusGained(FocusEvent arg0) { repaintSelf(); }
});
}
// Non-custom display properties
this.setForeground(clrText);
this.setBackground(clrMain);
@@ -269,25 +291,23 @@ public class FLabel extends JLabel implements ILocalRepaint {
}
};
private void _doMouseAction() {
if (selectable) { setSelected(!selected); }
if (cmdClick != null && FLabel.this.isEnabled()) { cmdClick.execute(); }
}
// Mouse event handler
private final MouseAdapter madEvents = new MouseAdapter() {
@Override
public void mouseEntered(final MouseEvent e) {
if (hoverable) {
hovered = true; repaintSelf();
}
hovered = true;
repaintSelf();
}
@Override
public void mouseExited(final MouseEvent e) {
if (hoverable) {
hovered = false; repaintSelf();
}
}
private void _doMouseAction() {
if (selectable) { setSelected(!selected); }
if (cmdClick != null && FLabel.this.isEnabled()) { cmdClick.execute(); }
hovered = false;
repaintSelf();
}
@Override
@@ -328,7 +348,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
/** Sets alpha if icon is in background.
* @param f0 &emsp; float */
// NOT public; must be set when label is built.
private void setIconAlpha(final float f0) {
private void setUnhoveredAlpha(final float f0) {
this.alphaDim = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, f0);
this.alphaStrong = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
}
@@ -426,6 +446,12 @@ public class FLabel extends JLabel implements ILocalRepaint {
int w = getWidth();
int h = getHeight();
boolean paintWithHover = hoverable && hovered && isEnabled();
Composite oldComp = g2d.getComposite();
if (hoverable) {
g2d.setComposite(paintWithHover ? alphaStrong : alphaDim);
}
if (opaque) {
if (selected) {
paintDown(g2d, w, h);
@@ -440,10 +466,6 @@ public class FLabel extends JLabel implements ILocalRepaint {
}
}
if (hoverable && hovered && isEnabled()) {
paintHover(g2d, w, h);
}
// Icon in background
if (iconInBackground) {
int sh = (int) (h * iconScaleFactor);
@@ -455,16 +477,21 @@ public class FLabel extends JLabel implements ILocalRepaint {
int y = (int) (((h - sh) / 2) + iconInsets.getY());
Composite oldComp = g2d.getComposite();
g2d.setComposite(hoverable && hovered && !selected ? alphaStrong : alphaDim);
g2d.drawImage(img, x, y, sw + x, sh + y, 0, 0, iw, ih, null);
g2d.setComposite(oldComp);
}
super.paintComponent(g);
if (hoverable) {
g2d.setComposite(oldComp);
}
private void paintHover(final Graphics2D g, int w, int h) {
if (hasFocus() && isEnabled()) {
paintFocus(g2d, w, h);
}
}
private void paintFocus(final Graphics2D g, int w, int h) {
g.setColor(clrHover);
g.drawRect(0, 0, w - 2, h - 2);
g.setColor(l30);