How do I register an event for a raphael elements created through js? - raphael

Say I have n objects (say rectangles) whose size and position were randomly created when the user pushes a button. How do I register a click event in Raphael such that I know which rectangle/object was clicked on when the user clicks on one of the rectangles? The trick here is that n number are created inside of a loop. I need to be able to handle when any of the rectangles is clicked on so that I can perform some operation (eg. change the color of the clicked on rectangle to blue.) Here is the code for creating the rectangles:
for (var i=1;i<3;i++) {
x = Math.floor((Math.random()*200)+1);
y = Math.floor((Math.random()*200)+1);
width = Math.floor((Math.random()*25)+1) + 25;
height = Math.floor((Math.random()*100)+1) + 50;
r1 = paper.rect(x,y,width,height).attr({fill:"red"});
}

I think I found it in another posting. That's just the way it is...you look and look and post here and then you find the answer:
I simply need to add the following handler inside the loop after the rectangle is created:
r1.click(function() { this.attr({fill:'blue'}); });
Thanks to: http://jsfiddle.net/CHUrB/298/

Related

Programmatically aligning a created TButton right next to an adjacent TComponent in an FMX Frame

Referring to the picture, I would like to align a dynamically created TButton at runtime right next to a BindNavigator.
TButton *Add_But;
Add_But = new TButton(this);
Add_But->Visible = true;
Add_But->Text = "Add";
//Add_But->Position->X = 300;
//Add_But->Position->Y = 350;
Add_But->Parent=Form1->BindNavigator1;
Form1->Frame1->AddObject(Form1->StringGridBindSourceDB1);
Form1->Frame1->AddObject(Form1->BindNavigator1);
Form1->Frame1->AddObject(Add_But);
Add_But->Align=Fmx::Types::TAlignLayout::Right;
If I execute the above code, the Add_But button would align next to BindNavigator enclosed portion of the area between the last three buttons starting from the refresh button. Positioning Add_But using X,Y is not the ideal solution as I would like the Add_But to space out by certain margin padding just by using the Align property.
How to programmatically construct a TBounds margin object to resolve the issue?
Not Optimum solution using Two FlowLayout ,Believe TGridPanelLayout is much better choice , quite difficult to code correctly at runtime on cell position placement as the Main Frame is Just An Empty container refresh to hold Any child item based on selection
TFlowLayout *tlayout=new TFlowLayout(this);
tlayout->AddObject(Form1->StringGridBindSourceDB1);
TFlowLayout *tlayout1=new TFlowLayout(this);
// approximate the size of the TGrid
tlayout1->Width=600;
tlayout1->AddObject(Form1->BindNavigator1);
Add_But->Margins->Left = 10;
tlayout1->AddObject(Add_But);
tlayout->AddObject(tlayout1);
Form1->Frame1->AddObject(tlayout);
I have not written any apps in FMX but I saw no reason why you could not simply drop a TPanel on your FMX form then drop a TBindNavigator onto the TPanel unless there is a reason it can't be done this way, just trying to help.
This code works fine in Builder 10.3 on FMX Form
TButton *b = new TButton(TPanel1);
b->Parent = TPanel1;
b->Visible = true;
b->Position->X = TBindNavigator1->Width + 25;
b->Position->Y = TPanel1->Height / 2 - b->Height / 2;
b->Width = b->Width * 2;
b->Text = "Runtime Button";
How it looks when you run the code

VTK: Trying to select visible cells in area with vtkrubberbandpick & vtkHardwareSelector

