// Copyright 1996, Marimba Inc. All Rights Reserved.


// @(#)DropDownTextBoxWidget.java, 1.19, 12/23/96





package marimba.gui;





import java.awt.*;


import java.util.*;





import marimba.persist.*;





/**


 * A text widget with an associated pull down menu


 * which has to be used by other widgets and cannot


 * be used standalone.


 *


 * @author	Arthur van Hoff


 * @version 	1.19, 12/23/96


 */


class DropDownTextBoxWidget extends TextBoxWidget {


    final static int  SIZ = 17;





    /**


     * Should the down arrowbutton be displayed at the left or the right.


     * @see #getAlign


     * @see #setAlign


     */


    public int  align = RIGHT;





    /**


     * Determines whether the menu is being displayed right now.


     * @see #isDown


     * @see #setDown


     */


    public boolean  down;





    /**


     * If true, the dropdown button will be filled.


     * @see #getFillButton


     * @see #setFillButton


     */


    public boolean  fillButton;








    /**


     * Constructor.


     */


    public DropDownTextBoxWidget() {


	setBackground(null);


    }





    /**


     * Get the properties of the dropdown textbox.


     */


    public void getProperties(PropertyList list) {


	super.getProperties(list);


	list.setBoolean("fillButton", fillButton, false);


    }





    /**


     * Set the properties of the dropdown textbox.


     */


    public void setProperties(PropertyList list) {


	super.setProperties(list);


	fillButton = list.getBoolean("fillButton", false);


	transparent = !(style == FILLED && fillButton);


    }





    /**


     * Check whether the DropDownTextBox is down.


     * @see #down


     */


    public boolean isDown() {


	return down;


    }





    /**


     * Set down.


     * @see #down


     */


    public void setDown(boolean down) {


	if (this.down != down) {


	    this.down = down;


	    repaint();


	}


    }





    /**


     * Get the current alignment.


     * @see #align


     */


    public int getAlign() {


	return align;


    }





    /**


     * Set align.


     * @see #align


     */


    public void setAlign(int align) {


	if (this.align != align) {


	    this.align = align;


	    repaint();


	}


    }





    /**


     * Check whether the dropdown button is being filled.


     * @see #fillButton


     */


    public boolean getFillButton() {


	return fillButton;


    }





    /**


     * Fill the dropdown button or not.


     * @see #fillButton


     */


    public void setFillButton(boolean fillButton) {


	if (this.fillButton != fillButton) {


	    this.fillButton = fillButton;


	    transparent = !(fillButton && style == FILLED);


	    repaint();


	}


    }





    /**


     * Set the style of this widget the same as in the


     * super class, but adjust the transparent boolean.


     * @see #style


     */


    public void setStyle(int style) {


	super.setStyle(style);


	transparent = !(fillButton && style == FILLED);


    }





    /**


     * Left Margin


     * @see #rightMargin


     */


    public int leftMargin() {


	return (align == LEFT) ? SIZ-2 : 0;


    }





    /**


     * Right Margin


     * @see #leftMargin


     */


    public int rightMargin() {


	return (align == RIGHT) ? SIZ-2 : 0;


    }





    /**


     * Paint the text in the correct foreground color.


     */


    public void paint(Graphics g) {


	if (hasFocus() && !editable) {


	    textColor = getSelForeground();


	    super.paint(g);


	    textColor = foreground;


	} else {


	    super.paint(g);


	}


    }





    /**


     * Paint the menu button too.


     * @see TextBoxWidget#paintBackground


     */


    public void paintBackground(Graphics g) {


	super.paintBackground(g);


	int  lx = (align == LEFT) ? 2 : width-SIZ;





	g.setColor(background);


	switch (style) {


	    case FILLED:


	    case BOXED:


		if (fillButton) {


		    g.fillRect(lx, 2, SIZ-2, height-4);


		}


		Bevel.drawBorder(g, lx, 2, SIZ-2, height-4, !down);


		break;


	    default:


		if (fillButton) {


		    g.fillRect(lx, 0, SIZ-2, height);


		}


		Bevel.drawBorder(g, lx, 0, SIZ-2, height, !down);


		break;


	}


	int  x1 = lx + SIZ/2 - 1;


	int  y1 = height/2 + 1;





	if (down) {


	    x1 += 1;


	    y1 += 1;


	}





	if (hasFocus() && !editable) {


	    int  x = (align == LEFT) ? SIZ + 1 : 3;


	    int  margin = (style != PLAIN) ? 3 : 0;


	    g.setColor(getSelBackground());


	    g.fillRect(x, margin, width - SIZ - 6, height - margin*2);


	    g.setColor(getSelFocusColor());


	    Dash.drawFocusRect(g, x, margin, width - SIZ - 6, height - margin*2);


	}





	g.setColor(foreground);


	for (int i = SIZ/4 - 1 ; i-- > 0;) {


	    g.drawLine(x1-i, y1-i, x1+i, y1-i);


	}


    }





    /**


     * Event is not in text area when it is on button.


     */


    protected boolean eventInText(Event evt) {


	boolean  result = super.eventInText(evt);


	if (align == LEFT) {


	    result = (result && evt.x > SIZ);


	} else {


	    result = (result && evt.x < width - SIZ);


	}


	return result;


    }





    /**


     * Handle mouse and character events.


     */


    public boolean handleEvent(Event evt) {


	switch (evt.id) {


	    case Event.GOT_FOCUS:


		setDown(false);


		break;





	    case Event.KEY_PRESS:


		return super.handleEvent(evt);





	    case Event.MOUSE_DOWN: {


		evt.arg = new Boolean(!eventInText(evt));


		if (!disabled) {


		    switch(align) {


			case LEFT:


			    if (evt.x > SIZ) {


				return super.handleEvent(evt);


			    }


			    break;





			case RIGHT:


			    if (evt.x <= width - SIZ) {


				return super.handleEvent(evt);


			    }


			    break;


		    }


		}


		return false;


	    }





	    case Event.MOUSE_DRAG: {


		if (down) {


		    if (evt.y < -height - 1 || evt.y > 1) {


			setDown(false);


		    } else if (align == LEFT) {


			if (evt.x < 1 || evt.x > SIZ - 1) {


			    setDown(false);


			}


		    } else if (align == RIGHT) {


			if (evt.x < width - SIZ + 1 || evt.x > width - 1) {


			    setDown(false);


			}


		    }


		}


		break;


	    }


	}


	super.handleEvent(evt);


	return false;


    }





    /**


     * Support for input focus, when it is NOT editable too!


     */


    public boolean focusInterest() {


	return !disabled;


    }


}


