andromeda-cad / andromeda-rfcs

AndromEDA development plans
0 stars 1 forks source link

QtGraphicsScene #13

Closed SchrodingersGat closed 6 years ago

SchrodingersGat commented 8 years ago

TL;DR

I think the QGraphicsView / QGraphicsScene functionality is a key part of what we are trying to do. If people are generally happy with the notes below, I can make an RFC in a more formal manner.

TL;Still Read

Qt provides a toolkit for rendering large scale "scenes" via the QtGraphicsScene. The QtGraphicsScene holds many (unlimited) graphics objects and handles the rendering of these objects in (single or multiple) QtGraphicsView

This is a really powerful toolset and I think it is very appropriate for rending entire schematics and PCB layouts.

A good starting point for an example application 40000 Chips.

The scene describes the graphical layout, and the view describes the user-facing viewport looking at a particular part of the scene. Each view only renders objects which are currently visible, and handles functionality such as updating an individual object, or a portion of the screen, etc.

The scene holds many items which can be added/removed from the scene, and easily moved around the scene using scene coordinates. Each subclass of QGraphicsItem must define the paint() routine, and this allows powerful functionality as (for e.g.) a SymbolGraphicsItem class can be defined which draws the symbol, and this can be inserted into the scene at any point.

Each item can also be assigned a z-layer to enforce rendering order (e.g. for defining layer order in PCB viewer).

If we examine the case of defining a SymbolGraphicsItem class (for rendering schematic symbols), the paint() function would draw a sequence of shapes, texts, pins (defined by the symbol) around (0,0) - the shapes are translated to the appropriate position when added to the scene.

The scene is more than just a grid of pixels as it knows much information about the various shapes and objects drawn within. Each individual shape can support selecting, moving, and even receive drag-and-drop events from the filesystem!

Selection of multiple objects is also supported.

Zooming a viewport is very simple - I have written a very simple test project which enables zooming using both the x/y scrollbars and the mouse scroll wheel, and using the middle button to pan the window.

Converting a mouse-press event to real scene coordinates (no matter the zoom / pan) is as simple as calling QPointF scenePos = view->mapToScene(QPoint mousePos);.

If an individual item is to be updated (e.g. maybe we change the value of a resistor), it would be as simple as:

resistor->updateValue("10K");
resistor->update();

This assumes that 'resistor' is a subclass of QGraphicsItem and also AndromedaSymbol

The update function automatically sends a signal to the graphicsscene to redraw only the area affected by that item. It takes all the hassle out of working out which bits of the screen to re-blit.

QGraphicsScene also supports OpenGL rendering natively.

SchrodingersGat commented 8 years ago

Also, mouse events are propagated through the scene to the actual items embedded in the scene - with the top item receiving the event first in the case there is a stack of items. So we do not need to implement complex checks to determine what is clicked on in a scene.