Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

basic UI layout - Group, Container, or Snapshot?
Started by greg886 Nov 20 2013 09:01 PM

25 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

greg886

[GLOBAL: userInfoPane.html]
greg886
  • Pro
  • PipPipPipPipPipPip
  • 861 posts
  • Jedi

Getting a little confused working out which grouping type mechanism's I should now be using for basic layout of my screen elements/components using an inheritance type approach.  I note Group's don't support anchor points so does this mean I need to run with "container" or "snapshot" then.   So my user requirements in this case say are:

 

* ability to group display objects together for layout purposes

* will want to have multiple levels of groups (e.g. stars collected icons in a stars group, this within say the titleBarGroup, and this then within the overall scene group)

* can position each individual display object within it's immediate group based on setting it's position relative it's immediate container.  Then this immediate container could be positioned within it's parent group relative to it's location so to speak.  In more detail then say:

  - 3 stars indicators spaced out equally across a stars group, centered vertically

  - the stars group itself may appear 2/3rds the way along the title bar group, at top re vertically

  - title bar group then at the top and center of the scene.view, at top re vertically

* so goal is that I can layout the elements of each layer independently of the above layer so to speak

* also if I add later another element to a layer it should not affect the positioning of that layer's positioning within it's parent (hope this makes sense)

 

 

What approach should I use?    Is a "group" not possible here as I read groups do not respect anchor points?  

 

 



[TOPIC: post.html]
#2

jack95

[GLOBAL: userInfoPane.html]
jack95
  • Starter
  • PipPipPipPipPipPip
  • 120 posts
  • Jedi

I too am confused. I have been using scene objects with background images and then groups/buttons on top of that. Interactions have been by manipulating ad-hoc groups/buttons as needed to avoid various bugs (like events propogating through buttons and sprites despite handling them correctly). Graphics 2.0 throws all the reference points out and my layouts (all 50 of them) are blown. My process for translating Photoshop comps to layouts (setRef topLeft and match to scaled photoshop comp), gone. It's horrific.

 

I was using a grand mask to constrain my display to reasonable bounds (3/4 area) with a massive bleed to account for any aberrant devices and the mask no longer works as expected. Now it moves about with sprites placed far to the left and right, making it useless. What's the equivalent for such a mask that doesn't move based on children (which I've never even heard of before)?

 

local _mask = graphics.newMask( "images/massivemask.png" )

 

group:setMask(_mask)
group:setReferencePoint( display.TopLeftReferencePoint )
group.maskX = myX
group.maskY = myY
 



[TOPIC: post.html]
#3

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Pro
  • PipPipPipPipPipPip
  • 635 posts
  • Jedi

With groups there is a setting about it respecting its children's anchor points, though I have not tried that yet.

 

In any app a group should be the first port of call. Containers and snapshots both have overheads.



[TOPIC: post.html]
#4

rakoonic

[GLOBAL: userInfoPane.html]
rakoonic
  • Pro
  • PipPipPipPipPipPip
  • 500 posts
  • Jedi

Containers currently have a not-insignificant bug - they don't limit touch events to their view area, so if you are hoping for that functionality, you might well be disappointed.

Snapshots are normally for more complex things than simply grouping, they enable visual effects and what-not on their contents. In this case I think this is overkill for what you need.

 

To be honest you probably just want a group. If you need purely visual clipping, you could try containers, but you can't nest them indefinitely.

 

As Matthew says above - always start with a group and go from there if it doesn't fulfill your requirements.

 

I list some of the main differences between the three types here: http://coronalabs.com/blog/2013/10/22/tutorial-snapshots-in-graphics-2-0/?utm_source=facebook&utm_medium=social&utm_campaign=blogpost



[TOPIC: post.html]
#5

greg886

[GLOBAL: userInfoPane.html]
greg886
  • Pro
  • PipPipPipPipPipPip
  • 861 posts
  • Jedi

So use groups here, but just have to always position the group within its parent group based on its top left position then? As there now no way to set a referent point or anchor point for a group right?

[TOPIC: post.html]
#6

mpappas

[GLOBAL: userInfoPane.html]
mpappas
  • Enterprise
  • PipPipPipPipPipPip
  • 527 posts
  • Jedi

Currently I'm thinking that --

 

Containers -- Best high level grouping mechanism. Has built in masking/clipping to a rectangular region, such as the screen. I'm thinking of using this for my highest level screen controllers.

 

Groups -- Best abstract graphics grouping/control mechanism. I'm planning on using these for my more generic objects, which may or may not get clipped at some point (depending on how they're used on the display).

 

