zooui.objects.scene.scene module

A collection of media objects.

class zooui.objects.scene.scene.Scene(config=None)[source]

Bases: PhysicalObject

Constructor :

Scene()

Parameters :

None

Scene() –> None

Scene objects are used to hold a collection of MediaObjects. This class manages all the objects that can be rendered in the interface, Their positioning (_x, _y) on the scene and their zoom (_z) and the acces to them.

Scene objects can also be saved to files, and loaded from files.

New scene is made by initiating a PhysicalObject, creating an objects list __objects and thread safe selection for __objects given by declaring RLock list __objects_lock, seting up __viewport_size, setting up mouse selection variables selection and right_selection and logger setup __logger.

For better explaining of this scheme look at : zooui.objects.mediaobjects.mediaobject

World:

 --------------------------------------->
|   Scene
|  @ ------------------------------+--->
|  |  ViewPort        MediaObj     |
|  |  (Screen View)   *-------+--> |
|  |                  |   &   |    |
|  |               %  +-------"    |
|  |                  |            |
|  |                  ∨            |
|  |                               |
|  +-------------------------------#
|  |
|  ∨
∨

Legend:

(All MediaObject attributes are relative to screen view)
* -> MediaObject.topleft()
" -> MediaObject.bottomright()
& -> MediaObject.center()
# -> Scene.viewport_size()
% -> Scene.center()
@ -> Scene.origin()

We have a center relative to the scene, ‘center’ and a center relative to the absolute frame of reference _center

@ origin position of the scene it’s relative to an absolute frame of reference, with 0,0 as it’s origin.

% Scene center it’s given by:

scene.centre[0] = scene.origin + (Scene.viewport_size[0]/2)*2**(zoomlevel)
scene.centre[1] = scene.origin + (Scene.viewport_size[1]/2)*2**(zoomlevel)
standard_viewport_size = (1280, 720)

an arbitrary size that is common to all scenes upon creation scene size

_needs_repaint = False

Flag to indicate that a repaint is needed

shutdown_threads()[source]

Shutdown all background threads managed by the scene.

Stops the parallel renderer thread executor. Called during application shutdown before Qt cleanup.

save(filename)[source]
Method :

Scene.save(filename)

Parameters :

filename : str

Scene.save(filename) –> None

Save the scene to the location given by filename.

It is recommended (but not compulsory) that the file extension of filename be ‘.pzs’.

open a file filename, writes on the first line zoom level (z) and position (x, y) of the scene origin defined by Scene.__set_origin() then thread safely, once sorted __objects, cicles through them, writing for each of them a line on fielname with:

object type: `type(mediaobject).__name__`

media id: mediaobject.media_id (replacing '%3A' with :)

zoomlevel: mediaobject.zoomlevel

x position: mediaobject.pos[0]

y position: mediaobject.pos[1]
_get_processed_media_id(mediaobject)[source]

Process media_id for saving, handling SVG embedding if needed.

Parameters:

mediaobject – MediaObject to process

Returns:

Processed media_id string ready for writing to file

Return type:

str

_write_mediaobject_line(f, mediaobject, offset=None)[source]

Write a mediaobject line to file.

Parameters:
  • f – File object

  • mediaobject – MediaObject to write

  • offset – Optional offset to apply to position (for save_selection)

save_selection(filename)[source]
Method :

Scene.save_selection(filename)

Parameters :

filename : str

Scene.save_selection(filename) –> None

Save selected mediaobjects to file.

Saves only the currently selected mediaobjects to the specified file, preserving their relative positions. The first line of the file is “0 0 0” to indicate no scene origin/zoom information.

The saved positions are offsets from the centroid of the selected objects, allowing import_scene to place them at the viewport centre while maintaining their relative arrangement.

add(mediaobject)[source]
Method :

Scene.add(mediaobject)

Parameters :

mediaobject : MediaObject

Scene.add(mediaobject) –> None

