Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
UIKit plugin extra - Gideros Forum

UIKit plugin extra

techdojotechdojo Guru
edited August 2012 in Plugins
Just a quick post - I've been playing with some plugin's with a view to extending the UIKit one and I thought someone might find the following code useful.

It add's an animated UIActivityIndicator to the root view which you can use to show that your app is busy (ie dealing with a UrlLoader request).

You need to add the following code to UIKit.mm
//----------------------------------------------------------------------------------------------
 
static bool busyActive = false;
 
static int showBusyIcon(lua_State* L)
{
    static UIActivityIndicatorView *myBusy = NULL;
 
    UIViewController* controller = g_getRootViewController();
    UIView* rootView = controller.view;
 
    bool show = lua_toboolean(L,1);
 
    lua_Number lx = lua_tonumber(L,2);
    lua_Number ly = lua_tonumber(L,3);
 
    // NSLog(<a href="/profile/Show%20Busy%20Icon%20%25d%2C%25d%20%28%25s%29">@Show Busy Icon %d,%d (%s)</a>,(int)lx,(int)ly,show==true?"show":"hide");  // So far so good! 8-)
 
    if(show)
    {
        if(!busyActive)
        {
            busyActive = true;
 
            if((lx == 0) && (ly == 0)) { lx = 160; ly = 240; }      // default to center
 
            myBusy = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
            myBusy.center = CGPointMake(lx,ly);
            myBusy.hidesWhenStopped = NO;
 
            [rootView addSubview:myBusy];
            [myBusy startAnimating];
        }
    }
    else
    {
        if(busyActive)
        {
            busyActive = false;
 
            [myBusy stopAnimating];
            [myBusy removeFromSuperview];
            [myBusy dealloc];
 
            myBusy = NULL;
        }
    }
 
    return 0;
}
And then in the function "loader" add the following line after the 4 lua_pushcfunction() calls
   // Add in my simple busy icon element!
    lua_pushcfunction(L, showBusyIcon);  lua_setglobal(L, "showBusyIcon"); busyActive = false; // Assume off to start!
To use from within Lua simply call it like so
    showBusyIcon(true,x,y)   -- display the busy icon at the specified position (default 160,240 if x & y not specified)
    showBusyIcon(false)       -- remove the busy icon from the display
Feel free to add feedback or (ab)use as you see fit.

Anyone fancy doing an Android version?
WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
+1 -1 (+3 / -0 ) Share on Facebook

