- a few simplifications and cleanups in the WINGs python code
[wmaker-crm.git] / WINGs / python / WINGs.py
blob1ac49adcbadf554ea7f2d82c64069ec64c14e0bc
1 #!/usr/bin/env python
3 import sys
4 import wings
6 # Some useful constants
8 False = 0
9 True = 1
11 # check about None as action for buttonAction/windowCloseAction ...
13 ################################################################################
14 # Exceptions
15 ################################################################################
16 from exceptions import Exception, StandardError
18 class Error(StandardError):
19 pass
21 del Exception, StandardError
23 class WMTimer:
24 def __init__(self, milliseconds, callback, cdata=None, persistent=False):
25 if persistent:
26 self._o = wings.pyWMAddPersistentTimerHandler(milliseconds, (callback, cdata))
27 else:
28 self._o = wings.pyWMAddTimerHandler(milliseconds, (callback, cdata))
30 def __del__(self):
31 wings.pyWMDeleteTimerHandler(self._o)
32 #delete = __del__
34 class WMPersistentTimer(WMTimer):
35 def __init__(self, milliseconds, callback, cdata=None):
36 WMTimer.__init__(self, milliseconds, callback, cdata, persistent=True)
39 class WMScreen:
40 __readonly = ('display', 'width', 'height', 'depth')
42 def __init__(self, appname, display="", simpleapp=False):
43 wings.WMInitializeApplication(appname, len(sys.argv), sys.argv)
44 self._o = wings.pyWMOpenScreen(display, simpleapp)
45 if not self._o:
46 raise Error, "Cannot open display %s" % display
47 self.__dict__['display'] = wings.WMScreenDisplay(self._o)
48 self.__dict__['width'] = wings.WMScreenWidth(self._o)
49 self.__dict__['height'] = wings.WMScreenHeight(self._o)
50 self.__dict__['depth'] = wings.WMScreenDepth(self._o)
52 def __setattr__(self, name ,value):
53 if name in self.__readonly:
54 #raise AttributeError, "'%s' is a read-only WMScreen attribute" % name
55 raise Error, "'%s' is a read-only WMScreen attribute" % name
56 self.__dict__[name] = value
58 def mainLoop(self):
59 wings.pyWMScreenMainLoop(self._o)
61 def breakMainLoop(self):
62 wings.pyWMBreakScreenMainLoop(self._o)
64 def runModalLoop(self, view):
65 wings.pyWMRunModalLoop(self._o, view)
67 def breakModalLoop(self):
68 wings.WMBreakModalLoop(self._o)
70 def size(self):
71 return (self.width, self.height)
74 class WMView:
75 pass
78 class WMWidget(WMView):
79 def __init__(self):
80 self._o = None
81 if self.__class__ == WMWidget:
82 raise Error, "a WMWidget can't be instantiated directly"
84 def __del__(self):
85 if (self._o != None):
86 wings.WMDestroyWidget(self._o)
88 def resize(self, width, height):
89 wings.WMResizeWidget(self._o, width, height)
91 def move(self, x, y):
92 wings.WMMoveWidget(self._o, x, y)
94 def realize(self):
95 wings.WMRealizeWidget(self._o)
97 def show(self):
98 wings.WMMapWidget(self._o)
100 def hide(self):
101 wings.WMUnmapWidget(self._o)
103 def redisplay(self):
104 wings.WMRedisplayWidget(self._o)
106 def width(self):
107 return wings.WMWidgetWidth(self._o)
109 def height(self):
110 return wings.WMWidgetHeight(self._o)
112 def screen(self):
113 return wings.WMWidgetScreen(self._o)
115 def view(self):
116 return wings.WMWidgetView(self._o)
118 def setFocusTo(self, other):
119 wings.WMSetFocusToWidget(other._o)
122 class WMWindow(WMWidget):
123 def __init__(self, screen, name, style=wings.WMTitledWindowMask
124 |wings.WMClosableWindowMask|wings.WMMiniaturizableWindowMask
125 |wings.WMResizableWindowMask):
126 WMWidget.__init__(self)
127 self._o = wings.WMCreateWindowWithStyle(screen._o, name, style)
129 def setMinSize(self, minWidth, minHeight):
130 wings.WMSetWindowMinSize(self._o, minWidth, minHeight)
132 def setMaxSize(self, maxWidth, maxHeight):
133 wings.WMSetWindowMaxSize(self._o, maxWidth, maxHeight)
135 def setInitialPosition(self, x, y):
136 wings.WMSetWindowInitialPosition(self._o, x, y)
138 def setTitle(self, title):
139 wings.WMSetWindowTitle(self._o, title)
141 def setCloseAction(self, action, data=None):
142 if action!=None and (not callable(action)):
143 raise Error, "action needs to be a callable object or None"
144 wings.pyWMSetWindowCloseAction(self._o, (self, action, data))
147 class WMPanel(WMWindow):
148 def __init__(self, owner, name, style=wings.WMTitledWindowMask
149 |wings.WMClosableWindowMask|wings.WMResizableWindowMask):
150 WMWidget.__init__(self)
151 self._o = wings.WMCreatePanelWithStyleForWindow(owner._o, name, style)
153 class WMFrame(WMWidget):
154 def __init__(self, parent, title=None):
155 WMWidget.__init__(self)
156 self._o = wings.WMCreateFrame(parent._o)
157 self.setTitle(title)
159 def setRelief(self, relief):
160 wings.WMSetFrameRelief(self._o, relief)
162 def setTitle(self, title=""):
163 wings.WMSetFrameTitle(self._o, title)
165 def setTitlePosition(self, position):
166 wings.WMSetFrameTitlePosition(self._o, position)
168 class WMLabel(WMWidget):
169 def __init__(self, parent, text=None):
170 WMWidget.__init__(self)
171 self._o = wings.WMCreateLabel(parent._o)
172 self.setText(text)
174 def setWraps(self, flag):
175 # bool(flag) for python2.2
176 wings.WMSetLabelWraps(self._o, flag)
178 def setRelief(self, relief):
179 wings.WMSetLabelRelief(self._o, relief)
181 def setText(self, text=""):
182 wings.WMSetLabelText(self._o, text)
184 def setTextColor(self, color):
185 wings.WMSetLabelTextColor(self._o, color)
187 def setFont(self, font):
188 wings.WMSetLabelFont(self._o, font)
190 def setTextAlignment(self, alignment):
191 wings.WMSetLabelTextAlignment(self._o, alignment)
193 def setImage(self, image):
194 wings.WMSetLabelImage(self._o, image)
196 def setImagePosition(self, position):
197 wings.WMSetLabelImagePosition(self._o, position)
199 def text(self):
200 return wings.WMGetLabelText(self._o)
202 def font(self):
203 return wings.WMGetLabelFont(self._o)
205 def image(self):
206 return wings.WMGetLabelImage(self._o)
209 class WMBox(WMWidget):
210 def __init__(self, parent):
211 WMWidget.__init__(self)
212 self._o = wings.WMCreateBox(parent._o)
214 def setHorizontal(self, flag):
215 # bool(flag) for python2.2
216 wings.WMSetBoxHorizontal(self._o, flag)
218 def setBorderWidth(self, width):
219 wings.WMSetBoxBorderWidth(self._o, width)
221 def addSubview(self, view, expand, fill, minSize, maxSize, space):
222 wings.WMAddBoxSubview(self._o, view, expand, fill, minSize, maxSixe, space)
224 def addSubviewAtEnd(self, view, expand, fill, minSize, maxSize, space):
225 wings.WMAddBoxSubviewAtEnd(self._o, view, expand, fill, minSize, maxSixe, space)
227 def removeSubview(self, view):
228 wings.WMRemoveBoxSubview(self._o, view)
231 class WMButton(WMWidget): # not for user instantiation
232 def __init__(self, parent):
233 WMWidget.__init__(self)
234 if self.__class__ == WMButton:
235 raise Error, "a WMButton can't be instantiated directly"
238 def setText(self, text=""):
239 wings.WMSetButtonText(self._o, text)
241 def setAction(self, action, data=None):
242 if action!=None and (not callable(action)):
243 raise Error, "action needs to be a callable object or None"
244 wings.pyWMSetButtonAction(self._o, (self, action, data))
246 def performClick(self):
247 wings.WMPerformButtonClick(self._o)
249 def setEnabled(self, flag):
250 # bool(flag) for python2.2
251 wings.WMSetButtonEnabled(self._o, flag)
253 def isEnabled(self):
254 return wings.WMGetButtonEnabled(self._o)
256 def setImageDimsWhenDisabled(self, flag):
257 # bool(flag)
258 wings.WMSetButtonImageDimsWhenDisabled(self._o, flag)
260 def setImage(self, image):
261 wings.WMSetButtonImage(self_.o, image)
263 def setAlternateImage(self, image):
264 wings.WMSetButtonAltImage(self._o, image)
266 def setImagePosition(self, position):
267 wings.WMSetButtonImagePosition(self._o, position)
269 def setImageDefault(self):
270 wings.WMSetButtonImageDefault(self._o)
273 class WMCommandButton(WMButton):
274 def __init__(self, parent):
275 WMButton.__init__(self, parent)
276 self._o = wings.WMCreateCommandButton(parent._o)
279 class WMSwitchButton(WMButton):
280 def __init__(self, parent):
281 WMButton.__init__(self, parent)
282 self._o = wings.WMCreateSwitchButton(parent._o)
285 class WMRadioButton(WMButton):
286 def __init__(self, parent, group=None):
287 WMButton.__init__(self, parent)
288 self._o = wings.WMCreateRadioButton(parent._o)
289 if group:
290 wings.WMGroupButtons(group._o, self._o)
293 class WMListItem:
294 pass
297 class WMList(WMWidget):
298 def __init__(self, parent):
299 WMWidget.__init__(self)
300 self._o = wings.WMCreateList(parent._o)
302 def allowEmptySelection(self, flag):
303 # bool(flag)
304 wings.WMSetListAllowEmptySelection(self._o, flag)
306 def allowMultipleSelection(self, flag):
307 # bool(flag)
308 wings.WMSetListAllowMultipleSelection(self._o, flag)
310 def addItem(self, item):
311 wings.WMAddListItem(self._o, item)
313 def insertItem(self, row, item):
314 wings.WMInsertListItem(self._o, row, item)
316 def sortItems(self):
317 wings.WMSortListItems(self._o)
319 def rowWithTitle(self, title):
320 return wings.WMFindRowOfListItemWithTitle(self._o, title)
322 def selectedItemRow(self):
323 return wings.WMGetListSelectedItemRow(self._o)
325 def selectedItem(self):
326 return wings.WMGetListSelectedItem(self._o)
328 def removeItem(self, index):
329 wings.WMRemoveListItem(self._o, index)
331 def selectItem(self, index):
332 wings.WMSelectListItem(self._o, index)
334 def unselectItem(self, index):
335 wings.WMUnselectListItem(self._o, index)
338 class WMTextFieldDelegate:
339 __callbacks = ('didBeginEditing', 'didChange', 'didEndEditing',
340 'shouldBeginEditing', 'shouldEndEditing')
342 def __init__(self):
343 self.__dict__['data'] = None
344 self.__dict__['didBeginEditing'] = None
345 self.__dict__['didChange'] = None
346 self.__dict__['didEndEditing'] = None
347 self.__dict__['shouldBeginEditing'] = None
348 self.__dict__['shouldEndEditing'] = None
350 def __setattr__(self, name ,value):
351 if name in self.__callbacks and value!=None and (not callable(value)):
352 #raise AttributeError, "%s.%s needs to be a callable object or None" % (self.__class__.__name__, name)
353 raise Error, "%s.%s needs to be a callable object or None" % (self.__class__.__name__, name)
354 else:
355 self.__dict__[name] = value
358 class WMTextField(WMWidget):
359 def __init__(self, parent, text=""):
360 WMWidget.__init__(self)
361 self._o = wings.WMCreateTextField(parent._o)
362 wings.WMSetTextFieldText(self._o, text)
364 def setDelegate(self, delegate):
365 if delegate.__class__ != WMTextFieldDelegate:
366 raise Error, "textfield delegate must be of type 'WMTextFieldDelegate'"
367 wings.pyWMSetTextFieldDelegate(self._o, (self, delegate))
369 def delegate(self):
370 return wings.pyWMGetTextFieldDelegate(self._o)
372 def text(self):
373 return wings.WMGetTextFieldText(self._o)
375 def setEditable(self, flag):
376 # bool(flag)
377 wings.WMSetTextFieldEditable(self._o, flag)
379 def setBordered(self, flag):
380 # bool(flag)
381 wings.WMSetTextFieldBordered(self._o, flag)
383 def setBeveled(self, flag):
384 # bool(flag)
385 wings.WMSetTextFieldBeveled(self._o, flag)
387 def setSecure(self, flag):
388 # bool(flag)
389 wings.WMSetTextFieldSecure(self._o, flag)
391 def setCursorPosition(self, position):
392 wings.WMSetTextFieldCursorPosition(self._o, position)
394 def setNextText(self, next):
395 wings.WMSetTextFieldNextTextField(self._o, next._o)
397 def setPreviousText(self, previous):
398 wings.WMSetTextFieldPrevTextField(self._o, previous._o)
400 def setTextAlignment(self, alignment):
401 wings.WMSetTextFieldAlignment(self._o, alignment)
403 def isEditable(self):
404 return wings.WMGetTextFieldEditable(self._o)
406 def insertText(self, text, position):
407 wings.WMInsertTextFieldText(self._o, text, position)
409 def deleteText(self, start, count):
410 wings.WMDeleteTextFieldRange(self._o, wings.wmkrange(start, count))
412 def selectText(self, start, count):
413 wings.WMSelectTextFieldRange(self._o, wings.wmkrange(start, count))
415 def setFont(self, font):
416 wings.WMSetTextFieldFont(self._o, font)
418 def font(self):
419 return wings.WMGetTextFieldFont(self._o)
422 ################################################################################
423 # wrap the WINGs constants so we don't need wings.constant_name
424 ################################################################################
426 # WMWindow title style
427 WMTitledWindowMask = wings.WMTitledWindowMask
428 WMClosableWindowMask = wings.WMClosableWindowMask
429 WMMiniaturizableWindowMask = wings.WMMiniaturizableWindowMask
430 WMResizableWindowMask = wings.WMResizableWindowMask
432 # WMFrame title positions
433 WTPNoTitle = wings.WTPNoTitle
434 WTPAboveTop = wings.WTPAboveTop
435 WTPAtTop = wings.WTPAtTop
436 WTPBelowTop = wings.WTPBelowTop
437 WTPAboveBottom = wings.WTPAboveBottom
438 WTPAtBottom = wings.WTPAtBottom
439 WTPBelowBottom = wings.WTPBelowBottom
441 # Alingments
442 WALeft = wings.WALeft
443 WACenter = wings.WACenter
444 WARight = wings.WARight
445 WAJustified = wings.WAJustified # not valid for textfields
447 # Image positions
448 WIPNoImage = wings.WIPNoImage
449 WIPImageOnly = wings.WIPImageOnly
450 WIPLeft = wings.WIPLeft
451 WIPRight = wings.WIPRight
452 WIPBelow = wings.WIPBelow
453 WIPAbove = wings.WIPAbove
454 WIPOverlaps = wings.WIPOverlaps
456 # Relief types
457 WRFlat = wings.WRFlat
458 WRSimple = wings.WRSimple
459 WRRaised = wings.WRRaised
460 WRSunken = wings.WRSunken
461 WRGroove = wings.WRGroove
462 WRRidge = wings.WRRidge
463 WRPushed = wings.WRPushed
466 # TextField events
467 WMReturnTextMovement = wings.WMReturnTextMovement
468 WMEscapeTextMovement = wings.WMEscapeTextMovement
469 WMIllegalTextMovement = wings.WMIllegalTextMovement
470 WMTabTextMovement = wings.WMTabTextMovement
471 WMBacktabTextMovement = wings.WMBacktabTextMovement
472 WMLeftTextMovement = wings.WMLeftTextMovement
473 WMRightTextMovement = wings.WMRightTextMovement
474 WMUpTextMovement = wings.WMUpTextMovement
475 WMDownTextMovement = wings.WMDownTextMovement
478 if __name__ == "__main__":
479 def quit(obj, data):
480 #sys.exit()
481 scr.breakMainLoop()
483 def click(btn, list):
484 print win.width(), win.height()
485 print list.selectedItemRow()
486 win2.show()
487 scr.runModalLoop(win2.view())
488 print txt2.text()
490 def sayhi(btn, data):
491 print "hi"
493 def breakLoop(btn, data):
494 #sys.exit()
495 scr.breakModalLoop()
496 win2.hide()
498 def dc(object, data, action):
499 print "didChange:", object, data, action
501 def dbe(object, data, action):
502 print "didBeginEditing:", object, data, action
504 def dee(object, data, action):
505 if action == wings.WMReturnTextMovement:
506 if object == txt:
507 object.setFocusTo(txt2)
508 else:
509 object.setFocusTo(txt)
510 print "didEndEditing:", object, data, action, object.text()
512 def tcb(one):
513 old = list.selectedItemRow()
514 list.selectItem(list.index)
515 list.unselectItem(old)
516 list.index = (list.index+1) % 3
517 #print one
519 scr = WMScreen("foobar")
520 win = WMWindow(scr, "aWindow")
521 win.setCloseAction(quit)
522 win.setTitle("test window")
523 win.resize(400, 180)
524 win.setInitialPosition((scr.width-win.width())/2, (scr.height-win.height())/2)
526 btn = WMCommandButton(win)
527 btn.setText("Click Me")
528 btn.resize(100, 25)
529 btn.move(20, 20)
530 btn.show()
532 sw = WMSwitchButton(win)
533 sw.setText("Some option")
534 sw.resize(100, 25)
535 sw.move(20, 50)
536 sw.show()
538 radios = []
539 r = None
540 j = 0
541 for i in ["One", "Two", "Four"]:
542 r = WMRadioButton(win, r)
543 radios.append(r)
544 r.show()
545 r.setText(i)
546 r.move(20, 70+j*25)
547 r.resize(100, 25)
548 j=j+1
550 sw.setAction(sayhi)
552 list = WMList(win)
553 list.resize(100,100)
554 list.move(130, 20)
555 list.addItem("one")
556 list.addItem("two")
557 list.addItem("three")
558 list.allowMultipleSelection(1)
559 list.show()
560 list.index = 0
562 txtdel = WMTextFieldDelegate()
563 txtdel.data = 'mydata'
564 txtdel.didBeginEditing = dbe
565 txtdel.didEndEditing = dee
566 txtdel.didChange = dc
568 txt = WMTextField(win, "abc")
569 txt.resize(95, 20)
570 txt.move(295, 20)
571 txt.setDelegate(txtdel)
572 txt.show()
573 txt2 = WMTextField(win, "01234567890")
574 txt2.resize(95, 20)
575 txt2.move(295, 45)
576 txt2.setDelegate(txtdel)
577 txt2.show()
579 txt.setNextText(txt2)
580 txt2.setNextText(txt)
582 label = WMLabel(win, "Text1:")
583 label.setTextAlignment(WARight)
584 label.move(240, 20)
585 label.resize(55, 20)
586 label.show()
588 label2 = WMLabel(win, "mytext2:")
589 label2.setTextAlignment(WARight)
590 label2.move(240, 45)
591 label2.resize(55, 20)
592 label2.show()
594 btn.setAction(click, list)
596 frame = WMFrame(win, "My Frame")
597 frame.resize(150, 50)
598 frame.move(240, 70)
599 #frame.setRelief(WRPushed)
600 frame.show()
602 ebtn = WMCommandButton(win)
603 ebtn.setText("Exit")
604 ebtn.resize(100, 25)
605 ebtn.move(290, 147)
606 ebtn.setAction(quit)
607 ebtn.show()
609 win.realize()
610 win.show()
612 timer = WMPersistentTimer(1000, tcb, win)
613 #del(timer)
614 #timer.delete()
616 win2 = WMPanel(win, "anotherWindow", WMTitledWindowMask)
617 win2.setTitle("transient test window")
618 win2.resize(150, 50)
619 win2.setInitialPosition((scr.width-win2.width())/2, (scr.height-win2.height())/2)
621 btn7 = WMCommandButton(win2)
622 btn7.setText("Dismiss")
623 btn7.resize(100, 25)
624 btn7.move(27, 10)
625 btn7.show()
626 btn7.setAction(breakLoop)
628 win2.realize()
630 scr.mainLoop()