| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to you under the Apache License, |
| * Version 2.0 (the "License"); you may not use this file except in |
| * compliance with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.pivot.wtk.skin.terra; |
| |
| import java.awt.BasicStroke; |
| import java.awt.Color; |
| import java.awt.Font; |
| import java.awt.GradientPaint; |
| import java.awt.Graphics2D; |
| import java.awt.geom.Line2D; |
| |
| import org.apache.pivot.collections.Dictionary; |
| import org.apache.pivot.collections.Sequence; |
| import org.apache.pivot.util.Utils; |
| import org.apache.pivot.wtk.Bounds; |
| import org.apache.pivot.wtk.BoxPane; |
| import org.apache.pivot.wtk.Button; |
| import org.apache.pivot.wtk.ButtonPressListener; |
| import org.apache.pivot.wtk.Component; |
| import org.apache.pivot.wtk.Cursor; |
| import org.apache.pivot.wtk.Dimensions; |
| import org.apache.pivot.wtk.Display; |
| import org.apache.pivot.wtk.Frame; |
| import org.apache.pivot.wtk.FrameListener; |
| import org.apache.pivot.wtk.GraphicsUtilities; |
| import org.apache.pivot.wtk.HorizontalAlignment; |
| import org.apache.pivot.wtk.ImageView; |
| import org.apache.pivot.wtk.Insets; |
| import org.apache.pivot.wtk.Keyboard; |
| import org.apache.pivot.wtk.Keyboard.KeyCode; |
| import org.apache.pivot.wtk.Keyboard.KeyLocation; |
| import org.apache.pivot.wtk.Keyboard.Modifier; |
| import org.apache.pivot.wtk.Label; |
| import org.apache.pivot.wtk.MenuBar; |
| import org.apache.pivot.wtk.Mouse; |
| import org.apache.pivot.wtk.Orientation; |
| import org.apache.pivot.wtk.Point; |
| import org.apache.pivot.wtk.PushButton; |
| import org.apache.pivot.wtk.Style; |
| import org.apache.pivot.wtk.TablePane; |
| import org.apache.pivot.wtk.Theme; |
| import org.apache.pivot.wtk.VerticalAlignment; |
| import org.apache.pivot.wtk.Window; |
| import org.apache.pivot.wtk.effects.DropShadowDecorator; |
| import org.apache.pivot.wtk.media.Image; |
| import org.apache.pivot.wtk.skin.WindowSkin; |
| import org.apache.pivot.wtk.util.ColorUtilities; |
| |
| /** |
| * Frame skin. |
| */ |
| public class TerraFrameSkin extends WindowSkin implements FrameListener { |
| /** |
| * Frame button. |
| */ |
| public static class FrameButton extends PushButton { |
| public FrameButton(Object buttonData) { |
| super(buttonData); |
| installSkin(FrameButton.class); |
| } |
| } |
| |
| /** |
| * Frame button skin. |
| */ |
| public static class FrameButtonSkin extends TerraPushButtonSkin { |
| public FrameButtonSkin() { |
| setPadding(3); |
| } |
| |
| @Override |
| public boolean isFocusable() { |
| return false; |
| } |
| |
| @Override |
| public boolean mouseDown(Component component, Mouse.Button button, int x, int y) { |
| super.mouseDown(component, button, x, y); |
| return true; |
| } |
| } |
| |
| /** |
| * Abstract base class for frame button images. |
| */ |
| protected abstract class ButtonImage extends Image { |
| @Override |
| public int getWidth() { |
| return 8; |
| } |
| |
| @Override |
| public int getHeight() { |
| return 8; |
| } |
| } |
| |
| /** |
| * Minimize button image. |
| */ |
| protected class MinimizeImage extends ButtonImage { |
| @Override |
| public void paint(Graphics2D graphics) { |
| Frame frame = (Frame) getComponent(); |
| graphics.setPaint(frame.isActive() ? titleBarColor : inactiveTitleBarColor); |
| graphics.fillRect(0, 6, 8, 2); |
| } |
| } |
| |
| /** |
| * Maximize button image. |
| */ |
| protected class MaximizeImage extends ButtonImage { |
| @Override |
| public void paint(Graphics2D graphics) { |
| Frame frame = (Frame) getComponent(); |
| graphics.setPaint(frame.isActive() ? titleBarColor : inactiveTitleBarColor); |
| graphics.fillRect(0, 0, 8, 8); |
| |
| graphics.setPaint(frame.isActive() ? titleBarBackgroundColor |
| : inactiveTitleBarBackgroundColor); |
| graphics.fillRect(2, 2, 4, 4); |
| } |
| } |
| |
| /** |
| * Restore button image. |
| */ |
| protected class RestoreImage extends ButtonImage { |
| @Override |
| public void paint(Graphics2D graphics) { |
| Frame frame = (Frame) getComponent(); |
| graphics.setPaint(frame.isActive() ? titleBarColor : inactiveTitleBarColor); |
| graphics.fillRect(1, 1, 6, 6); |
| |
| graphics.setPaint(frame.isActive() ? titleBarBackgroundColor |
| : inactiveTitleBarBackgroundColor); |
| graphics.fillRect(3, 3, 2, 2); |
| } |
| } |
| |
| /** |
| * Close button image. |
| */ |
| protected class CloseImage extends ButtonImage { |
| @Override |
| public void paint(Graphics2D graphics) { |
| Frame frame = (Frame) getComponent(); |
| graphics.setPaint(frame.isActive() ? titleBarColor : inactiveTitleBarColor); |
| graphics.setStroke(new BasicStroke(2)); |
| |
| GraphicsUtilities.setAntialiasingOn(graphics); |
| |
| graphics.draw(new Line2D.Double(0.5, 0.5, 7.5, 7.5)); |
| graphics.draw(new Line2D.Double(0.5, 7.5, 7.5, 0.5)); |
| } |
| } |
| |
| /** |
| * Resize button image. |
| */ |
| protected class ResizeImage extends Image { |
| private static final int ALPHA_IMAGE = 64; |
| |
| @Override |
| public int getWidth() { |
| return 5; |
| } |
| |
| @Override |
| public int getHeight() { |
| return 5; |
| } |
| |
| @Override |
| public void paint(Graphics2D graphics) { |
| graphics.setPaint(new Color(0, 0, 0, ALPHA_IMAGE)); |
| graphics.fillRect(3, 0, 2, 1); |
| graphics.fillRect(0, 3, 2, 1); |
| graphics.fillRect(3, 3, 2, 1); |
| |
| graphics.setPaint(ColorUtilities.setTransparencyInColor(contentBorderColor, ALPHA_IMAGE)); |
| graphics.fillRect(3, 1, 2, 1); |
| graphics.fillRect(0, 4, 2, 1); |
| graphics.fillRect(3, 4, 2, 1); |
| } |
| } |
| |
| private Image minimizeImage = new MinimizeImage(); |
| private Image maximizeImage = new MaximizeImage(); |
| private Image restoreImage = new RestoreImage(); |
| private Image closeImage = new CloseImage(); |
| private Image resizeImage = new ResizeImage(); |
| |
| private TablePane titleBarTablePane = new TablePane(); |
| private BoxPane titleBoxPane = new BoxPane(); |
| private BoxPane buttonBoxPane = new BoxPane(); |
| |
| private ImageView iconImageView = new ImageView(); |
| private Label titleLabel = new Label(); |
| |
| private FrameButton minimizeButton = null; |
| private FrameButton maximizeButton = null; |
| private FrameButton closeButton = null; |
| private ImageView resizeHandle = new ImageView(resizeImage); |
| |
| private DropShadowDecorator dropShadowDecorator = null; |
| |
| private Point dragOffset = null; |
| private Point resizeOffset = null; |
| |
| private Color titleBarColor; |
| private Color titleBarBackgroundColor; |
| private Color titleBarBorderColor; |
| private Color inactiveTitleBarColor; |
| private Color inactiveTitleBarBackgroundColor; |
| private Color inactiveTitleBarBorderColor; |
| private Color contentBorderColor; |
| private Insets padding; |
| private boolean resizable; |
| private boolean showContentBevel; |
| |
| // Derived colors |
| private Color titleBarBevelColor; |
| private Color inactiveTitleBarBevelColor; |
| private Color contentBevelColor; |
| |
| private static final float INACTIVE_ICON_OPACITY = 0.5f; |
| protected static final int ALPHA = 235; |
| |
| @SuppressWarnings("unused") |
| public TerraFrameSkin() { |
| Theme theme = currentTheme(); |
| setBackgroundColor(theme.getColor(10)); |
| |
| titleBarColor = theme.getColor(4); |
| titleBarBackgroundColor = theme.getColor(14); |
| titleBarBorderColor = theme.getColor(12); |
| inactiveTitleBarColor = theme.getColor(7); |
| inactiveTitleBarBackgroundColor = theme.getColor(9); |
| inactiveTitleBarBorderColor = theme.getColor(7); |
| contentBorderColor = theme.getColor(7); |
| padding = new Insets(8); |
| resizable = true; |
| showContentBevel = true; |
| |
| // Set the derived colors |
| titleBarBevelColor = TerraTheme.brighten(titleBarBackgroundColor); |
| inactiveTitleBarBevelColor = TerraTheme.brighten(inactiveTitleBarBackgroundColor); |
| |
| // The title bar table pane contains two nested box panes: one for |
| // the title contents and the other for the buttons |
| new TablePane.Column(titleBarTablePane, 1, true); |
| new TablePane.Column(titleBarTablePane, -1); |
| |
| TablePane.Row titleRow = new TablePane.Row(titleBarTablePane, -1); |
| |
| titleRow.add(titleBoxPane); |
| titleRow.add(buttonBoxPane); |
| |
| titleBarTablePane.getStyles().put(Style.padding, new Insets(2)); |
| |
| // Initialize the title box pane |
| titleBoxPane.add(iconImageView); |
| titleBoxPane.add(titleLabel); |
| titleBoxPane.getStyles().put(Style.verticalAlignment, VerticalAlignment.CENTER); |
| titleBoxPane.getStyles().put(Style.padding, new Insets(0, 0, 0, 2)); |
| |
| Font titleFont = theme.getFont().deriveFont(Font.BOLD); |
| titleLabel.getStyles().put(Style.font, titleFont); |
| |
| iconImageView.setPreferredSize(16, 16); |
| iconImageView.getStyles().put(Style.fill, true); |
| iconImageView.getStyles().put(Style.backgroundColor, null); |
| |
| // Initialize the button box pane |
| buttonBoxPane.getStyles().put(Style.horizontalAlignment, HorizontalAlignment.RIGHT); |
| buttonBoxPane.getStyles().put(Style.verticalAlignment, VerticalAlignment.CENTER); |
| } |
| |
| @Override |
| public void install(Component component) { |
| super.install(component); |
| |
| Frame frame = (Frame) getComponent(); |
| |
| if (!themeIsFlat()) { |
| // Attach the drop-shadow decorator |
| dropShadowDecorator = new DropShadowDecorator(5, 5, 5); |
| frame.getDecorators().add(dropShadowDecorator); |
| } |
| |
| frame.add(titleBarTablePane); |
| |
| // Create the frame buttons |
| minimizeButton = new FrameButton(minimizeImage); |
| maximizeButton = new FrameButton(maximizeImage); |
| closeButton = new FrameButton(closeImage); |
| |
| buttonBoxPane.add(minimizeButton); |
| buttonBoxPane.add(maximizeButton); |
| buttonBoxPane.add(closeButton); |
| |
| ButtonPressListener buttonPressListener = new ButtonPressListener() { |
| @Override |
| public void buttonPressed(Button button) { |
| Frame frameLocal = (Frame) getComponent(); |
| |
| if (button == minimizeButton) { |
| frameLocal.setVisible(false); |
| } else if (button == maximizeButton) { |
| frameLocal.moveToFront(); |
| frameLocal.setMaximized(!frameLocal.isMaximized()); |
| } else if (button == closeButton) { |
| frameLocal.close(); |
| } |
| } |
| }; |
| |
| minimizeButton.getButtonPressListeners().add(buttonPressListener); |
| maximizeButton.getButtonPressListeners().add(buttonPressListener); |
| closeButton.getButtonPressListeners().add(buttonPressListener); |
| |
| frame.add(resizeHandle); |
| |
| iconAdded(frame, null); |
| titleChanged(frame, null); |
| activeChanged(frame, null); |
| maximizedChanged(frame); |
| |
| setShowMinimizeButton(false); |
| } |
| |
| @Override |
| public int getPreferredWidth(int height) { |
| int preferredWidth = 0; |
| |
| Frame frame = (Frame) getComponent(); |
| |
| // Include title bar width plus left/right title bar borders |
| Dimensions titleBarSize = titleBarTablePane.getPreferredSize(); |
| preferredWidth = Math.max(titleBarSize.width + 2, preferredWidth); |
| |
| if (height != -1) { |
| // Subtract title bar height and top/bottom title bar borders |
| // from height constraint |
| height -= titleBarSize.height + 2; |
| } |
| |
| // Include menu bar width |
| MenuBar menuBar = frame.getMenuBar(); |
| if (menuBar != null) { |
| Dimensions menuBarSize = menuBar.getPreferredSize(); |
| preferredWidth = Math.max(preferredWidth, menuBarSize.width); |
| |
| if (height != -1) { |
| // Subtract menu bar height from height constraint |
| height -= menuBarSize.height; |
| } |
| } |
| |
| Component content = frame.getContent(); |
| if (content != null) { |
| if (height != -1) { |
| // Subtract padding, top/bottom content borders, and content bevel |
| // from height constraint |
| height -= (padding.top + padding.bottom) + (showContentBevel ? 1 : 0) + 2; |
| height = Math.max(height, 0); |
| } |
| |
| preferredWidth = Math.max(preferredWidth, content.getPreferredWidth(height)); |
| } |
| |
| // Add padding and left/right content borders |
| preferredWidth += (padding.left + padding.right) + 2; |
| |
| return preferredWidth; |
| } |
| |
| @Override |
| public int getPreferredHeight(int width) { |
| int preferredHeight = 0; |
| |
| Frame frame = (Frame) getComponent(); |
| |
| // Include title bar height plus top/bottom title bar borders |
| preferredHeight += titleBarTablePane.getPreferredHeight() + 2; |
| |
| // Include menu bar height |
| MenuBar menuBar = frame.getMenuBar(); |
| if (menuBar != null) { |
| preferredHeight += menuBar.getPreferredHeight(); |
| } |
| |
| Component content = frame.getContent(); |
| if (content != null) { |
| if (width != -1) { |
| // Subtract padding and left/right content borders from constraint |
| width -= (padding.left + padding.right) + 2; |
| width = Math.max(width, 0); |
| } |
| |
| preferredHeight += content.getPreferredHeight(width); |
| } |
| |
| // Add padding, top/bottom content borders, and content bevel |
| preferredHeight += (padding.top + padding.bottom) + (showContentBevel ? 1 : 0) + 2; |
| |
| return preferredHeight; |
| } |
| |
| @Override |
| public Dimensions getPreferredSize() { |
| int preferredWidth = 0; |
| int preferredHeight = 0; |
| |
| Frame frame = (Frame) getComponent(); |
| |
| // Include title bar width plus left/right title bar borders |
| Dimensions titleBarSize = titleBarTablePane.getPreferredSize(); |
| preferredWidth = Math.max(preferredWidth, titleBarSize.width + 2); |
| |
| // Include title bar height plus top/bottom title bar borders |
| preferredHeight += titleBarSize.height + 2; |
| |
| // Include menu bar size |
| MenuBar menuBar = frame.getMenuBar(); |
| if (menuBar != null) { |
| Dimensions preferredMenuBarSize = menuBar.getPreferredSize(); |
| |
| preferredWidth = Math.max(preferredWidth, preferredMenuBarSize.width); |
| preferredHeight += preferredMenuBarSize.height; |
| } |
| |
| Component content = frame.getContent(); |
| if (content != null) { |
| Dimensions preferredContentSize = content.getPreferredSize(); |
| |
| preferredWidth = Math.max(preferredWidth, preferredContentSize.width); |
| preferredHeight += preferredContentSize.height; |
| } |
| |
| // Add padding, borders, and content bevel |
| preferredWidth += (padding.left + padding.right) + 2; |
| preferredHeight += (padding.top + padding.bottom) + (showContentBevel ? 1 : 0) + 2; |
| |
| return new Dimensions(preferredWidth, preferredHeight); |
| } |
| |
| @Override |
| public void layout() { |
| Frame frame = (Frame) getComponent(); |
| |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| boolean maximized = frame.isMaximized(); |
| |
| if (!maximized || getShowWindowControls()) { |
| int clientX = 1; |
| int clientY = 1; |
| int clientWidth = Math.max(width - 2, 0); |
| int clientHeight = Math.max(height - 2, 0); |
| |
| // Size/position title bar |
| titleBarTablePane.setLocation(clientX, clientY); |
| titleBarTablePane.setSize(clientWidth, titleBarTablePane.getPreferredHeight()); |
| titleBarTablePane.setVisible(true); |
| |
| // Add bottom title bar border, top content border, and content |
| // bevel |
| clientY += titleBarTablePane.getHeight() + (showContentBevel ? 1 : 0) + 2; |
| |
| // Size/position resize handle |
| resizeHandle.setSize(resizeHandle.getPreferredSize()); |
| resizeHandle.setLocation(clientWidth - resizeHandle.getWidth(), clientHeight |
| - resizeHandle.getHeight()); |
| resizeHandle.setVisible(resizable && !maximized |
| && (frame.isPreferredWidthSet() || frame.isPreferredHeightSet())); |
| |
| // Size/position menu bar |
| MenuBar menuBar = frame.getMenuBar(); |
| if (menuBar != null && menuBar.isVisible()) { |
| menuBar.setLocation(clientX, clientY); |
| menuBar.setSize(clientWidth, menuBar.getPreferredHeight()); |
| |
| clientY += menuBar.getHeight(); |
| } |
| |
| // Size/position content |
| Component content = frame.getContent(); |
| if (content != null) { |
| int contentX = clientX + padding.left; |
| int contentY = clientY + padding.top; |
| int contentWidth = Math.max(clientWidth - (padding.left + padding.right), 0); |
| int contentHeight = Math.max(clientHeight |
| - (clientY + padding.top + padding.bottom) + (showContentBevel ? 1 : 0), 0); |
| |
| content.setLocation(contentX, contentY); |
| content.setSize(contentWidth, contentHeight); |
| } |
| } else { |
| titleBarTablePane.setVisible(false); |
| resizeHandle.setVisible(false); |
| |
| // Size/position menu bar |
| int clientY = 0; |
| MenuBar menuBar = frame.getMenuBar(); |
| if (menuBar != null && menuBar.isVisible()) { |
| menuBar.setLocation(0, clientY); |
| menuBar.setSize(width, menuBar.getPreferredHeight()); |
| |
| clientY += menuBar.getHeight(); |
| } |
| |
| Component content = frame.getContent(); |
| if (content != null) { |
| content.setLocation(padding.left, clientY + padding.top); |
| content.setSize(Math.max(width - (padding.left + padding.right), 0), |
| Math.max(height - (clientY + padding.top + padding.bottom), 0)); |
| } |
| } |
| } |
| |
| @Override |
| public void paint(Graphics2D graphics) { |
| // Call the base class to paint the background |
| super.paint(graphics); |
| |
| Frame frame = (Frame) getComponent(); |
| |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| boolean maximized = frame.isMaximized(); |
| |
| if (!maximized || getShowWindowControls()) { |
| int titleBarHeight = titleBarTablePane.getHeight(); |
| |
| // Draw the title area |
| Color titleBarBackgroundColorLocal = frame.isActive() ? this.titleBarBackgroundColor |
| : inactiveTitleBarBackgroundColor; |
| Color titleBarBorderColorLocal = frame.isActive() ? this.titleBarBorderColor |
| : inactiveTitleBarBorderColor; |
| Color titleBarBevelColorLocal = frame.isActive() ? this.titleBarBevelColor |
| : inactiveTitleBarBevelColor; |
| |
| if (!themeIsFlat()) { |
| graphics.setPaint(new GradientPaint(width / 2f, 0, titleBarBevelColorLocal, width / 2f, |
| titleBarHeight + 1, titleBarBackgroundColorLocal)); |
| graphics.fillRect(0, 0, width, titleBarHeight + 1); |
| |
| // Draw the border |
| graphics.setPaint(titleBarBorderColorLocal); |
| GraphicsUtilities.drawRect(graphics, 0, 0, width, titleBarHeight + 2); |
| |
| // Draw the content area |
| Bounds contentAreaRectangle = new Bounds(0, titleBarHeight + 2, width, height |
| - (titleBarHeight + 2)); |
| graphics.setPaint(contentBorderColor); |
| GraphicsUtilities.drawRect(graphics, contentAreaRectangle.x, contentAreaRectangle.y, |
| contentAreaRectangle.width, contentAreaRectangle.height); |
| |
| if (showContentBevel) { |
| graphics.setPaint(contentBevelColor); |
| GraphicsUtilities.drawLine(graphics, contentAreaRectangle.x + 1, |
| contentAreaRectangle.y + 1, contentAreaRectangle.width - 2, |
| Orientation.HORIZONTAL); |
| } |
| } else { |
| graphics.setPaint(titleBarBackgroundColorLocal); |
| graphics.fillRect(0, 0, width, titleBarHeight + 1); |
| |
| } |
| } |
| } |
| |
| @Override |
| public Bounds getClientArea() { |
| int width = getWidth(); |
| int height = getHeight(); |
| int titleBarHeight = titleBarTablePane.getHeight(); |
| |
| Frame frame = (Frame) getComponent(); |
| boolean maximized = frame.isMaximized(); |
| |
| Bounds clientArea; |
| if (maximized && !getShowWindowControls()) { |
| clientArea = new Bounds(0, 0, width, height); |
| } else { |
| clientArea = new Bounds(0, titleBarHeight + 2, width, height - (titleBarHeight + 2)); |
| } |
| |
| return clientArea; |
| } |
| |
| @Override |
| public void setBackgroundColor(Color backgroundColor) { |
| super.setBackgroundColor(backgroundColor); |
| contentBevelColor = TerraTheme.brighten(backgroundColor); |
| } |
| |
| public boolean getShowMinimizeButton() { |
| return minimizeButton.isVisible(); |
| } |
| |
| public void setShowMinimizeButton(boolean showMinimizeButton) { |
| minimizeButton.setVisible(showMinimizeButton); |
| } |
| |
| public boolean getShowMaximizeButton() { |
| return maximizeButton.isVisible(); |
| } |
| |
| public void setShowMaximizeButton(boolean showMaximizeButton) { |
| maximizeButton.setVisible(showMaximizeButton); |
| } |
| |
| public boolean getShowCloseButton() { |
| return closeButton.isVisible(); |
| } |
| |
| public void setShowCloseButton(boolean showCloseButton) { |
| closeButton.setVisible(showCloseButton); |
| } |
| |
| public boolean getShowWindowControls() { |
| return (getShowMinimizeButton() || getShowMaximizeButton() || getShowCloseButton()); |
| } |
| |
| public void setShowWindowControls(boolean showWindowControls) { |
| setShowMinimizeButton(showWindowControls); |
| setShowMaximizeButton(showWindowControls); |
| setShowCloseButton(showWindowControls); |
| } |
| |
| public Insets getPadding() { |
| return padding; |
| } |
| |
| public void setPadding(Insets padding) { |
| Utils.checkNull(padding, "padding"); |
| |
| this.padding = padding; |
| invalidateComponent(); |
| } |
| |
| public final void setPadding(Dictionary<String, ?> padding) { |
| setPadding(new Insets(padding)); |
| } |
| |
| public final void setPadding(Sequence<?> padding) { |
| setPadding(new Insets(padding)); |
| } |
| |
| public final void setPadding(int padding) { |
| setPadding(new Insets(padding)); |
| } |
| |
| public final void setPadding(Number padding) { |
| setPadding(new Insets(padding)); |
| } |
| |
| public final void setPadding(String padding) { |
| setPadding(Insets.decode(padding)); |
| } |
| |
| public boolean isResizable() { |
| return resizable; |
| } |
| |
| public void setResizable(boolean resizable) { |
| this.resizable = resizable; |
| invalidateComponent(); |
| } |
| |
| public boolean getShowContentBevel() { |
| return showContentBevel; |
| } |
| |
| public void setShowContentBevel(boolean showContentBevel) { |
| this.showContentBevel = showContentBevel; |
| invalidateComponent(); |
| } |
| |
| @Override |
| public boolean mouseMove(Component component, int x, int y) { |
| boolean consumed = super.mouseMove(component, x, y); |
| |
| if (Mouse.getCapturer() == component) { |
| Frame frame = (Frame) getComponent(); |
| Display display = frame.getDisplay(); |
| |
| Point location = frame.mapPointToAncestor(display, x, y); |
| |
| // Pretend that the mouse can't move off screen (off the display) |
| location = new Point(Math.min(Math.max(location.x, 0), display.getWidth() - 1), |
| Math.min(Math.max(location.y, 0), display.getHeight() - 1)); |
| |
| if (dragOffset != null) { |
| // Move the frame |
| frame.setLocation(location.x - dragOffset.x, location.y - dragOffset.y); |
| } else { |
| if (resizeOffset != null) { |
| // Resize the frame |
| int preferredWidth = -1; |
| int preferredHeight = -1; |
| |
| if (frame.isPreferredWidthSet()) { |
| preferredWidth = Math.max(location.x - frame.getX() + resizeOffset.x, |
| titleBarTablePane.getPreferredWidth(-1) + 2); |
| preferredWidth = Math.min(preferredWidth, frame.getMaximumWidth()); |
| preferredWidth = Math.max(preferredWidth, frame.getMinimumWidth()); |
| } |
| |
| if (frame.isPreferredHeightSet()) { |
| preferredHeight = Math.max(location.y - frame.getY() + resizeOffset.y, |
| titleBarTablePane.getHeight() + resizeHandle.getHeight() |
| + (showContentBevel ? 1 : 0) + 6); |
| preferredHeight = Math.min(preferredHeight, frame.getMaximumHeight()); |
| preferredHeight = Math.max(preferredHeight, frame.getMinimumHeight()); |
| } |
| |
| frame.setPreferredSize(preferredWidth, preferredHeight); |
| } |
| } |
| } else { |
| Cursor cursor = null; |
| if (resizeHandle.isVisible() && x > resizeHandle.getX() && y > resizeHandle.getY()) { |
| boolean preferredWidthSet = component.isPreferredWidthSet(); |
| boolean preferredHeightSet = component.isPreferredHeightSet(); |
| |
| if (preferredWidthSet && preferredHeightSet) { |
| cursor = Cursor.RESIZE_SOUTH_EAST; |
| } else if (preferredWidthSet) { |
| cursor = Cursor.RESIZE_EAST; |
| } else if (preferredHeightSet) { |
| cursor = Cursor.RESIZE_SOUTH; |
| } |
| } |
| |
| component.setCursor(cursor); |
| } |
| |
| return consumed; |
| } |
| |
| @Override |
| public boolean mouseDown(Component component, Mouse.Button button, int x, int y) { |
| boolean consumed = super.mouseDown(component, button, x, y); |
| |
| Frame frame = (Frame) getComponent(); |
| boolean maximized = frame.isMaximized(); |
| |
| if (button == Mouse.Button.LEFT && !maximized) { |
| Bounds titleBarBounds = titleBarTablePane.getBounds(); |
| |
| if (titleBarBounds.contains(x, y)) { |
| dragOffset = new Point(x, y); |
| Mouse.capture(component); |
| } else { |
| if (resizable && x > resizeHandle.getX() && y > resizeHandle.getY()) { |
| resizeOffset = new Point(getWidth() - x, getHeight() - y); |
| Mouse.capture(component); |
| } |
| } |
| } |
| |
| return consumed; |
| } |
| |
| @Override |
| public boolean mouseUp(Component component, Mouse.Button button, int x, int y) { |
| boolean consumed = super.mouseUp(component, button, x, y); |
| |
| if (Mouse.getCapturer() == component) { |
| dragOffset = null; |
| resizeOffset = null; |
| Mouse.release(); |
| } |
| |
| return consumed; |
| } |
| |
| @Override |
| public boolean keyPressed(Component component, int keyCode, KeyLocation keyLocation) { |
| boolean consumed = super.keyPressed(component, keyCode, keyLocation); |
| |
| Frame frame = (Frame) component; |
| MenuBar menuBar = frame.getMenuBar(); |
| |
| if (menuBar != null && keyCode == KeyCode.SPACE |
| && Keyboard.isPressed(Modifier.ALT)) { |
| MenuBar.Item activeItem = menuBar.getActiveItem(); |
| MenuBar.ItemSequence items = menuBar.getItems(); |
| |
| if (activeItem == null && items.getLength() > 0) { |
| items.get(0).setActive(true); |
| |
| consumed = true; |
| } |
| } |
| |
| return consumed; |
| } |
| |
| @Override |
| public void titleChanged(Window window, String previousTitle) { |
| String title = window.getTitle(); |
| titleLabel.setVisible(title != null); |
| titleLabel.setText(title != null ? title : ""); |
| } |
| |
| @Override |
| public void iconAdded(Window window, Image addedIcon) { |
| if (window.getIcons().getLength() > 0) { |
| iconImageView.setVisible(true); |
| iconImageView.setImage(window.getIcons().get(0)); |
| } else { |
| iconImageView.setVisible(false); |
| iconImageView.setImage((Image) null); |
| } |
| } |
| |
| @Override |
| public void iconsRemoved(Window window, int index, Sequence<Image> removed) { |
| if (window.getIcons().getLength() > 0) { |
| iconImageView.setVisible(true); |
| iconImageView.setImage(window.getIcons().get(0)); |
| } else { |
| iconImageView.setVisible(false); |
| iconImageView.setImage((Image) null); |
| } |
| } |
| |
| @Override |
| public void activeChanged(Window window, Window obverseWindow) { |
| boolean active = window.isActive(); |
| |
| titleLabel.getStyles().put(Style.color, active ? titleBarColor : inactiveTitleBarColor); |
| iconImageView.getStyles().put(Style.opacity, Float.valueOf(active ? 1.0f : INACTIVE_ICON_OPACITY)); |
| |
| updateButtonStyles(minimizeButton, active); |
| updateButtonStyles(maximizeButton, active); |
| updateButtonStyles(closeButton, active); |
| |
| repaintComponent(); |
| } |
| |
| @Override |
| public void maximizedChanged(Window window) { |
| super.maximizedChanged(window); |
| maximizeButton.setButtonData(window.isMaximized() ? restoreImage : maximizeImage); |
| } |
| |
| @Override |
| public void menuBarChanged(Frame frame, MenuBar previousMenuBar) { |
| invalidateComponent(); |
| } |
| |
| private void updateButtonStyles(FrameButton frameButton, boolean active) { |
| frameButton.getStyles().put(Style.color, active ? titleBarColor : inactiveTitleBarColor); |
| frameButton.getStyles().put(Style.backgroundColor, |
| active ? titleBarBackgroundColor : inactiveTitleBarBackgroundColor); |
| frameButton.getStyles().put(Style.borderColor, |
| active ? titleBarBorderColor : inactiveTitleBarBorderColor); |
| } |
| } |