How to detect double click with cocos2d-x - cocos2d-x

How do I port this cocos2d-iphone code to cocos2d-x?
(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
switch ([allTouches count]) {
case 1:
{
UITouch *touch = [[allTouches allObjects] objectAtIndex:0];
switch([touch tapCount])
{
case 1:
// 单击!
break;
case 2:
//Double tap.
// 双击!
break;
}
break;
}
}

There is no function to implement this,we can implement this by test the tick between two clicks.In general,the time interval of double click is between 250ms~300ms.Use this to get the system's current number of milliseconds
long millisecondNow()
{
struct cc_timeval now;
CCTime::gettimeofdayCocos2d(&now, NULL);
return (now.tv_sec * 1000 + now.tv_sec / 1000);
}

In MyScene.h, declare:
int tapCount;
Touch lastTouch;
void singleTap(float deltaTime);
Then in MyScene.cpp:
bool MyScene::onTouchBegan(Touch* touch, Event* event)
{
++tapCount;
lastTouch = *touch;
if (tapCount == 1) {
this->schedule(schedule_selector(MyScene::singleTap), 0.25, 1, 0);
}
else {
this->unschedule(schedule_selector(MyScene::singleTap));
tapCount = 0;
printf("\n\ndouble tap\n\n");
}
return true;
}
void MyScene::singleTap(float deltaTime)
{
this->unschedule(schedule_selector(LevelScene::singleTap));
tapCount = 0;
printf("\n\nsingle tap\n\n");
}
You can then access lastTouch in singleTap or your doubleTap method. If you don't need lastTouch to be a Touch object, you can use a Vec2 and set the coordinates. Note that the timer interval (0.25) is more accurate on the device. There is a lag in the simulator since the interval isn't actually wall-clock time.

You can do like this
void HelloWorld::callback1()
{
_tapCount = 0;
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
_tapCount = _tapCount + 1;
if (_tapCount == 1)
{
DelayTime* delayAction = DelayTime::create(0.3);
CallFunc*resetAction = CallFunc::create(CC_CALLBACK_0(HelloWorld::callback1, this));
Sequence *seq = Sequence::create(delayAction, resetAction, NULL);
this->runAction(seq);
}
else{
log("double tap");
};
}

Related

Facebook SDK Integration - LoadPicture Method ERROR

So hi to #ll this is my fist post/question on stackoverflow :D
I need help # following :
So i integrated the Facebook SDk sucessfully in my game but i´dont get the profile picture working ...
So i tryied it oldshool on Facebooks "Tutotial" Way and followed all steps to implement login functions and so on ...
I´ve downloaded the "friendsmash_start" Sample and implemented that Stuff ...
My Main Problem is i don´t get ahead with this problem and can´t figure out what i´m doing wrong so i´m hoping for help.
Here´s the complete Code from the MainMenu Script from the sample which is the only i´ve changed ... like in the tutorial ...
Unity shows me this Error -> "The name 'LoadPicture' does not exist in the current context ... so the errors are on these two parts of code :
"LoadPicture(Util.GetPictureURL("me", 128, 128), MyPictureCallback);" in the "OnLoggedIn" function
"LoadPicture(Util.GetPictureURL("me", 128, 128), MyPictureCallback);" in the "MyPictureCallback" function
I don´t understand it cause i searched myself in the script for this function "LoadPicture" and find nothing that was ... according to the "Tutorial" of facebook here :
https://developers.facebook.com/docs/games/unity/unity-tutorial?locale=de_DE
the function should be there cause they wrote there :
"Take a look at the LoadPicture method also in MainMenu.cs to see how we use the Unity WWW class to load the image returned by the graph API."
But i can´t find it :(
HOPE SOMEONE CAN HELP ME I DON´T GET IT ...
Have that problem unfortunately very long time ... thats enoying. :(
HERE`S THE FULL CODE OF MAINMENU.CS :
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Facebook.MiniJSON;
using System;
public class MainMenu : MonoBehaviour
{
// Inspector tunable members //
public Texture ButtonTexture;
public Texture PlayTexture; // Texture for main menu button icons
public Texture BragTexture;
public Texture ChallengeTexture;
public Texture StoreTexture;
public Texture FullScreenTexture;
public Texture FullScreenActiveTexture;
public Texture ResourcesTexture;
public Vector2 CanvasSize; // size of window on canvas
public Rect LoginButtonRect; // Position of login button
public Vector2 ResourcePos; // position of resource indicators (not used yet)
public Vector2 ButtonStartPos; // position of first button in main menu
public float ButtonScale; // size of main menu buttons
public float ButtonYGap; // gap between buttons in main menu
public float ChallengeDisplayTime; // Number of seconds the request sent message is displayed for
public Vector2 ButtonLogoOffset; // Offset determining positioning of logo on buttons
public float TournamentStep; // Spacing between tournament entries
public float MouseScrollStep = 40; // Amount score table moves with each step of the mouse wheel
public PaymentDialog paymentDialog;
public GUISkin MenuSkin;
public int CoinBalance;
public int NumLives;
public int NumBombs;
public Texture[] CelebTextures;
public string [] CelebNames;
// Private members //
private static MainMenu instance;
private static List<object> friends = null;
private static Dictionary<string, string> profile = null;
private static List<object> scores = null;
private static Dictionary<string, Texture> friendImages = new Dictionary<string, Texture>();
private Vector2 scrollPosition = Vector2.zero;
private bool haveUserPicture = false;
private float tournamentLength = 0;
private int tournamentWidth = 512;
private int mainMenuLevel = 0; // Level index of main menu
private string popupMessage;
private float popupTime;
private float popupDuration;
void Awake()
{
Util.Log("Awake");
paymentDialog = ((PaymentDialog)(GetComponent("PaymentDialog")));
// allow only one instance of the Main Menu
if (instance != null && instance != this)
{
Destroy(gameObject);
return;
}
#if UNITY_WEBPLAYER
// Execute javascript in iframe to keep the player centred
string javaScript = #"
window.onresize = function() {
var unity = UnityObject2.instances[0].getUnity();
var unityDiv = document.getElementById(""unityPlayerEmbed"");
var width = window.innerWidth;
var height = window.innerHeight;
var appWidth = " + CanvasSize.x + #";
var appHeight = " + CanvasSize.y + #";
unity.style.width = appWidth + ""px"";
unity.style.height = appHeight + ""px"";
unityDiv.style.marginLeft = (width - appWidth)/2 + ""px"";
unityDiv.style.marginTop = (height - appHeight)/2 + ""px"";
unityDiv.style.marginRight = (width - appWidth)/2 + ""px"";
unityDiv.style.marginBottom = (height - appHeight)/2 + ""px"";
}
window.onresize(); // force it to resize now";
Application.ExternalCall(javaScript);
#endif
DontDestroyOnLoad(gameObject);
instance = this;
// Initialize FB SDK
FB.Init(SetInit, OnHideUnity);
}
private void SetInit()
{
Util.Log("SetInit");
enabled = true; // "enabled" is a property inherited from MonoBehaviour
if (FB.IsLoggedIn)
{
Util.Log("Already logged in");
OnLoggedIn();
}
}
private void OnHideUnity(bool isGameShown)
{
Util.Log("OnHideUnity");
if (!isGameShown)
{
// pause the game - we will need to hide
Time.timeScale = 0;
}
else
{
// start the game back up - we're getting focus again
Time.timeScale = 1;
}
}
private void QueryScores()
{
FB.API("/app/scores?fields=score,user.limit(20)", Facebook.HttpMethod.GET, ScoresCallback);
}
private int getScoreFromEntry(object obj)
{
Dictionary<string,object> entry = (Dictionary<string,object>) obj;
return Convert.ToInt32(entry["score"]);
}
void ScoresCallback(FBResult result)
{
Util.Log("ScoresCallback");
if (result.Error != null)
{
Util.LogError(result.Error);
return;
}
scores = new List<object>();
List<object> scoresList = Util.DeserializeScores(result.Text);
foreach(object score in scoresList)
{
var entry = (Dictionary<string,object>) score;
var user = (Dictionary<string,object>) entry["user"];
string userId = (string)user["id"];
if (string.Equals(userId,FB.UserId))
{
// This entry is the current player
int playerHighScore = getScoreFromEntry(entry);
Util.Log("Local players score on server is " + playerHighScore);
if (playerHighScore < GameStateManager.Score)
{
Util.Log("Locally overriding with just acquired score: " + GameStateManager.Score);
playerHighScore = GameStateManager.Score;
}
entry["score"] = playerHighScore.ToString();
GameStateManager.HighScore = playerHighScore;
}
scores.Add(entry);
if (!friendImages.ContainsKey(userId))
{
// We don't have this players image yet, request it now
LoadPictureAPI(Util.GetPictureURL(userId, 128, 128),pictureTexture =>
{
if (pictureTexture != null)
{
friendImages.Add(userId, pictureTexture);
}
});
}
}
// Now sort the entries based on score
scores.Sort(delegate(object firstObj,
object secondObj)
{
return -getScoreFromEntry(firstObj).CompareTo(getScoreFromEntry(secondObj));
}
);
}
void OnApplicationFocus( bool hasFocus )
{
Util.Log ("hasFocus " + (hasFocus ? "Y" : "N"));
}
// Convenience function to check if mouse/touch is the tournament area
private bool IsInTournamentArea (Vector2 p)
{
return p.x > Screen.width-tournamentWidth;
}
// Scroll the tournament view by some delta
private void ScrollTournament(float delta)
{
scrollPosition.y += delta;
if (scrollPosition.y > tournamentLength - Screen.height)
scrollPosition.y = tournamentLength - Screen.height;
if (scrollPosition.y < 0)
scrollPosition.y = 0;
}
// variables for keeping track of scrolling
private Vector2 mouseLastPos;
private bool mouseDragging = false;
void Update()
{
if(Input.touches.Length > 0)
{
Touch touch = Input.touches[0];
if (IsInTournamentArea (touch.position) && touch.phase == TouchPhase.Moved)
{
// dragging
ScrollTournament (touch.deltaPosition.y*3);
}
}
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
ScrollTournament (MouseScrollStep);
}
else if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
ScrollTournament (-MouseScrollStep);
}
if (Input.GetMouseButton(0) && IsInTournamentArea(Input.mousePosition))
{
if (mouseDragging)
{
ScrollTournament (Input.mousePosition.y - mouseLastPos.y);
}
mouseLastPos = Input.mousePosition;
mouseDragging = true;
}
else
mouseDragging = false;
}
// Button drawing logic //
private Vector2 buttonPos; // Keeps track of where we've got to on the screen as we draw buttons
private void BeginButtons()
{
// start drawing buttons at the chosen start position
buttonPos = ButtonStartPos;
}
private bool DrawButton(string text, Texture texture)
{
// draw a single button and update our position
bool result = GUI.Button(new Rect (buttonPos.x,buttonPos.y, ButtonTexture.width * ButtonScale, ButtonTexture.height * ButtonScale),text,MenuSkin.GetStyle("menu_button"));
Util.DrawActualSizeTexture(ButtonLogoOffset*ButtonScale+buttonPos,texture,ButtonScale);
buttonPos.y += ButtonTexture.height*ButtonScale + ButtonYGap;
if (paymentDialog.DialogEnabled)
result = false;
return result;
}
void OnGUI()
{
GUI.skin = MenuSkin;
if (Application.loadedLevel != mainMenuLevel) return; // don't display anything except when in main menu
GUILayout.Box("", MenuSkin.GetStyle("panel_welcome"));
if (!FB.IsLoggedIn)
{
GUI.Label((new Rect(179, 11, 287, 160)), "Login to Facebook", MenuSkin.GetStyle("text_only"));
if (GUI.Button(LoginButtonRect, "", MenuSkin.GetStyle("button_login")))
{
FB.Login("email,publish_actions", LoginCallback);
}
}
if (FB.IsLoggedIn)
{
string panelText = "Welcome ";
panelText += (!string.IsNullOrEmpty(GameStateManager.Username)) ? string.Format("{0}!", GameStateManager.Username) : "Smasher!";
if (GameStateManager.UserTexture != null)
GUI.DrawTexture( (new Rect(8,10, 150, 150)), GameStateManager.UserTexture);
GUI.Label( (new Rect(179 , 11, 287, 160)), panelText, MenuSkin.GetStyle("text_only"));
}
string subTitle = "Let's smash some friends!";
if (GameStateManager.Score > 0)
{
subTitle = "Score: " + GameStateManager.Score.ToString();
}
if (!string.IsNullOrEmpty(subTitle))
{
GUI.Label( (new Rect(132, 28, 400, 160)), subTitle, MenuSkin.GetStyle("sub_title"));
}
BeginButtons();
if (DrawButton("Play",PlayTexture))
{
onPlayClicked();
}
if (FB.IsLoggedIn)
{
// Draw resources bar
Util.DrawActualSizeTexture(ResourcePos,ResourcesTexture);
Util.DrawSimpleText(ResourcePos + new Vector2(47,5) ,MenuSkin.GetStyle("resources_text"),string.Format("{0}",CoinBalance));
Util.DrawSimpleText(ResourcePos + new Vector2(137,5) ,MenuSkin.GetStyle("resources_text"),string.Format("{0}",NumBombs));
Util.DrawSimpleText(ResourcePos + new Vector2(227,5) ,MenuSkin.GetStyle("resources_text"),string.Format("{0}",NumLives));
}
#if UNITY_WEBPLAYER
if (Screen.fullScreen)
{
if (DrawButton("Full Screen",FullScreenActiveTexture))
SetFullscreenMode(false);
}
else
{
if (DrawButton("Full Screen",FullScreenTexture))
SetFullscreenMode(true);
}
#endif
DrawPopupMessage();
}
public void AddPopupMessage(string message, float duration)
{
popupMessage = message;
popupTime = Time.realtimeSinceStartup;
popupDuration = duration;
}
public void DrawPopupMessage()
{
if (popupTime != 0 && popupTime + popupDuration > Time.realtimeSinceStartup)
{
// Show message that we sent a request
Rect PopupRect = new Rect();
PopupRect.width = 800;
PopupRect.height = 100;
PopupRect.x = Screen.width / 2 - PopupRect.width / 2;
PopupRect.y = Screen.height / 2 - PopupRect.height / 2;
GUI.Box(PopupRect,"",MenuSkin.GetStyle("box"));
GUI.Label(PopupRect, popupMessage, MenuSkin.GetStyle("centred_text"));
}
}
void TournamentGui()
{
GUILayout.BeginArea(new Rect((Screen.width - 450),0,450,Screen.height));
// Title box
GUI.Box (new Rect(0, - scrollPosition.y, 100,200), "", MenuSkin.GetStyle("tournament_bar"));
GUI.Label (new Rect(121 , - scrollPosition.y, 100,200), "Tournament", MenuSkin.GetStyle("heading"));
Rect boxRect = new Rect();
if(scores != null)
{
var x = 0;
foreach(object scoreEntry in scores)
{
Dictionary<string,object> entry = (Dictionary<string,object>) scoreEntry;
Dictionary<string,object> user = (Dictionary<string,object>) entry["user"];
string name = ((string) user["name"]).Split(new char[]{' '})[0] + "\n";
string score = "Smashed: " + entry["score"];
boxRect = new Rect(0, 121+(TournamentStep*x)-scrollPosition.y , 100,128);
// Background box
GUI.Box(boxRect,"",MenuSkin.GetStyle("tournament_entry"));
// Text
GUI.Label (new Rect(24, 136 + (TournamentStep * x) - scrollPosition.y, 100,128), (x+1)+".", MenuSkin.GetStyle("tournament_position")); // Rank e.g. "1.""
GUI.Label (new Rect(250,145 + (TournamentStep * x) - scrollPosition.y, 300,100), name, MenuSkin.GetStyle("tournament_name")); // name
GUI.Label (new Rect(250,193 + (TournamentStep * x) - scrollPosition.y, 300,50), score, MenuSkin.GetStyle("tournament_score")); // score
Texture picture;
if (friendImages.TryGetValue((string) user["id"], out picture))
{
GUI.DrawTexture(new Rect(118,128+(TournamentStep*x)-scrollPosition.y,115,115), picture); // Profile picture
}
x++;
}
}
else GUI.Label (new Rect(180,270,512,200), "Loading...", MenuSkin.GetStyle("text_only"));
// Record length so we know how far we can scroll to
tournamentLength = boxRect.y + boxRect.height + scrollPosition.y;
GUILayout.EndArea();
}
// React to menu buttons //
private void onPlayClicked()
{
Util.Log("onPlayClicked");
if (friends != null && friends.Count > 0)
{
// Select a random friend and get their picture
Dictionary<string, string> friend = Util.RandomFriend(friends);
GameStateManager.FriendName = friend["first_name"];
GameStateManager.FriendID = friend["id"];
GameStateManager.CelebFriend = -1;
LoadPictureURL(friend["image_url"],FriendPictureCallback);
}
else
{
//We can't access friends
GameStateManager.CelebFriend = UnityEngine.Random.Range(0,CelebTextures.Length - 1);
GameStateManager.FriendName = CelebNames[GameStateManager.CelebFriend];
}
// Start the main game
Application.LoadLevel("GameStage");
GameStateManager.Instance.StartGame();
}
public void SetFullscreenMode (bool on)
{
if (on)
{
Screen.SetResolution (Screen.currentResolution.width, Screen.currentResolution.height, true);
}
else
{
Screen.SetResolution ((int)CanvasSize.x, (int)CanvasSize.y, false);
}
}
public static void FriendPictureCallback(Texture texture)
{
GameStateManager.FriendTexture = texture;
}
delegate void LoadPictureCallback (Texture texture);
IEnumerator LoadPictureEnumerator(string url, LoadPictureCallback callback)
{
WWW www = new WWW(url);
yield return www;
callback(www.texture);
}
void LoadPictureAPI (string url, LoadPictureCallback callback)
{
FB.API(url,Facebook.HttpMethod.GET,result =>
{
if (result.Error != null)
{
Util.LogError(result.Error);
return;
}
var imageUrl = Util.DeserializePictureURLString(result.Text);
StartCoroutine(LoadPictureEnumerator(imageUrl,callback));
});
}
void LoadPictureURL (string url, LoadPictureCallback callback)
{
StartCoroutine(LoadPictureEnumerator(url,callback));
}
void LoginCallback(FBResult result)
{
Util.Log("LoginCallback");
if (FB.IsLoggedIn)
{
OnLoggedIn();
}
}
void OnLoggedIn()
{
Util.Log("Logged in. ID: " + FB.UserId);
// Reqest player info and profile picture
FB.API("/me?fields=id,first_name,friends.limit(100).fields(first_name,id)", Facebook.HttpMethod.GET, APICallback);
LoadPicture(Util.GetPictureURL("me", 128, 128), MyPictureCallback);
}
void APICallback(FBResult result)
{
Util.Log("APICallback");
if (result.Error != null)
{
Util.LogError(result.Error);
// Let's just try again
FB.API("/me?fields=id,first_name,friends.limit(100).fields(first_name,id)", Facebook.HttpMethod.GET, APICallback);
return;
}
profile = Util.DeserializeJSONProfile(result.Text);
GameStateManager.Username = profile["first_name"];
friends = Util.DeserializeJSONFriends(result.Text);
}
void MyPictureCallback(Texture texture)
{
Util.Log("MyPictureCallback");
if (texture == null)
{
// Let's just try again
LoadPicture(Util.GetPictureURL("me", 128, 128), MyPictureCallback);
return;`
}
GameStateManager.UserTexture = texture;
}
}
change the word "LoadPicture" for "LoadPictureAPI".
For reference see:
https://github.com/fbsamples/friendsmash-unity/blob/master/friendsmash_payments_start/Assets/Scripts/MainMenu.cs

