How do I have user interaction events against MAUI::Image

13 posts / 0 new
Last post
musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:
How do I have user interaction events against MAUI::Image

How do i have user action events(pointerPressEvent, pointerMoveEvent, pointerReleaseEvent, keyPressEvent) on MAUI::Image.

Events on my  derived-from-Screen class containing Image object, never get fired.

I have a moblet class whose header file is below:

 

/*
 * MyFirstMoblet.h
 *
 *  Created on: Jan 30, 2012
 *      Author: Usman
 */

#ifndef MYFIRSTMOBLET_H_
#define MYFIRSTMOBLET_H_


#include <MAUtil/Moblet.h>
#include "MyFirstScreen.h"

using namespace MAUI;
using namespace MAUtil;


class MyFirstMoblet :public Moblet
{

public:
	MyFirstMoblet();
	virtual ~MyFirstMoblet();

	void keyPressEvent(int keyCode, int nativeCode);
private:
	MyFirstScreen* mScreen;
};

#endif /* MYFIRSTMOBLET_H_ */

 

MyFirstScreen's header file is as follows:

/*
 * MyFirstScreen.h
 *
 *  Created on: Jan 30, 2012
 *      Author: Usman
 */

#ifndef MYFIRSTSCREEN_H_
#define MYFIRSTSCREEN_H_

#include <MAUtil/Moblet.h>
#include <MAUI/Screen.h>
#include <MAUI/Label.h>
#include <MAUI/Image.h>

#include "MAHeaders.h"
#include "Globals.h"

#include "PlayingCard.h"


using namespace MAUI;
using namespace MAUtil;



class MyFirstScreen : public Screen
{
public:
	MyFirstScreen();
	virtual ~MyFirstScreen();

	//void keyPressEvent(int keyCode, int nativeCode);
	//void pointerPressEvent(MAPoint2d point);
	//void pointerMoveEvent(MAPoint2d point);

private:
	MAHandle intToCardHandel(int cardNumber);

private:
	Label* mBackgroundArea;
	PlayingCard *mCard;



};

#endif /* MYFIRSTSCREEN_H_ */

PlayerCard's header file is as follows:

 

/*
 * PlayingCard.h
 *
 *  Created on: Feb 2, 2012
 *      Author: Usman
 */

#ifndef PLAYINGCARD_H_
#define PLAYINGCARD_H_

#include <MAUtil/Moblet.h>
#include <MAUI/Screen.h>
#include <MAUI/Layout.h>
#include <MAUI/Image.h>

#include "MAHeaders.h"

using namespace MAUI;
using namespace MAUtil;

class PlayingCard : public Screen
{


public:
	PlayingCard(Widget* cardParent, MAHandle imageRes);
	virtual ~PlayingCard();

	//Events
	void keyPressEvent(int keyCode, int nativeCode);
	void pointerPressEvent(MAPoint2d point);
	void pointerMoveEvent(MAPoint2d point);
	void pointerReleaseEvent(MAPoint2d point);
	void setPosition(int xCord, int yCord);

private:
	MAHandle mImageResource;
	Widget* mParentArea;
	Image* mImage;
};

#endif /* PLAYINGCARD_H_ */

 the card is displayed on the screen, however the user touch & key press events does not get fired.

NOTE: If I uncomment the event handlers commented in MyFirstScree class, these get fired there, but are never fired in PlayingCard class.

 Do i need to achieve the functionality in somewhat different way?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Sam Pickard
rival's picture
Offline
Mobile Archmage
Joined: 19 Mar 2009
Posts:

Hi Usman,

As long as you've not overridden the show() method on PlayingCard.h, then pointerPressEvent() should fire.  You don't have to do anything special.  What makes you think that they're not being called?  Have you put some debug code in? (like lprintfln("Pointer pressed!"); )

What you will do in pointer press event is to see if the point pressed is inside the card image.

