Drawing row background in QTableView in Qt5 is not possible anymore? - qt5

with the following code we used to set the background color of a row in a QTableView when hovering over it:
void StableTable::mouseMoveEvent ( QMouseEvent * event ) {
int row = rowAt ( event->y() );
if( row == -1 ) return;
if ( row == mHoveredRow ) return;
QBrush background(palette().midlight());
QColor backColor = background.color();
background.setColor(backColor);
for (int col = 0; col < model()->columnCount(); col++) {
QModelIndex inn = model()->index(row, col);
model()->setData(inn, background, Qt::BackgroundRole);
if( mHoveredRow != -1 ) {
QModelIndex prevInn = model()->index(mHoveredRow, col);
model()->setData(prevInn, palette().base(), Qt::BackgroundRole);
}
}
mHoveredRow = row;
}
It worked fine with Qt4.8.x but now with Qt5.4 no background color ist set anymore. Does anyone has clue if something has changed here?

They changed some things around in Qt5. BackgroundRole is still available, but you have to wrap it in a QVariant. Here is how I set my background color in table widget items.
tableItem->setData(Qt::BackgroundRole, QVariant(QColor(Qt::yellow)));

Related

Script command to Align Slice Horizontally by Calibration

Is there a script command that I can specify a particular slice in a LinePlotImageDisplay and do the Align Slice Horizontally by Calibration (or Uncalibrated (channels)) action?
The following scipt is a complete implantation based on example codes provided by BmyGuest. It will align all slices in a LinePlotImageDisplay horizontally either by calibration or by channel (i.e. un-calibrated).
class SliceAlignment : object {
number true, false; // boolean
image imgLPID;
imageDisplay LPID; // line plot image display
number CalculateImageToGroupTransformFactors( object self, image slice_src, image slice_ref, number &relOff, number &relScale ) {
number origin_ref, scale_ref, origin_src, scale_src;
string unit_ref, unit_src;
number calFMT = 0; // origin is expressed in calibrated unit
//
slice_src.ImageGetDimensionCalibration( 0, origin_src, scale_src, unit_src, calFMT );
slice_ref.ImageGetDimensionCalibration( 0, origin_ref, scale_ref, unit_ref, calFMT );
//
relScale = scale_src / scale_ref;
relOff = (origin_src - origin_ref) / scale_ref ;
// check if both images are calibrated in same unit
if( unit_src != unit_ref ) return false
return true;
};
void AlignNthSliceHorizontallyByChannel( object self, number slice_idx ) {
// get current reference slice index
number refSlice_idx = LPID.LinePlotImageDisplayGetSlice();
// get slice ID's (as objects)
object slice_ref = LPID.ImageDisplayGetSliceIDByIndex(refSlice_idx);
object slice_src = LPID.ImageDisplayGetSliceIDByIndex(slice_idx);
number int_offset = 0, int_scale = 1.0; // vertical (intensity) offset and scaling factors
number pos_offset = 0, pos_scale = 1.0; // horizontal (position) offset and scaling factors
LPID.LinePlotImageDisplaySetImageToGroupTransform( slice_src, slice_ref, int_offset, int_scale, pos_offset, pos_scale );
};
void AlignNthSliceHorizontallyByCalibration( object self, number slice_idx ) {
// get current reference slice index
number refSlice_idx = LPID.LinePlotImageDisplayGetSlice();
// get slice ID's (as objects)
object slice_ref = LPID.ImageDisplayGetSliceIDByIndex(refSlice_idx);
object slice_src = LPID.ImageDisplayGetSliceIDByIndex(slice_idx);
number int_offset = 0, int_scale = 1.0; // vertical (intensity) offset and scaling factors
number pos_offset, pos_scale; // horizontal (position) offset and scaling factors
number unit_check = self.CalculateImageToGroupTransformFactors( imgLPID{slice_idx}, imgLPID{refSlice_idx}, pos_offset, pos_scale );
if( unit_check == false ) {
string prompt = "slice #" + slice_idx + " [" + LPID.ImageDisplayGetSliceLabelById( LPID.ImageDisplayGetSliceIDByIndex(slice_idx) ) + "] is calibrated in different unit!";
if( !ContinueCancelDialog( prompt ) ) return
};
LPID.LinePlotImageDisplaySetImageToGroupTransform( slice_src, slice_ref, int_offset, int_scale, pos_offset, pos_scale );
return;
};
void AlignAllSlicesHorizontallyByChannel( object self ) {
number nSlices = LPID.LinePlotImageDisplayCountSlices();
for( number idx = 0; idx < nSlices; idx++ ) self.AlignNthSliceHorizontallyByChannel( idx );
return;
};
void AlignAllSlicesHorizontallyByCalibration( object self ) {
number nSlices = LPID.LinePlotImageDisplayCountSlices();
for( number idx = 0; idx < nSlices; idx++ ) self.AlignNthSliceHorizontallyByCalibration( idx );
return;
};
object init( object self, image img ) {
// check if the image display is correct type
imgLPID := img;
LPID = imgLPID.ImageGetImageDisplay(0);
if( LPID.ImageDisplayGetDisplayType() != 3 ) throw( "Please choose a valid line plot display" );
return self;
};
SliceAlignment( object self ) {
true = 1; false = 0;
result( "SliceAlignment [obj ID:" + self.ScriptObjectGetID().hex() + "] constructured\n" );
};
~SliceAlignment( object self ) {
result( "SliceAlignment [obj ID:" + self.ScriptObjectGetID().hex() + "] destructured\n\n" );
}; };
{; object objAlign = alloc(SliceAlignment);
objAlign.init( GetFrontImage() );
if( OptionDown() ) objAlign.AlignAllSlicesHorizontallyByChannel();
else objAlign.AlignAllSlicesHorizontallyByCalibration(); };
No, there is no single 'convenience' command to achieve this alignment. You will have to create the according function yourself from reading a slices calibration and setting its display-coordinate system. You might find the following (old) tutorial PDF on the FELMI homepage might be useful:
SlicesInLinePlotDisplay.pdf
The following example script might also be useful. It shows how one slice is aligned relative to another slice. (Just on the X-axis)
// All Slices in a LinePlot are grouped into a single 'group'
// Slices can be moved relative to each other by specifying their image-to-group transform,
// and the whole image (i.e. the group) can be moved with respect to the display using the group-to-display transform.
// To set the image-to-group transform of the slice specified by 'slice_id', with respect to the slice specified by 'ref_id'
// use the command:
// LinePlotImageDisplaySetImageToGroupTransform( LinePlotImageDisplay lpid, ScriptObject slice_id, ScriptObject ref_id, double off_val, double scale_val, double off_dim_0, double scale_dim_0 )
/*********************************************************/
// Create 2 LinePlots and add them into one display
// (Initially they are aligned by their calibrations)
number sc1 = 1
number of1 = -50
number sc2 = 2
number of2 = -20
image sl1 := realImage("S1",4,300)
image sl2 := realImage("S2",4,300)
sl1 = (iwidth-icol)/iwidth
sl2 = (iwidth-icol)/iwidth
sl1[0,50,1,60] = 1
sl1[0,250,1,260] = 1
sl2[0,10,1,15] = 1
sl2[0,110,1,115] = 1
// Adding Calibrations
sl1.ImageSetDimensionCalibration(0,of1,sc1,"CH",0)
sl2.ImageSetDimensionCalibration(0,of2,sc2,"CH",0)
sl1.DisplayAt(20,30)
sl2.DisplayAt(750,30)
OKDialog( "Put into one Display" )
imageDisplay disp = sl1.ImageGetImageDisplay(0)
disp.ImageDisplayAddImage( sl2, "S2") // When added like this, the slices are automatically aligned by their respective calibration!
disp.LinePlotImageDisplaySetDoAutoSurvey( 0, 0 )
object ref_id = disp.ImageDisplayGetSliceIDByIndex(0) // Slice 0
object slice_id = disp.ImageDisplayGetSliceIDByIndex(1) // Slice 1
OKDialog("Now align by channels (i.e. undo any relative sclice alignment)")
// Simply set the relative "shifts" and "scales" to 0 and 1.
disp.LinePlotImageDisplaySetImageToGroupTransform( slice_id, ref_id, 0, 1, 0, 1 )
OKDialog("Now align by chalibration ")
number relScale = sc2/sc1
number relOff = of2-of1
disp.LinePlotImageDisplaySetImageToGroupTransform( slice_id, ref_id, 0, 1, relOff, relScale )