Libgdx destroying multiple bodies

So basically i get an error when trying to destroy bodies that are not in screen bounds. Also my one type bodies start to act strange when other type bodies are destroyed ( example bullets starts to move backwards) here are the code samples :
Maingame loop class:
Array<Body> bodies = new Array<Body>(world.getBodyCount());
world.getBodies(bodies);
for (Body body : bodies) {
check = 0;
if (BodyUtils.bodyIsEnemy(body)){
update(body);
check = 1;
}
if (BodyUtils.bodyIsBullet(body) && check == 0){
update1(body);
check = 0;
}
}
private void update(Body body) {
if (!BodyUtils.bodyInBounds(body)) {
if (BodyUtils.bodyIsEnemy(body) && !player.isHit()) {
createEnemy();
}
world.destroyBody(body);
}
}
private void update1(Body body) {
if (!BodyUtils.bulletInBounds(body))
world.destroyBody(body);
}
Other class:
public static boolean bodyInBounds(Body body) {
UserData userData = (UserData) body.getUserData();
switch (userData.getUserDataType()) {
case ENEMY:
return body.getPosition().x + userData.getWidth() / 2 > 0;
}
return true;
}
public static boolean bulletInBounds(Body body) {
UserData userData = (UserData) body.getUserData();
switch (userData.getUserDataType()) {
case BULLET:
return body.getPosition().x + userData.getWidth() < 20;
}
return true;
}
Fixed it , createEnemy() method placed after world.destroyBody(body) method.

