123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735 |
- """
- @package iscatt.frame
- @brief Main scatter plot widgets.
- Classes:
- - frame::IClassIScattPanel
- - frame::IScattDialog
- - frame::MapDispIScattPanel
- - frame::ScatterPlotsPanel
- - frame::CategoryListCtrl
- (C) 2013 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Stepan Turek <stepan.turek seznam.cz> (mentor: Martin Landa)
- """
- from __future__ import print_function
- import os
- import sys
- import six
- import wx
- import wx.lib.scrolledpanel as scrolled
- import wx.lib.mixins.listctrl as listmix
- from core import globalvar
- from core.gcmd import GException, GError, RunCommand
- from gui_core.gselect import Select
- from gui_core.dialogs import SetOpacityDialog
- from gui_core.wrap import StaticBox, Menu, ListCtrl
- from iscatt.controllers import ScattsManager
- from iscatt.toolbars import MainToolbar, EditingToolbar, CategoryToolbar
- from iscatt.iscatt_core import idScattToidBands
- from iscatt.dialogs import ManageBusyCursorMixin, RenameClassDialog
- from iscatt.plots import ScatterPlotWidget
- from iclass.dialogs import ContrastColor
- try:
- from agw import aui
- except ImportError:
- import wx.lib.agw.aui as aui
- class IClassIScattPanel(wx.Panel, ManageBusyCursorMixin):
- def __init__(self, parent, giface, iclass_mapwin=None,
- id=wx.ID_ANY):
- # wx.SplitterWindow.__init__(self, parent = parent, id = id,
- # style = wx.SP_LIVE_UPDATE)
- wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
- ManageBusyCursorMixin.__init__(self, window=self)
- self.scatt_mgr = self._createScattMgr(guiparent=parent, giface=giface,
- iclass_mapwin=iclass_mapwin)
- # toobars
- self.toolbars = {}
- self.toolbars['mainToolbar'] = self._createMainToolbar()
- self.toolbars['editingToolbar'] = EditingToolbar(
- parent=self, scatt_mgr=self.scatt_mgr)
- self._createCategoryPanel(self)
- self.plot_panel = ScatterPlotsPanel(self, self.scatt_mgr)
- self.mainsizer = wx.BoxSizer(wx.VERTICAL)
- self.mainsizer.Add(
- self.toolbars['mainToolbar'],
- proportion=0, flag=wx.EXPAND)
- self.mainsizer.Add(
- self.toolbars['editingToolbar'],
- proportion=0, flag=wx.EXPAND)
- self.mainsizer.Add(self.catsPanel, proportion=0,
- flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)
- self.mainsizer.Add(self.plot_panel, proportion=1, flag=wx.EXPAND)
- self.catsPanel.Hide()
- self.toolbars['editingToolbar'].Hide()
- self.SetSizer(self.mainsizer)
- self.scatt_mgr.computingStarted.connect(
- lambda: self.UpdateCur(busy=True))
- self.scatt_mgr.renderingStarted.connect(
- lambda: self.UpdateCur(busy=True))
- self.scatt_mgr.renderingFinished.connect(
- lambda: self.UpdateCur(busy=False))
- # self.SetSashGravity(0.5)
- #self.SplitHorizontally(self.head_panel, self.plot_panel, -50)
- self.Layout()
- def CloseWindow(self):
- self.scatt_mgr.CleanUp()
- def UpdateCur(self, busy):
- self.plot_panel.SetBusy(busy)
- ManageBusyCursorMixin.UpdateCur(self, busy)
- def _selCatInIScatt(self):
- return False
- def _createMainToolbar(self):
- return MainToolbar(parent=self, scatt_mgr=self.scatt_mgr)
- def _createScattMgr(self, guiparent, giface, iclass_mapwin):
- return ScattsManager(guiparent=self, giface=giface,
- iclass_mapwin=iclass_mapwin)
- def NewScatterPlot(self, scatt_id, transpose):
- return self.plot_panel.NewScatterPlot(scatt_id, transpose)
- def ShowPlotEditingToolbar(self, show):
- self.toolbars["editingToolbar"].Show(show)
- self.Layout()
- def ShowCategoryPanel(self, show):
- self.catsPanel.Show(show)
- # if show:
- # self.SetSashSize(5)
- # else:
- # self.SetSashSize(0)
- self.plot_panel.SetVirtualSize(self.plot_panel.GetBestVirtualSize())
- self.Layout()
- def _createCategoryPanel(self, parent):
- self.catsPanel = wx.Panel(parent=parent)
- self.cats_list = CategoryListCtrl(
- parent=self.catsPanel,
- cats_mgr=self.scatt_mgr.GetCategoriesManager(),
- sel_cats_in_iscatt=self._selCatInIScatt())
- self.catsPanel.SetMinSize((-1, 100))
- self.catsPanel.SetInitialSize((-1, 150))
- box_capt = StaticBox(parent=self.catsPanel, id=wx.ID_ANY,
- label=' %s ' % _("Classes"),)
- catsSizer = wx.StaticBoxSizer(box_capt, wx.VERTICAL)
- self.toolbars['categoryToolbar'] = self._createCategoryToolbar(
- self.catsPanel)
- catsSizer.Add(
- self.cats_list,
- proportion=1,
- flag=wx.EXPAND | wx.TOP,
- border=5)
- if self.toolbars['categoryToolbar']:
- catsSizer.Add(self.toolbars['categoryToolbar'], proportion=0)
- self.catsPanel.SetSizer(catsSizer)
- def _createCategoryToolbar(self, parent):
- return CategoryToolbar(parent=parent,
- scatt_mgr=self.scatt_mgr,
- cats_list=self.cats_list)
- class IScattDialog(wx.Dialog):
- def __init__(
- self, parent, giface,
- title=_("GRASS GIS Interactive Scatter Plot Tool"),
- id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE, **kwargs):
- wx.Dialog.__init__(
- self,
- parent,
- id,
- style=style,
- title=title,
- **kwargs)
- self.SetIcon(
- wx.Icon(
- os.path.join(
- globalvar.ICONDIR,
- 'grass.ico'),
- wx.BITMAP_TYPE_ICO))
- self.iscatt_panel = MapDispIScattPanel(self, giface)
- mainsizer = wx.BoxSizer(wx.VERTICAL)
- mainsizer.Add(self.iscatt_panel, proportion=1, flag=wx.EXPAND)
- self.SetSizer(mainsizer)
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
- self.SetMinSize((300, 300))
- def OnCloseWindow(self, event):
- event.Skip()
- # self.
- class MapDispIScattPanel(IClassIScattPanel):
- def __init__(self, parent, giface,
- id=wx.ID_ANY, **kwargs):
- IClassIScattPanel.__init__(self, parent=parent, giface=giface,
- id=id, **kwargs)
- def _createScattMgr(self, guiparent, giface, iclass_mapwin):
- return ScattsManager(guiparent=self, giface=giface)
- def _createMainToolbar(self):
- return MainToolbar(
- parent=self, scatt_mgr=self.scatt_mgr, opt_tools=['add_group'])
- def _selCatInIScatt(self):
- return True
- class ScatterPlotsPanel(scrolled.ScrolledPanel):
- def __init__(self, parent, scatt_mgr, id=wx.ID_ANY):
- scrolled.ScrolledPanel.__init__(self, parent)
- self.SetupScrolling(scroll_x=False, scroll_y=True, scrollToTop=False)
- self.scatt_mgr = scatt_mgr
- self.mainPanel = wx.Panel(parent=self, id=wx.ID_ANY)
- # self._createCategoryPanel()
- # Fancy gui
- self._mgr = aui.AuiManager(self.mainPanel)
- # self._mgr.SetManagedWindow(self)
- self._mgr.Update()
- self._doLayout()
- self.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
- self.Bind(wx.EVT_SCROLL_CHANGED, self.OnScrollChanged)
- self.Bind(aui.EVT_AUI_PANE_CLOSE, self.OnPlotPaneClosed)
- dlgSize = (-1, 400)
- # self.SetBestSize(dlgSize)
- # self.SetInitialSize(dlgSize)
- self.SetAutoLayout(1)
- # fix goutput's pane size (required for Mac OSX)
- # if self.gwindow:
- # self.gwindow.SetSashPosition(int(self.GetSize()[1] * .75))
- self.ignore_scroll = 0
- self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
- self.scatt_i = 1
- self.scatt_id_scatt_i = {}
- self.transpose = {}
- self.scatts = {}
- self.Bind(wx.EVT_CLOSE, self.OnClose)
- self.scatt_mgr.cursorPlotMove.connect(self.CursorPlotMove)
- def SetBusy(self, busy):
- for scatt in six.itervalues(self.scatts):
- scatt.UpdateCur(busy)
- def CursorPlotMove(self, x, y, scatt_id):
- try:
- x = int(round(x))
- y = int(round(y))
- coords = True
- except:
- coords = False
- pane = self._getPane(scatt_id)
- caption = self._creteCaption(scatt_id)
- if coords:
- caption += " %d, %d" % (x, y)
- pane.Caption(caption)
- self._mgr.RefreshCaptions()
- def _getPane(self, scatt_id):
- scatt_i = self.scatt_id_scatt_i[scatt_id]
- name = self._getScatterPlotName(scatt_i)
- return self._mgr.GetPane(name)
- def ScatterPlotClosed(self, scatt_id):
- scatt_i = self.scatt_id_scatt_i[scatt_id]
- name = self._getScatterPlotName(scatt_i)
- pane = self._mgr.GetPane(name)
- del self.scatt_id_scatt_i[scatt_id]
- del self.scatts[scatt_id]
- if pane.IsOk():
- self._mgr.ClosePane(pane)
- self._mgr.Update()
- def OnMouseWheel(self, event):
- # TODO very ugly find some better solution
- self.ignore_scroll = 3
- event.Skip()
- def ScrollChildIntoView(self, child):
- # For aui manager it does not work and returns position always to the
- # top -> deactivated.
- pass
- def OnPlotPaneClosed(self, event):
- if isinstance(event.pane.window, ScatterPlotWidget):
- event.pane.window.CleanUp()
- def OnScrollChanged(self, event):
- wx.CallAfter(self.Layout)
- def OnScroll(self, event):
- if self.ignore_scroll > 0:
- self.ignore_scroll -= 1
- else:
- event.Skip()
- # wx.CallAfter(self._mgr.Update)
- # wx.CallAfter(self.Layout)
- def _doLayout(self):
- mainsizer = wx.BoxSizer(wx.VERTICAL)
- mainsizer.Add(self.mainPanel, proportion=1, flag=wx.EXPAND)
- self.SetSizer(mainsizer)
- self.Layout()
- self.SetupScrolling()
- def OnClose(self, event):
- """Close dialog"""
- # TODO: why todo here, why print? just delete?
- print("closed")
- self.scatt_mgr.CleanUp()
- self.Destroy()
- def OnSettings(self, event):
- pass
- def _newScatterPlotName(self, scatt_id):
- name = self._getScatterPlotName(self.scatt_i)
- self.scatt_id_scatt_i[scatt_id] = self.scatt_i
- self.scatt_i += 1
- return name
- def _getScatterPlotName(self, i):
- name = "scatter plot %d" % i
- return name
- def NewScatterPlot(self, scatt_id, transpose):
- # TODO needs to be resolved (should be in this class)
- scatt = ScatterPlotWidget(parent=self.mainPanel,
- scatt_mgr=self.scatt_mgr,
- scatt_id=scatt_id,
- transpose=transpose)
- scatt.plotClosed.connect(self.ScatterPlotClosed)
- self.transpose[scatt_id] = transpose
- caption = self._creteCaption(scatt_id)
- self._mgr.AddPane(scatt,
- aui.AuiPaneInfo().Dockable(True).Floatable(True).
- Name(self._newScatterPlotName(scatt_id)).MinSize((-1, 300)).
- Caption(caption).
- Center().Position(1).MaximizeButton(True).
- MinimizeButton(True).CaptionVisible(True).
- CloseButton(True).Layer(0))
- self._mgr.Update()
- self.SetVirtualSize(self.GetBestVirtualSize())
- self.Layout()
- self.scatts[scatt_id] = scatt
- return scatt
- def _creteCaption(self, scatt_id):
- transpose = self.transpose[scatt_id]
- bands = self.scatt_mgr.GetBands()
- # TODO too low level
- b1_id, b2_id = idScattToidBands(scatt_id, len(bands))
- x_b = bands[b1_id].split('@')[0]
- y_b = bands[b2_id].split('@')[0]
- if transpose:
- tmp = x_b
- x_b = y_b
- y_b = tmp
- return "%s x: %s y: %s" % (_("scatter plot"), x_b, y_b)
- def GetScattMgr(self):
- return self.scatt_mgr
- class CategoryListCtrl(ListCtrl,
- listmix.ListCtrlAutoWidthMixin):
- # listmix.TextEditMixin):
- def __init__(self, parent, cats_mgr, sel_cats_in_iscatt, id=wx.ID_ANY):
- ListCtrl.__init__(
- self, parent, id, style=wx.LC_REPORT | wx.LC_VIRTUAL | wx.LC_HRULES |
- wx.LC_VRULES | wx.LC_SINGLE_SEL | wx.LC_NO_HEADER)
- self.columns = ((_('Class name'), 'name'), )
- #(_('Color'), 'color'))
- self.sel_cats_in_iscatt = sel_cats_in_iscatt
- self.Populate(columns=self.columns)
- self.cats_mgr = cats_mgr
- self.SetItemCount(len(self.cats_mgr.GetCategories()))
- self.rightClickedItemIdx = wx.NOT_FOUND
- listmix.ListCtrlAutoWidthMixin.__init__(self)
- # listmix.TextEditMixin.__init__(self)
- self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnCategoryRightUp) # wxMSW
- self.Bind(wx.EVT_RIGHT_UP, self.OnCategoryRightUp) # wxGTK
- #self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnEdit)
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSel)
- self.cats_mgr.setCategoryAttrs.connect(self.Update)
- self.cats_mgr.deletedCategory.connect(self.Update)
- self.cats_mgr.addedCategory.connect(self.Update)
- def Update(self, **kwargs):
- self.SetItemCount(len(self.cats_mgr.GetCategories()))
- if len(self.cats_mgr.GetCategories()):
- self.RefreshItems(0, len(self.cats_mgr.GetCategories()) - 1)
- def SetVirtualData(self, row, column, text):
- attr = self.columns[column][1]
- if attr == 'name':
- try:
- text.encode('ascii')
- except UnicodeEncodeError:
- GMessage(parent=self, message=_(
- "Please use only ASCII characters."))
- return
- cat_id = self.cats_mgr.GetCategories()[row]
- self.cats_mgr.setCategoryAttrs.disconnect(self.Update)
- self.cats_mgr.SetCategoryAttrs(cat_id, {attr: text})
- self.cats_mgr.setCategoryAttrs.connect(self.Update)
- self.Select(row)
- def Populate(self, columns):
- for i, col in enumerate(columns):
- self.InsertColumn(i, col[0]) # wx.LIST_FORMAT_RIGHT
- #self.SetColumnWidth(0, 100)
- #self.SetColumnWidth(1, 100)
- def AddCategory(self):
- self.cats_mgr.addedCategory.disconnect(self.Update)
- cat_id = self.cats_mgr.AddCategory()
- self.cats_mgr.addedCategory.connect(self.Update)
- if cat_id < 0:
- GError(_("Maximum limit of categories number was reached."))
- return
- self.SetItemCount(len(self.cats_mgr.GetCategories()))
- def DeleteCategory(self):
- indexList = sorted(self.GetSelectedIndices(), reverse=True)
- cats = []
- for i in indexList:
- # remove temporary raster
- cat_id = self.cats_mgr.GetCategories()[i]
- cats.append(cat_id)
- self.cats_mgr.deletedCategory.disconnect(self.Update)
- self.cats_mgr.DeleteCategory(cat_id)
- self.cats_mgr.deletedCategory.connect(self.Update)
- self.SetItemCount(len(self.cats_mgr.GetCategories()))
- def OnSel(self, event):
- if self.sel_cats_in_iscatt:
- indexList = self.GetSelectedIndices()
- sel_cats = []
- cats = self.cats_mgr.GetCategories()
- for i in indexList:
- sel_cats.append(cats[i])
- if sel_cats:
- self.cats_mgr.SetSelectedCat(sel_cats[0])
- event.Skip()
- def GetSelectedIndices(self, state=wx.LIST_STATE_SELECTED):
- indices = []
- lastFound = -1
- while True:
- index = self.GetNextItem(lastFound, wx.LIST_NEXT_ALL, state)
- if index == -1:
- break
- else:
- lastFound = index
- indices.append(index)
- return indices
- def DeselectAll(self):
- """Deselect all items"""
- indexList = self.GetSelectedIndices()
- for i in indexList:
- self.Select(i, on=0)
- # no highlight
- self.OnCategorySelected(None)
- def OnGetItemText(self, item, col):
- attr = self.columns[col][1]
- cat_id = self.cats_mgr.GetCategories()[item]
- return self.cats_mgr.GetCategoryAttrs(cat_id)[attr]
- def OnGetItemImage(self, item):
- return -1
- def OnGetItemAttr(self, item):
- cat_id = self.cats_mgr.GetCategories()[item]
- cattr = self.cats_mgr.GetCategoryAttrs(cat_id)
- if cattr['show']:
- c = cattr['color']
- back_c = wx.Colour(*map(int, c.split(':')))
- text_c = wx.Colour(*ContrastColor(back_c))
- else:
- back_c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_INACTIVECAPTION)
- text_c = wx.SystemSettings.GetColour(
- wx.SYS_COLOUR_INACTIVECAPTIONTEXT)
- # if it is in scope of the method, gui falls, using self solved it
- self.l = wx.ListItemAttr(colText=text_c, colBack=back_c)
- return self.l
- def OnCategoryRightUp(self, event):
- """Show context menu on right click"""
- item, flags = self.HitTest((event.GetX(), event.GetY()))
- if item != wx.NOT_FOUND and flags & wx.LIST_HITTEST_ONITEM:
- self.rightClickedItemIdx = item
- # generate popup-menu
- cat_idx = self.rightClickedItemIdx
- cats = self.cats_mgr.GetCategories()
- cat_id = cats[cat_idx]
- showed = self.cats_mgr.GetCategoryAttrs(cat_id)['show']
- menu = Menu()
- item = menu.Append(wx.ID_ANY, text=_("Rename class"))
- self.Bind(wx.EVT_MENU, self.OnRename, item)
- item = menu.Append(wx.ID_ANY, text=_("Set color"))
- self.Bind(wx.EVT_MENU, self.OnSetColor, item)
- item = menu.Append(item_id, text=_("Change opacity level"))
- self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, item)
- if showed:
- text = _("Hide")
- else:
- text = _("Show")
- item = menu.Append(wx.ID_ANY, text=text)
- self.Bind(
- wx.EVT_MENU,
- lambda event: self._setCatAttrs(
- cat_id=cat_id,
- attrs={
- 'show': not showed}),
- item)
- menu.AppendSeparator()
- item = menu.Append(wx.ID_ANY, text=_("Move to top"))
- self.Bind(wx.EVT_MENU, self.OnMoveTop, item)
- if cat_idx == 0:
- menu.Enable(item.GetId(), False)
- item = menu.Append(wx.ID_ANY, text=_("Move to bottom"))
- self.Bind(wx.EVT_MENU, self.OnMoveBottom, item)
- if cat_idx == len(cats) - 1:
- menu.Enable(item.GetId(), False)
- menu.AppendSeparator()
- item = menu.Append(wx.ID_ANY, text=_("Move category up"))
- self.Bind(wx.EVT_MENU, self.OnMoveUp, item)
- if cat_idx == 0:
- menu.Enable(item.GetId(), False)
- item = menu.Append(wx.ID_ANY, text=_("Move category down"))
- self.Bind(wx.EVT_MENU, self.OnMoveDown, item)
- if cat_idx == len(cats) - 1:
- menu.Enable(item.GetId(), False)
- menu.AppendSeparator()
- item = menu.Append(wx.ID_ANY, text=_("Export class raster"))
- self.Bind(wx.EVT_MENU, self.OnExportCatRast, item)
- self.PopupMenu(menu)
- menu.Destroy()
- def OnExportCatRast(self, event):
- """Export training areas"""
- # TODO
- # GMessage(parent=self, message=_("No class raster to export."))
- # return
- cat_idx = self.rightClickedItemIdx
- cat_id = self.cats_mgr.GetCategories()[cat_idx]
- self.cats_mgr.ExportCatRast(cat_id)
- def OnMoveUp(self, event):
- cat_idx = self.rightClickedItemIdx
- cat_id = self.cats_mgr.GetCategories()[cat_idx]
- self.cats_mgr.ChangePosition(cat_id, cat_idx - 1)
- self.RefreshItems(0, len(self.cats_mgr.GetCategories()))
- def OnMoveDown(self, event):
- cat_idx = self.rightClickedItemIdx
- cat_id = self.cats_mgr.GetCategories()[cat_idx]
- self.cats_mgr.ChangePosition(cat_id, cat_idx + 1)
- self.RefreshItems(0, len(self.cats_mgr.GetCategories()))
- def OnMoveTop(self, event):
- cat_idx = self.rightClickedItemIdx
- cat_id = self.cats_mgr.GetCategories()[cat_idx]
- self.cats_mgr.ChangePosition(cat_id, 0)
- self.RefreshItems(0, len(self.cats_mgr.GetCategories()))
- def OnMoveBottom(self, event):
- cat_idx = self.rightClickedItemIdx
- cats = self.cats_mgr.GetCategories()
- cat_id = cats[cat_idx]
- self.cats_mgr.ChangePosition(cat_id, len(cats) - 1)
- self.RefreshItems(0, len(self.cats_mgr.GetCategories()))
- def OnSetColor(self, event):
- """Popup opacity level indicator"""
- cat_idx = self.rightClickedItemIdx
- cat_id = self.cats_mgr.GetCategories()[cat_idx]
- col = self.cats_mgr.GetCategoryAttrs(cat_id)['color']
- col = map(int, col.split(':'))
- col_data = wx.ColourData()
- col_data.SetColour(wx.Colour(*col))
- dlg = wx.ColourDialog(self, col_data)
- dlg.GetColourData().SetChooseFull(True)
- if dlg.ShowModal() == wx.ID_OK:
- color = dlg.GetColourData().GetColour().Get()
- color = ':'.join(map(str, color))
- self.cats_mgr.SetCategoryAttrs(cat_id, {"color": color})
- dlg.Destroy()
- def OnPopupOpacityLevel(self, event):
- """Popup opacity level indicator"""
- cat_id = self.cats_mgr.GetCategories()[self.rightClickedItemIdx]
- cat_attrs = self.cats_mgr.GetCategoryAttrs(cat_id)
- value = cat_attrs['opacity'] * 100
- name = cat_attrs['name']
- dlg = SetOpacityDialog(self, opacity=value,
- title=_("Change opacity of class <%s>" % name))
- dlg.applyOpacity.connect(
- lambda value: self._setCatAttrs(
- cat_id=cat_id, attrs={
- 'opacity': value}))
- dlg.CentreOnParent()
- if dlg.ShowModal() == wx.ID_OK:
- self._setCatAttrs(cat_id=cat_id, attrs={'opacity': value})
- dlg.Destroy()
- def OnRename(self, event):
- cat_id = self.cats_mgr.GetCategories()[self.rightClickedItemIdx]
- cat_attrs = self.cats_mgr.GetCategoryAttrs(cat_id)
- dlg = RenameClassDialog(self, old_name=cat_attrs['name'])
- dlg.CentreOnParent()
- while True:
- if dlg.ShowModal() == wx.ID_OK:
- name = dlg.GetNewName().strip()
- if not name:
- GMessage(parent=self, message=_(
- "Empty name was inserted."))
- else:
- self.cats_mgr.SetCategoryAttrs(cat_id, {"name": name})
- break
- else:
- break
- dlg.Destroy()
- def _setCatAttrs(self, cat_id, attrs):
- self.cats_mgr.setCategoryAttrs.disconnect(self.Update)
- self.cats_mgr.SetCategoryAttrs(cat_id, attrs)
- self.cats_mgr.setCategoryAttrs.connect(self.Update)
|