Number of filled rows in a SapTable

I'm using Silk4J and I have a table which is reported as SapTable in the Locator Spy. From that table, I'm trying to get all the texts of the second column, but it hangs or terminates with an exception. In the following you find the code for my tries. Finally I reached the last row of the table, but it hangs there again.
In all examples I'm using a while loop instead of a for loop, because I want to insert more conditions later.
Try 1: Straight forward (I thought)
SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
while (row < maxrows)
{
String text = table.getCell(row, COLUMN).getText();
logger.debug(text);
row++;
}
However, this code prints all visible columns, then hangs.
Try 2: adding a PageDn keypress via Silk
Since try 1 printed only the visible cells, I thought adding a keypress every page could help. That was my code:
SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
String text = table.getCell(row, COLUMN).getText();
logger.debug(text);
row++;
if (row % visibleRows == 0)
window.sendVKey(VKey.PAGE_DOWN);
}
Unfortunately this results in an exception "The virtual key is not enabled".
Try 3: adding a PageDn keypress via AwtRobot
Since the built-in sendVKey method did not work, but pressing the PageDn manually works, I switched to an AwtRobot:
SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
String text = table.getCell(row, COLUMN).getText();
logger.debug(text);
row++;
if (row % visibleRows == 0)
{
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_PAGE_DOWN);
robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
}
}
Pressing the key now works and I can see the table scroll to the next entry. However, my test application still hangs.
Try 4: Resetting the row count
Using the Locator Spy again, I found out that the index of the row is reset to zero, so I mimiced that in my code:
SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
String text = table.getCell(row, COLUMN).getText();
logger.debug(text);
row++;
if (row % visibleRows == 0)
{
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_PAGE_DOWN);
robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
row = 0; // <--
}
}
In this case, it prints the first N (number of visible) items of the list, scrolls to position N+1, prints the name of the first (!) row and then hangs when accessing the item with index 1 (after the reset).
Try 5: Sleeping
With some sleeping, I can reach the end of the table:
SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
String text = table.getCell(row, COLUMN).getText();
logger.debug(text);
row++;
if (row % visibleRows == 0)
{
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_PAGE_DOWN);
robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
row = 0;
Thread.sleep(1000); // <--
}
}
In this case, I get all items in the table. But since I don't know when the table ends, it does another getCell() call, which results in a hang again.
The question
I'm really stuck. I've also looked for other methods like getting the real number of rows in the table (getRowCount() doesn't), but didn't find one yet.
How do I get the real number of rows of a SapTable in Silk4J?
It took some trying - the underlying SAP automation API is not really helpful in this case - but here is how you can make it work:
private List<String> fetchItems() {
SapTable table = desktop.find("sap.Table");
SapVerticalScrollBar scrollBar = table.find("/SapVerticalScrollBar");
// the scrollbar maximum value seems to be a more reliable
// way to get the number of items than getRowCount
int itemCount = scrollBar.getMaximum() + 1;
List<String> items = new ArrayList<String>();
int currentAbsoluteRow = 0;
// the first loop iterates through the table page by page
for (int firstRowInPage = 0;
firstRowInPage < itemCount;
firstRowInPage = scrollToNextPage(firstRowInPage)) {
// this loop goes through the items of the current page
for (int currentRowInPage = 0;
currentRowInPage < table.getVisibleRowCount();
currentRowInPage++) {
if(++currentAbsoluteRow > itemCount) {
// we've read all the available items
return items;
}
SapComponent cell = table.getCell(currentRowInPage, 1);
items.add(cell.getProperty("Text").toString());
}
}
return items;
}
private int scrollToNextPage(int firstRowInPage) {
SapTable table = desktop.find("sap.Table");
SapVerticalScrollBar scrollBar = table.find("/SapVerticalScrollBar");
firstRowInPage += scrollBar.getPageSize();
scrollBar.scrollTo(firstRowInPage);
return firstRowInPage;
}
Some pitfalls that I encountered:
getRowCount() returned a higher count than there was in actual items
getVisibleRowCount() returns the number of items that would fit on the current page, even if not all rows were filled with actual items
The returned cell objects are only valid as long as the cell is on the screen, so you'll need to pull the information you want before you scroll to the next page.

controlP5: matrix/ 2D array for multiple RadioButton results

I'm trying to query a user to select from 4 or more sets of radio buttons where there are 5 buttons in each set (Processing 2+). Where I'm having trouble is taking the array created by selecting from each set of buttons and getting it to fill columns in a matrix where the elements can be queried and the 2D array can be printed and ultimately written as csv or tab txt file.
import controlP5.*;
ControlP5 controlP5;
RadioButton c0;
RadioButton c1;
RadioButton c2;
RadioButton c3;
int cols = 5;
int rows = 4;
int[][] myArray = new int[cols][rows];
void setup() {
size(600,650);
controlP5 = new ControlP5(this);
c0 = controlP5.addRadioButton("ch0",60,60)
.setSize(20,20)
.setItemsPerRow(5)
.setSpacingColumn(50)
.addItem("c03", 1)
.addItem("c04", 2)
.addItem("c05", 3)
.addItem("c0AM", 4)
.addItem("c0AF", 5)
;
c1 = controlP5.addRadioButton("ch1",60,80)
.setSize(20,20)
.setItemsPerRow(5)
.setSpacingColumn(50)
.addItem("c13", 1)
.addItem("c14", 2)
.addItem("c15", 3)
.addItem("c1AM", 4)
.addItem("c1AF", 5)
;
c2 = controlP5.addRadioButton("ch2",60,100)
.setSize(20,20)
.setItemsPerRow(5)
.setSpacingColumn(50)
.addItem("c23", 1)
.addItem("c24", 2)
.addItem("c25", 3)
.addItem("c2AM", 4)
.addItem("c2AF", 5)
;
c3 = controlP5.addRadioButton("ch3",60,120)
.setSize(20,20)
.setItemsPerRow(5)
.setSpacingColumn(50)
.addItem("c33", 1)
.addItem("c34", 2)
.addItem("c35", 3)
.addItem("c3AM", 4)
.addItem("c3AF", 5)
;
}
void draw() {
background(0);
}
void controlEvent(ControlEvent theEvent) {
if(theEvent.isGroup() && theEvent.name().equals("ch0") || theEvent.name().equals("ch0") || theEvent.name().equals("ch2") || theEvent.name().equals("ch3")){
println(theEvent.name());
println(theEvent.arrayValue());
//float t=float(theEvent.arrayValue());
//int[][] = { {float getGroup(),float[] getArrayValue()}, {3,2,1,0}, {3,5,6,1}, {3,8,3,4} };
//int cols = 4;
//int rows = 5;
//int[][] myArray = new int[cols][rows];
// Two nested loops allow us to visit every spot in a 2D array.
// For every column I, visit every row J.
//for (int i = 0; i < cols; i++) {
// for (int j = 0; j < rows; j++) {
//myArray[i][j] = float(theEvent.arrayValue);
}
}
You were mixing different things together. Also you don't need to check whole array and store this information. Just update clicked button. Here is new version of your controlEvent
void controlEvent(ControlEvent theEvent) {
int cols = 4;
int rows = 5;
int[][] myArray = new int[cols][rows];
switch(theEvent.getId()){
case 0:
myArray[0][(int)theEvent.value()-1] = 1;
break;
case 1:
myArray[1][(int)theEvent.value()-1] = 1;
break;
case 2:
myArray[2][(int)theEvent.value()-1] = 1;
break;
case 3:
myArray[3][(int)theEvent.value()-1] = 1;
break;
}
println("==== " + theEvent.getId() + " ===");
println(myArray[theEvent.getId()]);
}
To do this simple switch you need to add ID parameter to all your radio buttons like this:
c3 = controlP5.addRadioButton("ch3", 60, 120)
.setId(3)
.setSize(20, 20)
...
I don't know how exactly you want use this array so my implementation use it as local variable so it will be deleted every time this event is called but this could be avoided by declaring array as global variable and then deleting only updated column.

Datagridview SelectionMode Alternative

I am trying to modify the way in which selections are made for my datagridview so that it selects in a similar way to text selection.
Currently when a series of cells are selected in multiple rows only the cells selected are highlighted.
However what i'd like it to do is when the second row is selected it also selects all cells to the right of the first selected cell, and all cells left of the second selected cell, exactly the same as highlighting text in a browser.
Is there some property or mode that I can set to make the datagridview selection behave like this?
You can use a built-in MonthCalendar control:
The Windows Forms MonthCalendar control can display up to twelve months at a time. By default, the control displays only one month, but you can specify how many months are displayed and how they are arranged within the control. When you change the calendar dimensions, the control is resized; so be sure there is enough room on the form for the new dimensions.
You can try capturing the mouse down, move and up events and handling the selection yourself. This works for dragging from top to bottom, additional logic needs to be added to drag the other direction, but that should doable for you.
{
dataGridView1.CellMouseDown += dataGridView1_CellMouseDown;
dataGridView1.CellMouseMove += dataGridView1_CellMouseMove;
dataGridView1.CellMouseUp += dataGridView1_CellMouseUp;
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
}
int startRow;
int startColumn;
bool beginSelection;
void dataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
beginSelection = false;
}
void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (!beginSelection)
return;
dataGridView1.ClearSelection();
int curRow = e.RowIndex;
int curCol = e.ColumnIndex;
for (int r = startRow; r <= curRow; r++)
{
int maxC = dataGridView1.ColumnCount-1;
int minC = 0;
if (r == curRow)
maxC = curCol;
if (r == startRow)
minC = startColumn;
for (int c = minC; c <= maxC; c++)
{
dataGridView1[c,r].Selected = true;
}
}
}
void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
beginSelection = true;
startRow = e.RowIndex;
startColumn = e.ColumnIndex;
}

