Skip to content

Commit

Permalink
Add a PluginConfig plugin (UI to manage other plugins)
Browse files Browse the repository at this point in the history
This adds a global plugin called "PluginConfig" which can be used to easily
manage which plugins are enabled/disabled for the Ginga reference viewer.
Additionally, it allows the user to configure how the plugins appear under
the menus.

Documentation has been added to the manual.
  • Loading branch information
ejeschke committed Jan 11, 2024
1 parent 7836c0f commit ba42250
Show file tree
Hide file tree
Showing 15 changed files with 472 additions and 99 deletions.
2 changes: 2 additions & 0 deletions doc/WhatsNew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Ver 5.0.0 (unreleased)
various MIME types
- Fixed an issue with the "none-move" event, affected Crosshair plugin
and "hover" event on canvas items
- Added PluginConfig plugin; allows configuration of all Ginga plugins
graphically; can enable/disable, change menu categories, etc.

Ver 4.1.0 (2022-06-30)
======================
Expand Down
2 changes: 1 addition & 1 deletion doc/dev_manual/modes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,5 @@ callback.

.. note:: To see what attributes are available in each event, see the
``KeyEvent``, ``PointEvent``, ``ScrollEvent``, ``PanEvent``, and
``PinchEvent`` in the :ref:`api` (look under `ginga.Bindings`).
``PinchEvent`` in the :ref:`api` (look under `ginga.events`).

1 change: 1 addition & 0 deletions doc/manual/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Global plugins
plugins_global/saveimage
plugins_global/downloads
plugins_global/loaderconfig
plugins_global/pluginconfig


.. _sec-localplugins:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions doc/manual/plugins_global/pluginconfig.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.. _sec-plugins-PluginConfig:

PluginConfig
============

.. image:: figures/pluginconfig-plugin.png
:align: center
:width: 1024px
:alt: PluginConfig plugin

.. automodapi:: ginga.rv.plugins.PluginConfig
:no-heading:
:skip: PluginConfig
3 changes: 3 additions & 0 deletions doc/ref_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Reference/API
.. automodapi:: ginga.Bindings
:no-inheritance-diagram:

.. automodapi:: ginga.events
:no-inheritance-diagram:

.. automodapi:: ginga.rv.main
:no-inheritance-diagram:

Expand Down
9 changes: 5 additions & 4 deletions ginga/examples/configs/general.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,13 @@ channel_prefix = "Image"
# temp directory (as defined by Python's 'tempfile' module)
#download_folder = None

# Name of a layout file to configure the GUI
layout_file = 'layout.json'

# Name of a file to configure the set of available plugins and where they
# should appear
plugin_file = 'plugins.json'
plugin_file = 'plugins.yml'

# Name of a file to configure the set of available loaders and which has
# priority
loader_file = 'loaders.yml'

# Confirm program exits with a dialog?
confirm_shutdown = True
20 changes: 9 additions & 11 deletions ginga/gw/Desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import math
import os.path

import yaml

from ginga.misc import Bunch, Callback
from ginga.gw import Widgets, Viewers
from ginga.util import json
Expand Down Expand Up @@ -696,28 +698,24 @@ def write_layout_conf(self, lo_file, layout=None):

self.record_sizes()

_n, ext = os.path.splitext(lo_file)
# write layout
_n, ext = os.path.splitext(lo_file)
with open(lo_file, 'w') as out_f:
if ext.lower() == '.json':
out_f.write(json.dumps(layout, indent=2))
if ext.lower() in ['.yml', '.yaml']:
out_f.write(yaml.dump(layout, indent=2))
else:
# older, python format
import pprint
pprint.pprint(layout, out_f)
out_f.write(json.dumps(layout, indent=2))

def read_layout_conf(self, lo_file):
# read layout
with open(lo_file, 'r') as in_f:
buf = in_f.read()

_n, ext = os.path.splitext(lo_file)
if ext.lower() == '.json':
layout = json.loads(buf)
if ext.lower() in ['.yml', '.yaml']:
layout = yaml.safe_load(buf)
else:
# older, python format
import ast
layout = ast.literal_eval(buf)
layout = json.loads(buf)
return layout

def build_desktop(self, layout, lo_file=None, widget_dict=None):
Expand Down
2 changes: 2 additions & 0 deletions ginga/gw/PluginManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def __init__(self, logger, gshell, ds, mm):
self.enable_callback(name)

def load_plugin(self, name, spec, chinfo=None):
if not spec.get('enabled', True):
return
try:
module = self.mm.get_module(spec.module)
className = spec.get('klass', spec.module)
Expand Down
10 changes: 6 additions & 4 deletions ginga/rv/Control.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,9 @@ def add_local_plugin(self, spec):

pfx = spec.get('pfx', pluginconfpfx)
path = spec.get('path', None)
self.mm.load_module(spec.module, pfx=pfx, path=path)
self.plugins.append(spec)
if spec.get('enabled', True):
self.mm.load_module(spec.module, pfx=pfx, path=path)

except Exception as e:
self.logger.error("Unable to load local plugin '%s': %s" % (
Expand All @@ -342,8 +343,9 @@ def add_global_plugin(self, spec):

pfx = spec.get('pfx', pluginconfpfx)
path = spec.get('path', None)
self.mm.load_module(spec.module, pfx=pfx, path=path)
self.plugins.append(spec)
if spec.get('enabled', True):
self.mm.load_module(spec.module, pfx=pfx, path=path)

self.gpmon.load_plugin(name, spec)

Expand All @@ -352,8 +354,6 @@ def add_global_plugin(self, spec):
name, str(e)))

def add_plugin(self, spec):
if not spec.get('enabled', True):
return
ptype = spec.get('ptype', 'local')
if ptype == 'global':
self.add_global_plugin(spec)
Expand Down Expand Up @@ -1774,6 +1774,8 @@ def add_plugin_menu(self, name, spec):
# NOTE: self.w.menu_plug is a ginga.Widgets wrapper
if 'menu_plug' not in self.w:
return
if not spec.get('enabled', True):
return
category = spec.get('category', None)
categories = None
if category is not None:
Expand Down
Loading

0 comments on commit ba42250

Please sign in to comment.