Add mediaobject from the list of elements that get to be rendered on the scene.

Inside a thread safe selection: add mediaobject to this scene by checking if given mediaobject is already in __objects list, if it is nothing is done, otherwise mediaobject it’s appended to the __objects list.

remove(mediaobject)[source]
Method :

Scene.remove(mediaobject)

Parameters :

mediaobject : MediaObject or List[MediaObject]

Scene.remove(mediaobject) –> None

Remove mediaobject(s) from the list of elements that get to be rendered on the scene and purge all’related tiles through TileManager.purge(‘media_id’) method.

Can accept either a single MediaObject or a list of MediaObjects. When passed a list, all objects in the list are removed.

Thread safely cycle through __objects until mediaobject match with the respective element of the __objects list and removes it from the __objects list. Then gets mediaobject.media_id attribute and check if other __objects elements have the same media_id, if it’s not the case the media_id gets purged from the TileManager.

See: zooui.tilesystem.tilemanager.purge()

static _parse_pdf_media_id(media_id)[source]

Parse a PDF media_id of the form pdf_path:page:N.

Returns:

(pdf_path, page_number) or (None, 0) if the path is missing or the media_id cannot be parsed.

_create_mediaobject_from_line(line)[source]

Helper method to create a mediaobject from a PZS file line.

Parameters:

line – A line from a PZS file containing mediaobject data

Returns:

MediaObject if successfully created, None if line should be ignored

_fit_imported_objects(mediaobjects)[source]

Scale imported mediaobjects to fit within the current viewport.

Calculates the combined on-screen bounding box of all imported objects and uniformly scales both their positions (relative to the group centroid) and zoomlevels so the bounding box fits within the middle 50% of the viewport.

Both position offsets and zoomlevels are scaled by the same factor, preserving the visual proportions (spacing and sizing) of the imported objects relative to each other.

This matches the behaviour of __open_media when adding single media files.

Parameters:

mediaobjects – List of mediaobjects with already-transformed positions. Both positions and zoomlevels will be adjusted.

import_scene(filename)[source]
Method :

Scene.import_scene(filename)

Parameters :

filename : str

Scene.import_scene(filename) –> None

Import mediaobjects from PZS file into current scene.

Loads mediaobjects from filename and adds them to the current scene, transforming their positions so they appear at the current viewport centre while preserving their relative positions to each other.

The saved scene’s zoom level and origin are discarded. Only the relative positions between mediaobjects are preserved.

copy_selection()[source]

Copy selected SVG objects to internal clipboard.

Only SVGMediaObjects are supported for copy/paste. Deselects copied objects after copying.

paste(offset_position=None)[source]

Paste SVG objects from clipboard with fixed offset.

Only SVGMediaObjects are supported for copy/paste. Selects pasted objects after pasting. Logs warning for unsupported object types.

Parameters:

offset_position – Optional offset position for pasted objects

Returns:

List of pasted MediaObject instances

get(topleft, bottomright=None)[source]
Method :

Scene.get(topleft, bottomright=None)

Parameters :

topleft : Tuple[float, float] bottomright : Optional[Tuple[float, float]] = None

Scene.get(topleft) –> MediaObject or None Scene.get(topleft, bottomright) –> List[MediaObject]

If only topleft is provided, return the foremost visible MediaObject which overlaps the on-screen point topleft.

If both topleft and bottomright are provided, return a list of all MediaObjects that intersect the rectangle defined by these two points, sorted by current render order (foremost to rearmost).

Return None or empty list if there are no MediaObjects overlapping the point or rectangle.

Mouse click event is caught by: zooui.qzui.QZUI.mousePressEvent() which returns mouse position pos

Thread safely cycle through __objects. For each mediaobject checks if pos is within mediaobject area. Objects are sorted by current render order, so the first match is the topmost on screen.

zoom(amount)[source]

Zoom by the given amount with the centre maintaining its position on the screen.