Snapshots -- Best higher level mechanism for reducing graphics overhead. I can occasionally take a snapshot of a group that contains 1000 objects that don't change much and use that on the display - saving massive amounts of render overhead (better frame rate). Snapshots can also be used to downscale oversize images (like user taken photos) to reduce the frame by frame render power needed to draw the image (improving the frame rate). ie; rendering a 1536x2048 image with xScale/yScale = 0.4 takes a lot more time than rendering a 640x960 image with scale = 1.  (Not sure, but I think there was a bug if the device went to sleep, snapshot image data was corrupted... maybe fixed now?)



[TOPIC: post.html]
#7

rakoonic

[GLOBAL: userInfoPane.html]
rakoonic
  • Pro
  • PipPipPipPipPipPip
  • 500 posts
  • Jedi

@mpappas - It isn't a bug as such, it is more to do with how snapshots work. If you just fill a snapshot full of normal display objects (lines, rects, images or whatever) you likely won't have any problems at all. Snapshots within snapshots can cause issues if they update in the wrong order (eg if the top level container self invalidates() before the child one, it'll show the contents of the child as blank as the child's image won't be updated and available until the next frame).

Snapshots lose their contents entirely if you do something like double buffering to store copies of images that you then manipulate, but so far I'm only aware of one other person even doing that, so for general purposes we can discount it.



[TOPIC: post.html]
#8

ingemar

[GLOBAL: userInfoPane.html]
ingemar
  • Enterprise
  • PipPipPipPipPipPip
  • 2,144 posts
  • Jedi

I wrote a small utility function to be able to align groups. Maybe something of interest.

http://forums.coronalabs.com/topic/41618-aligning-groups-no-reference-pointno-problem/

[TOPIC: post.html]
#9

greg886

[GLOBAL: userInfoPane.html]
greg886
  • Pro
  • PipPipPipPipPipPip
  • 861 posts
  • Jedi

@ingemar - that's the kind of support I'm after

 

But shouldn't this basic windows layout manager type functionality be fundamentally backed into Corona itself?  My thinking is:

 

- need the basic support for laying out UI elements in a nested fashion (like any UI dev environment)

- needs to support multiple levels of grouping/nesting => excludes containers and snapshots

- we're left with groups, but there is now no way to set reference points, nor use anchor points

- does this not imply Corona needs to do one of the following:

  a) provide layout mechanism back to Groups or

  b) update Containers so it can support multiple levels of nested containers, or

  c) create a new element that is somewhere between Groups & Containers that satisfies the need?



[TOPIC: post.html]
#10

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Pro
  • PipPipPipPipPipPip
  • 635 posts
  • Jedi

Would this answer the original question about respecting anchor points.

 

Groups however do not honor anchors by default. You must use set theanchorChildren property. See 'Aligning Children' in the Groups Guide.

 

 

Aligning children

Sometimes it's convenient to treat the children of a group as a single object and then anchor them like you would a single rectangle. This allows you to position the children relative to the group's origin.

You can do this by setting the following group property:

group.anchorChildren = true

By default, this property is false. However, for containers, this property defaults to true.

In this case, the children are all offset by the same amount. That offset is calculated by looking at the bounding box for all the children. In essence, the children are treated as if they were a single rectangle and the group's origin was the anchor point for that rectangle.

For example, if the group's anchor were (0.5,0.5), the children would collectively move so that their relative positions are preserved, but as a whole, they are centered about the group's origin.



[TOPIC: post.html]
#11

greg886

[GLOBAL: userInfoPane.html]
greg886
  • Pro
  • PipPipPipPipPipPip
  • 861 posts
  • Jedi

oh :unsure:  - this satisfies my requirement then doesn't it Matthew?    I thought I had read this in the doco before and noted a issue with this approach but I can't think what it was now...maybe I misread...   There's no negatives/cons re setting group.anchorChildren = true? 



[TOPIC: post.html]
#12

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Pro
  • PipPipPipPipPipPip
  • 635 posts
  • Jedi

I have not tried it as of yet. Just remembered reading it and wondering what it was all about.