How to insert text in CCTextFieldTTF?

I used setString but the string is not updated, so I have to write a CCLabel to show the string, which I feel very weird because showing the user input should be part of the textfield.. Do I missed anything?
I read the test_input example, it uses a CCLabel to show the user input, which I think is a really bad design.
You don't need a Label to show user input.
I have edited the default HelloWorld file with added CCTextFieldttf working example.
This is how your HelloWorld.h file should look
class HelloWorld : public cocos2d::CCLayer, public cocos2d::CCTextFieldDelegate
{
public:
virtual bool init();
static cocos2d::CCScene* scene();
void createTF();
cocos2d::CCTextFieldTTF* tf;
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void registerWithTouchDispatcher();
//CCtextFieldttf delegate begin
virtual bool onTextFieldAttachWithIME(CCTextFieldTTF * pSender);
virtual bool onTextFieldDetachWithIME(CCTextFieldTTF * pSender);
virtual bool onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen);
virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen);
virtual bool onDraw(CCTextFieldTTF * pSender);
//CCtextFieldttf delegate end
CREATE_FUNC(HelloWorld);
};
This is how your HelloWorld.cpp should be for minimum usage of CCTextFieldttf
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
if ( !CCLayer::init() )
{
return false;
}
this->setTouchEnabled(true);
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
createTF();
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
// position the label on the center of the screen
pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - pLabel->getContentSize().height));
this->addChild(pLabel, 1);
return true;
}
void HelloWorld::createTF()
{
tf = CCTextFieldTTF::textFieldWithPlaceHolder("123", CCSizeMake(100, 100), kCCTextAlignmentCenter, "helvetica", 20);
tf->setColorSpaceHolder(ccWHITE);
tf->setPosition(ccp(200,200));
tf->setHorizontalAlignment(kCCTextAlignmentCenter);
tf->setVerticalAlignment(kCCVerticalTextAlignmentCenter);
tf->setDelegate(this);
addChild(tf);
}
void HelloWorld::registerWithTouchDispatcher()
{
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
}
bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCLog("inside touchbegan");
return true;
}
void HelloWorld::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
CCLog("inside touchend");
tf->attachWithIME();
}
bool HelloWorld::onTextFieldAttachWithIME(CCTextFieldTTF * pSender)
{
return false;
}
bool HelloWorld::onTextFieldDetachWithIME(CCTextFieldTTF * pSender)
{
return false;
}
bool HelloWorld::onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen)
{
return false;
}
bool HelloWorld::onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen)
{
return false;
}
bool HelloWorld::onDraw(CCTextFieldTTF * pSender)
{
return false;
}
The CCTextFieldDelegate methods are implemented to gain more control over what is entered into CCTextFieldTTF. The only thing that CCTextFieldttf lacks is you have to call CCTextFieldTTF's attachWithIME() method yourself like in the above code it is being called in "ccTouchEnded".
in header
class CustomMultiplayerScene : public PZGBaseMenuScene,public CCIMEDelegate
{
public:
void keyboardWillShow(cocos2d::CCIMEKeyboardNotificationInfo &info);
void keyboardWillHide(cocos2d::CCIMEKeyboardNotificationInfo &info);
void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
};
in .cpp
CCTextFieldTTF *textfield = CCTextFieldTTF::textFieldWithPlaceHolder("Enter Name:", CCSize(480,30), kCCTextAlignmentCenter, "Arial", 12);
// textfield->setAnchorPoint(CCPointZero);
textfield->setPosition(ccp(screenSize.width/2,200));
textfield->setTag(100);
this->addChild(textfield,4);
CCLabelTTF *label = CCLabelTTF::create("ID : ", "", 12);
label->setPosition(ccp(screenSize.width/2,100));
label->setTag(200);
this->addChild(label,4);
implement methods in .cpp
void CustomMultiplayerScene::keyboardWillShow(CCIMEKeyboardNotificationInfo &info)
{
CCLOG("keyboardWillShow");
CCTextFieldTTF *textfield = (CCTextFieldTTF *)this->getChildByTag(100);
textfield->setString("");
}
void CustomMultiplayerScene::keyboardWillHide(CCIMEKeyboardNotificationInfo &info)
{
CCLog("keyboardWillHide");
CCTextFieldTTF *textfield = (CCTextFieldTTF *)this->getChildByTag(100);
CCLabelTTF *label = (CCLabelTTF *)this->getChildByTag(200);
label->setString(textfield->getString());
}
void CustomMultiplayerScene::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
CCTouch *pTouch = (CCTouch *)pTouches->anyObject();
CCPoint point = pTouch->getLocationInView();
point = CCDirector::sharedDirector()->convertToGL(point);
CCTextFieldTTF *textfield = (CCTextFieldTTF *)this->getChildByTag(100);
CCRect rect = textfield->boundingBox();
if(rect.containsPoint(point)) {
textfield->attachWithIME();
}
}
CCTextFieldTTF * pTextField = CCTextFieldTTF::textFieldWithPlaceHolder("click here for input",
"Thonburi",
20);
addChild(pTextField);