Parameters :

amount : float

zoom(float) -> None

property render_order
Property:

Scene.render_order

Parameters :

None

Scene.render_order –> str

Returns the current render order mode. ‘smaller_on_top’ means smaller objects are rendered above larger ones. ‘larger_on_top’ means larger objects are rendered above smaller ones.

See : zooui.objects.scene.scene.Scene.set_render_order()

set_render_order(mode)[source]
Method :

Scene.set_render_order(mode)

Parameters :

mode : str

Scene.set_render_order(mode) –> None

Set the render order mode. Valid values are ‘smaller_on_top’ and ‘larger_on_top’. The next render pass will use the new order.

See : zooui.objects.scene.scene.Scene.__sort_objects()

__sort_objects()
Method :

internal method self.__sort_objects()

Parameters :

None

__sort_objects() –> None

Sort self.__objects by onscreen_area. When render_order is ‘smaller_on_top’, objects are sorted ascending so that reversed iteration paints smaller objects last (on top). When ‘larger_on_top’, objects are sorted descending so that reversed iteration paints larger objects last (on top).

See : zooui.objects.mediaobjects.mediaobject.MediaObject.onscreen_area

action_draw_rect(topleft, bottomright, painter, color)[source]

Draws a colored rectangle around selected mediaobject

_get_text_objects()[source]

Get all StringMediaObjects in the scene.

Returns:

List of StringMediaObject instances

_precalculate_text_layouts()[source]

Pre-calculate text layouts for parallel rendering.

This method should be called before rendering when the scene is moving to prepare layout data for parallel rendering.

render_parallel_text(painter)[source]

Render text objects using parallel rendering.

Parameters:

painter – QPainter object to render with

Returns:

True if parallel rendering was used, False otherwise

enable_parallel_rendering(enabled=True)[source]

Enable or disable parallel rendering for the scene.

Parameters:

enabled – Whether to enable parallel rendering

get_parallel_stats()[source]

Get parallel rendering statistics.

Returns:

Dictionary with parallel rendering statistics

invalidate_parallel_cache()[source]

Invalidate parallel rendering cache.

render(painter, draft)[source]
Method :

Scene.render(painter, draft)

Parameters :

painter : QPainter draft : bool

Scene.render(painter, draft) –> List[MediaObject]

Render the scene using the given painter.

If draft is True, draft mode is enabled. Otherwise High-Quality mode is enabled.

If any errors occur rendering any of the MediaObjects, then they will be removed from the scene and a list of tuples representing the errors will be returned. Otherwise the empty list will be returned.

render(QPainter, bool) -> list[tuple[MediaObject,MediaObject.LoadError]]

See source code comments :

_open_string_dialog(dialog, obj_index)[source]

Open a string modification dialog deferred from render().

Must be called from the event loop (via QTimer.singleShot), not during paintEvent, to avoid recursive repaint and nested painter errors.

_open_svg_dialog(dialog, obj_index)[source]

Open an SVG modification dialog deferred from render().

Must be called from the event loop (via QTimer.singleShot), not during paintEvent, to avoid recursive repaint and nested painter errors.

step(t)[source]
Method :

Scene.step(t)

Parameters :

t : float

Scene.step(t) –> None

Step the scene and all contained MediaObjects forward t seconds in time.

Thread safely cycle through __objects mediaobjects set and for each of them call zooui.objects.physicalobject.PhysicalObject.step() inherited method.

property vzmoving
Property:

Scene.moving

Parameters :

None

Scene.vzmoving –> bool

Boolean value indicating whether the scene or any contained MediaObjects have a non-zero velocity.

Checks if the inherited, vx, vy and vz values from PhysicalObject are not zero. If it is that means the scene is moving and True is returned, If that’s not the case it thread safely cycles through mediaobjects in __objects checking if mediaobject.moving is True. If it is True is returned. mediaobject.moving is also inherited property of PhysicalObject class.

