cocos2d-x CCScrollview children not affected by anchor points? - cocos2d-x

I am creating a CCScrollview in my app
scrollView = CCScrollView::create();
scrollView->retain();
scrollView->setViewSize(CCSize(size.width,size.height - 100));
scrollView->setContentSize(CCSize(size.width,1000));
scrollView->setDirection( kCCScrollViewDirectionVertical );
scrollView->setPosition(ccp( 0,50 ) );
scrollView->setContainer( this->getParent() );
this->addChild(scrollView, 5);
now when i add a child to the scrollview like so:
titleLabel = CCLabelTTF::create("Squares", "Thonburi", 20);
titleLabel->setPosition(ccp(0, scrollView->getViewSize().height*0.90));
scrollView->addChild(titleLabel, 1);
it renders at the correct spot which is 0,50 with an anchor point on 0,0
if i change the anchor point though to say 1,1 like so
titleLabel->setAnchorPoint(ccp(1, 1));
it still renders as if it has an anchor point of 0,0
anyone know why this happens? or how i can fix it?

It happens, because CCScrollView resets the anchor point for added children to the container view:
void CCScrollView::addChild(CCNode * child, int zOrder, int tag)
{
child->ignoreAnchorPointForPosition(false);
child->setAnchorPoint(ccp(0.0f, 0.0f));
if (m_pContainer != child) {
m_pContainer->addChild(child, zOrder, tag);
} else {
CCLayer::addChild(child, zOrder, tag);
}
}
I am actually not sure, why this is necessary. A way to fix that would be to add a CCNode to the container first and add all your children to that container.

Related

Linking buttons to imported information from csv file

