/[thuban]/trunk/thuban/Thuban/UI/classifier.py
ViewVC logotype

Diff of /trunk/thuban/Thuban/UI/classifier.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 415 by jonathan, Wed Feb 19 16:52:51 2003 UTC revision 444 by jonathan, Thu Feb 27 16:02:59 2003 UTC
# Line 16  from wxPython.grid import * Line 16  from wxPython.grid import *
16    
17  from Thuban import _  from Thuban import _
18  from Thuban.common import *  from Thuban.common import *
19    from Thuban.UI.common import *
20    
21  from Thuban.Model.classification import * #Classification, ClassData  from Thuban.Model.classification import * #Classification, ClassData
22    
# Line 65  class ClassTable(wxPyGridTableBase): Line 66  class ClassTable(wxPyGridTableBase):
66    
67      __col_labels = [_("Visual"), _("Value"), _("Label")]      __col_labels = [_("Visual"), _("Value"), _("Label")]
68    
     # this is tied to the values of classification.ClassData  
     __row_labels = [_("Default"), _("Point"), _("Range"), _("Map")]  
   
69      def __init__(self, clazz, shapeType, view = None):      def __init__(self, clazz, shapeType, view = None):
70          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
71          self.SetView(view)          self.SetView(view)
# Line 89  class ClassTable(wxPyGridTableBase): Line 87  class ClassTable(wxPyGridTableBase):
87          if clazz is None:          if clazz is None:
88              clazz = Classification()              clazz = Classification()
89    
90          p = clazz.GetDefaultData()  #       p = clazz.GetDefaultGroup()
91          np = ClassDataPoint(classData = p)  #       np = ClassDataDefault(classData = p)
92          self.tdata.append([np, 'DEFAULT', np.GetLabel()])  #       self.tdata.append([np, 'DEFAULT', np.GetLabel()])
93    
94          for p in clazz.points.values():  #       for p in clazz.points.values():
95              np = ClassDataPoint(p.GetValue(), classData = p)  #           np = ClassDataPoint(p.GetValue(), classData = p)
96              self.tdata.append([np, np.GetValue(), np.GetLabel()])  #           self.tdata.append([np, np.GetValue(), np.GetLabel()])
97    
98          for p in clazz.ranges:  #       for p in clazz.ranges:
99              np = ClassDataRange(p.GetMin(), p.GetMax(), classData = p)  #           np = ClassDataRange(p.GetMin(), p.GetMax(), classData = p)
100              self.tdata.append([np,  #           self.tdata.append([np,
101                                 '%s - %s' % (np.GetMin(), np.GetMax()),  #                              '%s - %s' % (np.GetMin(), np.GetMax()),
102                                 np.GetLabel()])  #                              np.GetLabel()])
103    
104            i = 0
105            for p in clazz:
106                np = copy.copy(p)
107                self.__SetRow(i, np)
108                i += 1
109    
110    
111          self.modified = 0          self.modified = 0
112    
113          #          #
# Line 125  class ClassTable(wxPyGridTableBase): Line 130  class ClassTable(wxPyGridTableBase):
130    
131          self.GetView().EndBatch()          self.GetView().EndBatch()
132    
133        def __SetRow(self, row, group):
134    
135            if isinstance(group, ClassGroupDefault):
136                data = [group, 'DEFAULT', group.GetLabel()]
137            elif isinstance(group, ClassGroupSingleton):
138                data = [group, group.GetValue(), group.GetLabel()]
139            elif isinstance(group, ClassGroupRange):
140                data = [group,
141                        '%s - %s' % (group.GetMin(), group.GetMax()),
142                        group.GetLabel()]
143    
144            if row >= len(self.tdata):
145                self.tdata.append(data)
146            else:
147                self.tdata[row] = data
148    
149      def GetColLabelValue(self, col):      def GetColLabelValue(self, col):
150          return self.__col_labels[col]          return self.__col_labels[col]
151    
152      def GetRowLabelValue(self, row):      def GetRowLabelValue(self, row):
153          data = self.tdata[row][COL_VISUAL]          data = self.tdata[row][COL_VISUAL]
154          type = data.GetType()          if isinstance(data, ClassGroupDefault): return _("Default")
155          return self.__row_labels[type]          if isinstance(data, ClassGroupSingleton): return _("Singleton")
156            if isinstance(data, ClassGroupRange): return _("Range")
157            if isinstance(data, ClassGroupMap): return _("Map")
158    
159      def GetNumberRows(self):      def GetNumberRows(self):
160          return len(self.tdata)          return len(self.tdata)
# Line 167  class ClassTable(wxPyGridTableBase): Line 190  class ClassTable(wxPyGridTableBase):
190          # function.          # function.
191          #          #
192          try:          try:
193              return (ClassData.POINT, Str2Num(value))              return (Str2Num(value),)
194          except:          except:
195              i = value.find('-')              i = value.find('-')
196              if i == 0:              if i == 0:
197                  i = value.find('-', 1)                  i = value.find('-', 1)
198    
199              return (ClassData.RANGE,              return (Str2Num(value[:i]), Str2Num(value[i+1:]))
                     Str2Num(value[:i]),  
                     Str2Num(value[i+1:]))  
