class LayerArtist(LayerArtistBase): zorder = CallbackProperty() visible = CallbackProperty() _layer_state_cls = LayerState def __init__(self, viewer_state, layer_state=None, layer=None): super(LayerArtist, self).__init__(layer) self._viewer_state = viewer_state self.layer = layer or layer_state.layer self.state = layer_state or self._layer_state_cls( viewer_state=viewer_state, layer=self.layer) if self.state not in self._viewer_state.layers: self._viewer_state.layers.append(self.state) self.zorder = self.state.zorder self.visible = self.state.visible self._sync_zorder = keep_in_sync(self, 'zorder', self.state, 'zorder') self._sync_visible = keep_in_sync(self, 'visible', self.state, 'visible') def __gluestate__(self, context): return dict(state=context.id(self.state))
class SpecvizLayerState(LayerState): """ """ color = CallbackProperty(docstring='The color used to display the data') alpha = CallbackProperty(docstring='The transparency used to display the data') linewidth = CallbackProperty(1, docstring='The width of the line for the data') attribute = SelectionCallbackProperty(docstring='The attribute to use for the spectrum') statistic = SelectionCallbackProperty(docstring='The statistic to use to collapse data') def __init__(self, viewer_state=None, **kwargs): super(SpecvizLayerState, self).__init__(viewer_state=viewer_state, **kwargs) self.color = self.layer.style.color self.alpha = self.layer.style.alpha self._sync_color = keep_in_sync(self, 'color', self.layer.style, 'color') self._sync_alpha = keep_in_sync(self, 'alpha', self.layer.style, 'alpha') self._att_helper = ComponentIDComboHelper(self, 'attribute') self.add_callback('layer', self._on_layer_change) self._on_layer_change() SpecvizLayerState.statistic.set_choices(self, list(FUNCTIONS)) SpecvizLayerState.statistic.set_display_func(self, FUNCTIONS.get) def _on_layer_change(self, *args): if self.layer is None: self._att_helper.set_multiple_data([]) else: self._att_helper.set_multiple_data([self.layer])
class LayerState(State): """ A base class for all layer states. """ layer = CallbackProperty(docstring='The :class:`~glue.core.data.Data` or ' ':class:`~glue.core.subset.Subset` ' 'represented by the layer') zorder = CallbackProperty(0, docstring='A value used to indicate which ' 'layers are shown in front of which ' '(larger zorder values are on top of ' 'other layers)') visible = CallbackProperty( True, docstring='Whether the layer is currently visible') def __init__(self, viewer_state=None, **kwargs): super(LayerState, self).__init__(**kwargs) self.viewer_state = viewer_state def __repr__(self): if self.layer is None: return "%s with layer unset" % (self.__class__.__name__) else: return "%s for %s" % (self.__class__.__name__, self.layer.label)
class SubsetFacetState(State): log = CallbackProperty(False) v_min = CallbackProperty(0.) v_max = CallbackProperty(1.) steps = CallbackProperty(5) data = SelectionCallbackProperty() att = SelectionCallbackProperty() cmap = CallbackProperty() def __init__(self, data_collection): super(SubsetFacetState, self).__init__() self.data_helper = DataCollectionComboHelper(self, 'data', data_collection) self.att_helper = ComponentIDComboHelper(self, 'att') self.lim_helper = StateAttributeLimitsHelper(self, attribute='att', lower='v_min', upper='v_max', log='log') self.add_callback('data', self._on_data_change) self._on_data_change() def _on_data_change(self, *args, **kwargs): self.att_helper.set_multiple_data( [] if self.data is None else [self.data])
class LayerArtist(LayerArtistBase): zorder = CallbackProperty() visible = CallbackProperty() _layer_state_cls = LayerState def __init__(self, viewer_state, layer_state=None, layer=None): super(LayerArtist, self).__init__(layer) self._viewer_state = viewer_state self.layer = layer or layer_state.layer self.state = layer_state or self._layer_state_cls( viewer_state=viewer_state, layer=self.layer) if self.state not in self._viewer_state.layers: self._viewer_state.layers.append(self.state) self.zorder = self.state.zorder self.visible = self.state.visible self._sync_zorder = keep_in_sync(self, 'zorder', self.state, 'zorder') self._sync_visible = keep_in_sync(self, 'visible', self.state, 'visible') self.state.add_callback('visible', self._on_visibility_change) def _on_visibility_change(self, *args): if self.state.layer is not None and self.state.layer.hub is not None: self.state.layer.hub.broadcast(LayerArtistVisibilityMessage(self)) def __gluestate__(self, context): return dict(state=context.id(self.state))
class SimpleState(State): layer = CallbackProperty() comp = CallbackProperty() x_min = CallbackProperty() x_max = CallbackProperty() n_bin = CallbackProperty()
class AladinLiteLayerState(State): layer = CallbackProperty() visible = CallbackProperty(True) zorder = CallbackProperty(0) color = CallbackProperty() alpha = CallbackProperty() def __init__(self, **kwargs): super(AladinLiteLayerState, self).__init__(**kwargs) self._sync_color = None self._sync_alpha = None self.add_callback('layer', self._layer_changed) self._layer_changed() def _layer_changed(self): if self._sync_color is not None: self._sync_color.stop_syncing() if self._sync_alpha is not None: self._sync_alpha.stop_syncing() if self.layer is not None: self.color = self.layer.style.color self.alpha = self.layer.style.alpha self._sync_color = keep_in_sync(self, 'color', self.layer.style, 'color') self._sync_alpha = keep_in_sync(self, 'alpha', self.layer.style, 'alpha')
class SimpleState(State): layer = CallbackProperty() comp = CallbackProperty() lower = CallbackProperty() upper = CallbackProperty() scale = CallbackProperty()
class RangeModeState(State): x_min = CallbackProperty(None) x_max = CallbackProperty(None) @property def x_range(self): return self.x_min, self.x_max
class WWTDataViewerState(State): foreground = SelectionCallbackProperty(default_index=0) background = SelectionCallbackProperty(default_index=1) foreground_opacity = CallbackProperty(50) galactic = CallbackProperty(False) layers = ListCallbackProperty() def __init__(self, **kwargs): super(WWTDataViewerState, self).__init__() self.add_callback('layers', self._sync_all_attributes) self.update_from_dict(kwargs) def set_imagery_layers(self, imagery_layers): WWTDataViewerState.foreground.set_choices(self, imagery_layers) WWTDataViewerState.background.set_choices(self, imagery_layers) def _sync_attributes_single(self, reference, layer_state): with delay_callback(layer_state, 'ra_att', 'dec_att'): layer_state.ra_att = reference.ra_att layer_state.dec_att = reference.dec_att def _sync_all_attributes(self, layers=None, reference=None): # Make sure attributes are in sync between datasets and subsets if reference is None: data_layers = [ layer for layer in self.layers if isinstance(layer, Data) ] subset_layers = [ layer for layer in self.layers if isinstance(layer, Subset) ] for data_layer in data_layers: for subset_layer in subset_layers: self._sync_attributes_single(data_layer, subset_layer) elif isinstance(reference.layer, Data): reference_data = reference.layer for layer_state in self.layers: if isinstance( layer_state.layer, Subset) and layer_state.layer.data is reference.layer: self._sync_attributes_single(reference, layer_state) elif isinstance(reference.layer, Subset): reference_data = reference.layer.data for layer_state in self.layers: if isinstance(layer_state.layer, Data) and layer_state.layer is reference_data: self._sync_attributes_single(reference, layer_state) elif isinstance( layer_state.layer, Subset) and layer_state.layer.data is reference_data: self._sync_attributes_single(reference, layer_state)
class VolumeLayerState(VispyLayerState): """ A state object for volume layers """ attribute = SelectionCallbackProperty() vmin = CallbackProperty() vmax = CallbackProperty() subset_mode = CallbackProperty('data') limits_cache = CallbackProperty({}) def __init__(self, layer=None, **kwargs): super(VolumeLayerState, self).__init__(layer=layer) if self.layer is not None: self.color = self.layer.style.color self.alpha = self.layer.style.alpha self.att_helper = ComponentIDComboHelper(self, 'attribute') self.lim_helper = StateAttributeLimitsHelper(self, attribute='attribute', lower='vmin', upper='vmax', cache=self.limits_cache) self.add_callback('layer', self._on_layer_change) if layer is not None: self._on_layer_change() if isinstance(self.layer, Subset): self.vmin = 0 self.lim_helper.lower_frozen = True self.update_from_dict(kwargs) def _on_layer_change(self, layer=None): with delay_callback(self, 'vmin', 'vmin'): if self.layer is None: self.att_helper.set_multiple_data([]) else: self.att_helper.set_multiple_data([self.layer]) def update_priority(self, name): return 0 if name.endswith(('vmin', 'vmax')) else 1
class Vispy3DVolumeViewerState(Vispy3DViewerState): downsample = CallbackProperty(True) def __init__(self, **kwargs): super(Vispy3DVolumeViewerState, self).__init__() self.add_callback('layers', self._update_attributes) self.update_from_dict(kwargs) def _update_attributes(self, *args): for layer_state in self.layers: if getattr(layer_state.layer, 'ndim', None) == 3: data = layer_state.layer break else: data = None if data is None: type(self).x_att.set_choices(self, []) type(self).y_att.set_choices(self, []) type(self).z_att.set_choices(self, []) else: z_cid, y_cid, x_cid = data.pixel_component_ids type(self).x_att.set_choices(self, [x_cid]) type(self).y_att.set_choices(self, [y_cid]) type(self).z_att.set_choices(self, [z_cid])
class OpenSpaceLayerState(LayerState): layer = CallbackProperty() color = CallbackProperty() size = CallbackProperty() alpha = CallbackProperty() size_mode = SelectionCallbackProperty(default_index=0) color_mode = SelectionCallbackProperty(default_index=0) cmap_mode = color_mode def __init__(self, layer=None, **kwargs): self._sync_markersize = None super(OpenSpaceLayerState, self).__init__(layer=layer) self._sync_color = keep_in_sync(self, 'color', self.layer.style, 'color') self._sync_alpha = keep_in_sync(self, 'alpha', self.layer.style, 'alpha') self._sync_size = keep_in_sync(self, 'size', self.layer.style, 'markersize') self.color = self.layer.style.color self.size = self.layer.style.markersize self.alpha = self.layer.style.alpha OpenSpaceLayerState.color_mode.set_choices(self, ['Fixed']) OpenSpaceLayerState.size_mode.set_choices(self, ['Fixed']) self.update_from_dict(kwargs) def _layer_changed(self): super(OpenSpaceLayerState, self)._layer_changed() if self._sync_markersize is not None: self._sync_markersize.stop_syncing() if self.layer is not None: self.size = self.layer.style.markersize self._sync_markersize = keep_in_sync(self, 'size', self.layer.style, 'markersize')
class IsosurfaceLayerState(VispyLayerState): """ A state object for volume layers """ attribute = SelectionCallbackProperty() level_low = CallbackProperty() level_high = CallbackProperty() cmap = CallbackProperty() step = CallbackProperty(4) level_cache = CallbackProperty({}) def __init__(self, layer=None, **kwargs): super(IsosurfaceLayerState, self).__init__(layer=layer) self.att_helper = ComponentIDComboHelper(self, 'attribute') self.lim_helper = StateAttributeLimitsHelper(self, attribute='attribute', lower='level_low', upper='level_high') self.add_callback('layer', self._on_layer_change) if layer is not None: self._on_layer_change() self.cmap = colormaps.members[0][1] self.update_from_dict(kwargs) def _on_layer_change(self, layer=None): with delay_callback(self, 'level_low', 'level_high'): if self.layer is None: self.att_helper.set_multiple_data([]) else: self.att_helper.set_multiple_data([self.layer]) def update_priority(self, name): return 0 if name == 'level' else 1
class VispyLayerState(State): """ A base state object for all Vispy layers """ layer = CallbackProperty() visible = CallbackProperty(True) zorder = CallbackProperty(0) color = CallbackProperty() alpha = CallbackProperty() def __init__(self, **kwargs): super(VispyLayerState, self).__init__(**kwargs) self._sync_color = None self._sync_alpha = None self.add_callback('layer', self._layer_changed) self._layer_changed() self.add_global_callback(self._notify_layer_update) def _notify_layer_update(self, **kwargs): message = LayerArtistUpdatedMessage(self) if self.layer is not None and self.layer.hub is not None: self.layer.hub.broadcast(message) def _layer_changed(self): if self._sync_color is not None: self._sync_color.stop_syncing() if self._sync_alpha is not None: self._sync_alpha.stop_syncing() if self.layer is not None: self.color = self.layer.style.color self.alpha = self.layer.style.alpha self._sync_color = keep_in_sync(self, 'color', self.layer.style, 'color') self._sync_alpha = keep_in_sync(self, 'alpha', self.layer.style, 'alpha')
class WWTImageLayerState(LayerState): """A state object for WWT image layers """ layer = CallbackProperty() color = CallbackProperty() alpha = CallbackProperty() vmin = CallbackProperty() vmax = CallbackProperty() img_data_att = SelectionCallbackProperty(default_index=0) stretch = SelectionCallbackProperty( default_index=0, choices=VALID_STRETCHES ) def __init__(self, layer=None, **kwargs): super(WWTImageLayerState, self).__init__(layer=layer) self._sync_color = keep_in_sync(self, 'color', self.layer.style, 'color') self._sync_alpha = keep_in_sync(self, 'alpha', self.layer.style, 'alpha') self.color = self.layer.style.color self.img_data_att_helper = ComponentIDComboHelper(self, 'img_data_att', numeric=True, categorical=False) self.add_callback('layer', self._on_layer_change) if layer is not None: self._on_layer_change() self.update_from_dict(kwargs) def _on_layer_change(self, layer=None): if self.layer is None: self.img_data_att_helper.set_multiple_data([]) else: self.img_data_att_helper.set_multiple_data([self.layer]) def update_priority(self, name): return 0 if name.endswith(('vmin', 'vmax')) else 1
class Vispy3DVolumeViewerState(Vispy3DViewerState): downsample = CallbackProperty(True) resolution = SelectionCallbackProperty(4) def __init__(self, **kwargs): super(Vispy3DVolumeViewerState, self).__init__() self.add_callback('layers', self._update_attributes) Vispy3DVolumeViewerState.resolution.set_choices(self, [2**i for i in range(4, 12)]) self.update_from_dict(kwargs) def _first_3d_data(self): for layer_state in self.layers: if getattr(layer_state.layer, 'ndim', None) == 3: return layer_state.layer def _update_attributes(self, *args): data = self._first_3d_data() if data is None: type(self).x_att.set_choices(self, []) type(self).y_att.set_choices(self, []) type(self).z_att.set_choices(self, []) else: z_cid, y_cid, x_cid = data.pixel_component_ids type(self).x_att.set_choices(self, [x_cid]) type(self).y_att.set_choices(self, [y_cid]) type(self).z_att.set_choices(self, [z_cid]) @property def clip_limits_relative(self): data = self._first_3d_data() if data is None: return [0., 1., 0., 1., 0., 1.] else: nz, ny, nx = data.shape return (self.x_min / nx, self.x_max / nx, self.y_min / ny, self.y_max / ny, self.z_min / nz, self.z_max / nz)
class SimpleState(State): layer = CallbackProperty() comp = CallbackProperty() lower = CallbackProperty() upper = CallbackProperty() percentile = CallbackProperty() log = CallbackProperty()
class TestState(object): layer = CallbackProperty() comp = CallbackProperty(1) lower = CallbackProperty() higher = CallbackProperty() log = CallbackProperty() scale = CallbackProperty()
def ui_and_state(self): if len(self.params) == 3: default = self.params[2] else: default = 0.5 * (self.params[0] + self.params[1]) # We can't initialize QLabeledSlider yet because this could get called # before the Qt application has been initialized. So for now we just make # a subclass of QLabeledSlider with the range we need class CustomSlider(QLabeledSlider): range = self.params[:2] integer = isinstance(self.params[0], int) and isinstance( self.params[1], int) return 'value_', CustomSlider, CallbackProperty(default)
class Scatter3DLayerState(ScatterLayerState): # FIXME: the following should be a SelectionCallbackProperty geo = CallbackProperty('sphere', docstring="Type of marker") vz_att = SelectionCallbackProperty(docstring="The attribute to use for the z vector arrow") def __init__(self, viewer_state=None, layer=None, **kwargs): self.vz_att_helper = ComponentIDComboHelper(self, 'vz_att', numeric=True, categorical=False) super(Scatter3DLayerState, self).__init__(viewer_state=viewer_state, layer=layer) # self.update_from_dict(kwargs) def _on_layer_change(self, layer=None): super(Scatter3DLayerState, self)._on_layer_change(layer=layer) if self.layer is None: self.vz_att_helper.set_multiple_data([]) else: self.vz_att_helper.set_multiple_data([self.layer])
class TutorialLayerState(MatplotlibLayerState): # cmap is stuff used for colormap linewidth = CallbackProperty(1, docstring='line width') cmap_mode = DDSCProperty( docstring="Whether to use color to encode an attribute") cmap_att = DDSCProperty(docstring="The attribute to use for the color") cmap_vmin = DDCProperty(docstring="The lower level for the colormap") cmap_vmax = DDCProperty(docstring="The upper level for the colormap") cmap = DDCProperty(docstring="The colormap to use (when in colormap mode)") def __init__(self, viewer_state=None, layer=None, **kwargs): super(TutorialLayerState, self).__init__(viewer_state=viewer_state, layer=layer) # set choices basically poplutes drop down menus TutorialLayerState.cmap_mode.set_choices(self, ['Fixed', 'Linear']) self.cmap_att_helper = ComponentIDComboHelper(self, 'cmap_att', numeric=True, categorical=False) self.add_callback('layer', self._on_layers_change) # kind of initializing. not having this line # made errors for cmap initialization- didn't pull # up linear part # thanks tom self._on_layers_change() def _on_layers_change(self, layer=None): # not exactly sure of this with delay_callback(self, 'cmap_vmin', 'cmap_vmax'): self.cmap_att_helper.set_multiple_data([self.layer]) # not having this line threw None resulting in an error- can't # iterate over None.... # this initializes some colormap # thanks tom self.cmap = colormaps.members[0][1]
class VolumeLayerState(VolumeLayerState): opacity_scale = CallbackProperty() render_method = CallbackProperty() lighting = CallbackProperty() max_resolution = CallbackProperty() clamp_min = CallbackProperty() clamp_max = CallbackProperty() # attribute = SelectionCallbackProperty() data_min = CallbackProperty(0) data_max = CallbackProperty(1) def __init__(self, layer=None, **kwargs): super(VolumeLayerState, self).__init__(layer=layer, **kwargs) self.opacity_scale = 0.1 self.render_method = 'NORMAL' self.lighting = True self.max_resolution = 256 self.clamp_min = False self.clamp_max = False
class ViewerState3D(ViewerState): """ A common state object for all 3D viewers """ x_att = SelectionCallbackProperty() x_min = CallbackProperty(0) x_max = CallbackProperty(1) # x_stretch = CallbackProperty(1.) y_att = SelectionCallbackProperty(default_index=1) y_min = CallbackProperty(0) y_max = CallbackProperty(1) # y_stretch = CallbackProperty(1.) z_att = SelectionCallbackProperty(default_index=2) z_min = CallbackProperty(0) z_max = CallbackProperty(1) # z_stretch = CallbackProperty(1.) visible_axes = CallbackProperty(True) # perspective_view = CallbackProperty(False) # clip_data = CallbackProperty(False) # native_aspect = CallbackProperty(False) limits_cache = CallbackProperty() # def _update_priority(self, name): # if name == 'layers': # return 2 # elif name.endswith(('_min', '_max')): # return 0 # else: # return 1 def __init__(self, **kwargs): super(ViewerState3D, self).__init__(**kwargs) if self.limits_cache is None: self.limits_cache = {} self.x_lim_helper = StateAttributeLimitsHelper(self, attribute='x_att', lower='x_min', upper='x_max', cache=self.limits_cache) self.y_lim_helper = StateAttributeLimitsHelper(self, attribute='y_att', lower='y_min', upper='y_max', cache=self.limits_cache) self.z_lim_helper = StateAttributeLimitsHelper(self, attribute='z_att', lower='z_min', upper='z_max', cache=self.limits_cache) # TODO: if limits_cache is re-assigned to a different object, we need to # update the attribute helpers. However if in future we make limits_cache # into a smart dictionary that can call callbacks when elements are # changed then we shouldn't always call this. It'd also be nice to # avoid this altogether and make it more clean. self.add_callback('limits_cache', nonpartial(self._update_limits_cache)) def _update_limits_cache(self): self.x_lim_helper._cache = self.limits_cache self.x_lim_helper._update_attribute() self.y_lim_helper._cache = self.limits_cache self.y_lim_helper._update_attribute() self.z_lim_helper._cache = self.limits_cache self.z_lim_helper._update_attribute() # @property # def aspect(self): # # TODO: this could be cached based on the limits, but is not urgent # aspect = np.array([1, 1, 1], dtype=float) # if self.native_aspect: # aspect[0] = 1. # aspect[1] = (self.y_max - self.y_min) / (self.x_max - self.x_min) # aspect[2] = (self.z_max - self.z_min) / (self.x_max - self.x_min) # aspect /= aspect.max() # return aspect # def reset(self): # pass def flip_x(self): self.x_lim_helper.flip_limits() def flip_y(self): self.y_lim_helper.flip_limits() def flip_z(self): self.z_lim_helper.flip_limits()
class DatetimeState(State): a = CallbackProperty()
class LayerArtist(object): layer = Layer() size_mode = CallbackProperty(None) size = CallbackProperty() size_attribute = CallbackProperty() size_vmin = CallbackProperty() size_vmax = CallbackProperty() size_scaling = CallbackProperty() color_mode = CallbackProperty(None) color = CallbackProperty() cmap_attribute = CallbackProperty() cmap_vmin = CallbackProperty() cmap_vmax = CallbackProperty() cmap = CallbackProperty() alpha = CallbackProperty()
class SimpleState(State): layer = CallbackProperty() comp = CallbackProperty() val = CallbackProperty()
class SimpleTestState(State): a = CallbackProperty() b = CallbackProperty() flat = ListCallbackProperty() nested = ListCallbackProperty()
class Vispy3DVolumeViewerState(Vispy3DViewerState): downsample = CallbackProperty(True) resolution = SelectionCallbackProperty(4) reference_data = SelectionCallbackProperty( docstring='The dataset that is used to define the ' 'available pixel/world components, and ' 'which defines the coordinate frame in ' 'which the images are shown') def __init__(self, **kwargs): super(Vispy3DVolumeViewerState, self).__init__() self.ref_data_helper = ManualDataComboHelper(self, 'reference_data') self.add_callback('layers', self._layers_changed) Vispy3DVolumeViewerState.resolution.set_choices( self, [2**i for i in range(4, 12)]) self.update_from_dict(kwargs) def _first_3d_data(self): for layer_state in self.layers: if getattr(layer_state.layer, 'ndim', None) == 3: return layer_state.layer def _layers_changed(self, *args): self._update_combo_ref_data() self._set_reference_data() self._update_attributes() def _update_combo_ref_data(self, *args): self.ref_data_helper.set_multiple_data(self.layers_data) def _set_reference_data(self, *args): if self.reference_data is None: for layer in self.layers: if isinstance(layer.layer, BaseData): self.reference_data = layer.layer return def _update_attributes(self, *args): data = self._first_3d_data() if data is None: type(self).x_att.set_choices(self, []) type(self).y_att.set_choices(self, []) type(self).z_att.set_choices(self, []) else: z_cid, y_cid, x_cid = data.pixel_component_ids type(self).x_att.set_choices(self, [x_cid]) type(self).y_att.set_choices(self, [y_cid]) type(self).z_att.set_choices(self, [z_cid]) @property def clip_limits_relative(self): data = self._first_3d_data() if data is None: return [0., 1., 0., 1., 0., 1.] else: nz, ny, nx = data.shape return (self.x_min / nx, self.x_max / nx, self.y_min / ny, self.y_max / ny, self.z_min / nz, self.z_max / nz)
class WWTTableLayerState(LayerState): """ A state object for WWT layers """ layer = CallbackProperty() color = CallbackProperty() size = CallbackProperty() alpha = CallbackProperty() size_mode = SelectionCallbackProperty(default_index=0) size = CallbackProperty() size_att = SelectionCallbackProperty() size_vmin = CallbackProperty() size_vmax = CallbackProperty() size_scaling = CallbackProperty(1) color_mode = SelectionCallbackProperty(default_index=0) cmap_att = SelectionCallbackProperty() cmap_vmin = CallbackProperty() cmap_vmax = CallbackProperty() cmap = CallbackProperty() cmap_mode = color_mode size_limits_cache = CallbackProperty({}) cmap_limits_cache = CallbackProperty({}) img_data_att = SelectionCallbackProperty(default_index=0) def __init__(self, layer=None, **kwargs): self._sync_markersize = None super(WWTTableLayerState, self).__init__(layer=layer) self._sync_color = keep_in_sync(self, 'color', self.layer.style, 'color') self._sync_alpha = keep_in_sync(self, 'alpha', self.layer.style, 'alpha') self._sync_size = keep_in_sync(self, 'size', self.layer.style, 'markersize') self.color = self.layer.style.color self.size = self.layer.style.markersize self.alpha = self.layer.style.alpha self.size_att_helper = ComponentIDComboHelper(self, 'size_att', numeric=True, categorical=False) self.cmap_att_helper = ComponentIDComboHelper(self, 'cmap_att', numeric=True, categorical=False) self.img_data_att_helper = ComponentIDComboHelper(self, 'img_data_att', numeric=True, categorical=False) self.size_lim_helper = StateAttributeLimitsHelper( self, attribute='size_att', lower='size_vmin', upper='size_vmax', cache=self.size_limits_cache) self.cmap_lim_helper = StateAttributeLimitsHelper( self, attribute='cmap_att', lower='cmap_vmin', upper='cmap_vmax', cache=self.cmap_limits_cache) self.add_callback('layer', self._on_layer_change) if layer is not None: self._on_layer_change() self.cmap = colormaps.members[0][1] # Color and size encoding depending on attributes is only available # in PyWWT 0.6 or later. if PYWWT_LT_06: modes = ['Fixed'] else: modes = ['Fixed', 'Linear'] WWTTableLayerState.color_mode.set_choices(self, modes) WWTTableLayerState.size_mode.set_choices(self, modes) self.update_from_dict(kwargs) def _on_layer_change(self, layer=None): with delay_callback(self, 'cmap_vmin', 'cmap_vmax', 'size_vmin', 'size_vmax'): if self.layer is None: self.cmap_att_helper.set_multiple_data([]) self.size_att_helper.set_multiple_data([]) self.img_data_att_helper.set_multiple_data([]) else: self.cmap_att_helper.set_multiple_data([self.layer]) self.size_att_helper.set_multiple_data([self.layer]) self.img_data_att_helper.set_multiple_data([self.layer]) def update_priority(self, name): return 0 if name.endswith(('vmin', 'vmax')) else 1 def _layer_changed(self): super(WWTTableLayerState, self)._layer_changed() if self._sync_markersize is not None: self._sync_markersize.stop_syncing() if self.layer is not None: self.size = self.layer.style.markersize self._sync_markersize = keep_in_sync(self, 'size', self.layer.style, 'markersize') def flip_size(self): self.size_lim_helper.flip_limits() def flip_cmap(self): self.cmap_lim_helper.flip_limits()