See : zooui.objects.physicalobject.PhysicalObject

property moving
Property:

Scene.moving

Parameters :

None

Scene.moving –> bool

Boolean value indicating whether the scene or any contained MediaObjects have a non-zero velocity.

Checks if the inherited, vx, vy and vz values from PhysicalObject are not zero. If it is that means the scene is moving and True is returned, If that’s not the case it thread safely cycles through mediaobjects in __objects checking if mediaobject.moving is True. If it is True is returned. mediaobject.moving is also inherited property of PhysicalObject class.

See : zooui.objects.physicalobject.PhysicalObject

__get_origin()
Method :

__get_origin

Parameters :

None

__get_origin –> Tuple[float, float]

Returns the Scene origin by retrieving _x, and _y variables inherited by PhysicalObject class

__set_origin(origin)
Method :

__set_origin(origin)

Parameters :

origin : Tuple[float, float]

__set_origin –> None

Set PhysicalObject._x and PhysicalObject._y parameters to new values given as input parameters.

property origin

Creating Scene.origin property with __get_origin as getter and __set_origin as setter

__get_viewport_size()
Method :

__get_viewport_size

Parameters :

None

__get_viewport_size –> Tuple[int, int]

Return the current dimensions of the viewport.

__set_viewport_size(viewport_size)
Method :

__set_viewport_size(viewport_size)

Parameters :

viewport_size : Tuple[int, int]

__set_viewport_size –> None

Happens when mainwindow gets resized or a scene get’s loaded having different viewport_size than the current mainwindow size. All necessary adjustment are handled here

Centers PhysicalObject._x and PhysicalObject._y to the new input parameter viewport_size center, also adjourn PhysicalObject.centre. Calculates the ratio between previous viewport_size center and the input parameter viewport_size, then calls PhysicalObject.zoom() and zooms the scene by base 2 log of the ratio between old and new viewport.

then adjourn the __viewport_size variable with the value given by the input parameter viewport_size.

old_viewport:

--------------------------------->
|
|      ----------------------
|     |                      |
|     |             *------  |
|     |           % |      | |
|     |             +------" |
|     |                      |
|      ----------------------#
|
|
∨

new_viewport:

----------------------------------->
|
|  ------------------------------
| |                              |
| |                              |
| |                              |
| |                *------       |
| |              % |      |      |
| |                +------"      |
| |                              |
| |                              |
|  ------------------------------#
|
|
∨
property viewport_size

Creating Scene.viewport_size property with __get_viewport_size as getter and __set_viewport_size as setter

enable_autosave(interval_minutes)[source]

Enable autosave with specified interval.

Parameters:

interval_minutes – Autosave interval in minutes (minimum 1)

disable_autosave()[source]

Disable autosave and stop timer.

is_autosave_enabled()[source]

Check if autosave is currently enabled.

Returns:

True if autosave is enabled, False otherwise

get_autosave_interval()[source]

Get current autosave interval in seconds.

Returns:

Autosave interval in seconds

get_autosave_config()[source]

Get autosave configuration.

Returns:

Dictionary with autosave configuration

set_autosave_config(config)[source]

Update autosave configuration.

Parameters:

config – Dictionary with autosave configuration updates

check_and_clear_repaint_flag()[source]

Check if a repaint is needed and clear the flag.

Returns:

True if a repaint is needed, False otherwise

zooui.objects.scene.scene.new(config=None)[source]
Function :

new(config=None)

Parameters :
configOptional[Dict[str, Any]]

Configuration dictionary

new(config=None) –> Scene

Create and return a new Scene object.

zooui.objects.scene.scene.load_scene(filename)[source]
Function :

load_scene(filename)

Parameters :

filename : str

load_scene(filename) –> Scene

Load the scene stored in the file given by filename.

Precondition: filename refers to a file in the same format as produced by Scene.save

See source code comments: