/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 834 - (show annotations)
Tue May 6 15:52:36 2003 UTC (21 years, 10 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/classgen.py
File MIME type: text/x-python
File size: 33238 byte(s)
(ClassGenDialog.__init__)
(GenUniformPanel._OnRetrieve, GenUniquePanel._OnRetrieve): Adapt
to new table interface

1 # Copyright (c) 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with Thuban for details.
7
8 import sys
9
10 from Thuban import _
11
12 from wxPython.wx import *
13
14 from Thuban.Model.classification import Classification, ClassGroupRange, \
15 ClassGroupSingleton, ClassGroupProperties
16
17 from Thuban.Model.table import Table, FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
18 FIELDTYPE_STRING
19
20 from Thuban.Model.color import Color
21
22 import classifier
23
24 import resource
25
26 ID_CLASSGEN_GENCOMBO = 4007
27 ID_CLASSGEN_PROPCOMBO = 4008
28
29 USEALL_BMP = "group_use_all"
30 USE_BMP = "group_use"
31 USENOT_BMP = "group_use_not"
32 USENONE_BMP = "group_use_none"
33
34 GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
35 GENCOMBOSTR_UNIQUE = _("Unique Values")
36
37 PROPCOMBOSTR_CUSTOM = _("Custom Ramp")
38 PROPCOMBOSTR_GREY = _("Grey Ramp")
39 PROPCOMBOSTR_RED = _("Red Ramp")
40 PROPCOMBOSTR_GREEN = _("Green Ramp")
41 PROPCOMBOSTR_BLUE = _("Blue Ramp")
42 PROPCOMBOSTR_HOT2COLD = _("Hot-to-Cold Ramp")
43
44 class ClassGenDialog(wxDialog):
45
46 def __init__(self, parent, layer, fieldName):
47 """Inialize the class generating dialog.
48
49 parent -- this must be an instance of the Classifier class
50 """
51
52 wxDialog.__init__(self, parent, -1, _("Generate Classification"),
53 style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
54
55 self.parent = parent
56 self.clazz = None
57
58 col = layer.table.Column(fieldName)
59 self.type = col.type
60
61 #############
62 # we need to create genButton first because when we create the
63 # panels they will call AllowGenerate() which uses genButton.
64 #
65 self.genButton = wxButton(self, wxID_OK, _("Generate"))
66 self.genButton.SetDefault()
67
68 self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
69
70 uniq_panel = GenUniquePanel(self, layer, fieldName, self.type)
71
72 self.genPanel = uniq_panel
73 self.genChoice.Append(GENCOMBOSTR_UNIQUE, uniq_panel)
74
75 if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
76 uni_panel = GenUniformPanel(self, layer, fieldName, self.type)
77 self.genChoice.Append(GENCOMBOSTR_UNIFORM, uni_panel)
78
79 self.genChoice.SetSelection(0)
80
81 self.propPanel = None
82 custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
83
84 self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
85 self.propCombo.Append(PROPCOMBOSTR_GREY, GreyRamp())
86 self.propCombo.Append(PROPCOMBOSTR_RED, RedRamp())
87 self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
88 self.propCombo.Append(PROPCOMBOSTR_BLUE, BlueRamp())
89 self.propCombo.Append(PROPCOMBOSTR_HOT2COLD, HotToColdRamp())
90 self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
91
92 self.propCombo.SetSelection(0)
93
94 #############
95
96 sizer = wxBoxSizer(wxVERTICAL)
97
98 sizer.Add(wxStaticText(self, -1, _("Field: %s") % fieldName),
99 0, wxALL, 4)
100 sizer.Add(wxStaticText(
101 self, -1,
102 _("Data Type: %s") % classifier.Classifier.type2string[self.type]),
103 0, wxALL, 4)
104
105 psizer = wxBoxSizer(wxHORIZONTAL)
106 psizer.Add(wxStaticText(self, -1, _("Generate:")),
107 0, wxALIGN_CENTER_VERTICAL, 0)
108 psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
109
110 sizer.Add(psizer, 0, wxALL | wxGROW, 4)
111 sizer.Add(self.genPanel, 1, wxGROW | wxALL, 4)
112
113 sizer.Show(uniq_panel, True)
114 if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
115 sizer.Add(uni_panel, 1, wxGROW | wxALL, 4)
116 sizer.Show(uni_panel, False)
117
118 psizer = wxBoxSizer(wxHORIZONTAL)
119 psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
120 0, wxALIGN_CENTER_VERTICAL, 0)
121 psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
122 sizer.Add(psizer, 0, wxALL | wxGROW, 4)
123
124 sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
125 sizer.Show(custom_ramp_panel, False)
126
127 buttonSizer = wxBoxSizer(wxHORIZONTAL)
128 buttonSizer.Add(self.genButton, 0, wxALL, 4)
129 buttonSizer.Add(60, 20, 0, wxALL, 4)
130 buttonSizer.Add(wxButton(self, wxID_CANCEL, _("Close")),
131 0, wxALL, 4)
132 sizer.Add(buttonSizer, 0,
133 wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)
134
135 self.SetSizer(sizer)
136 self.SetAutoLayout(True)
137 sizer.SetSizeHints(self)
138
139 self.sizer = sizer
140
141 EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
142 EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
143 EVT_BUTTON(self, wxID_OK, self.OnOK)
144 EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
145
146
147 self.genChoice.SetFocus()
148
149 def GetClassification(self):
150 return self.clazz
151
152 def AllowGenerate(self, on):
153 pass #self.genButton.Enable(on)
154
155 def OnOK(self, event):
156 """This is really the generate button, but we want to override
157 the wxDialog class.
158 """
159
160 index = self.genChoice.GetSelection()
161
162 genSel = self.genChoice.GetString(index)
163 genPanel = self.genChoice.GetClientData(index)
164
165 propPanel = self.propPanel
166
167 if genSel in (GENCOMBOSTR_UNIFORM, GENCOMBOSTR_UNIQUE):
168 numGroups = genPanel.GetNumGroups()
169
170 index = self.propCombo.GetSelection()
171
172 propSel = self.propCombo.GetString(index)
173 propPanel = self.propCombo.GetClientData(index)
174
175 ramp = propPanel.GetRamp()
176
177 if genSel == GENCOMBOSTR_UNIFORM:
178
179 min = genPanel.GetMin()
180 max = genPanel.GetMax()
181
182 if min is not None \
183 and max is not None \
184 and numGroups is not None:
185
186 self.clazz = ClassGenerator().GenUnifromDistribution(
187 min, max, numGroups, ramp,
188 self.type == FIELDTYPE_INT)
189
190 self.parent._SetClassification(self.clazz)
191
192 elif genSel == GENCOMBOSTR_UNIQUE:
193
194 list = genPanel.GetValueList()
195
196 if len(list) > 0 \
197 and numGroups is not None:
198
199 self.clazz = ClassGenerator().GenSingletonsFromList(
200 list, numGroups, ramp)
201
202 self.parent._SetClassification(self.clazz)
203
204 def OnCancel(self, event):
205 self.Close()
206
207 def _OnGenTypeSelect(self, event):
208
209 combo = event.GetEventObject()
210
211 selIndex = combo.GetSelection()
212
213 if self.genPanel is not None:
214 self.sizer.Show(self.genPanel, False)
215
216 self.genPanel = combo.GetClientData(selIndex)
217 if self.genPanel is not None:
218 self.sizer.Show(self.genPanel, True)
219
220 self.sizer.SetSizeHints(self)
221 self.sizer.Layout()
222
223 def _OnPropTypeSelect(self, event):
224 combo = event.GetEventObject()
225
226 selIndex = combo.GetSelection()
227 sel = combo.GetString(selIndex)
228
229 if isinstance(self.propPanel, wxPanel):
230 self.sizer.Show(self.propPanel, False)
231
232 self.propPanel = combo.GetClientData(selIndex)
233
234 if isinstance(self.propPanel, wxPanel):
235 self.sizer.Show(self.propPanel, True)
236
237 self.sizer.SetSizeHints(self)
238 self.sizer.Layout()
239
240
241 ID_UNIFORM_MIN = 4001
242 ID_UNIFORM_MAX = 4002
243 ID_UNIFORM_NGROUPS = 4003
244 ID_UNIFORM_STEP = 4004
245 ID_UNIFORM_RETRIEVE = 4005
246
247 class GenUniformPanel(wxPanel):
248
249 def __init__(self, parent, layer, fieldName, fieldType):
250 wxPanel.__init__(self, parent, -1)
251
252 self.parent = parent
253 self.layer = layer
254 self.fieldName = fieldName
255 self.fieldType = fieldType
256
257 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
258 wxVERTICAL)
259
260 #############
261
262 sizer = wxBoxSizer(wxHORIZONTAL)
263
264 sizer.Add(wxStaticText(self, -1, _("Min:")), 0, wxALL, 4)
265 self.minCtrl = wxTextCtrl(self, ID_UNIFORM_MIN, style=wxTE_RIGHT)
266 sizer.Add(self.minCtrl, 1, wxALL, 4)
267 EVT_TEXT(self, ID_UNIFORM_MIN, self._OnRangeChanged)
268
269 sizer.Add(wxStaticText(self, -1, _("Max:")), 0, wxALL, 4)
270 self.maxCtrl = wxTextCtrl(self, ID_UNIFORM_MAX, style=wxTE_RIGHT)
271 sizer.Add(self.maxCtrl, 1, wxALL, 4)
272 EVT_TEXT(self, ID_UNIFORM_MAX, self._OnRangeChanged)
273
274 sizer.Add(wxButton(self, ID_UNIFORM_RETRIEVE, _("Retrieve From Table")),
275 0, wxALL, 4)
276 EVT_BUTTON(self, ID_UNIFORM_RETRIEVE, self._OnRetrieve)
277
278 topSizer.Add(sizer, 1, wxGROW, 0)
279
280 #############
281
282 sizer = wxBoxSizer(wxHORIZONTAL)
283
284 sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
285 self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
286 style=wxTE_RIGHT)
287 EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
288 EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
289 sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
290
291 sizer.Add(wxStaticText(self, -1, _("Stepping:")), 0, wxALL, 4)
292 self.stepCtrl = wxTextCtrl(self, ID_UNIFORM_STEP, style=wxTE_RIGHT)
293 EVT_TEXT(self, ID_UNIFORM_STEP, self._OnSteppingChanged)
294 sizer.Add(self.stepCtrl , 1, wxALL, 4)
295
296 topSizer.Add(sizer, 1, wxGROW, 0)
297
298 #############
299
300 self.SetSizer(topSizer)
301 self.SetAutoLayout(True)
302 topSizer.SetSizeHints(self)
303
304 self.numGroupsChanging = False
305 self.steppingChanging = False
306
307 self.numGroupsCtrl.SetRange(1, sys.maxint)
308
309 self.numGroupsCtrl.SetValue(1)
310 self.stepCtrl.SetValue("1")
311 self.maxCtrl.SetValue("0")
312 self.minCtrl.SetValue("0")
313 self.minCtrl.SetFocus()
314
315 def GetNumGroups(self):
316 value = self.numGroupsCtrl.GetValue()
317 return self.__GetValidatedTypeEntry(self.numGroupsCtrl,
318 value,
319 FIELDTYPE_INT,
320 None)
321
322 def GetStepping(self):
323 step = self.stepCtrl.GetValue()
324 return self.__GetValidatedTypeEntry(self.stepCtrl,
325 step,
326 self.fieldType,
327 0)
328
329 def GetMin(self):
330 min = self.minCtrl.GetValue()
331 max = self.maxCtrl.GetValue()
332 return self.__GetValidatedTypeEntry(self.minCtrl,
333 min,
334 self.fieldType,
335 max)
336
337 def GetMax(self):
338 min = self.minCtrl.GetValue()
339 max = self.maxCtrl.GetValue()
340 return self.__GetValidatedTypeEntry(self.maxCtrl,
341 max,
342 self.fieldType,
343 min)
344
345 def _OnRangeChanged(self, event):
346
347 hasFocus = wxWindow_FindFocus() == event.GetEventObject()
348 min = self.GetMin()
349 max = self.GetMax()
350
351 on = min is not None \
352 and max is not None
353
354 self.numGroupsCtrl.Enable(on)
355 self.stepCtrl.Enable(on)
356
357 ngroups = self.GetNumGroups()
358
359 if ngroups is not None \
360 and min is not None \
361 and max is not None \
362 and ngroups != 0:
363
364 #self.stepCtrl.SetValue(str((max - min) / ngroups))
365 self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
366 #self.numGroupsCtrl.SetValue(ngroups)
367
368 self.parent.AllowGenerate(self.GetStepping() is not None)
369 else:
370 self.parent.AllowGenerate(False)
371
372
373 if hasFocus:
374 event.GetEventObject().SetFocus()
375
376 def _OnNumGroupsChanged(self, event):
377 if self.steppingChanging:
378 self.steppingChanging = False
379 return
380
381
382 obj = event.GetEventObject()
383 ngroups = self.GetNumGroups()
384 min = self.GetMin()
385 max = self.GetMax()
386
387 if ngroups is not None \
388 and min is not None \
389 and max is not None \
390 and ngroups != 0:
391
392 #
393 # changing the value in the stepCtrl sends an event
394 # that the control is changing, at which point
395 # we try to update the numGroupsCtrl. This causes
396 # an infinite recursion. This flag and the one
397 # called steppingChanging tries to prevent the recursion.
398 #
399 self.numGroupsChanging = True
400
401 self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
402
403 self.parent.AllowGenerate(self.GetStepping() is not None)
404 else:
405 self.parent.AllowGenerate(False)
406
407
408 def _OnSteppingChanged(self, event):
409 if self.numGroupsChanging:
410 self.numGroupsChanging = False
411 return
412
413 step = self.GetStepping()
414 min = self.GetMin()
415 max = self.GetMax()
416
417 if step is not None \
418 and min is not None \
419 and max is not None \
420 and step != 0:
421
422 #
423 # see note in _OnNumGroupsChanged
424 #
425 self.steppingChanging = True
426 self.numGroupsCtrl.SetValue(self.__CalcNumGroups(min, max, step))
427
428 self.parent.AllowGenerate(self.GetNumGroups() is not None)
429 else:
430 self.parent.AllowGenerate(False)
431
432 def _OnRetrieve(self, event):
433
434 if self.layer.table is not None:
435 wxBeginBusyCursor()
436 min, max = self.layer.table.ValueRange(self.fieldName)
437 self.minCtrl.SetValue(str(min))
438 self.maxCtrl.SetValue(str(max))
439 wxEndBusyCursor()
440
441 def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
442
443 if type == FIELDTYPE_INT:
444 func = int
445 elif type == FIELDTYPE_DOUBLE:
446 func = float
447 elif type == FIELDTYPE_STRING:
448 func = str
449 else:
450 assert False, "Unsupported FIELDTYPE"
451 pass
452
453 if self.__ValidateEntry(win, value, func, badValue):
454 return func(value)
455
456 return None
457
458 def __ValidateEntry(self, win, value, test, badValue = None):
459
460 valid = value != ""
461
462 try:
463 if valid:
464 value = test(value)
465
466 if badValue is not None:
467 valid = value != test(badValue)
468 except ValueError:
469 valid = False
470
471 if valid:
472 win.SetForegroundColour(wxBLACK)
473 else:
474 win.SetForegroundColour(wxRED)
475
476 win.Refresh()
477
478 return valid
479
480 def __CalcStepping(self, min, max, ngroups):
481 step = (max - min) / float(ngroups)
482 if self.fieldType == FIELDTYPE_INT:
483 step = int(step)
484
485 return step
486
487 def __CalcNumGroups(self, min, max, step):
488 n = int((max - min) / step)
489 if n == 0:
490 n = 1
491
492 if self.fieldType == FIELDTYPE_INT and step == 1:
493 n += 1
494
495 return n
496
497
498 ID_UNIQUE_RETRIEVE = 4001
499 ID_UNIQUE_USEALL = 4002
500 ID_UNIQUE_USE = 4003
501 ID_UNIQUE_DONTUSE = 4004
502 ID_UNIQUE_USENONE = 4005
503 ID_UNIQUE_SORTAVAIL = 4006
504 ID_UNIQUE_SORTUSE = 4007
505 ID_UNIQUE_REVAVAIL = 4008
506 ID_UNIQUE_REVUSE = 4009
507
508 class GenUniquePanel(wxPanel):
509
510 def __init__(self, parent, layer, fieldName, fieldType):
511 wxPanel.__init__(self, parent, -1)
512
513 self.parent = parent
514 self.layer = layer
515 self.fieldName = fieldName
516 self.fieldType = fieldType
517
518 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
519 wxVERTICAL)
520
521
522 #bsizer = wxBoxSizer(wxVERTICAL)
523 topSizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,
524 _("Retrieve From Table")),
525 0, wxALL | wxALIGN_RIGHT, 4)
526
527 EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)
528
529 #topSizer.Add(bsizer, 0, wxALL, 4)
530
531 sizer = wxBoxSizer(wxHORIZONTAL)
532
533 self.dataList = []
534
535 psizer = wxBoxSizer(wxVERTICAL)
536 self.list_avail = wxListCtrl(self, -1,
537 style=wxLC_REPORT | wxLC_SINGLE_SEL)
538 self.list_avail.InsertColumn(0, "Available")
539 self.list_avail_data = []
540 psizer.Add(self.list_avail, 1, wxGROW, 0)
541
542 bsizer = wxBoxSizer(wxHORIZONTAL)
543 bsizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))
544 EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortList)
545
546 bsizer.Add(wxButton(self, ID_UNIQUE_REVAVAIL, _("Reverse")))
547 EVT_BUTTON(self, ID_UNIQUE_REVAVAIL, self._OnReverseList)
548
549 psizer.Add(bsizer, 0, wxGROW, 0)
550 sizer.Add(psizer, 1, wxGROW, 0)
551
552
553 bsizer = wxBoxSizer(wxVERTICAL)
554
555 bmp = resource.GetBitmapResource(USEALL_BMP, wxBITMAP_TYPE_XPM)
556 bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USEALL, bmp),
557 0, wxGROW | wxALL, 4)
558 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
559 bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USE, bmp),
560 0, wxGROW | wxALL, 4)
561 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
562 bsizer.Add(wxBitmapButton(self, ID_UNIQUE_DONTUSE, bmp),
563 0, wxGROW | wxALL, 4)
564 bmp = resource.GetBitmapResource(USENONE_BMP, wxBITMAP_TYPE_XPM)
565 bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USENONE, bmp),
566 0, wxGROW | wxALL, 4)
567
568 EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)
569 EVT_BUTTON(self, ID_UNIQUE_USE, self._OnUse)
570 EVT_BUTTON(self, ID_UNIQUE_DONTUSE, self._OnDontUse)
571 EVT_BUTTON(self, ID_UNIQUE_USENONE, self._OnUseNone)
572
573 sizer.Add(bsizer, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)
574
575 psizer = wxBoxSizer(wxVERTICAL)
576 self.list_use = wxListCtrl(self, -1,
577 style=wxLC_REPORT | wxLC_SINGLE_SEL)
578 self.list_use.InsertColumn(0, "Use")
579 self.list_use_data = []
580 psizer.Add(self.list_use, 1, wxGROW, 0)
581
582 bsizer = wxBoxSizer(wxHORIZONTAL)
583 bsizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))
584 EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortList)
585
586 bsizer.Add(wxButton(self, ID_UNIQUE_REVUSE, _("Reverse")))
587 EVT_BUTTON(self, ID_UNIQUE_REVUSE, self._OnReverseList)
588
589 psizer.Add(bsizer, 0, wxGROW, 0)
590
591 sizer.Add(psizer, 1, wxGROW, 0)
592
593
594 topSizer.Add(sizer, 1, wxGROW, 0)
595
596 self.SetSizer(topSizer)
597 self.SetAutoLayout(True)
598 topSizer.SetSizeHints(self)
599
600 self.parent.AllowGenerate(False)
601
602 self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]
603
604 def GetNumGroups(self):
605 return self.list_use.GetItemCount()
606
607 def GetValueList(self):
608 list = []
609 for i in range(self.list_use.GetItemCount()):
610 list.append(self.dataList[self.list_use.GetItemData(i)])
611 return list
612
613 def _OnSortList(self, event):
614 id = event.GetId()
615
616 if id == ID_UNIQUE_SORTUSE:
617 list = self.list_use
618 else:
619 list = self.list_avail
620
621 list.SortItems(lambda i1, i2: cmp(self.dataList[i1],
622 self.dataList[i2]))
623
624 def _OnReverseList(self, event):
625 id = event.GetId()
626
627 if id == ID_UNIQUE_REVUSE:
628 list = self.list_use
629 else:
630 list = self.list_avail
631
632 #
633 # always returning 1 reverses the list
634 #
635 list.SortItems(lambda i1, i2: 1)
636
637 def _OnRetrieve(self, event):
638 self.list_use.DeleteAllItems()
639 self.list_use_data = []
640 self.list_avail.DeleteAllItems()
641 self.list_avail_data = []
642
643 list = self.layer.table.UniqueValues(self.fieldName)
644 index = 0
645 for v in list:
646 self.dataList.append(v)
647 i = self.list_avail.InsertStringItem(index, str(v))
648 self.list_avail.SetItemData(index, i)
649
650 self.list_avail_data.append(v)
651 index += 1
652
653 def _OnUseAll(self, event):
654 for i in range(self.list_avail.GetItemCount()):
655 self.__MoveListItem(0, self.list_avail, self.list_use)
656
657 def _OnUse(self, event):
658 self.__MoveSelectedItems(self.list_avail, self.list_use)
659
660 def _OnDontUse(self, event):
661 self.__MoveSelectedItems(self.list_use, self.list_avail)
662
663 def _OnUseNone(self, event):
664
665 for i in range(self.list_use.GetItemCount()):
666 self.__MoveListItem(0, self.list_use, self.list_avail)
667
668 def __MoveSelectedItems(self, list_src, list_dest):
669 while True:
670 index = list_src.GetNextItem(-1,
671 wxLIST_NEXT_ALL,
672 wxLIST_STATE_SELECTED)
673
674 if index == -1:
675 break
676
677 self.__MoveListItem(index, list_src, list_dest)
678
679
680 def __MoveListItem(self, index, list_src, list_dest):
681
682 item = list_src.GetItem(index)
683
684 x = list_dest.InsertStringItem(
685 list_dest.GetItemCount(),
686 str(self.dataList[item.GetData()]))
687
688 list_dest.SetItemData(x, item.GetData())
689
690 list_src.DeleteItem(index)
691
692 # def _OnListSize(self, event):
693 # list = event.GetEventObject()
694
695 # list.SetColumnWidth(0, event.GetSize().GetWidth())
696 #
697
698 ID_CUSTOMRAMP_COPYSTART = 4001
699 ID_CUSTOMRAMP_COPYEND = 4002
700 ID_CUSTOMRAMP_EDITSTART = 4003
701 ID_CUSTOMRAMP_EDITEND = 4004
702 ID_CUSTOMRAMP_SPROP = 4005
703 ID_CUSTOMRAMP_EPROP = 4006
704
705 class CustomRampPanel(wxPanel):
706
707 def __init__(self, parent, shapeType):
708 wxPanel.__init__(self, parent, -1)
709
710 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""), wxHORIZONTAL)
711
712 bsizer = wxBoxSizer(wxVERTICAL)
713 bsizer.Add(wxStaticText(self, -1, _("Start:")), 0, wxALL | wxCENTER, 4)
714 self.startPropCtrl = classifier.ClassGroupPropertiesCtrl(
715 self, ID_CUSTOMRAMP_SPROP,
716 ClassGroupProperties(), shapeType,
717 style=wxSIMPLE_BORDER, size=(40, 20))
718 bsizer.Add(self.startPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
719 bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITSTART, _("Change")),
720 0, wxGROW | wxALL | wxCENTER, 4)
721
722 topSizer.Add(bsizer,
723 1, wxALL \
724 | wxSHAPED \
725 | wxALIGN_CENTER_HORIZONTAL \
726 | wxALIGN_CENTER_VERTICAL, \
727 4)
728
729 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
730 bsizer = wxBoxSizer(wxVERTICAL)
731 bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
732 0, wxGROW | wxALL, 4)
733 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
734 bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
735 0, wxGROW | wxALL, 4)
736
737 topSizer.Add(bsizer,
738 0, wxALL \
739 | wxALIGN_CENTER_HORIZONTAL \
740 | wxALIGN_CENTER_VERTICAL,
741 4)
742
743 bsizer = wxBoxSizer(wxVERTICAL)
744 bsizer.Add(wxStaticText(self, -1, _("End:")), 0, wxALL | wxCENTER, 4)
745 self.endPropCtrl = classifier.ClassGroupPropertiesCtrl(
746 self, ID_CUSTOMRAMP_EPROP,
747 ClassGroupProperties(), shapeType,
748 style=wxSIMPLE_BORDER, size=(40, 20))
749 bsizer.Add(self.endPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
750 bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITEND, _("Change")),
751 0, wxGROW | wxALL | wxCENTER, 4)
752
753 topSizer.Add(bsizer,
754 1, wxALL \
755 | wxSHAPED \
756 | wxALIGN_RIGHT \
757 | wxALIGN_CENTER_HORIZONTAL \
758 | wxALIGN_CENTER_VERTICAL,
759 4)
760
761 EVT_BUTTON(self, ID_CUSTOMRAMP_COPYSTART, self._OnCopyStart)
762 EVT_BUTTON(self, ID_CUSTOMRAMP_COPYEND, self._OnCopyEnd)
763 EVT_BUTTON(self, ID_CUSTOMRAMP_EDITSTART, self._OnEditStart)
764 EVT_BUTTON(self, ID_CUSTOMRAMP_EDITEND, self._OnEditEnd)
765
766 self.SetSizer(topSizer)
767 self.SetAutoLayout(True)
768 topSizer.SetSizeHints(self)
769
770 def GetRamp(self):
771 return CustomRamp(self.startPropCtrl.GetProperties(),
772 self.endPropCtrl.GetProperties())
773
774 def _OnCopyStart(self, event):
775 self.endPropCtrl.SetProperties(self.startPropCtrl.GetProperties())
776
777 def _OnCopyEnd(self, event):
778 self.startPropCtrl.SetProperties(self.endPropCtrl.GetProperties())
779
780 def _OnEditStart(self, event):
781 self.startPropCtrl.DoEdit()
782
783 def _OnEditEnd(self, event):
784 self.endPropCtrl.DoEdit()
785
786 class ClassGenerator:
787
788 def GenSingletonsFromList(self, list, numGroups, ramp):
789 """Generate a new classification consisting solely of singletons.
790
791 The resulting classification will consist of at most 'numGroups'
792 groups whose group properties ramp between 'prop1' and 'prop2'. There
793 could be fewer groups if 'list' contains fewer that 'numGroups' items.
794
795 list -- any object that implements the iterator interface
796
797 numGroups -- how many groups to generate. This can not be
798 determined while the classification is being
799 generated because the stepping values must
800 be precalculated to ramp between prop1 and prop2.
801
802 prop1 -- initial group property values
803
804 prop2 -- final group property values
805 """
806
807 clazz = Classification()
808 if numGroups == 0: return clazz
809
810 ramp.SetNumGroups(numGroups)
811
812 for value, prop in zip(list, ramp):
813 clazz.AppendGroup(ClassGroupSingleton(value, prop))
814
815 return clazz
816
817 def GenSingletons(self, min, max, numGroups, ramp):
818
819 clazz = Classification()
820
821 #step = int((max - min) / float(numGroups))
822
823 if numGroups > 0:
824
825 step = int((max - min + 1) / float(numGroups))
826 cur_value = min
827
828 ramp.SetNumGroups(numGroups)
829
830 for prop in ramp:
831 clazz.AppendGroup(ClassGroupSingleton(cur_value), prop)
832 cur_value += step
833
834 return clazz
835
836 def GenUnifromDistribution(self, min, max, numGroups,
837 ramp, intStep = False):
838 """Generate a classification with numGroups range groups
839 each with the same interval.
840
841 intStep -- force the calculated stepping to an integer.
842 Useful if the values are integers but the
843 number of groups specified doesn't evenly
844 divide (max - min).
845 """
846
847 clazz = Classification()
848 if numGroups == 0: return clazz
849
850 ramp.SetNumGroups(numGroups)
851
852 step = (max - min) / float(numGroups)
853
854 if intStep:
855 step = int(step)
856
857 cur_min = min
858 cur_max = cur_min + step
859
860 i = 0
861 for prop in ramp:
862
863 if i == (numGroups - 1):
864 cur_max = max
865
866 # this check guards against rounding issues
867 if cur_min != cur_max:
868 clazz.AppendGroup(ClassGroupRange(cur_min, cur_max, prop))
869
870 cur_min = cur_max
871 cur_max += step
872 i += 1
873
874 return clazz
875
876 CLR = 0
877 STEP = 1
878 class CustomRamp:
879
880 def __init__(self, prop1, prop2):
881 self.prop1 = prop1
882 self.prop2 = prop2
883
884 self.count = 0
885
886 def __iter__(self):
887 return self
888
889 def GetRamp(self):
890 return self
891
892 def SetNumGroups(self, num):
893
894 if num <= 0:
895 return False
896
897 self.count = int(num)
898 num = float(num)
899
900 prop1 = self.prop1
901 prop2 = self.prop2
902
903 clr = prop1.GetLineColor()
904 lineColor2 = prop2.GetLineColor()
905
906 self.noLine = clr is not Color.Transparent \
907 and lineColor2 is not Color.Transparent
908
909
910 self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),
911 prop2.GetLineColor(),
912 num)
913
914 self.fillInfo = self.__GetColorInfo(prop1.GetFill(),
915 prop2.GetFill(),
916 num)
917
918 self.lineWidth = prop1.GetLineWidth()
919 self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num
920
921 return True
922
923 def next(self):
924 if self.count == 0:
925 raise StopIteration
926
927 prop = ClassGroupProperties()
928
929 if self.lineInfo is None:
930 prop.SetLineColor(Color.Transparent)
931 else:
932 prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,
933 self.lineInfo[CLR][1] / 255,
934 self.lineInfo[CLR][2] / 255))
935
936 self.lineInfo[CLR][0] += self.lineInfo[STEP][0]
937 self.lineInfo[CLR][1] += self.lineInfo[STEP][1]
938 self.lineInfo[CLR][2] += self.lineInfo[STEP][2]
939
940 if self.fillInfo is None:
941 prop.SetFill(Color.Transparent)
942 else:
943 prop.SetFill(Color(self.fillInfo[CLR][0] / 255,
944 self.fillInfo[CLR][1] / 255,
945 self.fillInfo[CLR][2] / 255))
946
947 self.fillInfo[CLR][0] += self.fillInfo[STEP][0]
948 self.fillInfo[CLR][1] += self.fillInfo[STEP][1]
949 self.fillInfo[CLR][2] += self.fillInfo[STEP][2]
950
951
952 prop.SetLineWidth(int(self.lineWidth))
953 self.lineWidth += self.lineWidthStep
954
955 self.count -= 1
956
957 return prop
958
959 def __GetColorInfo(self, color1, color2, numGroups):
960
961 if color1 is Color.Transparent and color2 is Color.Transparent:
962 #
963 # returning early
964 #
965 return None
966 elif color1 is not Color.Transparent and color2 is Color.Transparent:
967 color = [color1.red * 255,
968 color1.green * 255,
969 color1.blue * 255]
970 step = (0, 0, 0)
971 elif color1 is Color.Transparent and color2 is not Color.Transparent:
972 color = [color2.red * 255,
973 color2.green * 255,
974 color2.blue * 255]
975 step = (0, 0, 0)
976 else:
977 color = [color1.red * 255,
978 color1.green * 255,
979 color1.blue * 255]
980 step = ((color2.red * 255 - color1.red * 255) / numGroups,
981 (color2.green * 255 - color1.green * 255) / numGroups,
982 (color2.blue * 255 - color1.blue * 255) / numGroups)
983
984
985 return (color, step)
986
987 class MonochromaticRamp(CustomRamp):
988 def __init__(self, start, end):
989 sp = ClassGroupProperties()
990 sp.SetLineColor(start)
991 sp.SetFill(start)
992
993 ep = ClassGroupProperties()
994 ep.SetLineColor(end)
995 ep.SetFill(end)
996
997 CustomRamp.__init__(self, sp, ep)
998
999 class GreyRamp(MonochromaticRamp):
1000 def __init__(self):
1001 MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))
1002
1003 class RedRamp(MonochromaticRamp):
1004 def __init__(self):
1005 MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(.8, 0, 0))
1006
1007 class GreenRamp(MonochromaticRamp):
1008 def __init__(self):
1009 MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, .8, 0))
1010
1011 class BlueRamp(MonochromaticRamp):
1012 def __init__(self):
1013 MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, .8))
1014
1015 class HotToColdRamp:
1016
1017 def __iter__(self):
1018 return self
1019
1020 def GetRamp(self):
1021 return self
1022
1023 def SetNumGroups(self, num):
1024 if num < 0:
1025 return False
1026
1027 self.num = float(num)
1028 self.index = 0
1029
1030 return True
1031
1032 def next(self):
1033 if self.index == self.num:
1034 raise StopIteration
1035
1036 clr = [1.0, 1.0, 1.0]
1037
1038 if self.index < (.25 * self.num):
1039 clr[0] = 0
1040 clr[1] = 4 * self.index / self.num
1041 elif self.index < (.5 * self.num):
1042 clr[0] = 0
1043 clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num
1044 elif self.index < (.75 * self.num):
1045 clr[0] = 4 * (self.index - .5 * self.num) / self.num
1046 clr[2] = 0
1047 else:
1048 clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num
1049 clr[2] = 0
1050
1051 self.index += 1
1052
1053 prop = ClassGroupProperties()
1054 prop.SetLineColor(Color(clr[0], clr[1], clr[2]))
1055 prop.SetFill(Color(clr[0], clr[1], clr[2]))
1056
1057 return prop
1058
1059 #class Colors16Ramp:
1060 #
1061 #def __iter__(self):
1062 #return self
1063 #
1064 #def GetRamp(self):
1065 #return self
1066 #
1067 #def SetNumGroups(self, num):
1068 #if num < 0:
1069 #return False
1070 #
1071 #self.index = 0
1072 #
1073 #return True
1074
1075

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26