After Deleting Shape.. I Cannot Rotate Anymore.. - JavaFX - list

I currently have a program where I can add rectangles to the scene. These can be selected, rotated, resized and deleted. If I select on a rectangle and click rotate it works, if I add another rectangle and click rotate it still works. However, If I 'DELETE' one of the rectangles then I cannot rotate the other one, or any additional added ones anymore.
I have the following fields and two methods:
private List<Node> selectedShapes = new ArrayList<>();
private double angle[] = {0};
#FXML
private AnchorPane container2;
Rotation:
public void rotateObject(ActionEvent event) throws IOException{
angle[0] = angle[0] + 45;
selectedShapes.get(0).setRotate(angle[0]);
}
Deletion
public void deleteButton(ActionEvent e) {
deletebutton.setOnAction(a -> container2.getChildren().removeAll(selectedShapes));
selectedShapes.remove(0);
}
I feel I am selecting or deleting the selected shapes in the incorrect way. Could someone guide me as to what the correct way to select the current item would be. So if I delete one of the rectangles, the other one should still be rotatable. Thanks

You want to create a Rectangle List, so instead of going through the base class Node why not use list of Rectangle/Shape directly :
List<Shape> selectedShapes = new ArrayList<>();
And for your problem, you use an array angle[], this one can not be extended, and there you call only index 0, i understand (if I'm not mistaken) that this array is to store the angle of each Rectangle to solve it uses a List there too:
List<Double> angle = new ArrayList<>();
And finally to find yourself in your list, uses an int that you increment (at the time of the addition) and decrement (at the time of the deletion) :
int Index = 0;
Edit:
Here's a simple methods that you could follow to organize your project :
private List<Rectangle> recs = new ArrayList<>();
private final double width = 50, height = 50;
private final double x = 200, y = 200;
public void add(){
recs.add(new Rectangle(x, y, width, height));
/*Properties of your rectangle (fill,shape...)*/
}
public void delete(int deleteIndex){
/*Here the root is the container of your Rectangles*/
root.getChildren().remove(recs.get(deleteIndex));
recs.remove(deleteIndex);
}
public void rotate(int recIndex, double angle){
recs.get(recIndex).setRotate(recs.get(recIndex).getRotate()+angle);
}
Good luck !

Related

How to get current visible portion of QGraphicsView in Qt?

I have QGraphicsView, which has multiple QGraphicsItem's. On this view, I am applying some transformation using features like Zoom-in, zoom-out, fit -In etc.
So before applying fit-in feature on my current view, I want to store view's current transformation ( view's current situation ) in a variable. And then I want to apply Fit-in feature. ( so that, in Undo-Redo I can use that stored position)
But I do not know how to store current position of view in a variable. I tried this way :
void myClass::FitIn()
{
QTransform t = _view->transform();
QScrollBar* hrSBar = _view->horizontalScrollBar();
QScrollBar* verSBar = _view->verticalScrollBar();
myCommand* c = new myCommand(t,hrSBar,verSBar);
undoStack->push(c);
_view->resetTransform();
}
How to store, current view in another variable ?
***** EDIT ******
myCommand.cpp
myCommand::myCommand(QTransform t, QScrollBar *hr, QScrollBar *vr)
{
this->trans = t;
this->horizontalSBar = hr;
this->verticalSBar = vr;
}
void myCommand::undo()
{
_mView->setTransform(trans);
_mView->horizontalScrollBar()->setValue(horizontalSBar->maximum());
_mView->verticalScrollBar()->setValue(verticalSBar->maximum());
}
void myCommand::redo()
{
_mView->setTransform(trans); // Segmentation Fault occurs
_mView->horizontalScrollBar()->setValue(horizontalSBar->maximum());
_mView->verticalScrollBar()->setValue(verticalSBar->maximum());
}
myCommand.h
class myCommand: public QUndoCommand
{
public:
myCommand(QTransform t, QScrollBar* hr, QScrollBar* vr);
private:
QGraphicsScene* _mScene;
QGraphicsView* _mView;
}
As revealed by source code of mapToScene, three parameters define the part of the scene that is visible on the viewport:
QGraphicsView::transform()
QAbstractScrollArea::horizontalScrollBar()->value()
QAbstractScrollArea::verticalScrollBar()->value()
To implement an undo-redo framework, those three parameters should be stored before every operation an restored upon undo.

How to insert pointer in QGraphicsItem so when they get selected pointer will be accessed?