I'm trying to do an area pick of visible cells on an object using a subclass of vtkInteractorStyleRubberBandPick. I've got everything working, except for one problem: If I change the perspective of the camera at all, the pick no longer works correctly. It just picks seemingly random cells on the object, instead of the ones inside the rubberband.
My LeftButtonUp in my InteractorStyle is basically like this:
vtkSmartPointer<vtkHardwareSelector> selector = vtkSmartPointer<vtkHardwareSelector>::New();
selector->SetRenderer(this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
unsigned int windowSize[4];
windowSize[0] = StartPosition[0] < EndPosition[0] ? StartPosition[0] : EndPosition[0]; // xmin
windowSize[1] = StartPosition[1] < EndPosition[1] ? StartPosition[1] : EndPosition[1]; // ymin
windowSize[2] = StartPosition[0] < EndPosition[0] ? EndPosition[0] : StartPosition[0]; // xmax
windowSize[3] = StartPosition[1] < EndPosition[1] ? EndPosition[1] : StartPosition[1]; // ymax
selector->SetArea(windowSize);
selector->SetFieldAssociation(vtkDataObject::FIELD_ASSOCIATION_CELLS);
selector->CaptureBuffers();
vtkSmartPointer<vtkSelection> selection = selector->GenerateSelection();
vtkSmartPointer<vtkExtractSelection> extractSelection = vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputData(0, actor->GetMapper()->GetInput());
extractSelection->SetInputData(1, selection);
extractSelection->Update();
vtkSmartPointer<vtkUnstructuredGrid> selected = vtkSmartPointer<vtkUnstructuredGrid>::New();
selected->ShallowCopy(extractSelection->GetOutput());
_faceSelectMapper->SetInputData(selected);
Do I need to do some kind of transformation somewhere? Do I need to somehow update the hardwareselector? I have searched everywhere but I'm at a loss...
Due to the clipping window effected part through the data is changing, you are getting different results every time you change camera orientation. You need to check whether the mode is selection or orientation like below
#define VTKISRBP_ORIENT 0
#define VTKISRBP_SELECT 1
if(this->CurrentMode == VTKISRBP_SELECT){
// interactor codes...
}
https://www.vtk.org/Wiki/VTK/Examples/Cxx/Picking/HighlightSelection

Saving data for multiple items while navigating through list of items

I am new this type of c++/cli language and i look for some help. I develop a project about the ListBoxes, i got some codes and learn basic steps on it. But i am actually stuck on the hardest part in this project.
The project counts framenumbers and keeps it. Its just an integer number and i got next and previous buttons in my code. when people click somewhere in the image, gui gets x and y coordinates and write it to the listbox correctly. What i trying to do is, when people push the next button, framenumber increased by one and clear listbox interface and ready for get other x and y coordinates. When people pressed previous button, ListBox should show the previous framenumbers x and y coordinates.
My question is, can i keep this x and y data in somewhere and reach at will? What should i do for keep these data? Any helps or thoughts will be appreciated for me.
Thank you for your helps.
What I would do is create a class to hold the data you want to save for each frame, and stick it into a collection of some sort as the user navigates through the frames. You could keep a List or a Stack, to implement retrieving the 'previous' item, but I'd probably use a Dictionary. Make the key of the dictionary the frame number, and have the value be the class of data you're saving for each frame.
Perhaps something like this:
public ref class FrameData
{
public:
int x;
int y;
public:
FrameData(int x, int y)
{
this->x = x;
this->y = y;
}
};
Dictionary<int, FrameData^>^ savedFrameData = gcnew Dictionary<int, FrameData^>();
// When they click the next or previous button:
// Save the data for the old frame.
savedFrameData->[oldFrameNumber] = gcnew FrameData(currentX, currentY);
// Retrieve the previous data for the new frame, if found.
FrameData^ dataForNewFrame;
if (savedFrameData->TryGetValue(newFrameNumber, dataForNewFrame))
{
currentX = dataForNewFrame->x;
currentY = dataForNewFrame->y;
}
else
{
currentX = 0;
currentY = 0;
}

Strange behavior of convertToWorldSpace for MenuItems in CCMenu

I have a menu attached to the layer . In the menu 4 items aligned vertically. I decleare the menu in this way (Warning! This is Javascript. Using COCOS2D-Html5, the framework is the same as per iphone):
menuHeight = sumofMenuItemsHeight(CategoryMiniSpriteArray);
var newMenu = cc.Menu.create(CategoryMiniSpriteArray);
newMenu.setAnchorPoint(cc.PointMake(1,1));
newMenu.setPosition(cc.PointMake(
ScreenSize.width, ScreenSize.height - (menuHeight / 2)
));
newMenu.alignItemsVertically();
After that at some point in the program I wanna to get the absolute coordinates of the menuitems relative to the screen.
And I execute this code:
var itemPosition = miniSprite.convertToWorldSpace(miniSprite.getPosition());
I get a very strange behavior. The X coordinate returned perfectly matches the real position. If I try to place this way:
sprite.setPosition(itemPosition);
another sprite to that coordinates X is perfectly aligned with the menuitems.
The problem is the Y. For every MenuItem I get a shifted Y but that's not all. The difference of Y between the menuitems is 2x times the menuitem height. So not only shifted Y but even shifted between items. What I'm doing wrong ? This is not the WorldSpace.
So the problem was that I'm calling convertToWorldSpace in the wrong way:
var itemPosition = miniSprite.convertToWorldSpace(miniSprite.getPosition());
Should be:
var itemPosition = miniSprite.getParent().convertToWorldSpace(miniSprite.getPosition());
I needed to call convertToWorldSpace from the CCMenu. From the parent and not from the child.

QGraphicsRectItem and QGraphicsScene problems at Scene change

what I want to do is the following:
I have a little GUI with a QGraphicsView. In this graphics View I load a picture:
// m_picture is QPixmap
// image is QImage
// m_graphic is QGraphicsScene
// graphicsView is QGraphicsView
m_picture.convertFromImage(image);
m_graphic->addPixmap(m_picture);
ui->graphicsView->setScene(m_graphic);
This doesn't cause any problems and I can always load a new image without problems.
Now in addition to just display the pictures I want to give the user the ability to draw a rectangle on them ( to "focus" on a specific area ). Actually the user just types in the coordinates in four text boxes on the GUI ( x,y, width,heigth). After providing the coordinates the User presses a button and the rectangle at the following coordinates shall be displayed.
I accomplished this with this code:
void tesseract_gui::show_preview_rect()
{
int x,y,h,w;
x = ui->numBox_x->value();
y = ui->numBox_y->value();
h = ui->numBox_h->value();
w = ui->numBox_w->value();
if( rect_initialized )
{
m_graphic->removeItem(m_rect);
}
else
{
rect_initialized = true;
}
m_rect->setPen(QPen(Qt::red));
m_rect->setRect(x,y,h,w);
m_graphic->addItem(m_rect);
return;
}
The remove call is because I always want to display just one rectangle.
Now as I mentioned this works fine. But if the user now loads another picture ( with the calls at the top of my post ) the program crashes when I try to draw a new rectangle. I
get a Segmentation fault at the call of
m_rect->setPen(QPen(Qt::red));
If I call
m_graphic->removeItem(m_rect);
after loading a new picture I get
QGraphicsScene::removeItem: item 0x8c04080's scene (0x0) is different from this scene (0x8c0a8b0)
and then it crashes with the same Error at setPen.
What I don't get is, I don't change the scene. I just add another picture to it ( or overwrite it) .
Well any suggestions how I could do this right?
Best Regards
// edit:
I tried to do it just with everytime a new rectangle like this:
void tesseract_gui::show_preview_rect()
{
int x,y,h,w;
x = ui->numBox_x->value();
y = ui->numBox_y->value();
h = ui->numBox_h->value();
w = ui->numBox_w->value();
m_graphic->clear();
m_graphic->addRect(x,y,h,w);
return;
}
Problem at this is that with the clear() call it also clears the picture itself from my GraphicsView... so no solution there
// edit:
As suggested I got rid of the Warning like this:
if( m_rect->scene() != 0 )
{
m_graphic->removeItem(m_rect);
}
m_rect->setPen(QPen(Qt::red));
m_rect->setRect(x,y,h,w);
m_graphic->addItem(m_rect);
I know it's not the best way but I tried it also this way ( did not work for me ):
I added the item in the constructor:
m_graphic->addItem(m_rect);
and then
m_rect->setPen(QPen(Qt::red));
m_rect->setRect(x,y,h,w);
m_graphic->update();
and I get the "same" error as always ( Program crashes at m_rect->setPen() )
So it seems the problem always occurs when I already added the rectangle to the graphic, THEN changed the image of m_graphic and then did any operation with m_rect. ( Actually I guess m_graphic takes ownership of m_rect and so this causes the segmentation fault ... ? )
The message QGraphicsScene::removeItem: item 0x8c04080's scene (0x0) is different from this scene (0x8c0a8b0) tells you m_rect is not in any scene at the time you call it. It's probably removed somewhere else in your code or you have 2 variables with the same name in the class hierarchy.
Also, you don't need to remove it from scene to change it. Just change it while it's in the scene. It will get repainted with the new color and geometry in the next paint event.
Even if you REALLY want to remove it before changing it, just check if it's in a scene by calling QGraphicsItem::scene(). There's no need for the init check variable.