void PlayingCard::pointerPressEvent(MAPoint2d p)
{
  if(mImage->contains(p.x, p.y)
  {
    lprintfln("Card has been touched");
  }
  else
  {
    lprintfln("Card not touched");
  }
}
musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:

I checked by placing breakpoints in implementation of each event handler of 'PlayingCard' and tried to debug on MoRe Emulator, but these break points do not get hit. On the other hand if I place breakpoints in event handlers inside 'MyFirstScreen', these get hit.

Sam Pickard
rival's picture
Offline
Mobile Archmage
Joined: 19 Mar 2009
Posts:

Can you try it with some debug? If this doesn't work, then I'm going to need to see the full source of PlayingCard,h and PlayingCard.cpp

musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:

Implementation of my 'MyFirstScreen' class is as following:

/*
 * MyFirstScreen.cpp
 *
 *  Created on: Jan 30, 2012
 *      Author: Usman
 */

#include "MyFirstScreen.h"

MyFirstScreen::MyFirstScreen()
{
	// TODO Auto-generated constructor stub

	mBackgroundArea = new Label(
				0, // Left
				0, // Top
				0, // Width
				0, // Height
				NULL // Parent widget
				);
			mBackgroundArea->setBackgroundColor(0xFFFFFF);


			mCard = new PlayingCard(mBackgroundArea,  diamonds10);

			// Set the main widget of the screen. This will
			// resize the widget to fit the screen.
			setMain(mBackgroundArea);
}



/*
void MyFirstScreen::keyPressEvent(int keyCode, int nativeCode)
{
	lprintfln("Inside MyFirstScreen::keyPressEvent");
}

void MyFirstScreen::pointerPressEvent(MAPoint2d point)
{
	lprintfln("Inside MyFirstScreen::pointerPressEvent");
}

void MyFirstScreen::pointerMoveEvent(MAPoint2d point)
{
	lprintfln("Inside MyFirstScreen::pointerMoveEvent");
}
*/






MyFirstScreen::~MyFirstScreen()
{
	// TODO Auto-generated destructor stub
	delete mBackgroundArea;
	delete mCard;
}

Implementation of my 'PlayCard' class is as following:

/*
 * PlayingCard.cpp
 *
 *  Created on: Feb 2, 2012
 *      Author: Usman
 */

#include "PlayingCard.h"

PlayingCard::PlayingCard(Widget* cardParent, MAHandle imageRes)
{
	// TODO Auto-generated constructor stub
	mImageResource = imageRes;
	mParentArea = cardParent;

	mIsMovable = false;

	mImage = new Image(
							0,	//Left
							0,	//Top
							50,		//Width
							50,		//Height
							mParentArea,
							true,
							true,
							mImageResource
							);
}





void PlayingCard::pointerPressEvent(MAPoint2d point)
{
	lprintfln("Inside PlayingCard::pointerPressEvent");
}


void PlayingCard::pointerMoveEvent(MAPoint2d point)
{

	lprintfln("Inside PlayingCard::pointerMoveEvent");
}

void PlayingCard::pointerReleaseEvent(MAPoint2d point)
{
	lprintfln("Inside PlayingCard::pointerReleaseEvent");
}


void PlayingCard::keyPressEvent(int keyCode, int nativeCode)
{
	lprintfln("Inside PlayingCard::keyPressEvent");
}


void PlayingCard::setPosition(int xCord, int yCord)
{
	mImage->setPosition(xCord, yCord);
}


PlayingCard::~PlayingCard()
{
	// TODO Auto-generated destructor stub
	delete mImage;
}

I can see the log from 'MyFirstScreen' events, as depicted by the attached image, however there comes no log to LogCat in case of 'PlayCard' class.

LogCat.png
Sam Pickard
rival's picture
Offline
Mobile Archmage
Joined: 19 Mar 2009
Posts:

OK, firstly, I'm sorry if this isn't the problem, I'm just trying everything. What you've written should work perfectly. What I think the problem is that in MyFirstScreen you have this line:

mCard = new PlayingCard(mBackgroundArea,  diamonds10);

But you don't have anywhere where you are going to show this screen.  You've created a screen, but it isn't the active screen.  You need to add

mCard->show();

Which will replace MyFirstScreen with PlayingCard.

 

musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:

The card image is properly getting displayed on the screen.

Are you suggesting to replace:

mCard = new PlayingCard(mBackgroundArea,  diamonds10);

// Set the main widget of the screen. This will
// resize the widget to fit the screen.
setMain(mBackgroundArea);

with

mCard = new PlayingCard(mBackgroundArea,  diamonds10);

mCard->show();

// Set the main widget of the screen. This will
// resize the widget to fit the screen.
setMain(mBackgroundArea);

If so, then it is still not working.

I am building userinterface without using any layout, while having child screen(playcard) on parent screen (MyFirstScreen). Can one build userinterace in such a way? I still doubt that it might have to do something with hierarchy of child and parent screens being renderred.

Sam Pickard
rival's picture
Offline
Mobile Archmage
Joined: 19 Mar 2009
Posts:

I wouldn't put it there. When you call mCard->show the screen 'MyFirstScreen' will be hidden, which you probably don't want to happen when you're building it. When you're ready to show the screen with the playing card, then call mCard->show(). If you can see the card, then there is code you're not sharing with me, like PlayingCard inheriting from Widget or Image and not Screen.

musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:

Here is my full project code.

AttachmentSize
SampleSingleImageClickable.zip 11.57 KB
Sam Pickard
rival's picture
Offline
Mobile Archmage
Joined: 19 Mar 2009
Posts:

Hi,

I can see what you've done now, thanks.

Your structure looks like this:

MyFirstMoblet
+-MyFirstScreen
  +-PlayingCard (screen)

When you create MyFirstMoblet, it creates MyFirstScreen, which in turn creates and shows PlayingCard, but when you create PlayingCard, you create a picture and put it into MyFirstScreen.  PlayingCard is a screen for showing a card, and it doesn't 'own' its widgets.

Here's what I think you're trying to do.  I think you're trying to make a screen which will show playing cards, and respond to touches on those cards.  If that is the case, then PlayingCard shouldn't be a full screen, it should only be a widget.  What I think you want to do is to create MyFirstScreen, and have a lot of Image widgets which represent cards.

If you are, then I've knocked up a very ropey game of BlackJack with too many rough edges to count, but it will be a much better starting place for you.  Download here

 

musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:

Thanks for the code, it helped me a little bit. However i still have one question, in the above example code, (which you have attached), pointer events are handled inside CardTable(derived from MAUI::Screen). Can we handle these events inside PlayingCard (derived from MAUI::Image)? Can we handle pointer events(pointerPressEvent, pointerMoveEvent, etc) inside our custom widgets?

I want to handle pointer events right inside my PlayingCard class, so that only the card clicked by user knows that it is clicked. I do not want to follow the approach of receiving the events from all the cards on dispaly into single CardTable:Screen and then check one by one, which PlayingCard got clicked, and propagate event to that specific PlayingCard. Do I need to derive my PlayingCard class to be derived from some other class than Screen/Image?

Sam Pickard
rival's picture
Offline
Mobile Archmage
Joined: 19 Mar 2009
Posts:

OK, I understand. What you need to do is inherit from both Image and PointerListener

class PlayingCard : public Image, public PointerListener

When the image is enabled, you need to add the widget to the list of pointer listeners, so override the widget setEnabled() method with:

setEnabled(bool e = true)
{
  if(e) Environment::getEnvironment().addPointerListener(this);
  else
    Environment::getEnvironment().removePointerListener(this);    
}

Its even better to have a bool to say whether this card is listening or not, so when you destroy the card it can remove itself from the listeners if necessary.

If you do these two things, then PlayingCard's pointerPressEvent() method should fire.

 

musmanh
musmanh's picture
Offline
Mobile Conjurer
Joined: 30 Jan 2012
Posts:

Yes that was what, I was trying to achieve. It worked :). Thanks