200                            
201    
202      def SetValueAsCustom(self, row, col, typeName, value):      def SetValueAsCustom(self, row, col, typeName, value):
# Line 185  class ClassTable(wxPyGridTableBase): Line 206  class ClassTable(wxPyGridTableBase):
206              self.tdata[row][COL_VISUAL] = value              self.tdata[row][COL_VISUAL] = value
207          elif col == COL_VALUE:          elif col == COL_VALUE:
208              if row != 0: # DefaultData row              if row != 0: # DefaultData row
                 type = data.GetType()  
209    
210                  if type == ClassData.MAP:                  if isinstance(data, ClassGroupMap):
211                      # something special                      # something special
212                      pass                      pass
213                  else: # POINT, RANGE                  else: # POINT, RANGE
# Line 197  class ClassTable(wxPyGridTableBase): Line 217  class ClassTable(wxPyGridTableBase):
217                          # bad input, ignore the request                          # bad input, ignore the request
218                      else:                      else:
219    
220                          if dataInfo[0] == ClassData.POINT:                          ndata = data
221                              if type != ClassData.POINT:                          if len(dataInfo) == 1:
222                                  data = ClassDataPoint(classData = data)                              if not isinstance(data, ClassGroupSingleton):
223                              data.SetValue(dataInfo[1])                                  ndata = ClassGroupSingleton(prop = data)
224                              self.tdata[row][COL_VALUE] = data.GetValue()                              ndata.SetValue(dataInfo[0])
225                          elif dataInfo[0] == ClassData.RANGE:                          elif len(dataInfo) == 2:
226                              if type != ClassData.RANGE:                              if not isinstance(data, ClassGroupRange):
227                                  data = ClassDataRange(classData = data)                                  data = ClassDataRange(classData = data)
228                              data.SetRange(dataInfo[1], dataInfo[2])                              data.SetRange(dataInfo[0], dataInfo[1])
229                              self.tdata[row][COL_VALUE] = \  
230                                  "%s - %s" % (data.GetMin(), data.GetMax())                          ndata.SetLabel(data.GetLabel())
231                            self.__SetRow(row, ndata)
232                          self.tdata[row][COL_VISUAL] = data  
233                            #self.tdata[row][COL_VISUAL] = data
234                          # i just want it to redraw!  
235                          self.GetView().BeginBatch()                          self.GetView().Refresh()
                         self.GetView().EndBatch()  
236    
237          elif col == COL_LABEL:          elif col == COL_LABEL:
238              data.SetLabel(value)              data.SetLabel(value)
# Line 233  class ClassTable(wxPyGridTableBase): Line 252  class ClassTable(wxPyGridTableBase):
252    
253          return attr          return attr
254    
255      def GetClassData(self, row):      def GetClassGroup(self, row):
256          return self.tdata[row][COL_VISUAL]          return self.tdata[row][COL_VISUAL]
257    
258      def __Modified(self):      def __Modified(self):
# Line 247  class ClassTable(wxPyGridTableBase): Line 266  class ClassTable(wxPyGridTableBase):
266          self.tdata.append([np, np.GetValue(), np.GetLabel()])          self.tdata.append([np, np.GetValue(), np.GetLabel()])
267          msg = wxGridTableMessage(self, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1)          msg = wxGridTableMessage(self, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1)
268          self.GetView().ProcessTableMessage(msg)          self.GetView().ProcessTableMessage(msg)
269          self.GetView().BeginBatch()          self.GetView().Refresh()
         self.GetView().EndBatch()  