I want to select rectangle/polyline through scene with mouse click and should be able to print it's name and other property. It's name and other properties are in the graph node. But I dont want to interact graph again.
So when I was drawing rectangle/polyline through graph co-ordinates, I should be able to store some pointer of graph node on rectangle/polyline so when I will click on rectangle/polyline, then through that pointer I can access it's name and other properties.
Question is `Is this possible ?
Among all above parameters, I want to store only _Ptr ( it is basically a pointer, but store as long, while using it will be type cast )
rect = new myRect();
while(true)
{
for(auto iter = verts.begin();iter != verts.end();++iter)
{
// getting co-ordinates of rectangle
QGraphicsRectItem* rectItem = rect->createRect(co-ordinates of rectangle);
rect->_Ptr = iter->_Ptr; // trying to store _crossRefPtr
}
}
myRect.h
class myRect : public QGraphicsRectItem
{
........
QGraphicsRectItem* createRect(QRectF& rect);
}
And when I will click on rectangle on scene through mouse I am doing like this:
if(_scene->selectedItems().count() != 0)
{
foreach(QGraphicsItem* currentItem, _scene->selectedItems())
{
QGraphicsRectItem* rItem = qgraphicsitem_cast<QGraphicsRectItem*>(currentItem);
if(rItem)
{
myRect* r = reinterpret_cast<myRect*>(rItem);
if(r)
{
Instance (rectangle)
Instance* i = reinterpret_cast<Instance*>(r->_boostRefPtr);
qDebug()<< i->Name();
}
}
But aobve way is wrong. Getting run time errors ( Showing Verbose stack trace)
So the question is :
How to store pointer on QGraphicsItem so that, once they get selected,
that pointer will be accessed ?
Use Qt's dynamic properties, check QObject::setProperty. It should do the trick.
But AFAIC, I would have used a double QMap to associate directly <graph_node, QGraphicsItem> AND <QGraphicsItem, graph_node> - so you can search quickly for both associations, and both in O(log2(n)) complexity. You can store this either as a static part of your graph (better) or standalone (not the best idea). Obviously, if your graph is already in O(log2(n)), you don't need this map and you need only the <QGraphicsItem, graph_node> one.

GLFW 3: How to get delta of the mouse scroll wheel with ScrollCallback (LWJGL 3)

I am following this tutorial on 3D game development with LWJGL and OpenGL. And in the series, the instructor is using LWJGL 2 while I'm using LWJGL 3 with GLFW. And in a certain section he uses LWJGL's input implementations only available in LWJGL 2, so I am forced to use GLFW's callback system. I was able to add input functionality for key input, cursor movement, and mouse button input, but when I tried to add a scrolling callback, it seemed that the offsets only return -1 and 1 for the scrolling directions, and when added, the (3rd person) camera translated forward and backwards indefinitely, and the intention was for every scroll movement the camera translates forward or backward a certain distance. In actuality I was expecting to get delta values for each scrolling movement. Previously I was messing around trying to see if I could set the offset values for an amount of delay time then set them back to 0 but to no avail. I tried searching for an answer, but I found nothing related to my problem. I may be stupid, but here's the code.
MouseScroll callback class:
import org.lwjgl.glfw.GLFWScrollCallback;
public class MouseScroll extends GLFWScrollCallback {
private static float XScroll;
private static float YScroll;
private static float DXScroll;
private static float DYScroll;
#Override
public void invoke(long window, double xoffset, double yoffset) {
XScroll = (float) xoffset;
YScroll = (float) yoffset;
// Don't know how to achieve this here
}
/* Returns raw offset values */
public float getXScroll() {
return XScroll;
}
public float getYScroll() {
return YScroll;
}
/* Returns the rate of each scrolling movement */
public float getDXScroll() {
return DXScroll;
}
public float getDYScroll() {
return DYScroll;
}
}
Method for getting YScroll in Input class:
public static float getMouseYScroll() {
return mouseScroll.getYScroll(); // mouseScroll is reference to MouseScroll callback
}
Method using the callback in Camera.java:
private void calculateZoom() {
float zoomLevel = Input.getMouseYScroll() * 0.1f;
distanceFromPlayer -= zoomLevel;
}
Update method in Camera.java:
public void move() {
calculateZoom();
calculatePitch();
calculateAngleAroundPlayer();
float horizontalDistance = calculateHorizontalDistance();
float verticalDistance = calculateVerticalDistance();
calculateCameraPosition(horizontalDistance, verticalDistance);
this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
}
And finally there is camera.move() that gets called every loop iteration
The GLFWScrollCallback is invoked whenever the user generates some scroll operation (up por down or even left or right). As a result, you will set XScroll / YScroll to -1 or 1 and leave it as such until the next scroll event happens. You need to implement some way to reset it to zero. Potentially you could do something like
public float getYScroll() {
float value = YScroll;
YScroll = 0.0f;
return value;
}
but this will only work if you call getYScroll only once per frame. It is not exactly clear how you want to deal with such events (i.e. do you want to store them until consumed - potentially not every frame), but most likely you get away by simply adding some reset method to MouseScroll which you call at the end of every frame - since you query the scroll wheel every frame, no event will be lost.

How to work with local coordinates in libgdx custom group?

I am creating a custom libgdx group to show a card image. It contains labels and images like these.
My first image is a texture region which is the actual size of the group. I now need to add the second image to the top left using local coordinate and a label for the name of the suit. This is the card I am using.
public class Card extends Group {
private Player player;
private AtlasRegion cardImage;
private Label lblCard;
public Card() {
super();
init();
}
#Override
public void draw(Batch batch, float alpha){
super.draw(batch, alpha);
batch.draw(cardImage, getX(), getY());
//lblName.draw()
lblCard.draw(batch, getOriginX() + 70..values I have used for this arent working so far);
}
#Override
public void act(float delta){
}
#Override
public void setSize(float width, float height) {
super.setSize(width, height);
}
private void init() {
cardImage = Assets.instance.cards.hearts;
// Add player name
lblName = new Label("H", Assets.instance.menu, "knul-medium", Color.BLACK);
}
}
I have tried using getX() and getY() values but when I draw the group inside a table, only the cardImage fits onto the table whereas the labels all draw at one point in the screen. How can I draw the labels and other texture regions inside my Card using local coordinates and appear at same appear as one image whenever I create a new instance of Card in another class?

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;
}