예제 #1
0
    def PostInit(self):
        try:
            self.sizer = wx.BoxSizer(wx.VERTICAL)
            self._tool_bar = wx.aui.AuiToolBar(self)
            self.sizer.Add(self._tool_bar, 0, flag=wx.TOP | wx.EXPAND)
            #     
            UIM = UIManager()
            canvas_controller = UIM.create('canvas_plotter_controller',
                                           self._controller_uid
                                           )
            #

            self._main_panel = canvas_controller.view
            # TODO: Keep this conection? (must be disconected at PreDelete??)
            #            self._main_panel.mpl_connect('motion_notify_event', 
            #                                                     self.on_canvas_mouse_move)
            self.sizer.Add(self._main_panel, 1, flag=wx.EXPAND)
            #
            self._status_bar = PlotStatusBar(self)
            self.sizer.Add(self._status_bar, 0, flag=wx.BOTTOM | wx.EXPAND)
            self.SetSizer(self.sizer)
            #
            self._build_tool_bar()
            self.Layout()
        except Exception as e:
            print('ERROR IN CrossPlot.PostInit:', e)
            raise
예제 #2
0
 def __init__(self, controller_uid):
     super().__init__(controller_uid)
     # Top
     self.sizer = wx.BoxSizer(wx.VERTICAL)
     self._tool_bar = wx.aui.AuiToolBar(self)
     self.sizer.Add(self._tool_bar, 0, flag=wx.TOP | wx.EXPAND)
     # Center
     self._main_panel = wx.Panel(self)
     self.sizer.Add(self._main_panel, 1, flag=wx.EXPAND)
     # Bottom
     self._status_bar = PlotStatusBar(self)
     self.sizer.Add(self._status_bar, 0, flag=wx.BOTTOM | wx.EXPAND)
     self.SetSizer(self.sizer)
     #
     # Then, let's construct our ToolBar
     self._build_tool_bar()
     #
     # Main panel is subdivided into a Tracks panel on left side and
     # a Overview panel in right side. The last one is used as a 'ruler' to
     # guide data navigation (zoom in and  zoom out).
     self._hbox = wx.BoxSizer(wx.HORIZONTAL)
     #
     # The tracks panel is a horizontal wx.SplitterWindow object containing
     # 2 wx.MultiSplitterWindow (redesigned). In each of these, Track labels
     # canvas and Track data canvas are respectively placed.
     self._tracks_panel = WellPlotInternal(self._main_panel)
     self._hbox.Add(self._tracks_panel, 1, wx.EXPAND)
     #
     # Overview
     self._overview = None
     self._overview_border = 1
     self._overview_width = 120
     self._overview_base_panel = wx.Panel(self._main_panel)
     self._overview_base_panel.SetBackgroundColour('black')
     self._overview_base_panel.SetInitialSize((0, 0))
     self._overview_sizer = wx.BoxSizer(wx.HORIZONTAL)
     self._overview_base_panel.SetSizer(self._overview_sizer)
     self._hbox.Add(self._overview_base_panel, 0, wx.EXPAND)
     #
     self._main_panel.SetSizer(self._hbox)
     self._hbox.Layout()
     self.Layout()
     #
     # When a sash (width bar) changes Panel width in a MultiSplitterWindow
     # the other one must answer with same change. For example, if a user
     # drags the sash at a Track data canvas, its Track label canvas must
     # have the same new width setted.
     self._tracks_panel.top_splitter.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED,
                                          self._on_change_sash_pos)
     self._tracks_panel.bottom_splitter.Bind(
         wx.EVT_SPLITTER_SASH_POS_CHANGED, self._on_change_sash_pos)
