/*******************************************************************************
* Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* emil.crumhorn@gmail.com - initial API and implementation
*******************************************************************************/
package com.hexapixel.widgets.ribbon;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Rectangle;
public class QuickAccessShellToolbar extends RibbonToolbar {
private RibbonShell mRibbonShell;
private List<RibbonButton> mButtons;
private List<RibbonButton> mSelectedButtons;
private Rectangle mBounds;
private RibbonButton mHoverButton;
private RibbonTooltip mArrowTooltip;
public QuickAccessShellToolbar(RibbonShell parent) {
super(parent);
mRibbonShell = parent;
mButtons = new ArrayList<RibbonButton>();
mSelectedButtons = new ArrayList<RibbonButton>();
}
public RibbonShell getRibbonShell() {
return mRibbonShell;
}
public List<RibbonButton> getButtons() {
return mButtons;
}
void addButton(RibbonButton button) {
if (!mButtons.contains(button)) {
mButtons.add(button);
updateBounds();
}
}
public void removeButton(RibbonButton button) {
mButtons.remove(button);
mRibbonShell.redrawContents();
updateBounds();
}
public void setArrowTooltip(RibbonTooltip tooltip) {
mArrowTooltip = tooltip;
}
public RibbonTooltip getArrowTooltip() {
return mArrowTooltip;
}
void updateBounds() {
if (mButtons.size() == 0)
return;
int x = 0;
int y = 0;
int width = 0;
int height = 0;
for (int i = 0; i < mButtons.size(); i++) {
RibbonButton button = mButtons.get(i);
Rectangle bounds = button.getBounds();
if (bounds == null)
continue;
y = Math.min(y, bounds.y);
x = Math.min(x, bounds.x);
width = Math.max(width, bounds.x+bounds.width);
height = Math.max(height, bounds.y+bounds.height);
}
// so that we can de-hover when mouse exits an area, we want this slightly higher and wider than any strip of buttons, just a few pixels
y -= 3;
x -= 3;
width += 6;
height += 6;
mBounds = new Rectangle(x, y, width, height);
}
public Rectangle getBounds() {
return mBounds;
}
boolean dehover() {
if (mHoverButton != null) {
mHoverButton.setHoverButton(false);
mHoverButton = null;
return true;
}
return false;
}
boolean mouseMove(MouseEvent me) {
boolean redraw = false;
boolean any = false;
for (int i = 0; i < mButtons.size(); i++) {
RibbonButton button = mButtons.get(i);
if (!button.isEnabled())
continue;
if (isInside(me.x, me.y, button.getBounds())) {
any = true;
if (!button.isHoverButton()) {
if (mHoverButton != null && mHoverButton != button) {
mHoverButton.setHoverButton(false);
redraw = true;
}
button.setHoverButton(true);
mHoverButton = button;
redraw = true;
}
// if split button, determine what part is hover
if (button.isSplit() && !button.isToolbarButton()) {
if (isInside(me.x, me.y, button.getTopBounds())) {
if (!button.isTopHovered()) {
redraw = true;
}
button.setTopHovered(true);
}
if (isInside(me.x, me.y, button.getBottomBounds())) {
if (!button.isBottomHovered()) {
redraw = true;
}
button.setBottomHovered(true);
}
}
else if (button.isToolbarButton()) {
boolean changed = false;
// if split item, determine what part is hover
if ((button.getStyle() & RibbonButton.STYLE_ARROW_DOWN_SPLIT) != 0) {
if (isInside(me.x, me.y, button.getLeftBounds())) {
if (!button.isLeftHovered()) {
changed = true;
}
button.setLeftHovered(true);
}
else if (isInside(me.x, me.y, button.getRightBounds())) {
if (!button.isRightHovered()) {
changed = true;
}
button.setRightHovered(true);
}
if (!changed)
continue;
else
redraw = true;
}
}
}
}
if (!any) {
if (mHoverButton != null)
mHoverButton.setHoverButton(false);
mHoverButton = null;
redraw = true;
}
return redraw;
}
boolean mouseDown(MouseEvent me) {
boolean redraw = false;
for (int i = 0; i < mButtons.size(); i++) {
RibbonButton button = mButtons.get(i);
if (!button.isEnabled())
continue;
if (isInside(me.x, me.y, button.getBounds())) {
if (!button.isSelected()) {
redraw = true;
if (!mSelectedButtons.contains(button))
mSelectedButtons.add(button);
button.setSelected(true);
// if split item, determine what part is hover
if ((button.getStyle() & RibbonButton.STYLE_ARROW_DOWN_SPLIT) != 0) {
if (isInside(me.x, me.y, button.getLeftBounds())) {
// if it's a toggle, untoggle, but only left / top side
if ((button.getStyle() & RibbonButton.STYLE_TOGGLE) != 0) {
if (button.isLeftSelected())
button.setLeftSelected(false);
else
button.setLeftSelected(true);
}
}
if (isInside(me.x, me.y, button.getRightBounds())) {
button.setRightSelected(true);
}
}
if (button.isSelected())
button.notifySelectionListeners(me);
}
else {
redraw = true;
button.setSelected(false);
mSelectedButtons.remove(button);
// if split button, determine what part is hover
if ((button.getStyle() & RibbonButton.STYLE_ARROW_DOWN_SPLIT) != 0) {
if (isInside(me.x, me.y, button.getLeftBounds()))
button.setLeftSelected(true);
if (isInside(me.x, me.y, button.getRightBounds()))
button.setRightSelected(true);
}
//button.notifySelectionListeners(me);
}
}
}
return redraw;
}
private boolean isInside(int x, int y, Rectangle rect) {
if (rect == null) {
return false;
}
return x >= rect.x && y >= rect.y && x <= (rect.x + rect.width-1) && y <= (rect.y + rect.height-1);
}
}