270    
271  class Classifier(wxDialog):  class Classifier(wxDialog):
272            
# Line 273  class Classifier(wxDialog): Line 291  class Classifier(wxDialog):
291                                       style = wxCB_READONLY)                                       style = wxCB_READONLY)
292    
293          self.num_cols = layer.table.field_count()          self.num_cols = layer.table.field_count()
294          self.__cur_prop = -1          # just assume the first field in case one hasn't been
295            # specified in the file.
296            self.__cur_prop = 0
297          field = layer.GetClassification().GetField()          field = layer.GetClassification().GetField()
298          for i in range(self.num_cols):          for i in range(self.num_cols):
299              type, name, len, decc = layer.table.field_info(i)              type, name, len, decc = layer.table.field_info(i)
# Line 337  class Classifier(wxDialog): Line 357  class Classifier(wxDialog):
357    
358          if numRows > 0:          if numRows > 0:
359              table = self.classGrid.GetTable()              table = self.classGrid.GetTable()
360              clazz.SetDefaultData(table.GetClassData(0))              clazz.SetDefaultGroup(table.GetClassGroup(0))
361    
362              for i in range(1, numRows):              for i in range(1, numRows):
363                  clazz.AddClassData(table.GetClassData(i))                  clazz.AddGroup(table.GetClassGroup(i))
364    
365          return clazz          return clazz
366    
# Line 390  class Classifier(wxDialog): Line 410  class Classifier(wxDialog):
410          r = event.GetRow()          r = event.GetRow()
411          c = event.GetCol()          c = event.GetCol()
412          if c == COL_VISUAL:          if c == COL_VISUAL:
413              prop = self.classGrid.GetTable().GetValueAsCustom(r, c, None)              # XXX: getting the properties is only possible with non-Maps!!!
414                group = self.classGrid.GetTable().GetValueAsCustom(r, c, None)
415                prop = group.GetProperties()
416              propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())              propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())
417              if propDlg.ShowModal() == wxID_OK:              if propDlg.ShowModal() == wxID_OK:
418                  new_prop = propDlg.GetClassData()                  new_prop = propDlg.GetClassGroupProperties()
419                  prop.SetStroke(new_prop.GetStroke())                  prop.SetStroke(new_prop.GetStroke())
420                  prop.SetStrokeWidth(new_prop.GetStrokeWidth())                  prop.SetStrokeWidth(new_prop.GetStrokeWidth())
421                  prop.SetFill(new_prop.GetFill())                  prop.SetFill(new_prop.GetFill())
422                  self.classGrid.BeginBatch()                  self.classGrid.Refresh()
                 self.classGrid.EndBatch()  
423              propDlg.Destroy()              propDlg.Destroy()
424    
425    
426  ID_SELPROP_OK = 4001  ID_SELPROP_OK = 4001
427  ID_SELPROP_CANCEL = 4002  ID_SELPROP_CANCEL = 4002
428  ID_SELPROP_SPINCTRL = 4002  ID_SELPROP_SPINCTRL = 4002
429    ID_SELPROP_PREVIEW = 4003
430    ID_SELPROP_STROKECLR = 4004
431    ID_SELPROP_FILLCLR = 4005
432    
433  class SelectPropertiesDialog(wxDialog):  class SelectPropertiesDialog(wxDialog):
434    
# Line 412  class SelectPropertiesDialog(wxDialog): Line 436  class SelectPropertiesDialog(wxDialog):
436          wxDialog.__init__(self, parent, -1, _("Select Properties"),          wxDialog.__init__(self, parent, -1, _("Select Properties"),
437                            style = wxRESIZE_BORDER)                            style = wxRESIZE_BORDER)
438    
439            self.prop = ClassGroupProperties(prop)
440    
441          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
   
         self.prop = ClassData(classData = prop)  