Pathfinding / Deciding on direction

i'm making a simple iPhone game using cocos2d-iphone. I have an array of fiends, the "fiendSet" which has to navigate around a field full of obstacles. I spent the last three nights trying to get my A* pathfinding to work. I found the actual A* implementation here on stackoverflow and it works brilliantly. However, once i try to move my fiends around i run into trouble.
Each of my fiends has a CGPoint called motionTarget which contains the x and y values for where the fiend has to go. If only set the positions x and y to absolute values once a second, it works, like so:
-(void) updateFiendPositions:(ccTime)dt {
for (MSWFiend *currFiend in fiendSet) {
currFiend.position = ccp(currFiend.motionTarget.x,currFiend.motionTarget.y);
}
}
However, this doesn't look very nice, the fiends just "jump" 20px each second instead of animating nicely. I only implemented this as a placeholder method to verify the pathfinding. Now i want smooth animation. This is what i did:
-(void) updatePositions:(ccTime) dt {
for (MSWFiend *currFiend in fiendSet) {
if (currFiend.motionTarget.x != -1 && currFiend.motionTarget.y != -1) {
float x,y;
if ((int)floor(currFiend.position.x) < (int)floor(currFiend.motionTarget.x)) {
x = currFiend.position.x+(currFiend.speed*dt);
}
if ((int)floor(currFiend.position.x) > (int)floor(currFiend.motionTarget.x)) {
x = currFiend.position.x-(currFiend.speed*dt);
}
if (abs((int)floor(currFiend.position.x)-(int)floor(currFiend.motionTarget.x)) < 2) {
x = currFiend.motionTarget.x;
}
if ((int)floor(currFiend.position.y) < (int)floor(currFiend.motionTarget.y)) {
y = currFiend.position.y+(currFiend.speed*dt);
}
if ((int)floor(currFiend.position.y) > (int)floor(currFiend.motionTarget.y)) {
y = currFiend.position.y-(currFiend.speed*dt);
}
if (abs((int)floor(currFiend.position.y)-(int)floor(currFiend.motionTarget.y)) < 2) {
y = currFiend.motionTarget.y;
}
currFiend.position = ccp(x,y);
}
}
}
This works great for fiends moving in one direction. As soon as a fiend is supposed to go around a bend, trouble starts. Instead of for example first going up, then right, then down; my fiends will combine the up/right motion into one, they are "cutting corners". I only want my fiends to move either north/south OR east/west for each position update, not both. In other words, i don't want to animate changes to x and y simultaneously. I hope this explanation is clear enough..
I'm pretty sure i have a logic error somewhere.. i just havn't been able to figure it out for the last three sleepless nights after work.. Help!
You have to keep track of each node in the path to the target. That way you only animate the motion to the next node. Also you can use a CCMoveTo action instead on doing the animation yourself.
#Aleph thanks for your suggestion. I found that it was the code which determines when to assign a new motionTarget, that was faulty, not the code i posted to begin with. When you mentioned keeping track of each nodes position, i thought of my motionTarget determination code and found the error after 2-3 hours. I ended up doing it like this:
-(void) updatePositions:(ccTime) dt {
for (MSWFiend *currFiend in fiendSet) {
int fiendGX,fiendGY,targetGX,targetGY,dGX,dGY;
float x,y,snappedX,snappedY;
BOOL snappedIntoPosition = FALSE;
fiendGX = (int)round(100.0f*(currFiend.position.x/20));
fiendGY = (int)round(100.0f*(currFiend.position.y/20));
targetGX = (int)round(100.0f*(currFiend.motionTarget.x/20));
targetGY = (int)round(100.0f*(currFiend.motionTarget.y/20));
snappedX = currFiend.position.x;
snappedY = currFiend.position.y;
dGX = abs(fiendGX-targetGX);
dGY = abs(fiendGY-targetGY);
float snappingThreshold; //1 = snap when 0.1 from motionTarget.
snappingThreshold = currFiend.speed/10;
if (dGX < snappingThreshold && dGY < snappingThreshold) {
snappingThreshold = currFiend.motionTarget.x;
snappingThreshold = currFiend.motionTarget.y;
int newPathStep;
newPathStep = currFiend.pathStep + 1;
currFiend.pathStep = newPathStep;
}
int gX,gY;
gX = [[currFiend.path objectAtIndex:currFiend.pathStep] nodeX];
gY = (tileMap.mapSize.height-[[currFiend.path objectAtIndex:currFiend.pathStep] nodeY])-1;
currFiend.motionTarget = ccp(gX*20,gY*20); //Assign motion target to the next A* node. This is later used by the position updater.
if (currFiend.motionTarget.x != -1 && currFiend.motionTarget.y != -1) {
x = currFiend.motionTarget.x;
y = currFiend.motionTarget.y;
if ((int)floor(currFiend.position.x) < (int)floor(currFiend.motionTarget.x)) {
//Move right
x = snappedX+(currFiend.speed*dt);
if (x > currFiend.motionTarget.x) {
x = currFiend.motionTarget.x;
}
y = snappedY;
}
if ((int)floor(currFiend.position.x) > (int)floor(currFiend.motionTarget.x)) {
//Move left
x = snappedX-(currFiend.speed*dt);
if (x < currFiend.motionTarget.x) {
x = currFiend.motionTarget.x;
}
y = snappedY;
}
if ((int)floor(currFiend.position.y) < (int)floor(currFiend.motionTarget.y)) {
//Move up
y = snappedY+(currFiend.speed*dt);
if (y > currFiend.motionTarget.y) {
y = currFiend.motionTarget.y;
}
x = snappedX;
}
if ((int)floor(currFiend.position.y) > (int)floor(currFiend.motionTarget.y)) {
//Move down
y = snappedY-(currFiend.speed*dt);
if (y < currFiend.motionTarget.y) {
y = currFiend.motionTarget.y;
}
x = snappedX;
}
}
currFiend.position = ccp(x,y);
}
}