def get_keyboard_frame(self,frame=None): '''get corrected keyboard frame, in the screen coordinates. built in function breaks when in fullscreen, as it reports kbframe relative to a landscape screen''' #TODO: remove dependence on webview, use xaxis/yaxis to determine rotation instead if frame is None: frame=ui.get_keyboard_frame() origin=ui.convert_point((0,0),None,self ) xaxis=ui.convert_point((1,0),None,self ) xaxis=[xaxis[j]-origin[j] for j in (0,1)] yaxis=ui.convert_point((0,1),None,self ) yaxis=[yaxis[j]-origin[j] for j in (0,1)] o=self.__w.eval_js('window.orientation') (w,h)=ui.get_screen_size() if xaxis[0]==1 and yaxis[1]==1 and frame[0]==0: #we are not in fullscreen, just return kbframe fixedframe=frame elif o=='0': fixedframe= frame #ok elif o=='-90': fixedframe= [frame[1], frame[0], h,frame[2]] elif o=='180': fixedframe= [frame[0], h-frame[1]-frame[3], frame[2],frame[3]] #okrqq elif o=='90': fixedframe= [frame[1], w-frame[0]-frame[2],h,frame[2]] else: raise Error('UnexpectedOrientation') return fixedframe
def convert_point(point=(0,0),from_view=None,to_view=None): '''fixed convert point for fullscreen application. works for any present type existing function in fullscreen reports relative to portrait TODO: does not work if from_view or to_view has been Transformed''' (w,h)=ui.get_screen_size() #detect what convert_point things rotation is. origin=ui.convert_point((0,0),from_view,to_view ) xaxis=ui.convert_point((1,0),from_view,to_view ) xaxis=[xaxis[j]-origin[j] for j in (0,1)] yaxis=ui.convert_point((0,1),from_view,to_view ) yaxis=[yaxis[j]-origin[j] for j in (0,1)] pt_c=ui.convert_point(tuple(point),from_view,to_view) pt=[0,0] if from_view is not None: pt[0]=( (xaxis[0]==-1)*h + xaxis[0]*pt_c[0] + (yaxis[0]==1)*w - yaxis[0]*pt_c[1]) pt[1] = ( (xaxis[1]==1)*h - xaxis[1]*pt_c[0] + (yaxis[1]==-1)*w + yaxis[1]*pt_c[1]) else: #just get corrected origin, and subtract out origin_offset=RootView.convert_point((0,0),to_view,from_view) pt[0]= point[0] - origin_offset[0] pt[1]= point[1] - origin_offset[1] return tuple(pt)
def get_keyboard_frame(self): '''get corrected keyboard frame, in the screen coordinates. built in function breaks when in fullscreen, as it reports kbframe relative to a landscape screen''' #TODO: remove dependence on webview, use xaxis/yaxis to determine rotation instead origin=ui.convert_point((0,0),None,self ) xaxis=ui.convert_point((1,0),None,self ) xaxis=[xaxis[j]-origin[j] for j in (0,1)] yaxis=ui.convert_point((0,1),None,self ) yaxis=[yaxis[j]-origin[j] for j in (0,1)] o=self.__w.eval_js('window.orientation') frame=ui.get_keyboard_frame() (w,h)=ui.get_screen_size() if xaxis[0]==1 and yaxis[1]==1 and frame[0]==0: #we are not in fullscreen, just return kbframe fixedframe=frame elif o=='0': fixedframe= frame #ok elif o=='-90': fixedframe= [frame[1], frame[0], h,frame[2]] elif o=='180': fixedframe= [frame[0], h-frame[1]-frame[3], frame[2],frame[3]] #okrqq elif o=='90': fixedframe= [frame[1], w-frame[0]-frame[2],h,frame[2]] else: raise Error('UnexpectedOrientation') return fixedframe
def screen(source_value, target, source): if not source.superview or not target.superview: return (0, 0) return ui.convert_point( ui.convert_point(source_value, source.superview), to_view=target.superview, )
def fix_touch(self, touch): '''convert to root coords. i think this doesnt quite work, ''' t = Touch(touch) t.location = ui.convert_point(t.location, self, self.superview) t.prev_location = ui.convert_point(t.prev_location, self, self.superview) return t
def fix_touch(self,touch): '''convert to root coords. i think this doesnt quite work, ''' t=Touch(touch) t.location=ui.convert_point(tuple(t.location),self,self.superview) t.prev_location=ui.convert_point(tuple(t.prev_location),self,self.superview) return t
def convert_point(self,point=(0,0),from_view=None,to_view=None): '''fixed convert point for fullscreen application. works for any present type existing function in fullscreen reports relative to portrait TODO: does not work if from_view or to_view has been Transformed''' (w,h)=ui.get_screen_size() #detect what convert_point things rotation is. origin=ui.convert_point((0,0),from_view,to_view ) xaxis=ui.convert_point((1,0),from_view,to_view ) xaxis=[xaxis[j]-origin[j] for j in (0,1)] yaxis=ui.convert_point((0,1),from_view,to_view ) yaxis=[yaxis[j]-origin[j] for j in (0,1)] pt_c=ui.convert_point(tuple(point),from_view,to_view) pt=[0,0] if from_view is not None: pt[0]=( (xaxis[0]==-1)*h + xaxis[0]*pt_c[0] + (yaxis[0]==1)*w - yaxis[0]*pt_c[1]) pt[1] = ( (xaxis[1]==1)*h - xaxis[1]*pt_c[0] + (yaxis[1]==-1)*w + yaxis[1]*pt_c[1]) else: #just get corrected origin, and subtract out origin_offset=self.convert_point((0,0),to_view,from_view) pt[0]= point[0] - origin_offset[0] pt[1]= point[1] - origin_offset[1] return tuple(pt)
def ani(): dialog.x, dialog.y = ui.convert_point( (self.textfield.x, self.textfield.y + self.textfield.height), self, root) dialog.width = self.textfield.width dialog.height = min( 400, root.height - ui.convert_point( (0, dialog.y), self, root)[1])
def on_rotate(self, data): if not self.rotate: return if data.began: self.start_rotation = self.rotation if data.changed: focus_pos = ui.convert_point(data.location, self, self.zoomer) self.rotation = self.start_rotation + data.rotation if self.min_rotation is not None: self.rotation = max(self.rotation, self.min_rotation) if self.max_rotation is not None: self.rotation = min(self.rotation, self.max_rotation) #self.zoomer.transform = ui.Transform.rotation(math.radians(self.rotation)) self._set_transforms() focus_location = ui.convert_point(focus_pos, self.zoomer, self) self.zoomer.center -= focus_location - data.location
def on_pinch(self, data): if not self.zoom: return if data.began: self.start_scale = self.scale if data.changed: focus_pos = ui.convert_point(data.location, self, self.zoomer) self.scale = self.start_scale * data.scale if self.min_scale is not None: self.scale = max(self.scale, self.min_scale) if self.max_scale is not None: self.scale = min(self.scale, self.max_scale) #self.zoomer.transform = ui.Transform.scale(*(self.scale,)*2) self._set_transforms() focus_location = ui.convert_point(focus_pos, self.zoomer, self) self.zoomer.center -= focus_location - data.location
def relay_touch(self, touch, func_name): v = self.superview while v: f = getattr(v, func_name, None) if f: t = SimpleNamespace( touch_id=touch.touch_id, prev_location=ui.convert_point(touch.prev_location, self, v), location=ui.convert_point(touch.location, self, v), phase=touch.phase, timestamp=touch.timestamp) f(t) break v = self.superview
def do_long_touch(self): if self.touched: self.doing_longtouch=True root=self.get_top_view() flow=self.flow #set popup flow as child to root, in proper location # root needs to be a plain view without layout manager myposinroot=ui.convert_point((0,0),self,root) flow.x=myposinroot[0] flow.y=myposinroot[1] root.add_subview(flow) flow.layout() flow.bg_color=self.bg_color flow.border_color=self.border_color flow.tint_color=self.tint_color flow.hidden=False def pop(): flow.y=flow.y-flow.height-20 flow.x=flow.x ui.animate(pop,0.05) self.set_needs_display() # add delayed cleanup of the popup, for panel mode where this deosnt behave self.longtouchcleanuptimer=Timer(3.0,self.longtouch_cleanup) self.longtouchcleanuptimer.start()
def on_rotate(self, data): if not self.rotate: return if data.began: self.start_rotation = self.rotation if data.changed: focus_pos = ui.convert_point( data.location, self, self.zoomer) self.rotation = self.start_rotation + data.rotation if self.min_rotation is not None: self.rotation = max(self.rotation, self.min_rotation) if self.max_rotation is not None: self.rotation = min(self.rotation, self.max_rotation) #self.zoomer.transform = ui.Transform.rotation(math.radians(self.rotation)) self._set_transforms() focus_location = ui.convert_point( focus_pos, self.zoomer, self) self.zoomer.center -= focus_location - data.location
def on_pinch(self, data): if not self.zoom: return if data.began: self.start_scale = self.scale if data.changed: focus_pos = ui.convert_point( data.location, self, self.zoomer) self.scale = self.start_scale * data.scale if self.min_scale is not None: self.scale = max(self.scale, self.min_scale) if self.max_scale is not None: self.scale = min(self.scale, self.max_scale) #self.zoomer.transform = ui.Transform.scale(*(self.scale,)*2) self._set_transforms() focus_location = ui.convert_point( focus_pos, self.zoomer, self) self.zoomer.center -= focus_location - data.location
def childHits(self,location): location=list(location) location[1]-=25 # allow room for a finger, mske virtual hit point a little higher for s in self.flow.subviews: if PopupButton.hit(s,ui.convert_point(tuple(location),self,s)): s.bg_color=(0,0,1) yield s else : s.bg_color=(.8,.8,.8)
def btn_action(sender): print sender f = (0,0,400, 800) pt = tuple(sender.center) v = ui.View(frame = f) loc = ui.convert_point(pt, sender, None) #loc = ui.convert_point(loc, None, v) v.present('popover', popover_location = tuple(loc) )
def relay_touch(self, touch, func_name): v = self.superview while v: f = getattr(v, func_name, None) if f: t = SimpleNamespace( touch_id=touch.touch_id, prev_location=ui.convert_point( touch.prev_location, self, v), location=ui.convert_point( touch.location, self, v), phase=touch.phase, timestamp=touch.timestamp) f(t) break v = self.superview
def move_node(self, label, location): self.stop_animation() loc = ui.convert_point(location, label, self) label.center = loc n = self.node_lookup[label.name] self.positions[n] = graph.Vector.from_pos(loc) self.fixed_nodes.add(n) self.tick()
def get_absolute_y(view): """ :type view: ui.View """ if view.superview: return get_absolute_y(view.superview) + view.frame[1] else: # see https://forum.omz-software.com/topic/2701/keyboard-hiding-textview point_in_system_coordinates = ui.convert_point(point=(0, 0), from_view=view, to_view=None) return point_in_system_coordinates[1]
def touch_ended(self,touch): # dispatch whatever is under the touch # for multitouch probably only want to execute when there are no active touches left. # this method would need to clean out touches, but still keep info on the active gesture. when there are no active touches left, then kill the gesture # for now.... just look under the touch, and call something appropriate. # need to handle each ui type! #print self.name, 'touch ended' for s in self.subviews: #probably need to check whether another view is on top... if TouchDispatcher.hit(s,ui.convert_point(touch.location,self,s)): if isinstance(s,ui.TextField): #print '..textfield begin editing' s.begin_editing() #think about setting cursor.... HARD! but possible i think? elif isinstance(s, ui.Button): #print '..button launch' s.action(s) elif isinstance(s, TouchDispatcher): # adjust touch location to subviews coordinates, then dispatch # print '..touch end: dispatch: ', s.name t=Touch(touch) t.location=ui.convert_point(touch.location,self,s) s.touch_ended(t)
def touch_ended(self, touch): # dispatch whatever is under the touch # for multitouch probably only want to execute when there are no active touches left. # this method would need to clean out touches, but still keep info on the active gesture. when there are no active touches left, then kill the gesture # for now.... just look under the touch, and call something appropriate. # need to handle each ui type! print(self.name, 'touch ended') for s in self.subviews: #probably need to check whether another view is on top... if TouchDispatcher.hit(s, ui.convert_point(touch.location, self, s)): if isinstance(s, ui.TextField): print('..textfield begin editing') s.begin_editing() #think about setting cursor.... HARD! but possible i think? elif isinstance(s, ui.Button): print('..button launch') s.action(s) elif isinstance(s, TouchDispatcher): # adjust touch location to subviews coordinates, then dispatch print('..touch end: dispatch: ', s.name) t = Touch(touch) t.location = ui.convert_point(touch.location, self, s) s.touch_ended(t)
def ani(): dialog.x,dialog.y=ui.convert_point((self.textfield.x,self.textfield.y+self.textfield.height),self,root) dialog.width=self.textfield.width dialog.height=min(400,root.height-ui.convert_point((0,dialog.y),self,root)[1])
def touch_moved(self, touch): (x, y) = ui.convert_point(touch.location, self, self.superview) self.center = (x - 20, y - 20)
def touch_ended(self, touch): (x, y) = ui.convert_point(touch.location, self, self.superview) if x < 20: self.superview.remove_waypoint(self)