442    
443          topBox.Add(wxStaticText(self, -1, _("Stroke Color: ")),          itemBox = wxBoxSizer(wxHORIZONTAL)
444              0, wxALIGN_LEFT | wxALL, 4)  
445            # preview box
446            previewBox = wxBoxSizer(wxVERTICAL)
447            previewBox.Add(wxStaticText(self, -1, _("Preview:")),
448                0, wxALIGN_LEFT | wxALL, 4)
449            self.previewer = ClassDataPreviewer(None, self.prop, shapeType,
450                                                self, ID_SELPROP_PREVIEW, (40, 40))
451            previewBox.Add(self.previewer, 1, wxGROW, 15)
452    
453            itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
454    
455            # control box
456            ctrlBox = wxBoxSizer(wxVERTICAL)
457            ctrlBox.Add(
458                wxButton(self, ID_SELPROP_STROKECLR, "Change Stroke Color"),
459                0, wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)
460            EVT_BUTTON(self, ID_SELPROP_STROKECLR, self.OnChangeStrokeColor)
461    
462            if shapeType != SHAPETYPE_ARC:
463                ctrlBox.Add(
464                    wxButton(self, ID_SELPROP_FILLCLR, "Change Fill Color"),
465                    0, wxALIGN_LEFT | wxALL | wxGROW, 4)
466                EVT_BUTTON(self, ID_SELPROP_FILLCLR, self.OnChangeFillColor)
467    
468          spinBox = wxBoxSizer(wxHORIZONTAL)          spinBox = wxBoxSizer(wxHORIZONTAL)
469          spinBox.Add(wxStaticText(self, -1, _("Stroke Width: ")),          spinBox.Add(wxStaticText(self, -1, _("Stroke Width: ")),
470                  0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxBOTTOM, 4)                  0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)
471          self.spinCtrl = wxSpinCtrl(self, ID_SELPROP_SPINCTRL,          self.spinCtrl = wxSpinCtrl(self, ID_SELPROP_SPINCTRL,
472                                     min=1, max=10,                                     min=1, max=10,
473                                     value=str(prop.GetStrokeWidth()),                                     value=str(prop.GetStrokeWidth()),
# Line 431  class SelectPropertiesDialog(wxDialog): Line 477  class SelectPropertiesDialog(wxDialog):
477    
478          spinBox.Add(self.spinCtrl, 0, wxALIGN_LEFT | wxALL, 4)          spinBox.Add(self.spinCtrl, 0, wxALIGN_LEFT | wxALL, 4)
479    
480          topBox.Add(spinBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          ctrlBox.Add(spinBox, 0, wxALIGN_RIGHT | wxALL, 0)
481            itemBox.Add(ctrlBox, 0, wxALIGN_RIGHT | wxALL | wxGROW, 0)
482            topBox.Add(itemBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
483    
         if shapeType != SHAPETYPE_ARC:  
             topBox.Add(wxStaticText(self, -1, _("Fill Color: ")),  
                 0, wxALIGN_LEFT | wxBOTTOM, 4)  
484    
485          #          #
486          # Control buttons:          # Control buttons:
# Line 463  class SelectPropertiesDialog(wxDialog): Line 508  class SelectPropertiesDialog(wxDialog):
508    
509      def OnSpin(self, event):      def OnSpin(self, event):
510          self.prop.SetStrokeWidth(self.spinCtrl.GetValue())          self.prop.SetStrokeWidth(self.spinCtrl.GetValue())
511            self.previewer.Refresh()
512    
513        def __GetColor(self, cur):
514            dialog = wxColourDialog(self)
515            dialog.GetColourData().SetColour(Color2wxColour(cur))
516            ret = None
517            if dialog.ShowModal() == wxID_OK:
518                ret = wxColour2Color(dialog.GetColourData().GetColour())
519    
520            dialog.Destroy()
521    
522            return ret
523            
524        def OnChangeStrokeColor(self, event):
525            clr = self.__GetColor(self.prop.GetStroke())
526            if clr is not None:
527                self.prop.SetStroke(clr)
528            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
529    
530        def OnChangeFillColor(self, event):
531            clr = self.__GetColor(self.prop.GetFill())
532            if clr is not None:
533                self.prop.SetFill(clr)
534            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
535    
536      def GetClassData(self):      def GetClassGroupProperties(self):
537          return self.prop          return self.prop
538    
539    
540  class ClassDataPreviewer:  class ClassDataPreviewer(wxWindow):
541    
542        def __init__(self, rect, prop, shapeType,
543                           parent = None, id = -1, size = wxDefaultSize):
544            if parent is not None:
545                wxWindow.__init__(self, parent, id, size=size)
546                EVT_PAINT(self, self.OnPaint)
547    
548            self.rect = rect
549            self.prop = prop
550            self.shapeType = shapeType
551    
552        def OnPaint(self, event):
553            dc = wxPaintDC(self)
554    
555            # XXX: this doesn't seem to be having an effect:
556            dc.DestroyClippingRegion()
557    
558            self.Draw(dc, None)
559    
560        def Draw(self, dc, rect, prop = None, shapeType = None):
561    
562      def Draw(self, dc, rect, data, shapeType):          if prop is None: prop = self.prop
563            if shapeType is None: shapeType = self.shapeType
564    
565          stroke = data.GetStroke()          if rect is None:
566                x = y = 0
567                w, h = self.GetClientSizeTuple()
568            else:
569                x = rect.GetX()
570                y = rect.GetY()
571                w = rect.GetWidth()
572                h = rect.GetHeight()
573    
574            stroke = prop.GetStroke()
575          if stroke is Color.None:          if stroke is Color.None:
576              pen = wxTRANSPARENT_PEN              pen = wxTRANSPARENT_PEN
577          else:          else:
578              pen = wxPen(wxColour(stroke.red * 255,              pen = wxPen(Color2wxColour(stroke),
579                                   stroke.green * 255,                          prop.GetStrokeWidth(),
                                  stroke.blue * 255),  
                         data.GetStrokeWidth(),  
580                          wxSOLID)                          wxSOLID)
581    
582          stroke = data.GetFill()          stroke = prop.GetFill()
583          if stroke is Color.None:          if stroke is Color.None:
584              brush = wxTRANSPARENT_BRUSH              brush = wxTRANSPARENT_BRUSH
585          else:          else:
586              brush = wxBrush(wxColour(stroke.red * 255,              brush = wxBrush(Color2wxColour(stroke), wxSOLID)
                                      stroke.green * 255,  
                                      stroke.blue * 255), wxSOLID)  
587    
588          dc.SetPen(pen)          dc.SetPen(pen)
589          dc.SetBrush(brush)          dc.SetBrush(brush)
590    
591          if shapeType == SHAPETYPE_ARC:          if shapeType == SHAPETYPE_ARC:
592              dc.DrawSpline([wxPoint(rect.GetX(), rect.GetY() + rect.GetHeight()),              dc.DrawSpline([wxPoint(x, y + h),
593                             wxPoint(rect.GetX() + rect.GetWidth()/2,                             wxPoint(x + w/2, y + h/4),
594                                     rect.GetY() + rect.GetHeight()/4),                             wxPoint(x + w/2, y + h/4*3),
595                             wxPoint(rect.GetX() + rect.GetWidth()/2,                             wxPoint(x + w, y)])
                                    rect.GetY() + rect.GetHeight()/4*3),  
                            wxPoint(rect.GetX() + rect.GetWidth(), rect.GetY())])  
596    
597          elif shapeType == SHAPETYPE_POINT or \          elif shapeType == SHAPETYPE_POINT or \
598               shapeType == SHAPETYPE_POLYGON:               shapeType == SHAPETYPE_POLYGON:
599    
600              dc.DrawCircle(rect.GetX() + rect.GetWidth()/2,              dc.DrawCircle(x + w/2, y + h/2,
601                            rect.GetY() + rect.GetHeight()/2,                            (min(w, h) - prop.GetStrokeWidth())/2)
                           (min(rect.GetWidth(), rect.GetHeight())  
                            - data.GetStrokeWidth())/2)  
602    
603  class ClassRenderer(wxPyGridCellRenderer):  class ClassRenderer(wxPyGridCellRenderer):
604    
605      def __init__(self, shapeType):      def __init__(self, shapeType):
606          wxPyGridCellRenderer.__init__(self)          wxPyGridCellRenderer.__init__(self)
607          self.shapeType = shapeType          self.previewer = ClassDataPreviewer(None, None, shapeType)
608    
609      def Draw(self, grid, attr, dc, rect, row, col, isSelected):      def Draw(self, grid, attr, dc, rect, row, col, isSelected):
610          data = grid.GetTable().GetValueAsCustom(row, col, "")          data = grid.GetTable().GetValueAsCustom(row, col, "")
# Line 526  class ClassRenderer(wxPyGridCellRenderer Line 617  class ClassRenderer(wxPyGridCellRenderer
617          dc.DrawRectangle(rect.GetX(), rect.GetY(),          dc.DrawRectangle(rect.GetX(), rect.GetY(),
618                           rect.GetWidth(), rect.GetHeight())                           rect.GetWidth(), rect.GetHeight())
619    
620          ClassDataPreviewer().Draw(dc, rect, data, self.shapeType)          if not isinstance(data, ClassGroupMap):
621                self.previewer.Draw(dc, rect, data.GetProperties())
622    
623          if isSelected:          if isSelected:
624              dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),              dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),

Legend:
Removed from v.415  
changed lines
  Added in v.444

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26