Package pyjamas :: Package ui :: Module AreaSlider
[hide private]
[frames] | no frames]

Source Code for Module pyjamas.ui.AreaSlider

  1  """ Control Widgets.  Presently comprises a Vertical Slider and derivatives. 
  2   
  3      HorizontalSlider and HorizontalSlider2 added by Bill Winder  
  4      AreaSlider and AreaSlider2 added by Bill Winder  
  5   
  6      Copyright (C) 2008, 2009, 2010 Luke Kenneth Casson Leighton <lkcl@lkcl.net> 
  7      Copyright (C) 2010 - Cedric Gestes <gestes@aldebaran-robotics.com> 
  8      Copyright (C) 2009, 2010 - Bill Winder <wgwinder@gmail.com>  
  9   
 10   
 11      To do: All controls with draggable=True do not fire the OnFocus methon on single click. 
 12      the control does not activate the OnFocus method. Clicking the handle does fire OnFocus, however. 
 13   
 14  """ 
 15   
 16  from pyjamas import Factory 
 17  from pyjamas import DOM 
 18  from pyjamas.ui import Focus 
 19  from DoubleControl import DoubleControl 
 20   
 21   
22 -class AreaSlider(DoubleControl):
23
24 - def __init__(self, min_value, max_value, 25 start_value=None, step=None, 26 **kwargs):
27 28 if not kwargs.has_key("StyleName"): 29 kwargs['StyleName'] = "gwt-VerticalSlider" 30 31 if kwargs.has_key('Element'): 32 # XXX FIXME: Focus.createFocusable is here for a reason... 33 element = kwargs.pop('Element') 34 else: 35 element = Focus.createFocusable() 36 DOM.setStyleAttribute(element, "position", "relative") 37 DOM.setStyleAttribute(element, "overflow", "hidden") 38 39 self.handle = DOM.createDiv() 40 DOM.appendChild(element, self.handle) 41 42 self.setHandleStyle("1px", "100%", "10px", "#808080") 43 44 # must use DoubleControl; otherwise, this init is = Vertical init, 45 # plus a change in the handle style 46 # this should be refactored, so that the AreaSlider 47 # can be built on VerticalSlider 48 DoubleControl.__init__(self, element, min_value, max_value, 49 start_value, step, 50 **kwargs) 51 52 self.addClickListener(self) 53 self.addFocusListener(self) 54 self.addMouseListener(self) 55 56 #Redefine VDS's styles for handle 57 self.setHandleStyle("1px", "10px", "10px", "#808080")
58
59 - def setHandleStyle(self, border, width, height, backgroundColor):
60 if border is not None: 61 DOM.setStyleAttribute(self.handle, "border", border) 62 if width is not None: 63 DOM.setStyleAttribute(self.handle, "width", width) 64 if height is not None: 65 DOM.setStyleAttribute(self.handle, "height", height) 66 if backgroundColor is not None: 67 DOM.setStyleAttribute(self.handle, "backgroundColor", backgroundColor)
68
69 - def setValue(self, new_value, notify=1):
70 old_value = [self.value_x, self.value_y] 71 72 self.value_x = new_value[0] 73 self.value_y = new_value[1] 74 75 if not notify: 76 return 77 78 for listener in self.valuechange_listeners: 79 # how to handle this? ??? 80 listener.onControlValueChanged(self, old_value, new_value)
81
82 - def onFocus(self, sender):
83 self.addStyleName("gwt-VerticalSlider-focussed")
84
85 - def onLostFocus(self, sender):
86 self.removeStyleName("gwt-VerticalSlider-focussed") 87 self.dragging = False 88 DOM.releaseCapture(self.getElement())
89
90 - def moveControl(self, mouse_x, mouse_y):
91 handle_height = DOM.getIntAttribute(self.handle, "offsetHeight") 92 widget_height = self.getOffsetHeight() 93 height_range = widget_height - 10 # handle height is hard-coded 94 relative_y = mouse_y - (handle_height / 2) 95 if relative_y < 0: 96 relative_y = 0 97 if relative_y >= height_range: 98 relative_y = height_range 99 100 # turn round (bottom to top) for x 101 relative_y = height_range - relative_y 102 103 handle_width = DOM.getIntAttribute(self.handle, "offsetWidth") 104 widget_width = self.getOffsetWidth() 105 length_range = widget_width - 10 # handle width is hard-coded 106 relative_x = mouse_x - (handle_width / 2) 107 if relative_x < 0: 108 relative_x = 0 109 if relative_x >= length_range: 110 relative_x = length_range 111 112 val_diff_x = self.max_value_x - self.min_value_x 113 new_value_x = ((val_diff_x * relative_x) / length_range) + \ 114 self.min_value_x 115 116 val_diff_y = self.max_value_y - self.min_value_y 117 new_value_y = ((val_diff_y * relative_y) / height_range) + \ 118 self.min_value_y 119 120 new_value = [new_value_x, new_value_y] 121 new_value = self.processValue(new_value) 122 self.setControlPos(new_value) 123 self.setValue(new_value)
124
125 - def setControlPos(self, value):
126 value_x = value[0] 127 value_y = value[1] 128 129 widget_width = self.getOffsetWidth() 130 length_range = widget_width - 10 # handle width is hard-coded 131 val_diff_x = self.max_value_x - self.min_value_x 132 relative_x = length_range * (value_x - self.min_value_x) / val_diff_x 133 134 # limit the position to be in the widget! 135 if relative_x < 0: 136 relative_x = 0 137 if relative_x >= length_range: 138 relative_x = length_range 139 140 widget_height = self.getOffsetHeight() 141 height_range = widget_height - 10 # handle height is hard-coded 142 val_diff_y = self.max_value_y - self.min_value_y 143 relative_y = height_range * (value_y - self.min_value_y) / val_diff_y 144 145 # limit the position to be in the widget! 146 if relative_y < 0: 147 relative_y = 0 148 if relative_y >= height_range: 149 relative_y = height_range 150 151 relative_y = height_range - relative_y # turn round (bottom to top) 152 153 # move the handle 154 DOM.setStyleAttribute(self.handle, "top", "%dpx" % relative_y) 155 DOM.setStyleAttribute(self.handle, "left", "%dpx" % relative_x) 156 DOM.setStyleAttribute(self.handle, "position", "absolute")
157 158 Factory.registerClass('pyjamas.ui.AreaSlider', AreaSlider) 159