I would like to ask some help turning this representation into something more interactive. Im working with Processsing latest version. The main idea is I have a table in excel, I imported it into processsing. So far so good. Displayed the values as bubbles. My problem is that would like to create buttons to See further details from each bubble. So, click a button A, the corresponding bubbleA would light up and display its specific value, according to the imported table. I dont know how to connect the button to each bubble, neither how to turn the bubble to its original state once the button is pressed again.
I`m not from the programming field, I just manage to get this far with info that I have found online, so the code must be pretty messed up. I was trying to use the libraries from Processing but I cant really understand how the controlP5 works.. I asssume the structure is way more advanced than what I can handle now.
So, if anyone can help me, I would appreciate it very much.
Table B_A_table;
//Bubble[] bubbles = new Bubble[29];
ArrayList<Bubble> bubbles = new ArrayList<Bubble>();
float scale = 3;
int c_verdeClaro = color(182,189,149);
import controlP5.*;
ControlP5 cp5;
PFont font;
PFont font1;
void setup() {
size(1000, 1000);
colorMode(HSB,255);
loadData();
font = createFont("Verdana", 18);
font1 = createFont("Verdana Bold", 18);
//font = loadFont("Arial-Black-48.vlw");
//BEGIN TEST
cp5 = new ControlP5(this);
noStroke();
smooth();
//TEST
cp5 = new ControlP5(this);
ButtonBar b = cp5.addButtonBar("bar")
.setPosition(500, 0)
.setSize(400, 20)
.addItems(split("Man Woman 20s 30s 40s 50s µµ½É±Ç"," "))
;
println(b.getItem("Man"));
b.changeItem("a","text","first");
b.changeItem("b","text","second");
b.changeItem("c","text","third");
b.onMove(new CallbackListener(){
public void controlEvent(CallbackEvent ev) {
ButtonBar bar = (ButtonBar)ev.getController();
println("hello ",bar.hover());
}
});
//WND TEST
}
void draw() {
// Display all bubbles
background(0);
Graph_Bike_Aware_Experience_Sim();
//Graph_Bike_Uso_Satisf();
pushMatrix();
translate(400,500);
for (Bubble bubble : bubbles){
bubble.display();
}
popMatrix();
}
void loadData() {
// "header" indicates the file has header row. The size of the array
// is then determined by the number of rows in the table.
B_A_table = loadTable("BikeAwareExpr_Nao.csv", "header");
for (int i = 0; i<B_A_table.getRowCount(); i++) {
// Iterate over all the rows in a table.
TableRow row = B_A_table.getRow(i);
// Access the fields via their column name (or index).
float x = row.getFloat("awareness_x")*scale;
float y = row.getFloat("experi")*scale;
float d = row.getFloat("awareness_x")*0.2;
String n = row.getString("Awareness_Bike");
Float id = row.getFloat("ID");
// Make a Bubble object out of the data from each row.
bubbles.add(new Bubble(x, y, d, n,id));
//bubbles[i] = new Bubble(x, y, d, n);
}
}
// This simple Bubble class draws a circle to the window
// and displays a text label when the mouse hovers.
class Bubble {
float x, y;
float diameter;
String name;
Float id;
// Create the Bubble
Bubble(float tempX, float tempY, float tempD, String s, Float id) {
x = tempX;
y = tempY;
diameter = tempD;
name = s;
}
// Display the Bubble
void display() {
stroke(220);
strokeWeight(1);
noFill();
ellipse(x, y, diameter, diameter);
fill(200);
textFont(font,15);
textAlign(CENTER);
text(name, x,y);
}
}
void Graph_Bike_Aware_Experience_Sim(){
pushMatrix();
int tam_table = B_A_table.getRowCount();
translate(400,500);
stroke(150);
strokeWeight(1);
line( - 100 *scale, 0*scale, + 100*scale, 0*scale);
line(0*scale, - 100*scale, 0*scale, + 100*scale);
//fill(c_verdeClaro);
noStroke();
fill(255);
textFont(font,13);
text("Experience", 40 , -97*scale);
text("Awareness", -89*scale, -10);
fill(50);
//textFont(Arial-Black-48, 32);
text("0", 10,15);
pushMatrix();
fill(0);
textFont(font1,30 );
text("IDEAL", 80*scale , -120*scale);
fill(70);
textFont(font1,25 );
text("Bicycle", 0 , -110*scale);
popMatrix();
popMatrix();
}
/*void Graph_Bike_Uso_Satisf(){
pushMatrix();
int tam_table = B_A_table.getRowCount();
translate(900,400);
stroke(150);
strokeWeight(1);
line( - 100 *scale, 0*scale, + 100*scale, 0*scale);
line(0*scale, - 100*scale, 0*scale, + 100*scale);
//fill(c_verdeClaro);
noStroke();
c_verdeClaro_grad();
c_verdeEscuro_grad();
c_Vermelho_grad();
fill(255);
text("Experience", 40 , -97*scale);
text("Awareness", -89*scale, -10);
fill(0);
//textFont(Arial-Black-48, 32);
text("word", 10, 50);
text("IDEAL", 97*scale , -97*scale);
popMatrix();
}
*/
To handle this without Object Oriented Programing, or 'OOP' is a waste of time and code.
But relax OOP also referred to as "Objects" or " Classes". It is not that hard to get. In fact it is simple to learn, I mean, the basic stuff. And it makes things very easy.
In your case, you need to build an object to represent your data. Then you create several of them, populate with data, and all will be hold together. Kind of knowing it own business.
The usual example is
Class car
has those properties
color
plate
Then you can say:
Make a Blue, 3231 car!
Make a Red, 3001 car!
and so on...
When you need it you can ask, Blue car what's your plate, and it will know.
They can also have kind of "behaviours" known as functions or methods. Those do things, so you could say: "Red, turn right", or "Bubble, show me your data!" and they will OBEY you. :)
There is no point in trying to teach this hear though. There are TONs of great tutorials around. Use Duck Duck Go :) or google if you like.
This one here are from Processing's tutorials section itself. Great ones to begin with. :)

How to stop a sprite at exact touchdown position coordinates

I want to move a sprite (which happens to be a Rectangle) from any position of the screen and make it stop at exactly the touched position of the screen. Now, I can stop my sprite already, but not at the exact touched position. I cannot find a good way of doing this without sacrificing either accuracy or risking the sprite to not stop at all.
Naturally - the problem arises because the current position is Float, so that Vector will never (or extremely rarely) have the exact same coordinates as the touch point (which is an int).
In the code below, I stop my sprite by simply checking the distance between the current position and the target position (i.e. the touched position Vector3), like so if (touch.dst(currentPsition.x, currentPosition.y, 0) < 4).
For example, if the sprite is at position (5,5) and I touch the screen at (100,100), it will stop at like (98.5352,96.8283).
My question is, how do I stop the sprite at exactly the touch position, without having to approximate?
void updateMotion() {
if (moveT) {
movement.set(velocity).scl(Gdx.graphics.getDeltaTime());
this.setPosition(currentPosition.add(movement));
if (touch.dst(currentPosition.x, currentPosition.y, 0) < 4)
moveT = false;
}
}
public void setMoveToTouchPosition(boolean moveT) {
this.moveT = moveT;
this.touch = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
GameScreen.getCamera().unproject(touch);
currentPosition = new Vector2(this.x, this.y);
direction.set(new Vector2(touch.x, touch.y)).sub(currentPosition).nor();
velocity = new Vector2(direction).scl(speed);
}
Of course sprite can't move smoothly to touch position and then stop in exactly the same position because of many reasons. Just change this
if (touch.dst(currentPosition.x, currentPosition.y, 0) < 4)
moveT = false;
to this
if (touch.dst(currentPosition.x, currentPosition.y, 0) < 2) {
currentPosition.x = touch.x;
currentPosition.y = touch.y;
moveT = false;
}
A quick yet acceptable solution to this could be the use of the Rectangle class. Considering you make a Rectangle surrounding the moving entity and constantly update it's bounds based on its current location, it's texture width, and it's texture height. You could stop it when it overlaps with the "target position". If you do this you guarantee yourself that it will stop exactly at that position. For example:
Texture entityTexture = new Texture("assets/image.png");
Rectangle entityBounds = new Rectangle();
entityBounds.set((currentPosition.x, currentPosition.y, entityTexture .getWidth(), entityTexture .getHeight()));
Rectangle targetBounds = new Rectangle();
targetBounds.set((targetPosition.x, targetPosition.y, 1, 1)); // make width and height 1 by 1 for max accuracy
public void update(){
// update bounds based on new position
entityBounds.set((currentPosition.x, currentPosition.y, entityTexture.getWidth(), entityTexture.getHeight()));
targetBounds.set((targetPosition.x, targetPosition.y, 1, 1));
if(entityBounds.overlaps(targetBounds)){
// do something
}
}

Vertical paper-slider element

I like the Polymer paper elements and I want to use a paper-slider element.
However, i would like it to be vertical. I've tried to apply css to rotate it;
transform: rotate(90deg);
This rotates the slider, but not the "input"; one must still click and drag the mouse horizontally in order to get the "knob" to move up and down.
This is very annoying and any help is rely appreciated!
tk-vslider is a tweaked paper-slider with rotate functionality. Use this instead of paper-slider to solve this issue. Install using bower "tkvslider": "0.5.5"
<tk-vslider rotate="true"></tk-vslider>
Tweaks.
if rotate == true then
div#sliderContainer is css rotated by 90deg
Event on-trackx of the div#sliderKnob is replaced by on-track
In the method tracktake e.dy instead of e.dx.
This might be a pretty hacky way to do it, but we're coming up a year since you requested this as feature and it doesn't look like it's much of a priority yet. I figure this will (for the most part) allow for continued updates of paper-slider from the Polymer team without depending on third parties that might not continue support (from what I can tell, the custom element tk-vslider mentioned here hasn't been updated to support Polymer 1.0).
First, the css. I found that if I rotated 90 degrees, the smaller values were at the top of the slider, which I found to be counter-intuitive. So instead I rotate by -90. Some weird stuff happens with the margins but this is what finally did it for me:
paper-slider {
width: 20vh;
margin: 10vh -10vh;
--webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
I had my paper-slider inside my own custom element, so I put the following code in the ready callback, but I imagine you could put it anywhere you needed, as long as you can select the slider element. We're basically just going to override the method that paper-slider uses to respond to drag events. Here's how:
var slider = this.$.slider;
slider._trackX = function(e) {
if (!slider.dragging) {
slider._trackStart(e);
}
var dx = Math.min(slider._maxx, Math.max(slider._minx, (-1 * e.detail.dy)));
slider._x = slider._startx + dx;
var immediateValue = slider._calcStep(slider._calcKnobPosition(slider._x / slider._w));
slider._setImmediateValue(immediateValue);
// update knob's position
var translateY = ((slider._calcRatio(immediateValue) * slider._w) - slider._startx);
slider.translate3d(translateY + 'px', 0, 0, slider.$.sliderKnob);
};
Almost the entirety of this method is copied over from paper-slider source code, the only real change is that instead of grabbing the x coordinate in e.detail.dx we grab the y in e.detail.dy. The negative multiplier is only necessary if you want smaller values at the bottom of your slider, and you rotated your paper-slider by -90 degrees. Note that if the Polymer team ever changes the name of the method _trackX, it'll break this solution. I know this is a bit late but hopefully it'll help anyone else finding themselves in a similar situation (as I did).
UPDATE: Probably should have tested this solution a bit more, turns out there's another function that needs to be overwritten to handle click events (the other one only handles drag). I got it to work by adding this below my other method:
slider._bardown = function(event) {
slider._w = slider.$.sliderBar.offsetWidth;
var rect = slider.$.sliderBar.getBoundingClientRect();
var ratio = ((rect.bottom - event.detail.y) / slider._w);
var prevRatio = slider.ratio;
slider._setTransiting(true);
slider._positionKnob(ratio);
slider.debounce('expandKnob', slider._expandKnob, 60);
// if the ratio doesn't change, sliderKnob's animation won't start
// and `_knobTransitionEnd` won't be called
// Therefore, we need to manually update the `transiting` state
if (prevRatio === slider.ratio) {
slider._setTransiting(false);
}
slider.async(function() {
slider.fire('change');
});
// cancel selection
event.preventDefault();
}
The main change to this method is the line that calculates the ratio. Before it was var ratio = (event.detail.x - rect.left) / this._w;
<s-slider> has vertical property for vertical orientation https://github.com/StartPolymer/s-slider
zberry's answer didnt work for me anymore. However, I took his answer and updated it. The Polymer3 solution to make the paper-slider vertically responsive would look like this (given the same CSS zberry used):
let slider = this.shadowRoot.querySelector('paper-slider');
slider._trackX = function(event) {
if (!slider.dragging) {
slider._trackStart(event);
}
var dx =
Math.min(slider._maxx, Math.max(slider._minx, -1 * event.detail.dy));
slider._x = slider._startx + dx;
var immediateValue =
slider._calcStep(slider._calcKnobPosition(slider._x / slider._w * 100));
slider._setImmediateValue(immediateValue);
// update knob's position
var translateX =
((slider._calcRatio(slider.immediateValue) * slider._w) -
slider._knobstartx);
slider.translate3d(translateX + 'px', 0, 0, slider.$.sliderKnob);
};
slider._barclick = function(event) {
slider._w = slider.$.sliderBar.offsetWidth;
var rect = slider.$.sliderBar.getBoundingClientRect();
var ratio = (rect.bottom - event.detail.y) / slider._w * 100;
if (slider._isRTL) {
ratio = 100 - ratio;
}
var prevRatio = slider.ratio;
slider._setTransiting(true);
slider._positionKnob(ratio);
// if the ratio doesn't change, sliderKnob's animation won't start
// and `_knobTransitionEnd` won't be called
// Therefore, we need to manually update the `transiting` state
if (prevRatio === slider.ratio) {
slider._setTransiting(false);
}
slider.async(function() {
slider.fire('change', {composed: true});
});
// cancel selection
event.preventDefault();
// set the focus manually because we will called prevent default
slider.focus();
};
If you want to slide from top to down you have to fiddle with the directions

Increase width without moving image

I'm developing a drawing app, and I ran into a problem, and a possible solution would be to be able to resize horizontally (increase or decrease the width) of an image without altering it's pivot, but ending with a "directional resize", it means, that if I start dragging the right resize anchor, the image starts increasing it's width to the right, instead of always taking into consideration the pivot.
So, what I'm doing now is to increase the width and at the same time I move the image width/2, it works, however when I have to rotate the image.. everything starts to get broken, and even if I set the pivot in the middle of the sprite, since the image (that is contained inside the sprite) x is altered, it doesn't matter.
I've read some about matrices, but I'm not sure if this is possible.
Thanks.
There a few ways you can accomplish this. The first is to use a transform matrix.
Here is a function I use to rotate an object around a point in that fashion:
*You'll need to import fl.motion.MatrixTransformer, if not using flashPro you can get it here: https://code.google.com/p/artitem-as3/source/browse/trunk/ArtItem/src/fl/motion/MatrixTransformer.as?r=3
/**
* Rotates a displayObject around the passed local point.
* #param displayObj
* #param relativeDegrees - the relative amount of degrees to rotate the object
* #param point - a local point to rotate the object around, if null, center of bounding box will be used.
*/
public static function rotateAroundPoint(displayObj:DisplayObject, relativeDegrees:Number, point:Point = null):void {
var m:Matrix = displayObj.transform.matrix.clone();
if (!point) {
//default is center of bounding box
var r:Rectangle = displayObj.getBounds(displayObj);
point = new Point(r.x + (r.width * .5), r.y + (r.height * .5));
}
MatrixTransformer.rotateAroundInternalPoint(m, point.x, point.y, relativeDegrees);
displayObj.transform.matrix = m;
}
Another more lazy way to do this, is to use a dummy parent object and just rotate that:
var dummy:Sprite = new Sprite();
dummy.addChild(yourObjectToRotate);
//this effectively makes the anchor point of dummy in the center, so when you rotate it it rotate from the center.
yourObjectToRotate.x = -(yourObjectToRotate.width * .5);
yourObjectToRotate.y = -(yourObjectToRotate.height * .5);
dummy.rotation = 90;

Intersecting JLabels inside a JTable

In the below image I am trying to achieve the following.I have a table and lots of labels embossed over table cells.The height of the labels is always equal to the cell height.So if two labels come in the same point one hides the another as shown in the longer rectangles with red rect over blue.Alternatively what I want is to make the height as half and there by show both the rectangles(showing starting and end points of the rectangle since height is of no use I can half the height of the rectangle to accomodate one more in the same cell.)
I have to do this inside a JTable.To attach a label we can create a JLabel object by setting the rectangular bounds and using table.add(label);
image here
Where did you get the idea that you can do table.add(label) and hope that the label be magically painted over the table?
(Same ??? for #dpatch's answer.)
You have to use cell renderer/editor for any custom painting inside table. (Or layered pane/glass pane if it's something floating above table, but it looks like you want the labels in the cells.)
A crude renderer that paints cell (0, 0) as half-height blue on top of full-height red:
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer()
{
private int row_ = 0;
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
row_ = row;
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
public void setUI(LabelUI ui)
{
super.setUI(new BasicLabelUI()
{
public void paint(Graphics g, JComponent c)
{
super.paint(g, c);
if( row_ == 0 )
{
Rectangle r = g.getClipBounds();
g.setColor(Color.RED);
g.fillRect(r.x, r.y, r.width, r.height);
g.setColor(Color.BLUE);
g.fillRect(r.x, r.y + 1, r.width, r.height/2 - 1);
}
}
});
}
});
Check out the following presentation. I think it talks about solution to similar problem
http://developers.sun.com/learning/javaoneonline/2008/pdf/TS-4982.pdf?cid=925395
When you find two labels that need to be in the same cell, create a JPanel with the red and blue labels each taking up half the height of the panel. Then just add the panel to the table.