[TOPIC: post.html]
#13

rakoonic

[GLOBAL: userInfoPane.html]
rakoonic
  • Pro
  • PipPipPipPipPipPip
  • 500 posts
  • Jedi

I haven't looked at anchorChildren either - frankly I can't even begin to understand what it does, as group functionality hasn't changed from G1 to G2, and there were no problems beforehand. Hopefully it is just some shortcut helper feature, although really I dunno what that might be.



[TOPIC: post.html]
#14

ingemar

[GLOBAL: userInfoPane.html]
ingemar
  • Enterprise
  • PipPipPipPipPipPip
  • 2,144 posts
  • Jedi

Normally groups don't have any real bounds/anchor points in Graphics 2.0, however when you set anchorChildren=true the group will be assigned a bounding box encapsulating all child objects, and an anchor point (0.5, 0.5 by default).

 

First I though that the anchor point couldn't be changed for the group, but it turns out that you can.



[TOPIC: post.html]
#15

jack95

[GLOBAL: userInfoPane.html]
jack95
  • Starter
  • PipPipPipPipPipPip
  • 120 posts
  • Jedi

This isn't fun at all (guessing what everything is supposed to do)

 

local _mask = graphics.newMask( "images/massivemask.png" )

 

group.anchorX = 0

group.anchorY = 0
group:setMask(_mask)
group.maskX = myX
group.maskY = myY

 

Now the mask is behaving as it did. Having a group's default anchor points (which don't work) to 0.5, 0.5 makes no sense to me. Now I know and just have to remember.



[TOPIC: post.html]
#16

rakoonic

[GLOBAL: userInfoPane.html]
rakoonic
  • Pro
  • PipPipPipPipPipPip
  • 500 posts
  • Jedi

Ingemar - why would you want to do that exactly? Does the boundary update when you move sprites? I can see all sorts of weirdness going on.

 

 

Seems like a very odd extra function to use - you can set up a 'fake' anchor point in a group just by positioning the children correctly.

Looks like I'll just ignore it really - after all I still have issues with anchor points because (1) they don't work in pixels and (2) you can't move them outside of the boundaries. So, I'll just keep using nested groups which gives the same functionality plus more I suppose :s



[TOPIC: post.html]
#17

ingemar

[GLOBAL: userInfoPane.html]
ingemar
  • Enterprise
  • PipPipPipPipPipPip
  • 2,144 posts
  • Jedi

 you can set up a 'fake' anchor point in a group just by positioning the children correctly.

 So, I'll just keep using nested groups which gives the same functionality plus more I suppose 

 

That's very true.



[TOPIC: post.html]
#18

greg886

[GLOBAL: userInfoPane.html]
greg886
  • Pro
  • PipPipPipPipPipPip
  • 861 posts
  • Jedi

@rakoonic - what did you mean by "positioning the children correctly" in fact? 

 

The main issue I think is that with groups if you align the group based on it's position, things could screw up if you added another object to the group say that was above and to the left of any existing objects in the group.  So (thinking out loud) you need (a) an easy way to position the group in it's parent group, but also (B) know that if you do add additional objects to groups that this won't change/screw up the layout.  Perhaps you suggesting one positions the group within it's parent group by reference to one of the children of the group?



[TOPIC: post.html]
#19

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Corona Staff
  • 9,308 posts
  • Jedi

Before G2.0 you had groups.  Groups had no width or height, so they never worked with reference points.  Groups did have a faux center, called it's origin point, which is 0, 0 and by default that is located at 0, 0 on the screen.   If you could use groups before for building UI's, grouping things and moving them together, you can still do that in the exact same way.   You didn't have Anchor Points or even Reference points with groups before, so not having them now is the same thing.

 

You can also still apply masks to groups to get container like effects too.



[TOPIC: post.html]
#20

greg886

[GLOBAL: userInfoPane.html]
greg886
  • Pro
  • PipPipPipPipPipPip
  • 861 posts
  • Jedi

thanks for chiming in Rob - you're right that I had some challenges before G2.0 so will continue to have them now in the same sense then.

 

Rob, can I ask for your advice here, in terms of moving forward with what we have.  Mainly:

 

i) do you understand where I'm coming from re looking for (a) an easy way to position the group in it's parent group but also (b) know that if you do add additional objects to groups that this won't change/screw up the layout?  Perhaps I'm missing something...

 

ii) what would recommend as the best approach to use right now that covers off point a) and b) above? 



[TOPIC: post.html]
#21

mpappas

[GLOBAL: userInfoPane.html]
mpappas
  • Enterprise
  • PipPipPipPipPipPip
  • 527 posts
  • Jedi

There's not a lot of magic going on here, and (unless you're migrating) it's pretty easy to determine how containers (and anchorChildren=false) work and write new code accordingly.

 

The anchorChildren=false works like a champ (a sage corona addition IMHO - it melds containers and groups together well)... I've used it, and the container insertions acted like I would have expected group insertions to (in my case with a bg graphic and a few dozen other object placed around in random spots). And like Rob said, you don't have to use containers at all. Just stick to the old fashioned way - groups and masks.

 

 
    local c = display.newContainer(640,960)    -- 640x960 is my config lua content size
    c.anchorChildren = false
    
    c.anchorX = 0.0  -- top left of contatiner
    c.anchorY = 0.0        

    c.x = 0   -- top left of screen coord
    c.y = 0    
 
    -- insert things now... they're where I expect..
    -- AND everything is clipped to the container bounds... (can make it wider/taller for bleed if you want...)
 
    local Background = display.newImageRect("Bg02.png",640,960)

    Background.x = 320 -- image origin is it's centerpoint, so image is centered onscreen
    Background.y = 480
    c:insert(Background)
 
    -- etc etc



[TOPIC: post.html]
#22

jack95

[GLOBAL: userInfoPane.html]
jack95
  • Starter
  • PipPipPipPipPipPip
  • 120 posts
  • Jedi

> If you could use groups before for building UI's, grouping things and moving them together, you can still do that in the exact same way.

 

 

Same way? Kinda. You now have to translate each displayObject that was added to a group like so:

 

displayObject:translate(displayObject.width/-2,displayObject.height/-2)

 

I'm using a utility g2xlate function to pick through my code and strategically update elements that need it.

You also need to add group.anchorX = 0, group.anchorY = 0 for the exact same nested group/mask behaviors.

 

For complex objects using 3rd party libraries (like x-pressive) ... good luck! I haven't gotten that far.



[TOPIC: post.html]
#23

rakoonic

[GLOBAL: userInfoPane.html]
rakoonic
  • Pro
  • PipPipPipPipPipPip
  • 500 posts
  • Jedi

@jack95 - I think you can just set default values for the anchor points (display.setDefault( "anchorX", 0 ) I think off top of my head).

@Greg - I was referring to the fact that if you want the 'reference point' (or in this case, group origin) to be in the middle of all your objects, I'd just place the objects either side of the origin, and use it like that. For more complicated origin needs like rotation groups etc, I just used nested groups, which IMO is still going to be more flexible than anchor points as you can place the rotation / scale point anywhere, not just within the bounds like anchor points.



[TOPIC: post.html]
#24

jack95

[GLOBAL: userInfoPane.html]
jack95
  • Starter
  • PipPipPipPipPipPip
  • 120 posts
  • Jedi

@rakoonic

display.setDefault( "anchorX", 0 )
display.setDefault( "anchorY", 0 )

 

These setting do not apply to all child groups. At this time (since .2085) I must assign anchorX and anchorY individually, even with these set.



[TOPIC: post.html]
#25

ingemar

[GLOBAL: userInfoPane.html]
ingemar
  • Enterprise
  • PipPipPipPipPipPip
  • 2,144 posts
  • Jedi

Ingemar - why would you want to do that exactly? Does the boundary update when you move sprites? I can see all sorts of weirdness going on.

 

The problem I have is with the name anchorChildren. It might be just me, but my brain doesn't process the term since it doesn't modify the behavior of the children per se.

 

Regardless of if anchorChildren is true or false, adding objects to the group will still use the children's common anchor point to position them relative to each other.

 

The only time anchorChildren comes into play is when you want to position the group on the stage. 

When anchorChildren=true, the group will get its own anchor point which you can set like with any other object. This makes it easier to position if you have groups where the children's common anchor point is at an arbitrary position.

When anchorChildren=false, the group's positioning will be using the children's common anchor point which may prove to be tricky to position the way you want.

 

To me the term anchorGroup=true makes more sense than anchorChildren=true as the ultimate effect of setting this property affects the group's positioning, not the children.




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]