예제 #3
0
class WellPlot(WorkPage):
    tid = 'wellplot'
    _TID_FRIENDLY_NAME = 'Well Plot'

    def __init__(self, controller_uid):
        super().__init__(controller_uid)
        # Top
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self._tool_bar = wx.aui.AuiToolBar(self)
        self.sizer.Add(self._tool_bar, 0, flag=wx.TOP | wx.EXPAND)
        # Center
        self._main_panel = wx.Panel(self)
        self.sizer.Add(self._main_panel, 1, flag=wx.EXPAND)
        # Bottom
        self._status_bar = PlotStatusBar(self)
        self.sizer.Add(self._status_bar, 0, flag=wx.BOTTOM | wx.EXPAND)
        self.SetSizer(self.sizer)
        #
        # Then, let's construct our ToolBar
        self._build_tool_bar()
        #
        # Main panel is subdivided into a Tracks panel on left side and
        # a Overview panel in right side. The last one is used as a 'ruler' to
        # guide data navigation (zoom in and  zoom out).
        self._hbox = wx.BoxSizer(wx.HORIZONTAL)
        #
        # The tracks panel is a horizontal wx.SplitterWindow object containing
        # 2 wx.MultiSplitterWindow (redesigned). In each of these, Track labels
        # canvas and Track data canvas are respectively placed.
        self._tracks_panel = WellPlotInternal(self._main_panel)
        self._hbox.Add(self._tracks_panel, 1, wx.EXPAND)
        #
        # Overview
        self._overview = None
        self._overview_border = 1
        self._overview_width = 120
        self._overview_base_panel = wx.Panel(self._main_panel)
        self._overview_base_panel.SetBackgroundColour('black')
        self._overview_base_panel.SetInitialSize((0, 0))
        self._overview_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._overview_base_panel.SetSizer(self._overview_sizer)
        self._hbox.Add(self._overview_base_panel, 0, wx.EXPAND)
        #
        self._main_panel.SetSizer(self._hbox)
        self._hbox.Layout()
        self.Layout()
        #
        # When a sash (width bar) changes Panel width in a MultiSplitterWindow
        # the other one must answer with same change. For example, if a user
        # drags the sash at a Track data canvas, its Track label canvas must
        # have the same new width setted.
        self._tracks_panel.top_splitter.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED,
                                             self._on_change_sash_pos)
        self._tracks_panel.bottom_splitter.Bind(
            wx.EVT_SPLITTER_SASH_POS_CHANGED, self._on_change_sash_pos)

    def PostInit(self):
        OM = ObjectManager()
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.subscribe(self.set_fit, 'change.fit')
        controller.subscribe(self.set_multicursor, 'change.multicursor')
        #
        well = OM.get(controller.obj_uid)
        controller.attach(well.uid)
        # Populate index type Choice
        for z_axis_dt in well.get_z_axis_datatypes().keys():
            self._tool_bar.choice_IT.Append(z_axis_dt)
        # Setting index type Choice
        idx_index_type = self._tool_bar.choice_IT.GetItems().index(
            controller.index_type)
        self._tool_bar.choice_IT.SetSelection(idx_index_type)
        #
        self._tool_bar.choice_IT.Bind(wx.EVT_CHOICE, self._on_index_type)
        # Setting min and max Z axis TextCtrls
        self._reload_z_axis_textctrls()
        # Create Overview Track
        UIM.create('track_controller',
                   self._controller_uid,
                   overview=True,
                   plotgrid=False)

    def PreDelete(self):
        try:
            self.sizer.Remove(0)
            del self._tool_bar
            super().PreDelete()
        except Exception as e:
            msg = 'PreDelete ' + self.__class__.__name__ + \
                                            ' ended with error: ' + str(e)
            print(msg)
            raise

    def _on_change_sash_pos(self, event):
        idx = event.GetSashIdx()
        new_width = event.GetSashPosition()
        track_ctrl = self.get_track_on_position(idx)
        track_ctrl.width = new_width

    def _on_change_float_panel(self, event):
        # TODO: Integrar binds de toggle buttons...
        if event.GetId() == WP_FLOAT_PANEL:
            UIM = UIManager()
            controller = UIM.get(self._controller_uid)
            controller.float_mode = event.IsChecked()

    # Posicao absoluta considera os tracks invisiveis
    # Posicao relativa considera somente os tracks visiveis
    # Posicao -1 retorna overview track ou None se nao existir overview
    def get_track_on_position(self, pos, relative_position=True):
        if pos == -1:
            return self.get_overview_track()
        b_splitter = self._tracks_panel.bottom_splitter
        if relative_position:
            pos = b_splitter.get_windows_indexes_shown()[pos]
        bottom_window = b_splitter.GetWindow(pos)
        UIM = UIManager()
        for tcc in UIM.list('track_canvas_controller'):
            if tcc.view == bottom_window:
                track_ctrl_uid = UIM._getparentuid(tcc.uid)
                return UIM.get(track_ctrl_uid)
        raise Exception('Informed position [{}] is invalid.'.format(pos))

    def _place_as_overview(self, track_canvas_window):
        """Places a TrackCanvas window at overview place.
        It is a inner function and should (must) be used only by WellPlot.    
        """
        if not self._overview_sizer.IsEmpty():
            raise Exception('Overview sizer is not empty.')
        self._overview_base_panel.SetInitialSize((self._overview_width, 10))
        self._overview_sizer.Add(track_canvas_window, 1, wx.EXPAND | wx.ALL,
                                 self._overview_border)
        self._hbox.Layout()

    def _remove_from_overview(self):
        """Remove track is at overview place."""
        if self._overview_sizer.IsEmpty():
            raise Exception('Overview sizer is empty.')

        self._overview_sizer.Clear()

        self._overview_base_panel.SetInitialSize((0, 0))
        self._hbox.Layout()

    def _get_wx_parent(self, flag):
        """
        """
        if flag == 'overview':
            return self._overview_base_panel
        elif flag == 'track':
            return self._tracks_panel.bottom_splitter
        elif flag == 'label':
            return self._tracks_panel.top_splitter
        raise Exception('Wrong type window informed. ' +
                        'Valid values are overview, label or track.')

    def get_friendly_name(self):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        OM = ObjectManager()
        well = OM.get(controller.obj_uid)
        idx = self._get_sequence_number()
        name = self._get_tid_friendly_name() \
                               + ': ' + well.name + ' ['+ str(idx) + ']'
        return name

    def _reload_z_axis_textctrls(self, *args):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        ymin, ymax = controller.shown_ylim
        z_start_str = "{0:.2f}".format(ymin)
        self._tool_bar.z_start.SetValue(z_start_str)
        z_end_str = "{0:.2f}".format(ymax)
        self._tool_bar.z_end.SetValue(z_end_str)

    def on_change_z_start(self, event):
        print('on_change_z_start:', event.GetString())

    def on_change_z_end(self, event):
        print('on_change_z_end:', event.GetString())

    # Posicao absoluta considera os tracks invisiveis
    # Posicao relativa considera somente os tracks visiveis
    # retorna -1 se o track for overview
    # gera exception se o track nao for filho deste wellplot
    def get_track_position(self, track_uid, relative_position=True):
        UIM = UIManager()
        if UIM._getparentuid(track_uid) != self._controller_uid:
            raise Exception()
        track = UIM.get(track_uid)
        if track.overview:
            return -1
        tcc = track._get_canvas_controller()
        #if relative_position:
        #    return self._tracks_panel.bottom_splitter.GetVisibleIndexOf(bottom)
        #return self._tracks_panel.bottom_splitter.IndexOf(bottom)
        if relative_position:
            ret = self._tracks_panel.bottom_splitter.GetVisibleIndexOf(
                tcc.view)
        else:
            ret = self._tracks_panel.bottom_splitter.IndexOf(tcc.view)
        #print 'get_track_position({}, {}): {}'.format(track_uid, relative_position, ret)
        return ret

    # Posicao absoluta, considerando overview
    def get_adjusted_absolute_track_position(self, track_uid):
        pos = self.get_track_position(track_uid, False)
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        track = UIM.get(track_uid)
        ot = controller.get_overview_track()
        if ot and ot.pos < track.pos:
            pos -= 1
        return pos
