Tags: ejeschke/ginga
Tags
Ginga v7.2.0
- Fixed gtk4 application shutdown. Confirming a quit popped the
confirmation dialog a *second* time and then crashed while recording
window sizes on already-deleted widgets, and the application could fail
to terminate. Two causes: a toplevel window's ``destroy`` signal
re-entered the close-confirmation flow while the window was being torn
down deliberately, and the gtk4 main loop (``Gtk.Application.run``) does
not poll ``ev_quit`` the way the other backends' loops do. The
deliberate teardown now disconnects its ``destroy`` handler, ``get_size``
tolerates a torn-down widget, and ``Application.process_end()`` stops the
Gtk loop -- so ``gui_quit()`` / ``ev_quit``-driven shutdown works as on
the other backends.
- ``TableView`` gained spreadsheet-style cell editing. A new
``set_editable(tf)`` makes every text column editable in one call (instead
of per-column ``editable`` flags), and a new ``set_header_font()`` sets the
column-header font (headers are now non-bold by default for a more compact
table; pass a bold font to embolden). On the ``qt`` and ``pg`` backends the
table also has a current-cell cursor with arrow/Tab navigation and
spreadsheet editing (type to replace, Delete/Backspace to clear, and
commit-and-move on Tab/Enter/arrow). The qt ``TableView`` was reimplemented
on ``QTableWidget`` (from ``QTreeWidget``) to get native cell navigation,
grid lines, row-number header and per-cell editability. The gtk backends
get ``set_editable()`` and ``set_header_font()``; their spreadsheet cursor/
editing is a later refactor.
- The web (``pg``) backend's ``Timer`` is now a *server-side* timer for the
websocket case instead of a browser-side JavaScript timer. The old timer
only fired while a browser was connected and every tick round-tripped the
websocket, so a deferred redraw scheduled before the browser connected was
lost and the viewer's redraw could wedge (e.g. a plugin's plot not updating
until you zoomed). Timers now schedule on a ``heaptimer`` heap owned by the
``Application`` and fire their callbacks on the GUI thread regardless of
browser state, matching the qt/gtk/tk backends; async (single event loop)
mode uses the asyncio timer heap so it stays thread-free, and in-situ
(Pyodide) keeps the browser timer. Also fixed ``Application.make_timer()``
(it returned a raw pgwidgets timer) and ``Application.quit()`` (it raised
instead of shutting down via ``GwMain.gui_quit()``).
application (from the ``appname`` setting) instead of hardcoding "Ginga",
so an application built on Ginga shows its own name. The translated
message catalogs were updated accordingly (the message id now takes a
``{}`` placeholder).
- Fixed the qt ``TableView`` selection becoming unreadable (white text on a
white background) when ``show_grid=True``. The grid-line stylesheet forces
Qt into stylesheet-based item rendering, which ignored the palette-based
selection highlight; the selection colours are now also stated in the
stylesheet so the blue highlight stays visible under the grid.
- Added a ``pixi.toml`` manifest (https://pixi.sh) for a reproducible
conda-forge based development environment: ``pixi run ginga`` launches the
viewer and ``pixi run -e dev test`` runs the test suite.
- Window-fixed overlays now stay pinned to the viewport under a 3D camera in
the OpenGL and Vulkan renderers. Objects drawn in window/percentage
coordinates (the onscreen message, mode indicator, color bar, etc.) are
routed through a 2D orthographic projection instead of the (possibly
tumbled) camera, so they no longer drift or scale with the 3D view.
Relatedly, a ``Text`` object's background/border box is now built in window
coordinates (matching the mode indicator and color bar) so it keeps a
constant pixel size instead of growing with zoom under the camera, and
``set_onscreen_message()`` measures text extents accurately via Pillow.
- The **agg** renderer (``renderer='agg'``) has been reimplemented on top of
matplotlib's Anti-Grain Geometry rasterizer (``backend_agg.RendererAgg``)
instead of the unmaintained ``aggdraw`` package, dropping that dependency
(matplotlib is already required). The port also restores native drawing of
Bezier curves and (rotated) ellipses -- ellipses now take a direct
``draw_ellipse`` path instead of a 13-point Bezier approximation -- and adds
rotated text.
- The **pil** renderer now draws rotated text (previously rotation was
ignored) by rasterizing the string to a scratch tile and rotating it; the
common unrotated case still uses the fast direct-draw path.
- Requesting the generic ``qt`` toolkit (``-t qt``, or letting Ginga
auto-choose) no longer emits a ``qtpy`` ``PythonQtWarning`` about falling
back from ``pyqt5`` when that binding is absent: Ginga now points
``$QT_API`` at whichever Qt binding is actually installed and selects it
directly. A *specific* request (``qt5``/``qt6``/``pyside2``/``pyside6``)
still forces that binding and warns if it is missing, and a user-set
``$QT_API`` is respected.
- The ``mkapp`` folder for building a standalone desktop application (a macOS
``.app`` or Windows ``.exe``) has been modernized to use **PyInstaller**
(replacing the obsolete py2app/py2exe ``setup.py``): a single ``ginga.spec``
builds either platform, driven by a cross-platform ``build.py``. Install
the tooling with the new ``pyinstaller`` extra (``pip install
ginga[pyinstaller]``). See ``mkapp/README.rst``.
Ginga release v7.1.0
- Added an experimental **Vulkan renderer** (``renderer='vulkan'``), a
GPU-accelerated, toolkit-agnostic renderer built as an alternative to the
OpenGL one. It renders GPU-native (images colormapped in-shader with live
cut levels/distribution, shapes/wide/dashed lines, native Pillow text, RGBA
alpha, and a 3D camera mode) into an *offscreen* Vulkan image and hands the
result back as an array, so every backend (qt, gtk3, gtk4, tk, and the pg
web/websocket backend) can use it via the same array path as the pil/agg
renderers. Select it with ``ginga -t <toolkit> -r vulkan`` or the new
per-viewer ``renderer`` setting; it falls back automatically when the
``vulkan`` binding or a device is unavailable. Requires the optional
``vulkan`` dependency (``pip install ginga[vulkan]``) and a system Vulkan
driver (Mesa lavapipe works for a CPU/headless device). See the developer
manual ("The Vulkan renderer") for details. Not available in-situ under
Pyodide/PyScript.
- The OpenGL renderer now draws text by rasterizing it with Pillow and
blitting a texture (filled, anti-aliased) instead of converting it to
cairo path outlines, and supports wide and dashed lines by expanding them
into filled triangles (OpenGL does not guarantee ``lineWidth > 1`` or
stippling). This drops the cairo dependency for OpenGL text.
- bump required version of a few dependencies
- Menu items can now show an icon as well as (or instead of) text, like
toolbar actions. ``Menu.add_name()``, ``Menu.add_menu()`` and
``Menubar.add_name()`` accept ``iconpath``/``iconsize`` keyword arguments,
and ``MenuAction`` gains a ``set_icon()`` method. An ``icon_only`` flag
requests showing just the icon where the backend can render it, always
falling back to the text label otherwise, so the same calling code shows
the icon, the text, or both depending on the backend. Fully supported on
the qt, gtk3, and pg (web) backends; the gtk4 backend accepts the
arguments for API parity but renders text only for now
- The qt ``RadioButton`` now honors the ``group`` keyword across different
containers. Previously qt only made radio buttons mutually exclusive when
they shared a parent widget; grouped buttons now use a shared
``QButtonGroup``, matching the gtk3/gtk4/pg backends
- Added a ``TreeView.delete_tree()`` method (qt/gtk3/gtk4/pg) that removes
the nodes named by a subtree of keys -- individual leaves or whole
subtrees -- from a loaded tree, optionally pruning branches left empty,
preserving the selection on surviving items, and firing the ``selected``
callback if the selection changed and ``changed`` if anything was deleted
- The ``ColorDist`` color distribution classes now produce a normalized
0.0-1.0 floating point curve; the RGB mapping ``Distribute`` stage scales
that to the output level (bit depth) and quantizes to the index type.
This preserves precision (no longer capped at 256 levels for deeper
outputs) and is slightly faster. The ``colorlen`` argument to the
``ColorDist`` classes is now vestigial and deprecated (it has no effect).
Custom ``ColorDist`` subclasses should now install their curve as a
normalized 0.0-1.0 float array via the new public ``set_hash()`` method
(formerly ``_set_hash``). For backward compatibility, a subclass whose
``calc_hash()`` still stores a pre-7.1 integer/``colorlen``-scaled hash is
detected at build time and normalized automatically, with a
``PendingDeprecationWarning``; this shim will be removed in a future
release (github issue #1148)
- Color maps are now resolution-independent: ``ginga.cmap.ColorMap`` gains
``get_colors(n)``, which samples/interpolates the map to any size, and can
be built from a discrete list (as before), piecewise-linear control points
(``ColorMap.from_control_points``), or a callable (``from_function``).
matplotlib color maps are captured without retaining a runtime dependency
on matplotlib
- Added a ``color_depth`` viewer setting that controls the resolution (in
bits) at which pseudocolor is distributed, decoupled from the RGB output
depth. Raising it (e.g. to 12) yields much smoother gradients -- many more
distinct colors and far less banding -- for colorful color maps on a
standard 8-bit display, at negligible cost. The default (8) is unchanged.
Both the standard and OpenGL renderers honor the setting (the OpenGL
renderer sizes its GPU colormap texture up to 4096 entries)
- The DS9-derived color maps (``gray``, ``ramp``, ``red``, ``green``,
``blue``, ``heat``, ``ds9_cool``, ``ds9_a``, ``ds9_b``, ``ds9_bb``,
``ds9_he``) are now defined by their authoritative SAOImageDS9
piecewise-linear control points instead of baked 256-entry arrays. They
are exact, resolution-independent (smooth at any color depth), and small
(this also removed ~2600 lines from ``ginga/cmap.py``)
- Fixed an issue with matplotlib plots getting their axes labels cut off
Ginga v7.0.0 - Adopted the new ``pgwidgets`` widget set (JavaScript widgets + Python bindings) as the basis of the ``ginga.web.pgw`` backend. (More information on pgwidgets can be found at the `pgwidgets-js home page <https://github.com/naojsoft/pgwidgets-js>`__ and `pgwidgets-python page <https://github.com/naojsoft/pgwidgets-python>`__) - The reference viewer and the ``pg`` (web) widget set can now run *entirely in the browser* via Pyodide/PyScript ("in-situ"), in addition to the existing remote (web socket) mode; the widgets, image viewer (``ImageViewPg``), plot viewer and ``ipg`` were reworked to support this - Added an optional asyncio-based, single-event-loop task pool (with an async timer heap) so background ("nongui") work can run cooperatively on the browser event loop where there are no threads; added ``GwMain.nongui_foreach`` for responsive chunked work - Refactored the font assistant to support family/style/weight, added ``Application`` methods to register shipped/loadable fonts and set a default font, changed the default font from "Roboto" to "sans", and fixed font handling across the PIL, OpenCV, AGG and Matplotlib backends - Added a central ``download_file()`` (Downloads delegates to it), a ``fetch_url`` helper plus a Sesame name server, a backend-aware ``open_url``, and an ``is_in_situ()`` check, so network access works both natively and in the browser (via a same-origin CORS proxy) - Remember position and size of a window in an MDI workspace after a plugin has been closed and reopened - Plugin updates: PixTable now uses a ``TableView``; fixes to Contents, Errors, FBrowser, Blink (close), WCSAxes, label color, and the startup banner under the ``pg`` backend - Many backend fixes (Qt/Gtk3/Gtk4/pg): font resolution, cell padding, label colors, Gtk4 menu styling and Info-panel label alignment - Fixed application shutdown under Qt6: ``Application.quit()`` now calls ``QApplication.exit()`` instead of ``quit()``. On Qt6, ``quit()`` sends a close event to every top-level window and cancels the shutdown if any window ignores it -- which Ginga's windows do by default -- so ``app.mainloop()`` would never return. Window-close (``'close'``) callbacks are unaffected, so applications can still intervene in a window closing - Added internationalization (i18n) support to the reference viewer: most UI strings, ``build_info`` captions, and plugin/mode help are now translatable through ``ginga.locale``, with a ``Language`` menu to switch and translations provided for German, Japanese, French, Italian, Chinese, Korean and Spanish; the machinery is reusable by downstream applications via ``localize.register()`` - Added two general settings (in ``general.cfg``) to control the UI language: ``language`` selects the language (``None`` honors the environment locale, otherwise a code like ``"ja"``, falling back to English if unavailable), and ``show_languages`` (default ``True``) controls whether the ``Language`` menu is offered in the menubar -- set it to ``False`` to lock down the language while still honoring the ``language`` setting See doc/WhatsNew.rst for a full description of changes
Ginga release v6.0.0
- Added ability to add icons to Ginga-wrapped Button widgets
- Refactored Pan and Header plugins to use new parent/child plugin
implementation
- Fixed an issue with setting filters in Gtk based FileDialogs
- Refactoring of the Control module of the reference viewer to separate viewer
logic from the workspace and plugin management
- You can now set the start attribute for a local plugin in the plugin
spec and it will start when a new channel is created
- New ability to have more than one instance of a global plugin (if enabled)
and more than one instance of a local plugin per channel (if enabled)
- local plugins with this enabled: Pick, Cuts, Histogram, Ruler, Drawing,
PlotTable. Check use of "ident" attribute in the plugin code and setting
singeton=False in the plugin spec
- Added a background to Crosshair text for better readability
- Refactored cursor readout to allow for more flexible ways to override the
default. You can now register a function to the 'pixel-info' callback
on a canvas, and return the information to show in the readout.
- Fixed an issue where there was an unintended fill in drawing a Bezier
curve with the Qt backend
- Improvements to plugins to use the new the plot viewer (event callback
API is changed, thus bump to new major version), but should be backward
compatible aside from event callbacks
- Fix to handling of pan/scroll with touchpads in Qt6
Ginga v5.5.0 - fixed default port number for Ginga remote control in the docstring - fixed an issue with the Pan viewer not redrawing when only the overlay graphics change in the associated channel viewer - fixed an issue where the Preferences plugin did not show the color distribution algorithm that was saved in the channel correctly - Added internal support for dask and zarr arrays - Fixed an issue with the close confirmation dialog under Gtk3 backend - Adds keyboard mode support for the plot viewer - Adds thumbnails for plot and table viewer items - Fixed a mouse scrolling issue for Gtk4 backend - Fixed an issue where the thumbnail labels were not highlighted correctly in the Thumbs plugin
Ver 5.4.0 (2025-08-10) - Wrapped widget enhancements - added methods and callbacks for expansion and collapse of rows in TreeView - ability to set color of Button widgets - add ColorDialog, a color selection dialog - add FileDialog, a file/directory dialog (can replace FileSelection) - fixed an issue with custom styling being inherited unnecessarily - Fixed a bug where FITS loader preference on command line options or configuration file was not working - Add ability to dynamically reload separately distributed plugins using the Command plugin (with reload_local or reload_global commands) - Changed default port for Remote Control plugin and made a command line switch (--rcport) to allow launch time changing of the port - Fixed an spurious error when closing Ginga after shutting down the RC plugin manually - A fix for the Tk widget on Windows and Mac OSX to allow proper scrolling - Better formatting of cuts and plot limits (limit excessive decimals) - Fixed an error in reference viewer with detection of Gtk toolkits - Gtk4 backend support is much improved - Enhancements to the thread pool, with dynamic adding of threads when busy and stopping of threads when they have been idle
Ginga v5.3.0 - Fixed an issue with editing objects in the Pick plugin - Fixed an issue where image metadata not always loaded correctly with Pillow for RGB images - Added support for Apple HEIF (.HEIC) RGB images if pillow-heif is installed - Fixed an issue with circular import of loader entry points under python 3.12 - Updates of minimum required versions of support packages
Ginga version v5.2.0
- Substituted puremagic package for python-magic (works better across
platforms).
- Fixed an issue with the mouse wheel event scrolling MDI workspaces.
- Fixed a spurious warning when moving the cursor in the Pan plugin
window and a table or plot viewer is running in the channel
- Made the enter_focus property default to False
- Viewer windows will not steal the keyboard focus if the mouse moves
over them
- Added alternate versions of installed fonts to the default font set
(bold, italic, light)
- Some minor bug fixes for TreeView in Gtk3 backend
- Enhanced Plot viewer can plot 1D images or from tables via Table viewer
- Toolbar and Info (Synopsis) bars change GUIs according to which
viewer is active in the channel
- Text canvas type gets new attributes: bgcolor, bgalpha, bordercolor,
borderpadding, borderalpha, borderlinewidth
- Deprecate Gtk.Table from GTK3 backend (switch to Gtk.Grid)
- Added experimental support for GTK4 backend
- Fixed an issue with toggling CheckBoxes in Qt6
- Closing a workspace now doesn't require closing all windows first
Ginga v5.1.0
- Fixed an issue where --modules option did not start a global plugin
automatically
- Improved error checking on contains_pts() method for canvas items
- Removed references to distutils module, deprecated in python 3.12
- Made menubar a plugin; this allows very flexible menu configuration
for users implementing their own variations on the reference viewer;
NOTE: if you don't see Ginga menus, delete your $HOME/.ginga/layout*
- Added default antialiasing to cairo renderer
- Fixed drawing of dimension labels for rectangles specified in WCS
coordinates
- Fixed drawing of Crosshair canvas object in opengl backend
- Fixed drawing of XRange and YRange in non-data coordinates
- Refactoring of rendering primitives; simplifies renderer implementation
- "Text" objects now have linewidth (default: 0), fill (default: True),
fillcolor (default: None) and fillalpha (default: 1.0) attributes.
Default behavior if fillcolor isn't specified is to default to the
"color" attribute, thus preserving backward-compatible behavior.
- Fixed broken WCS compass in Pan plugin
- Fixed broken Close button in FBrowser and ColorMapPicker when activated
as global plugins
- Fixed a bug in PixTable plugin where it would report a table for X and Y
values outside the image
- Fixed bokeh back end to be up to date with recent bokeh changes
PreviousNext