Image Based Button

I’d like to try my hand at an Image Based Button Widget. Assuming the work hasn’t already been started by someone else.



Go No Go?

by all means…

Don’t want to step on any toes. :?



http://mojomonkeycoding.com/jmeforum/viewtopic.php?t=449



Seemed like DarkProphet may be already doing something along this line.

DarkProphet always says is going to do something… :slight_smile:

Are there any coding standards? Other than the defacto self documented kind within the code itself? :smiley:

we just use Sun’s standard.

Ok, I’ve got a good start. I’m really trying to base this on the work that is already done.



The one thing I can’t just figure out easily is how to get the Mouse Exit and Mouse Enter messages to fire right. Once that’s done, so will the widget be.



This is actually pretty strait forward. The odd thing to me is that I had to put my own overridding handleMouseButton down method in place to get the doMouseButtonDown and doMouseButtonUp for fire correctly. WidgetAbstractImpl has the exact same code but doesn’t work the same way. Which is really odd. :?



I really do think there is someting inherantly at issue with how the mouse messages are getting propagated to children such that one underlying frame may take mouse ownership even when one of it’s children or subchildren really should have ownership. I’m trying to track this down.



Oh yeah, I also change WidgetButtonStateType to add an OVER state, I’ve attached changes after this.



/*
 *
 */
package com.jme.widget.button;

import com.jme.widget.panel.*;
import com.jme.widget.image.*;
import com.jme.widget.*;
import com.jme.widget.layout.*;
import com.jme.image.Image;

/**
 *
 */
public class WidgetImageButton extends WidgetPanel {
   
   protected Image _imageUp = null;
   protected Image _imageDown = null;
   protected Image _imageOver = null;
   
   protected WidgetImage _image = null;
   
   protected WidgetButtonStateType _buttonState = WidgetButtonStateType.BUTTON_UP;
   
   public WidgetImageButton( Image imageUp, Image imageDown, Image imageOver) {
      super();
      _imageUp = imageUp;
      _imageDown = imageDown;
      _imageOver = imageOver;
      init();
   }
   
   public void init() {
      setLayout( new WidgetGridLayout(1, 1));
      _image = new WidgetImage( _imageUp, WidgetAlignmentType.ALIGN_CENTER, WidgetImage.SCALE_MODE_RELATIVE);
      add( _image);
   }
   
   public void doMouseButtonUp() {
      System.out.println( "UP");
      if( isMouseInWidget() ) {
         _buttonState = WidgetButtonStateType.BUTTON_OVER;
         _image.setImage( _imageOver);
      } else {
         _image.setImage( _imageUp);
      }
   }
   
   public void doMouseButtonDown() {
      System.out.println( "DOWN");
      _image.setImage( _imageDown);
      _buttonState = WidgetButtonStateType.BUTTON_DOWN;
   }
   
   public void doMouseEnter() {
      System.out.println( "OVER");
      if( _buttonState != WidgetButtonStateType.BUTTON_OVER) {
         _buttonState = WidgetButtonStateType.BUTTON_OVER;
         _image.setImage( _imageOver);
      }
   }
   
   public void doMouseExit() {
      System.out.println( "NOT OVER");
      if( _buttonState == WidgetButtonStateType.BUTTON_OVER) {
         _buttonState = WidgetButtonStateType.BUTTON_UP;
         _image.setImage( _imageUp);
      }
   }
   
   public void handleMouseButtonDown() {
      if (isVisible() == false)
         return;
      boolean b = isMouseInWidget();
      if (b) {
         setMouseOwner(this);
      }
   }
}




public final class WidgetButtonStateType extends JmeType {
   public final static WidgetButtonStateType BUTTON_OVER =
      new WidgetButtonStateType("BUTTON_OVER");
    public final static WidgetButtonStateType BUTTON_UP =
        new WidgetButtonStateType("BUTTON_UP");
    public final static WidgetButtonStateType BUTTON_DOWN =
        new WidgetButtonStateType("BUTTON_DOWN");
    public final static WidgetButtonStateType BUTTON_DISABLED =
        new WidgetButtonStateType("BUTTON_DISABLED");

    private WidgetButtonStateType(String name) {
        super(name);
    }

    public JmeType getType(String name) {
        JmeType type = null;

        if (BUTTON_UP.name.equals(name)) {
            type = BUTTON_UP;
        } else if (BUTTON_DOWN.name.equals(name)) {
            type = BUTTON_DOWN;
        } else if (BUTTON_DISABLED.name.equals(name)) {
            type = BUTTON_DISABLED;
        } else if (BUTTON_DISABLED.name.equals(name)) {
         type = BUTTON_OVER;
      }

        return type;
    }

}

This:


 protected ArrayList widgetList = new ArrayList();


from WidgetAbstractContainer contains all the children. Somehow since children are added to the end, maybe going backwards in this list and breaking out of the loop when one of the children (and thus subchildren) finds that it's under the mouse and becomes mouse owner.

i indeed always say im going to do something, but i always always get sidetracked, and never get it finished. Someone needs to lock me up and say get on with it, or else! :slight_smile:

Add this to the end of the class:



   public void handleMouseMove() {
      if (isVisible() == false)
         return;

      boolean b = isMouseInWidget();

      if (b) {
         setWidgetUnderMouse(this);
         doMouseEnter();
      } else {
         doMouseExit();
      }
   }



This does a lot of extra processing so it's not ideal yet. I'd really like someone to look at this with me that knows the current widget stuff.

If I have time, I’ll look at this later today. I plan to be a heavy user of animated image buttons (which is why I provided first-draft objects for ImageWidget).



I haven’t had a chance to even update my jme snapshot, but have you designed the button in such a way as to make it a container of another widget object? For example, my conception of an ideal “image” button would be a button object that can take an ImageWidget (or AnimatedImageWidget) object as its rendering core. I see the button object itself merely as a handler of input and a delegator of rendering.



Of course, “something that works” is better than theorizing at this stage :slight_smile:

Right now I create the image button from three passed in Images, I then change them out in the WidgetImage. So providing another constructor for three WidgetImages instead would be straitforward. However it would mean more overhead since I wouldn’t just be switching out images, I’d have to stwitch out WidgetImages instead.

No, I’m not saying that each image button should be constructed from user-provided ImageWidgets, merely that ImageWidgets be used internally rather than “recreating the wheel.” It sounds like that’s what you’re doing.



However, you should provide some kind of factory method for creating that image class. I would like to be able to specify that a button that a button displays an ImageWidget subclass as well (AnimatedImageWidget).



Maybe even have a “setImageWidgetClass()” method or perhaps pass an ImageWidget class as part of the constructor.



I will hold off commenting further until I have actually looked at the code.



Thanks for working on this!

Add this to get this to work with absolute layout:



   public Vector2f getPreferredSize() {
      System.out.println( "Getting Pref Size Button: " + _image.getWidth() + " " + _image.getHeight());
      
      return _image.getPreferredSize();
   }




Now that i'm somewhat close to having something worth checking in, I'm wondering what the best method of working with you cvs repository is.

Do you know if I'm supposed to make a branch? Label in a specific way or??? :?

create a patch in issue tracker for now.

Sorry to be troublesome, but is there a faq or some-such on how to go about that?

This should help, it’s the issue tracker “manual”.



https://www.dev.java.net/scdocs/ProjectIssues#accessissues

Ask Mojo for Contributor status if you’ve not already done so.



Create a patch archive (for new files, just include them; for patched files, including a context-sensitive diff). I use Eclipse, and just use the “create patch” menu item. Alternately, you could use “diff -u” directly. For my archive, I just put them all into a zip file.



That will allow you to go to the following URL (after logging in)



https://jme.dev.java.net/



Choose “issue tracker” from the left-side menu.



Open a new issue probably for feature or enhancement.



Fill out the form, and attach the file (I can’t remember if attaching the file is a separate step or not).



If you only have Observer status, you will only be able to open the initial issue and will not be able to update it.



-Mike

I’ve checked in WidgetImageButton and WidgetButtonStateType.



Do I need to make a Test for it? ( I think I already know the answer :))



Mojo… Thanks for developer status :smiley:

Do I need to make a Test for it? ( I think I already know the answer )


*nod* yep. :) Also try to write one up for the octagon... actually, octahedron I guess.