Table Of Contents

Previous topic

7.2. Reading/writing an image from/to a binary format

Next topic

7.4. Internationalization

Download

7.3. Handling many shapes

Note

To begin with, the Selection class will need to be modified so each and every new Shape type will be added to the already existing shapes on screen.

Then, an option allowing the user to choose between the Replace shape and Add shape modes shall be implemented.

  1. Modify the Selection class to handle an std::vector<Shape*> in lieu of a Shape*.

    1. in the method:

      void Selection::HandleNewShape(Shape *s);
      

      use std::vector::push_back(Shape *s) to add a new Shape.

    2. in the method:

      void Selection::Draw(QPainter *);
      

      write a loop to handle and represent all cached shapes.

    3. all the methods of the type GetWidth(), GetHeight(),... aren’t sensible. At this stage, one could just have them return the values associated with the last shape having been drawn.

    At this stage, it is possible to concurrently represent many different shapes on screen.

  2. It is now time to add the option allowing the user to choose between the modes Replace shape and Add shape.

    1. Create a button in WFrame to select the mode Add. An icon is available in the directory data/icons: Add.bmp

    2. Add a boolean data member in Visu2D to know which mode is active. This variable needs to be updated each time the user clicks on the ad hoc button in WFrame.

    3. Amend the method:

      void Selection::HandleNewShape(Shape *s);
      

      Add a boolean argument to know if the shape is added anew or is replacing the old one.

  3. Finally, the user needs to be able to pick a shape among those already painted on screen and to display the informations related to this shape. You should associate the mouse right click (Control-click) within a shape to its selection.

    1. Implement a method to find and return the index of the shape which contains a given point (x,y):

      /**
       * @brief Return the index of the shape nearest to a given point (x,y)
       * @param x: x coordinate.
       * @param y: y coordinate.
       */
      int GetNearestShape(int x, int y);
      

      To achieve this, the method will loop over all the shapes stored in the std::vector and will ask the method bool Shape::IsInside(int x, int y) if the point (x,y) falls inside the shape.

    2. In the method:

      void Visu2D::HandleMouse(int type, QMouseEvent *e);
      

      add for the right-click case the search for the nearest shape and the emission of an update signal:

      emit(UpdateStats(m_selection, idx))
      

      where idx is the index of the nearest shape. If the shapes’ translation has already been implemented, add as a fourth argument to the method:

      void Visu2D::MoveShape(int type, int x, int y);
      

      the index of the shape to be moved around.

    3. Implement 2 methods, to – respectively – compute the total area of all currently displayed shapes and compute the total number of counts.

    4. In the WFrame class, update the method:

      void WFrame::UpdateStats(Selection *pSelection);
      

      so it takes a second argument of type int to represent the index of the shape.

    5. Modify the connection accordingly, in the constructor of the class WFrame, i.e.: add an argument of type int for the index of the shape:

      connect(m_visu2d,
              SIGNAL(UpdateStats(Selection*, int)),
              SLOT(UpdateStats(Selection*, int)))
      
  4. In the Selection class, update the read/write methods of several shapes. One can retrieve and reuse the code of the previous sessions.

  5. Check that everything is working correctly !

../_images/validate-step1.jpg

Validate this step