Metro App CollectionViewSource ObservableCollection Filter

It appears that filtering an ObservableCollection with CollectionViewSource is not possible in WinRT:
See here!
I can filter using LINQ, but how do I get the UI to update if changes that affect the filtered data are made?
I ended up writing my own class to achieve the desired effect:
public class ObservableCollectionView<T> : ObservableCollection<T>
{
private ObservableCollection<T> _view;
private Predicate<T> _filter;
public ObservableCollectionView(IComparer<T> comparer)
: base(comparer)
{
}
public ObservableCollectionView(IComparer<T> comparer, IEnumerable<T> collection)
: base(comparer, collection)
{
}
public ObservableCollectionView(IComparer<T> comparer, IEnumerable<T> collection, Predicate<T> filter)
: base(comparer, collection == null ? new T[] { } : collection)
{
if (filter != null)
{
_filter = filter;
if (collection == null)
_view = new ObservableCollection<T>(comparer);
else
_view = new ObservableCollection<T>(comparer, collection);
}
}
public ObservableCollection<T> View
{
get
{
return (_filter == null ? this : _view);
}
}
public Predicate<T> Filter
{
get
{
return _filter;
}
set
{
if (value == null)
{
_filter = null;
_view = new ObservableCollection<T>(Comparer);
}
else
{
_filter = value;
Fill();
}
}
}
private void Fill()
{
_view = new ObservableCollection<T>(Comparer);
foreach (T item in this)
{
if (Filter(item))
View.Add(item);
}
}
private int this[T item]
{
get
{
int foundIndex = -1;
for (int index = 0; index < View.Count; index++)
{
if (View[index].Equals(item))
{
foundIndex = index;
break;
}
}
return foundIndex;
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
if (_filter != null)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (T item in e.NewItems)
if (Filter(item))
View.Add(item);
break;
case NotifyCollectionChangedAction.Move:
break;
case NotifyCollectionChangedAction.Remove:
foreach (T item in e.OldItems)
if (Filter(item))
View.Remove(item);
break;
case NotifyCollectionChangedAction.Replace:
for (int index = 0; index < e.OldItems.Count; index++)
{
T item = (T)e.OldItems[index];
if (Filter(item))
{
int foundIndex = this[item];
if (foundIndex != -1)
View[foundIndex] = (T)e.NewItems[index];
}
}
break;
case NotifyCollectionChangedAction.Reset:
Fill();
break;
}
}
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (_filter != null)
{
// TODO: Implement code for property changes
}
}
}
Not yet perfect. So improvements/suggestions welcomed.
You can now bind this object, directly to a control using the View property.
You need to make sure the filtering changes are observable, so you can set the source of the CollectionViewSource to an ObservableCollection and make the changes on that collection or assign a new Source of the CVS to a new, filtered collection.