Comments

  • Hey thanks. I am active again so it will be a welcome addition. Have to find the most recent version of my plugin code. Do you know where?
  • I just got the latest version from Carolines GitHub page https://github.com/carolight/MHUIKit
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • I have just posted a pull request to carolight on github with some new functions for existing UI elements and added UIImageView to it.
    She said she will review my changes and merge it tomorrow.
  • @Caroline - If your going to be merging in some changes, would you be happy to add in the busy icon? I haven't got a clue with GitHub and it seems to trivial to make an official fork.

    :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • Would it be ok if I added it to my one then it will be merged in tomorrow with my changes?
  • Of course - we haven't seen @Caroline on here for a while so she might not have got the message.
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • Thanks, done :)
    I modified the implementation a bit to match the other UIKit elements
    Where you create the object then set the position after.
    You can set White, White Large or Gray and I added a setColor method

    local activity = ActivityIndicator.new("White Large")
    activity:setPosition(135,200)
    activity:setColor(1.0,0,0,1.0) --red
    addToRootView(activity)
  • @techdojo - I may be falling behind in the post count, but I try and visit most days :). I'll take a look at everything tomorrow, including your busy icon.

    Likes: chipster123

    +1 -1 (+1 / -0 ) Share on Facebook
  • MellsMells Guru
    edited August 2012
    @techdojo & SimpleLoop
    Thanks for sharing!
    does your version include the work from @ianchia? On Github
    Also i was thinking that an example file showing the possibilities + a few screenshots in your original posts would be great to get more downloads and feedback.

    I's sad if this doesn't get as much attention as possible.
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • @Caroline - sorry I didnt mean to sound snarky, I'd just assumed you were busy with other stuff as we hadn't heard from you for a while. No disrespect intended :(

    @SimpleLoop - no worries, I'd have probably implemented it like that if I'd known how to :) I think your way is better, I just needed the function and it was my first attempt, I'll be sure to look at your version to see how to do it properly for next time
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • @Mells I'm just working on adding UITableViewCell so that you can make custom cells for the tables, after that is done I'll look into an example app containing all the possibilities.

    @techDojo thanks :). I just copied the way all the others were written but I'm sure @Caroline will spot some mistakes as it is was the first plugin I have done anything with in Gideros.

    I have to say the way plugins are made is brilliant, very easy to do once you wrap your head around all the lua binding stuff.
  • CarolineCaroline Guru
    edited August 2012
    @SimpleLoop - I merged your files which look absolutely fine - good job!, and then changed them a tiny bit:

    1. Changed uikit.mm to accept button.new() as being "Rounded Rect" by
    default, in case people are already using it that way.
    2. Project demonstrates label:setFont()
    3. Project includes Gideros Studio icon for demonstrating ImageView.
    4. Project demonstrates ImageView
    5. Project demonstrates ActivityIndicator.

    I didn't check out TableView, as I need at some time to refresh myself on what the problems that I came across it were. I seem to remember that simple TableViews were OK, but if you wanted to add views to rows, then garbage collection becomes a problem. I think, but could be wrong, it is because the view gets released, but the view binder doesn't.

    Yes, plugins are great, but if you take a couple of months away from them, beware 8-}!

    @techDojo - I haven't much of a clue with github either - and it didn't occur to me that you might be dissing me :).

    Likes: gorkem, techdojo

    +1 -1 (+2 / -0 ) Share on Facebook
  • @Caroline - me never, I'm too much of a Gentleman ;) thanks for including the update, must get my head round GitHub soon!
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • DaleDale Member
    I've made a small set of mods to uikit.mm, to allow a setRotation(degrees) to the various objects. (I originally needed a 90 degree rotated webview, so I came up with these changes.)

    I'm new to Git/GitHub, and unsure of the best way to put forth these diffs for consideration, so, here they are...:
    *** uikit.mm.orig       2012-08-31 00:22:48.000000000 -0300
    --- uikit.mm    2012-08-31 00:24:36.000000000 -0300
    ***************
    *** 229,234 ****
    --- 229,239 ----
                    frame.size.height = height;
                    uiView.frame = frame;
            }
    +
    +       void setRotation(float angle)
    +       {
    +               uiView.transform = CGAffineTransformMakeRotation(angle * M_PI / 180);
    +       }
     
            UIView* uiView;
            SelectorToEvent* selectorToEvent;
    ***************
    *** 248,253 ****
    --- 253,259 ----
            static int removeFromParent(lua_State* L);
            static int setPosition(lua_State* L);
            static int setSize(lua_State* L);
    +       static int setRotation(lua_State* L);
      };
     
      ViewBinder::ViewBinder(lua_State* L)
    ***************
    *** 257,262 ****
    --- 263,269 ----
                    //{"removeFromParent", removeFromParent},
                    {"setPosition", setPosition},
                    {"setSize", setSize},
    +               {"setRotation", setRotation},
                    {NULL, NULL},
            };
     
    ***************
    *** 334,339 ****
    --- 341,357 ----
            return 0;
      }
     
    + int ViewBinder::setRotation(lua_State* L)
    + {
    +       GReferenced* viewObject = static_cast<GReferenced*>(g_getInstance(L, "View", 1));
    +       View* view = static_cast<View*>(viewObject->proxy());
    +
    +       float rot = luaL_checknumber(L, 2);
    +       view->setRotation(rot);
    +
    +       return 0;
    + }
    +
      //----------------------------------------------------------------------------------------------
      #pragma mark ---- UISwitch ----
  • @Dale - thank you - hopefully I'll get to looking at this on the weekend.


  • @Dale - I've updated the github repository with your changes - it works well - thank you :)
  • Got the latest version thanks @Caroline :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • scurvyratscurvyrat Member
    edited September 2012
    I made three small changes to uikit.mm. They are:
    1) Slider -- pass in arg to have continuous value sent or final value after the slider stops
    2) set the alpha value for a labels BGColor
    3) set the alpha value for a labels TextColor

    Hopefully, these will be useful for others and can be incorporated in the github version.

    Note: I'm a novice at iOS development and Object-C, so someone with a better understanding should take a look at the below diff. The changes work in my Gideros code, so I think its fine.
    781c781
    < 	virtual void create(float min, float max)
    ---
    > 	virtual void create(float min, float max, BOOL continuous)
    789c789
    < 		slider.continuous = YES;
    ---
    > 		slider.continuous = continuous;
    851a852
    >     BOOL continuous = luaL_checknumber(L, 3);
    853c854
    < 	slider->create(min, max);
    ---
    > 	slider->create(min, max, continuous);
    1628c1629
    < 	void setTextColor(CGFloat r, CGFloat g, CGFloat b)
    ---
    > 	void setTextColor(CGFloat r, CGFloat g, CGFloat b, CGFloat a)
    1630c1631
    < 		UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:1.0];
    ---
    > 		UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:a];
    1634c1635
    < 	void setBGColor(CGFloat r, CGFloat g, CGFloat b)
    ---
    > 	void setBGColor(CGFloat r, CGFloat g, CGFloat b, CGFloat a)
    1636c1637
    < 		UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:1.0];
    ---
    > 		UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:a];
    1717c1718,1719
    < 	label->setTextColor(red, green, blue);
    ---
    > 	float alpha = luaL_checknumber(L, 5);
    > 	label->setTextColor(red, green, blue, alpha);
    1730c1732,1733
    < 	label->setBGColor(red, green, blue);
    ---
    > 	float alpha = luaL_checknumber(L, 5);
    > 	label->setBGColor(red, green, blue, alpha);
  • @scurvyrat - thank you for the changes. I'm away from my Gideros computer for a few weeks, so I'm unable to check them out until then. But someone could create a new Github fork, then I can do the merge when I can check out your code :). Otherwise I will look at it when I'm back with my Gideros computer.
  • @Caroline. Thank!
    I've now added the shadowColor, shadowOffset and textAlignment parameters as well. I've added in the number of lines, but have to figure out why this line:

    [(UILabel*)uiView sizeToFit];

    is not working (it is commented out in the current code base). Currently, it resets the label o a single line. I think it has to do with the UIView not having a width setting, but not sure.

    If I get it working, I'll post up a new diff.

    Thanks again!
  • I'm having a small issue with the activity indicator.
    this is the function I have to turn it on and off.
    function showActivity(display)
    	if(display) then
    		activityIndicator = ActivityIndicator.new("White")
    		activityIndicator:setPosition(290,30)
    		addToRootView(activityIndicator)
    		print("Activity Indicator ON")
    	else
    		removeFromRootView(activityIndicator)
    		print("Activity Indicator OFF")
    	end
    end
    If I call showActivity(true) from within a function, they Indicator never shows up until after that function has completed. I think it might have something to do with when addToRootView gets called or activated.

    Any help appreciated.
  • @scurvyrat - That is actually the behaviour I would expect.

    In Cocoa Touch Objective C, if I have a function (pseudo code):

    Show Activity indicator
    Do a ton of stuff
    Hide Activity indicator

    Then the Activity indicator will never show.

    If you were writing in Objective C, then you would need to do this:

    Show Activity Indicator
    Call a second function with the ton of stuff using performSelector:withObject:afterDelay: and Hide the Activity Indicator at the end of that function.

    This is because the device display is only updated at the end of a "run loop".

    Anything within a single function (or functions called from that function) is performed in a single run loop. So if you want the Activity Indicator to show, then you need to perform the ton of stuff on a second run loop.

    Did that make sense?
  • Looking at StackOverflow, there are a lot of questions about this - this question has a good answer:
    http://stackoverflow.com/questions/8600125/activity-indicator-not-showing-up?rq=1

    Most of the answers suggest using performSelectorInBackground:withObject: but I haven't tried background threading with Gideros Studio.

    performSelector:withObject:afterDelay: will work in foreground and block user input. (I use afterDelay of 0.0 seconds, if I remember correctly, and it's also possible you don't need to use afterDelay at all.)

  • Thanks! I wasn't able to find the right way to put that into the MHUikit.mm file.

    My hack workaround is to set a timer in Gideros that calls the function. In Pseudo code:

    Show Activity Indicator
    set Timer.new(1,1) to do a bunch of stuff
    on TIMER_COMPLETE Hide Activity Indicator

    Seems to work OK.
  • @scurvyrat - That is actually the behaviour I would expect.

    In Cocoa Touch Objective C, if I have a function (pseudo code):

    Show Activity indicator
    Do a ton of stuff
    Hide Activity indicator

    Then the Activity indicator will never show.

    If you were writing in Objective C, then you would need to do this:

    Show Activity Indicator
    Call a second function with the ton of stuff using performSelector:withObject:afterDelay: and Hide the Activity Indicator at the end of that function.

    This is because the device display is only updated at the end of a "run loop".

    Anything within a single function (or functions called from that function) is performed in a single run loop. So if you want the Activity Indicator to show, then you need to perform the ton of stuff on a second run loop.

    Did that make sense?
    Perfectly :) I had the same "issue", basically when I use the activity indicator, I turn it on before I signal a network request and then turn it off in the either the onComplete or onError callbacks. I couldn't get it to work if I did it in a sequence, however what you *CAN* do is have some kind of state based mechanism in your onEnterFrame function, so I set it active, then set the "state", then in my EnterFrame function pick up the change in state, do the work and then when it's finished then set it inactive.

    Obviously it can take a "little" longer (up to 16ms depending on the frame rate) to complete the task, but that's generally not a problem as the task already takes long enough to require the indicator and an extra 16ms isn't that much of an issue :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • anybody have good idea for custom cell in table view?
Sign In or Register to comment.