#    """

    def change_absolute_track_position_on_splitter(self, track_uid, new_pos):
        UIM = UIManager()
        track = UIM.get(track_uid)
        #
        tlc = track._get_label_controller()
        tcc = track._get_canvas_controller()
        #
        self._tracks_panel.top_splitter.ChangeWindowPosition(tlc.view, new_pos)
        self._tracks_panel.bottom_splitter.ChangeWindowPosition(
            tcc.view, new_pos)

    def refresh_overview(self):
        self._overview_track._reload_canvas_positions_from_depths()

    def _detach_top_window(self, top_win):
        try:
            self._tracks_panel.top_splitter.DetachWindow(top_win)
        except:
            raise

    def _detach_bottom_window(self, bot_win):
        try:
            self._tracks_panel.bottom_splitter.DetachWindow(bot_win)
        except:
            raise

    def show_track(self, track_uid, show):
        UIM = UIManager()
        track = UIM.get(track_uid)
        if track.view.label:
            self._tracks_panel.top_splitter.ShowWindow(track.view.label, show)
        if not track.overview:
            self._tracks_panel.bottom_splitter.ShowWindow(
                track.view.track, show)
        else:
            raise Exception('show_track overview track???')
        tracks_affected = UIM.exec_query('track_controller',
                                         self._controller_uid,
                                         'pos>=' + str(track.pos))
        for track_affected in tracks_affected:
            if track_affected.uid != track.uid:
                #print 'track_affected.uid:', track_affected.uid
                track_affected.reload_track_title()

    def _on_bottom_splitter_size(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.update_adaptative()

    def _do_change_width(self, idx, width, event_object=None):
        self._tracks_panel.top_splitter._sashes[idx] = width
        self._tracks_panel.bottom_splitter._sashes[idx] = width
        if self._tracks_panel.top_splitter._windows[idx].IsShown():
            self._tracks_panel.top_splitter._SizeComponent()
        if self._tracks_panel.bottom_splitter._windows[idx].IsShown():
            self._tracks_panel.bottom_splitter._SizeComponent()

    def _on_toolbar_insert_track(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.insert_track()

    def _on_toolbar_remove_track(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.remove_selected_tracks()

    def _on_change_tool(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        if event.GetId() == WP_NORMAL_TOOL:
            controller.cursor_state = WellPlotState.NORMAL_TOOL
        elif event.GetId() == WP_SELECTION_TOOL:
            controller.cursor_state = WellPlotState.SELECTION_TOOL
        else:
            raise Exception()

    def _OnEditFormat(self, event):
        UIM = UIManager()
        lp_editor_ctrl = UIM.create('well_plot_editor_controller',
                                    self._controller_uid)
        lp_editor_ctrl.view.Show()

    def _OnResetZAxis(self, event):
        """
        Reset based on controller.wellplot_ylim, not on a new DataIndex inclusion.
        """
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.shown_ylim = controller.wellplot_ylim

    def _OnSetZAxis(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        ymin, ymax = controller.wellplot_ylim
        z_start_str = self._tool_bar.z_start.GetValue()
        z_end_str = self._tool_bar.z_end.GetValue()
        ok = True
        if not round(float(z_start_str), 2) >= round(ymin, 2):
            self._tool_bar.z_start.SetValue(z_start_str)
            ok = False
        if not round(float(z_end_str), 2) <= round(ymax, 2):
            self._tool_bar.z_start.SetValue(z_end_str)
            ok = False
        if ok:
            controller.shown_ylim = (float(z_start_str), float(z_end_str))

    def set_fit(self, new_value, old_value):
        """From object monitored attributes fit.
        """
        if self._tool_bar.cbFit.IsChecked() != new_value:
            self._tool_bar.cbFit.SetValue(new_value)

        self._tracks_panel.top_splitter._SetFit(new_value)
        self._tracks_panel.bottom_splitter._SetFit(new_value)

    def _on_fit(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.fit = event.IsChecked()

    def _on_multicursor(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.multicursor = event.GetString()

    def _on_index_type(self, event):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.index_type = event.GetString()

    def _insert_windows_on_track_panel(self,
                                       pos,
                                       label_window,
                                       canvas_window,
                                       initial_width=200):
        self._tracks_panel.insert(pos, label_window, canvas_window,
                                  initial_width)

    def set_multicursor(self, new_value, old_value):
        UIM = UIManager()
        tracks = UIM.list('track_controller', self._controller_uid)
        if not tracks:
            return
        for track in tracks:
            track.view.track.update_multicursor(new_value)

    def show_status_message(self, msg):
        self._status_bar.SetStatusText(msg, 0)

    def _build_tool_bar(self):
        self.fp_item = self._tool_bar.AddTool(
            WP_FLOAT_PANEL, wx.EmptyString,
            GripyBitmap('restore_window-25.png'), wx.NullBitmap, wx.ITEM_CHECK,
            'Float Panel', 'Float Panel', None)
        self._tool_bar.ToggleTool(WP_FLOAT_PANEL, False)
        self._tool_bar.Bind(wx.EVT_TOOL, self._on_change_float_panel, None,
                            WP_FLOAT_PANEL)
        self._tool_bar.AddSeparator()
        #
        self._tool_bar.AddTool(WP_NORMAL_TOOL, wx.EmptyString,
                               GripyBitmap('cursor_24.png'), wx.NullBitmap,
                               wx.ITEM_RADIO, 'Normal Tool', 'Normal Tool',
                               None)
        self._tool_bar.ToggleTool(WP_NORMAL_TOOL, True)
        #
        self._tool_bar.AddTool(WP_SELECTION_TOOL, wx.EmptyString,
                               GripyBitmap('cursor_filled_24.png'),
                               wx.NullBitmap, wx.ITEM_RADIO, 'Selection Tool',
                               'Selection Tool', None)
        self._tool_bar.Bind(wx.EVT_TOOL, self._on_change_tool, None,
                            WP_NORMAL_TOOL, WP_SELECTION_TOOL)
        #
        self._tool_bar.AddSeparator()
        #
        tb_item = self._tool_bar.AddTool(-1, u"Insert Track",
                                         GripyBitmap('table_add_24.png'),
                                         'Insert a new track')
        self._tool_bar.Bind(wx.EVT_TOOL, self._on_toolbar_insert_track,
                            tb_item)
        #
        tb_item = self._tool_bar.AddTool(-1, u"Remove Track",
                                         GripyBitmap('table_delete_24.png'),
                                         'Remove selected tracks')
        self._tool_bar.Bind(wx.EVT_TOOL, self._on_toolbar_remove_track,
                            tb_item)
        #
        self._tool_bar.AddSeparator()
        #
        button_edit_format = wx.Button(self._tool_bar, label='Edit Plot')
        button_edit_format.Bind(wx.EVT_BUTTON, self._OnEditFormat)
        self._tool_bar.AddControl(button_edit_format, '')
        self._tool_bar.AddSeparator()
        #
        self._tool_bar.cbFit = wx.CheckBox(self._tool_bar, -1, 'Fit')
        self._tool_bar.cbFit.Bind(wx.EVT_CHECKBOX, self._on_fit)
        self._tool_bar.AddControl(self._tool_bar.cbFit, '')
        #
        self._tool_bar.AddSeparator()
        self._tool_bar.label_MC = wx.StaticText(self._tool_bar,
                                                label='Multi cursor:  ')
        self._tool_bar.AddControl(self._tool_bar.label_MC, '')
        self._tool_bar.choice_MC = wx.Choice(
            self._tool_bar, choices=['None', 'Horizon', 'Vertical', 'Both'])
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        idx_mc = ['None', 'Horizon', 'Vertical',
                  'Both'].index(controller.multicursor)
        self._tool_bar.choice_MC.SetSelection(idx_mc)
        self._tool_bar.choice_MC.Bind(wx.EVT_CHOICE, self._on_multicursor)
        self._tool_bar.AddControl(self._tool_bar.choice_MC, '')
        #
        self._tool_bar.AddSeparator()
        #
        self._tool_bar.label_IT = wx.StaticText(self._tool_bar,
                                                label='Z Axis:  ')
        self._tool_bar.AddControl(self._tool_bar.label_IT, '')

        self._tool_bar.choice_IT = wx.Choice(self._tool_bar, choices=[])
        #
        self._tool_bar.AddControl(self._tool_bar.choice_IT, '')
        #
        static_z_start = wx.StaticText(self._tool_bar, label='Start:')
        self._tool_bar.AddControl(static_z_start, '')
        self._tool_bar.z_start = wx.TextCtrl(self._tool_bar, size=(60, 23))

        self._tool_bar.AddControl(self._tool_bar.z_start, '')
        static_z_end = wx.StaticText(self._tool_bar, label='End:')
        self._tool_bar.AddControl(static_z_end, '')
        self._tool_bar.z_end = wx.TextCtrl(self._tool_bar, size=(60, 23))
        self._tool_bar.AddControl(self._tool_bar.z_end, '')
        #
        button_set_zaxis = wx.Button(self._tool_bar,
                                     label='Set',
                                     size=(40, 23))
        button_set_zaxis.Bind(wx.EVT_BUTTON, self._OnSetZAxis)
        self._tool_bar.AddControl(button_set_zaxis, '')
        #
        button_reset_zaxis = wx.Button(self._tool_bar,
                                       label='Reset',
                                       size=(40, 23))
        button_reset_zaxis.Bind(wx.EVT_BUTTON, self._OnResetZAxis)
        self._tool_bar.AddControl(button_reset_zaxis, '')
        self._tool_bar.AddSeparator()
        #
        self._tool_bar.Realize()
예제 #4
0
class CrossPlot(WorkPage):
    tid = 'crossplot'
    _TID_FRIENDLY_NAME = 'Cross Plot'

    def __init__(self, controller_uid):
        super().__init__(controller_uid)

    def PostInit(self):
        try:
            self.sizer = wx.BoxSizer(wx.VERTICAL)
            self._tool_bar = wx.aui.AuiToolBar(self)
            self.sizer.Add(self._tool_bar, 0, flag=wx.TOP | wx.EXPAND)
            #     
            UIM = UIManager()
            canvas_controller = UIM.create('canvas_plotter_controller',
                                           self._controller_uid
                                           )
            #

            self._main_panel = canvas_controller.view
            # TODO: Keep this conection? (must be disconected at PreDelete??)
            #            self._main_panel.mpl_connect('motion_notify_event', 
            #                                                     self.on_canvas_mouse_move)
            self.sizer.Add(self._main_panel, 1, flag=wx.EXPAND)
            #
            self._status_bar = PlotStatusBar(self)
            self.sizer.Add(self._status_bar, 0, flag=wx.BOTTOM | wx.EXPAND)
            self.SetSizer(self.sizer)
            #
            self._build_tool_bar()
            self.Layout()
        except Exception as e:
            print('ERROR IN CrossPlot.PostInit:', e)
            raise

    def PreDelete(self):
        try:
            self.sizer.Remove(0)
            del self._tool_bar
        except Exception as e:
            msg = 'PreDelete ' + self.__class__.__name__ + \
                  ' ended with error: ' + str(e)
            print(msg)
            pass

    def get_friendly_name(self):
        return self._get_tid_friendly_name()

    def _set_own_name(self):
        """
        """
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        controller.title = self.get_friendly_name()

    def _get_wx_parent(self, *args):
        flag = args[0]
        return self

    def on_canvas_mouse_move(self, event):
        axes = event.inaxes
        if axes is None:
            return
        x_axis_label = 'X'
        y_axis_label = 'Y'
        msg = '{}: {:0.2f}, {}: {:0.2f}'.format(x_axis_label, event.xdata,
                                                y_axis_label, event.ydata
                                                )
        self._status_bar.SetStatusText(msg)

    def get_canvas_plotter_controller(self):
        UIM = UIManager()
        return UIM.list('canvas_plotter_controller',
                        self._controller_uid)[0]

    def _on_change_float_panel(self, event):
        # TODO: Integrar binds de toggle buttons...
        if event.GetId() == CP_FLOAT_PANEL:
            UIM = UIManager()
            controller = UIM.get(self._controller_uid)
            controller.float_mode = event.IsChecked()

    def _OnEditFormat(self, event):
        cpc = self.get_canvas_plotter_controller()
        interface.create_properties_dialog(cpc.uid, size=(600, 600))

    def _on_change_tool(self, event):
        if event.GetId() == CP_NORMAL_TOOL:
            print('\nCP_NORMAL_TOOL')
        elif event.GetId() == CP_SELECTION_TOOL:
            print('\nCP_SELECTION_TOOL')

    def _build_tool_bar(self):
        self.fp_item = self._tool_bar.AddTool(CP_FLOAT_PANEL,
                                              wx.EmptyString,
                                              GripyBitmap('restore_window-25.png'),
                                              wx.NullBitmap,
                                              wx.ITEM_CHECK,
                                              'Float Panel',
                                              'Float Panel',
                                              None
                                              )
        self._tool_bar.ToggleTool(CP_FLOAT_PANEL, False)
        self._tool_bar.Bind(wx.EVT_TOOL, self._on_change_float_panel, None,
                            CP_FLOAT_PANEL
                            )
        self._tool_bar.AddSeparator()
        #
        self._tool_bar.AddTool(CP_NORMAL_TOOL,
                               wx.EmptyString,
                               GripyBitmap('cursor_24.png'),
                               wx.NullBitmap,
                               wx.ITEM_RADIO,
                               'Normal Tool',
                               'Normal Tool',
                               None
                               )
        self._tool_bar.ToggleTool(CP_NORMAL_TOOL, True)
        #
        self._tool_bar.AddTool(CP_SELECTION_TOOL,
                               wx.EmptyString,
                               GripyBitmap('cursor_filled_24.png'),
                               wx.NullBitmap,
                               wx.ITEM_RADIO,
                               'Selection Tool',
                               'Selection Tool',
                               None
                               )
        self._tool_bar.Bind(wx.EVT_TOOL, self._on_change_tool, None,
                            CP_NORMAL_TOOL, CP_SELECTION_TOOL
                            )
        #
        self._tool_bar.AddSeparator()

        self._tool_bar.label_MC = wx.StaticText(self._tool_bar,
                                                label='MPL Theme:  '
                                                )
        self._tool_bar.AddControl(self._tool_bar.label_MC, '')

        styles = ['default'] + mstyle.available[:]
        self._tool_bar.choice_Style = wx.Choice(self._tool_bar, choices=styles)
        self._tool_bar.choice_Style.SetSelection(0)
        #
        self._tool_bar.choice_Style.Bind(wx.EVT_CHOICE, self._on_choice_style)
        self._tool_bar.AddControl(self._tool_bar.choice_Style, '')

        self._tool_bar.AddSeparator()

        button_edit_format = wx.Button(self._tool_bar, label='Edit Crossplot')
        button_edit_format.Bind(wx.EVT_BUTTON, self._OnEditFormat)
        self._tool_bar.AddControl(button_edit_format, '')
        self._tool_bar.AddSeparator()
        #   
        self._tool_bar.Realize()

    def set_own_name(self):
        UIM = UIManager()
        controller = UIM.get(self._controller_uid)
        idx = 0
        lpcs = UIM.list('crossplot_controller')
        for lpc in lpcs:
            idx += 1
        controller.title = self._get_tid_friendly_name() + ' [' + str(idx) + ']'

    def _on_choice_style(self, event):
        lib_name = event.GetString()
        UIM = UIManager()
        cc = UIM.list('canvas_plotter_controller', self._controller_uid)[0]
        cc.load_style(lib_name)