IllegalStateException BlackBerry

public class show extends MainScreen {
private String date1;
private long date1l;
private long date2l;
private LabelField curDate = new LabelField();
private LabelField toDate = new LabelField();
private LabelField diffe = new LabelField();
// private LabelField info;
// private LabelField empty;
// private InvokeBrowserHyperlinkField hello;
ButtonField activate = null;
ButtonField disactivate = null;
Timer timer;
Timer timer2;
public String date1s[];
int d, m, y;
int x = 1;
String day, hour, minute;
Date date = new Date();
Calendar calendar = Calendar.getInstance();;
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MM yyyy HH mm");
public show() {
add(curDate);
add(toDate);
add(new SeparatorField());
add(diffe);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTick(), 0, 1000);
}
private class TimerTick extends TimerTask {
public void run() {
if (x != 0) {
date1l = date.getTime();
try {
date1 = dateFormat.format(calendar.getTime());
} catch (Exception e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("GMT+7:00"));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DATE, 1);
cal.set(Calendar.YEAR, 2012);
date2l = cal.getTime().getTime();
date1s = StringUtilities.stringToWords(date1);
d = Integer.parseInt(date1s[0]);
m = Integer.parseInt(date1s[1]);
y = Integer.parseInt(date1s[2]);
display();
} else {
timer.cancel();
}
}
}
public void display() {
String monw = convertToWords(m);
curDate.setText("Current Date = " + d + " " + monw + " " + y + " "
+ date1s[3] + ":" + date1s[4]);
toDate.setText("To Date = 1 February 2012 00:00");
long diffms = date2l - date1l;
long ds = diffms / 1000;
long dm = ds / 60;
long dh = dm / 60;
long dd = dh / 24;
long q = dd;
long h = (ds - (dd * 24 * 60 * 60)) / (60 * 60);
long m = (ds - (dh * 60 * 60)) / 60;
diffe.setText("Remaining Time : \n" + Long.toString(q) + " day(s) "
+ Long.toString(h) + " hour(s) " + Long.toString(m)
+ " minute(s)");
day = Long.toString(q);
hour = Long.toString(h);
minute = Long.toString(m);
showMessage();
}
/*
* private void link() { empty = new LabelField("\n\n"); add(empty); hello =
* new InvokeBrowserHyperlinkField("Click here",
* "http://indri.dedicated-it.com/wordpress/?page_id=17"); add(hello); info
* = new LabelField("\n\nPress menu then choose \"Get Link\" to access");
* add(info); }
*/
void showMessage() {
activate = new ButtonField("Activate", FIELD_HCENTER) {
protected boolean navigationClick(int action, int time) {
if (activate.isFocus()) {
Dialog.alert("Started!!");
Start();
}
return true;
}
};
add(activate);
disactivate = new ButtonField("Disactivate", FIELD_HCENTER) {
protected boolean navigationClick(int action, int time) {
if (disactivate.isFocus()) {
Dialog.alert("Stopped!!");
timer2.cancel();
}
return true;
}
};
add(disactivate);
/*
* UiEngine ui = Ui.getUiEngine(); Screen screen = new
* Dialog(Dialog.D_OK, data, Dialog.OK,
* Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
* Manager.VERTICAL_SCROLL); ui.queueStatus(screen, 1, true);
*/
}
public void Start() {
timer2 = new Timer();
timer2.scheduleAtFixedRate(new TimerTick2(), 0, 6000);
}
private class TimerTick2 extends TimerTask {
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
synchronized (Application.getEventLock()) {
UiEngine ui = Ui.getUiEngine();
Screen screen = new Dialog(Dialog.D_OK, "Hello!",
Dialog.OK,
Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
Manager.VERTICAL_SCROLL);
ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE);
}
}
});
}
}
private String convertToWords(int m) {
String w = "";
switch (m) {
case 1:
w = "January";
break;
case 2:
w = "February";
break;
case 3:
w = "March";
break;
case 4:
w = "April";
break;
case 5:
w = "May";
break;
case 6:
w = "June";
break;
case 7:
w = "July";
break;
case 8:
w = "August";
break;
case 9:
w = "September";
break;
case 10:
w = "October";
break;
case 11:
w = "November";
break;
case 12:
w = "December";
break;
}
return w;
}
public boolean onClose() {
UiApplication.getUiApplication().requestBackground();
return true;
}
}
What actually is JVM 104 IllegalStateException? This program is a countdown program, which counts the remaining time from today until February 1st. Also, I implement a timer function that appears even if the application is closed. Can u please help me locate the problem? Thank you
As Richard said, you are trying to update LabelField from another thread. Try the following code snippet:
synchronized (UiApplication.getEventLock()) {
labelField.setText();
}
Try this below code and change according to your requirement;
public class FirstScreen extends MainScreen implements FieldChangeListener
{
LabelField label;
Timer timer;
TimerTask timerTask;
int secs=0;
long start,end;
String startDate="2012-01-28",endDate="2012-01-29";
ButtonField startCountDown;
public FirstScreen()
{
createGUI();
}
private void createGUI()
{
startCountDown=new ButtonField("Start");
startCountDown.setChangeListener(this);
add(startCountDown);
}
public void fieldChanged(Field field, int context)
{
if(field==startCountDown)
{
start=System.currentTimeMillis();
//this is the current time milliseconds; if you want to use two different dates
//except current date then put the comment for "start=System.currentTimeMillis();" and
//remove comments for the below two lines;
//Date date=new Date(HttpDateParser.parse(startDate));
//start=date.getTime();
Date date=new Date(HttpDateParser.parse(endDate));
end=date.getTime();
int difference=(int)(end-start);
difference=difference/1000;//Now converted to seconds;
secs=difference;
Status.show("Seconds: "+secs,100);
callTheTimer();
}
}
public void callTheTimer()
{
label=new LabelField();
add(label);
timer=new Timer();
timerTask=new TimerTask()
{
public void run()
{
synchronized (UiApplication.getEventLock())
{
if(secs!=0)
{
label.setText(""+(secs--)+" secs");
}
else
{
timer.cancel();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
label.setText("");
Dialog.alert("Times Up");
}
});
}
}
}
};
timer.schedule(timerTask, 0, 1000);
}
protected boolean onSavePrompt()
{
return true;
}
public boolean onMenu(int instance)
{
return true;
}
public boolean onClose()
{
UiApplication.getUiApplication().requestBackground();
return super.onClose();
}
}
In this code I am taking taking two different dates and start the countdown by taking their difference(in seconds); See the comments in the code;