<s> from math import sin , cos , pi , floor , ceil <EOL> import wx <EOL> import numpy as np <EOL> import koko <EOL> from koko . prims . menu import show_menu <EOL> from koko . struct import Struct <EOL> class Canvas ( wx . Panel ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent , app , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> wx . Panel . __init__ ( self , parent , * args , ** kwargs ) <EOL> self . mark_changed_view = app . mark_changed_view <EOL> self . bind_callbacks ( ) <EOL> self . click = self . mouse = wx . Point ( ) <EOL> self . center = [ <NUM_LIT:0.0> , <NUM_LIT:0.0> ] <EOL> self . alpha = self . beta = <NUM_LIT:0> <EOL> self . scale = <NUM_LIT> <EOL> self . mm_per_unit = <NUM_LIT> <EOL> self . image = None <EOL> self . drag_target = None <EOL> self . dc = None <EOL> self . paths = [ ] <EOL> self . traverses = None <EOL> self . snap = True <EOL> def bind_callbacks ( self ) : <EOL> """<STR_LIT>""" <EOL> self . Bind ( wx . EVT_PAINT , self . paint ) <EOL> self . Bind ( wx . EVT_MOTION , self . mouse_move ) <EOL> self . Bind ( wx . EVT_LEFT_DOWN , self . mouse_lclick ) <EOL> self . Bind ( wx . EVT_LEFT_DCLICK , self . mouse_dclick ) <EOL> self . Bind ( wx . EVT_LEFT_UP , self . mouse_lrelease ) <EOL> self . Bind ( wx . EVT_RIGHT_DOWN , self . mouse_rclick ) <EOL> self . Bind ( wx . EVT_MOUSEWHEEL , self . mouse_scroll ) <EOL> self . Bind ( wx . EVT_SIZE , self . mark_changed_view ) <EOL> self . Bind ( wx . EVT_ERASE_BACKGROUND , lambda e : None ) <EOL> self . Bind ( wx . EVT_CHAR , self . char ) <EOL> @ property <EOL> def border ( self ) : <EOL> """<STR_LIT>""" <EOL> return getattr ( self , '<STR_LIT>' , None ) <EOL> @ border . setter <EOL> def border ( self , value ) : <EOL> """<STR_LIT>""" <EOL> self . _border = value <EOL> wx . CallAfter ( self . Refresh ) <EOL> def mouse_move ( self , event ) : <EOL> """<STR_LIT>""" <EOL> self . mouse = wx . Point ( event . GetX ( ) , event . GetY ( ) ) <EOL> x , y = self . pixel_to_pos ( * self . mouse ) <EOL> if koko . PRIMS . mouse_pos ( x , y ) : self . Refresh ( ) <EOL> if self . drag_target is not None : <EOL> self . dragged = True <EOL> delta = self . mouse - self . click <EOL> self . click = self . mouse <EOL> self . drag_target . drag ( delta . x / self . scale , - delta . y / self . scale ) <EOL> self . Refresh ( ) <EOL> def mouse_lclick ( self , event ) : <EOL> """<STR_LIT>""" <EOL> self . mouse = wx . Point ( event . GetX ( ) , event . GetY ( ) ) <EOL> self . click = self . mouse <EOL> self . dragged = bool ( self . drag_target ) <EOL> x , y = self . pixel_to_pos ( * self . mouse ) <EOL> t = koko . PRIMS . get_target ( x , y ) <EOL> if t : <EOL> self . drag_target = t <EOL> else : <EOL> self . drag_target = self <EOL> def mouse_lrelease ( self , event ) : <EOL> """<STR_LIT>""" <EOL> if self . drag_target : <EOL> if self . dragged and self . drag_target != self : <EOL> koko . PRIMS . push_stack ( ) <EOL> elif not self . dragged : <EOL> koko . PRIMS . close_panels ( ) <EOL> self . drag_target = None <EOL> def mouse_rclick ( self , event ) : <EOL> '''<STR_LIT>''' <EOL> menu = show_menu ( ) <EOL> menu . AppendSeparator ( ) <EOL> snap = menu . Append ( wx . ID_ANY , text = '<STR_LIT>' ) <EOL> self . Bind ( wx . EVT_MENU , lambda e : self . snap_bounds ( ) , snap ) <EOL> self . mouse = wx . Point ( event . GetX ( ) , event . GetY ( ) ) <EOL> x , y = self . pixel_to_pos ( * self . mouse ) <EOL> t = koko . PRIMS . get_target ( x , y ) <EOL> delete = menu . Append ( wx . ID_ANY , text = '<STR_LIT>' ) <EOL> if t is not None : <EOL> self . Bind ( wx . EVT_MENU , lambda e : koko . PRIMS . delete ( t ) , delete ) <EOL> else : <EOL> delete . Enable ( False ) <EOL> undo = menu . Append ( wx . ID_ANY , text = '<STR_LIT>' ) <EOL> if koko . PRIMS . can_undo : <EOL> self . Bind ( wx . EVT_MENU , koko . PRIMS . undo , undo ) <EOL> else : <EOL> undo . Enable ( False ) <EOL> self . PopupMenu ( menu ) <EOL> def char ( self , event ) : <EOL> """<STR_LIT>""" <EOL> if event . CmdDown ( ) and event . GetKeyCode ( ) == ord ( '<STR_LIT>' ) : <EOL> if koko . PRIMS . can_undo : koko . PRIMS . undo ( ) <EOL> elif event . GetKeyCode ( ) == <NUM_LIT> : <EOL> x , y = self . pixel_to_pos ( * self . mouse ) <EOL> t = koko . PRIMS . get_target ( x , y ) <EOL> koko . PRIMS . delete ( t ) <EOL> else : <EOL> event . Skip ( ) <EOL> def mouse_dclick ( self , event ) : <EOL> '''<STR_LIT>''' <EOL> self . mouse = wx . Point ( event . GetX ( ) , event . GetY ( ) ) <EOL> x , y = self . pixel_to_pos ( * self . mouse ) <EOL> target = koko . PRIMS . get_target ( x , y ) <EOL> if target is not None : <EOL> target . open_panel ( ) <EOL> def mouse_scroll ( self , event ) : <EOL> '''<STR_LIT>''' <EOL> width , height = self . Size <EOL> origin = ( ( width / <NUM_LIT:2> - self . mouse [ <NUM_LIT:0> ] ) / self . scale - self . center [ <NUM_LIT:0> ] , <EOL> ( self . mouse [ <NUM_LIT:1> ] - height / <NUM_LIT:2> ) / self . scale - self . center [ <NUM_LIT:1> ] ) <EOL> dScale = <NUM_LIT> <EOL> if event . GetWheelRotation ( ) < <NUM_LIT:0> : <EOL> dScale = <NUM_LIT:1> / dScale <EOL> for i in range ( abs ( event . GetWheelRotation ( ) ) ) : <EOL> self . scale *= dScale <EOL> if self . scale > ( <NUM_LIT:1> << <NUM_LIT:32> ) : <EOL> self . scale = <NUM_LIT:1> << <NUM_LIT:32> <EOL> self . center = ( ( width / <NUM_LIT:2> - self . mouse [ <NUM_LIT:0> ] ) / self . scale - origin [ <NUM_LIT:0> ] , <EOL> ( self . mouse [ <NUM_LIT:1> ] - height / <NUM_LIT:2> ) / self . scale - origin [ <NUM_LIT:1> ] ) <EOL> self . mark_changed_view ( ) <EOL> self . Refresh ( ) <EOL> def drag ( self , dx , dy ) : <EOL> '''<STR_LIT>''' <EOL> self . center = ( self . center [ <NUM_LIT:0> ] - dx , self . center [ <NUM_LIT:1> ] - dy ) <EOL> self . mark_changed_view ( ) <EOL> self . Refresh ( ) <EOL> def mm_to_pixel ( self , x , y = None ) : <EOL> """<STR_LIT>""" <EOL> width , height = self . Size <EOL> xcenter , ycenter = self . center <EOL> xcenter *= self . mm_per_unit <EOL> ycenter *= self . mm_per_unit <EOL> scale = self . scale / self . mm_per_unit <EOL> if y is None : <EOL> return int ( x * scale ) <EOL> else : <EOL> return map ( int , <EOL> [ ( x - xcenter ) * scale + ( width / <NUM_LIT> ) , <EOL> height / <NUM_LIT> - ( y - ycenter ) * scale ] <EOL> ) <EOL> def pos_to_pixel ( self , x , y = None ) : <EOL> """<STR_LIT>""" <EOL> width , height = self . Size <EOL> xcenter , ycenter = self . center <EOL> if y is None : <EOL> return int ( x * self . scale ) <EOL> else : <EOL> return map ( int , <EOL> [ ( x - xcenter ) * self . scale + ( width / <NUM_LIT> ) , <EOL> height / <NUM_LIT> - ( y - ycenter ) * self . scale ] <EOL> ) <EOL> def pixel_to_pos ( self , i , j ) : <EOL> """<STR_LIT>""" <EOL> width , height = self . Size <EOL> xcenter , ycenter = self . center <EOL> return ( ( i - width / <NUM_LIT:2> ) / self . scale + xcenter , <EOL> ( height / <NUM_LIT:2> - j ) / self . scale + ycenter ) <EOL> def get_crop ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . image . xmin < self . xmin * self . mm_per_unit : <EOL> x0 = floor ( <EOL> self . image . pixels_per_mm * <EOL> ( self . xmin * self . mm_per_unit - self . image . xmin ) <EOL> ) <EOL> else : <EOL> x0 = <NUM_LIT:0> <EOL> if self . image . xmax > self . xmax * self . mm_per_unit : <EOL> x1 = ceil ( <EOL> self . image . width - ( self . image . pixels_per_mm * <EOL> ( self . image . xmax - self . xmax * self . mm_per_unit ) ) <EOL> ) <EOL> else : <EOL> x1 = self . image . width <EOL> if self . image . ymin < self . ymin * self . mm_per_unit : <EOL> y1 = ceil ( <EOL> self . image . height - ( self . image . pixels_per_mm * <EOL> ( self . ymin * self . mm_per_unit - self . image . ymin ) ) <EOL> ) <EOL> else : <EOL> y1 = self . image . height <EOL> if self . image . ymax > self . ymax * self . mm_per_unit : <EOL> y0 = floor ( <EOL> self . image . pixels_per_mm * <EOL> ( self . image . ymax - self . ymax * self . mm_per_unit ) <EOL> ) <EOL> else : <EOL> y0 = <NUM_LIT:0> <EOL> return wx . Rect ( x0 , y0 , x1 - x0 , y1 - y0 ) <EOL> def paint ( self , event = None ) : <EOL> '''<STR_LIT>''' <EOL> self . dc = wx . PaintDC ( self ) <EOL> self . dc . SetBackground ( wx . Brush ( ( <NUM_LIT:20> , <NUM_LIT:20> , <NUM_LIT:20> ) ) ) <EOL> self . dc . Clear ( ) <EOL> self . draw_image ( ) <EOL> if koko . FRAME . get_menu ( '<STR_LIT>' , '<STR_LIT>' ) . IsChecked ( ) : <EOL> self . draw_bounds ( ) <EOL> if koko . FRAME . get_menu ( '<STR_LIT>' , '<STR_LIT>' ) . IsChecked ( ) : <EOL> self . draw_axes ( ) <EOL> self . draw_paths ( ) <EOL> self . draw_border ( ) <EOL> koko . PRIMS . draw ( self ) <EOL> self . dc = None <EOL> def draw_image ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not self . image : return <EOL> width , height = self . Size <EOL> xcenter , ycenter = self . center [ <NUM_LIT:0> ] , self . center [ <NUM_LIT:1> ] <EOL> if self . scale / self . mm_per_unit == self . image . pixels_per_mm : <EOL> bitmap = wx . BitmapFromImage ( self . image . wximg ) <EOL> xmin = self . image . xmin <EOL> ymax = self . image . ymax <EOL> else : <EOL> crop = self . get_crop ( ) <EOL> if crop . Width <= <NUM_LIT:0> or crop . Height <= <NUM_LIT:0> : return <EOL> scale = self . scale / ( self . mm_per_unit * self . image . pixels_per_mm ) <EOL> img = self . image . wximg . Copy ( ) . GetSubImage ( crop ) <EOL> if int ( img . Width * scale ) == <NUM_LIT:0> or int ( img . Height * scale ) == <NUM_LIT:0> : <EOL> return <EOL> img . Rescale ( img . Width * scale , <EOL> img . Height * scale ) <EOL> bitmap = wx . BitmapFromImage ( img ) <EOL> xmin = ( <EOL> self . image . xmin + <EOL> crop . Left * self . image . mm_per_pixel <EOL> ) <EOL> ymax = ( <EOL> self . image . ymax - <EOL> crop . Top * self . image . mm_per_pixel <EOL> ) <EOL> imgX , imgY = self . mm_to_pixel ( xmin , ymax ) <EOL> self . dc . SetBrush ( wx . Brush ( ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) ) ) <EOL> self . dc . SetPen ( wx . TRANSPARENT_PEN ) <EOL> self . dc . DrawRectangle ( imgX , imgY , bitmap . Width , bitmap . Height ) <EOL> self . dc . DrawBitmap ( bitmap , imgX , imgY ) <EOL> def load_paths ( self , paths , xmin , ymin ) : <EOL> """<STR_LIT>""" <EOL> cuts = [ ] <EOL> for p in paths : <EOL> if p . closed : <EOL> cuts . append ( <EOL> np . append ( p . points [ : , <NUM_LIT:0> : <NUM_LIT:2> ] , [ p . points [ <NUM_LIT:0> , <NUM_LIT:0> : <NUM_LIT:2> ] ] , axis = <NUM_LIT:0> ) <EOL> ) <EOL> else : <EOL> cuts . append ( np . copy ( p . points [ : , <NUM_LIT:0> : <NUM_LIT:2> ] ) ) <EOL> cuts [ - <NUM_LIT:1> ] [ : , <NUM_LIT:0> ] += xmin <EOL> cuts [ - <NUM_LIT:1> ] [ : , <NUM_LIT:1> ] += ymin <EOL> traverses = np . empty ( ( <NUM_LIT:0> , <NUM_LIT:6> ) ) <EOL> for i in range ( len ( paths ) - <NUM_LIT:1> ) : <EOL> p = paths [ i ] <EOL> start = p . points [ <NUM_LIT:0> , : ] if p . closed else p . points [ - <NUM_LIT:1> , : ] <EOL> end = paths [ i + <NUM_LIT:1> ] . points [ <NUM_LIT:0> , : ] <EOL> traverses = np . append ( traverses , <EOL> [ np . append ( start , end ) ] , axis = <NUM_LIT:0> ) <EOL> traverses [ : , <NUM_LIT:0> ] += xmin <EOL> traverses [ : , <NUM_LIT:1> ] += ymin <EOL> traverses [ : , <NUM_LIT:3> ] += xmin <EOL> traverses [ : , <NUM_LIT:4> ] += ymin <EOL> wx . CallAfter ( self . _load_paths , cuts , traverses ) <EOL> def _load_paths ( self , paths , traverses ) : <EOL> """<STR_LIT>""" <EOL> self . paths = paths <EOL> self . traverses = traverses <EOL> self . Refresh ( ) <EOL> def clear ( self ) : <EOL> """<STR_LIT>""" <EOL> self . images = [ ] <EOL> self . image = None <EOL> self . paths = None <EOL> self . Refresh ( ) <EOL> def clear_path ( self ) : <EOL> """<STR_LIT>""" <EOL> self . paths = None <EOL> self . Refresh ( ) <EOL> return <EOL> def draw_paths ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . paths is None : return <EOL> self . dc . SetBrush ( wx . TRANSPARENT_BRUSH ) <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT:100> , <NUM_LIT:255> , <NUM_LIT> ) , <NUM_LIT:1> ) ) <EOL> scale = self . scale / self . mm_per_unit <EOL> center = ( <EOL> self . center [ <NUM_LIT:0> ] * self . mm_per_unit , <EOL> self . center [ <NUM_LIT:1> ] * self . mm_per_unit <EOL> ) <EOL> for i in range ( len ( self . paths ) ) : <EOL> d = i / float ( len ( self . paths ) ) <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT:100> * d , <NUM_LIT:200> * d + <NUM_LIT:50> , <NUM_LIT:255> * ( <NUM_LIT:1> - d ) ) , <NUM_LIT:1> ) ) <EOL> p = self . paths [ i ] <EOL> i = ( p [ : , <NUM_LIT:0> ] - center [ <NUM_LIT:0> ] ) * scale + self . Size [ <NUM_LIT:0> ] / <NUM_LIT> <EOL> j = self . Size [ <NUM_LIT:1> ] / <NUM_LIT> - ( p [ : , <NUM_LIT:1> ] - center [ <NUM_LIT:1> ] ) * scale <EOL> self . dc . DrawLines ( zip ( i , j ) ) <EOL> if koko . FRAME . get_menu ( '<STR_LIT>' , '<STR_LIT>' ) . IsChecked ( ) : <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT:255> , <NUM_LIT:100> , <NUM_LIT:100> ) , <NUM_LIT:1> ) ) <EOL> t = self . traverses <EOL> if t is None or t . size == <NUM_LIT:0> : return <EOL> i0 = ( t [ : , <NUM_LIT:0> ] - center [ <NUM_LIT:0> ] ) * scale + self . Size [ <NUM_LIT:0> ] / <NUM_LIT> <EOL> j0 = self . Size [ <NUM_LIT:1> ] / <NUM_LIT> - ( t [ : , <NUM_LIT:1> ] - center [ <NUM_LIT:1> ] ) * scale <EOL> i1 = ( t [ : , <NUM_LIT:3> ] - center [ <NUM_LIT:0> ] ) * scale + self . Size [ <NUM_LIT:0> ] / <NUM_LIT> <EOL> j1 = self . Size [ <NUM_LIT:1> ] / <NUM_LIT> - ( t [ : , <NUM_LIT:4> ] - center [ <NUM_LIT:1> ] ) * scale <EOL> self . dc . DrawLineList ( zip ( i0 , j0 , i1 , j1 ) ) <EOL> def draw_axes ( self ) : <EOL> """<STR_LIT>""" <EOL> def spin ( x , y , z , alpha , beta ) : <EOL> ca , sa = cos ( alpha ) , sin ( alpha ) <EOL> x , y , z = ( ca * x - sa * y , sa * x + ca * y , z ) <EOL> cb , sb = cos ( beta ) , sin ( beta ) <EOL> x , y , z = ( x , cb * y + sb * z , - sb * y + cb * z ) <EOL> return x , y , z <EOL> center = self . pos_to_pixel ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT:255> , <NUM_LIT:0> , <NUM_LIT:0> ) , <NUM_LIT:2> ) ) <EOL> x , y , z = spin ( <NUM_LIT:50> , <NUM_LIT:0> , <NUM_LIT:0> , - self . alpha , - self . beta ) <EOL> self . dc . DrawLine ( center [ <NUM_LIT:0> ] , center [ <NUM_LIT:1> ] , center [ <NUM_LIT:0> ] + x , center [ <NUM_LIT:1> ] - y ) <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT:0> , <NUM_LIT:255> , <NUM_LIT:0> ) , <NUM_LIT:2> ) ) <EOL> x , y , z = spin ( <NUM_LIT:0> , <NUM_LIT:50> , <NUM_LIT:0> , - self . alpha , - self . beta ) <EOL> self . dc . DrawLine ( center [ <NUM_LIT:0> ] , center [ <NUM_LIT:1> ] , center [ <NUM_LIT:0> ] + x , center [ <NUM_LIT:1> ] - y ) <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:255> ) , <NUM_LIT:2> ) ) <EOL> x , y , z = spin ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:50> , - self . alpha , - self . beta ) <EOL> self . dc . DrawLine ( center [ <NUM_LIT:0> ] , center [ <NUM_LIT:1> ] , center [ <NUM_LIT:0> ] + x , center [ <NUM_LIT:1> ] - y ) <EOL> def draw_border ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . border : <EOL> self . dc . SetPen ( wx . TRANSPARENT_PEN ) <EOL> self . dc . SetBrush ( wx . Brush ( self . border ) ) <EOL> border_width = <NUM_LIT:3> <EOL> self . dc . DrawRectangle ( <NUM_LIT:0> , <NUM_LIT:0> , self . Size [ <NUM_LIT:0> ] , border_width ) <EOL> self . dc . DrawRectangle ( <NUM_LIT:0> , self . Size [ <NUM_LIT:1> ] - border_width , <EOL> self . Size [ <NUM_LIT:0> ] , border_width ) <EOL> self . dc . DrawRectangle ( <NUM_LIT:0> , <NUM_LIT:0> , border_width , self . Size [ <NUM_LIT:1> ] ) <EOL> self . dc . DrawRectangle ( self . Size [ <NUM_LIT:0> ] - border_width , <NUM_LIT:0> , <EOL> border_width , self . Size [ <NUM_LIT:1> ] ) <EOL> def draw_bounds ( self ) : <EOL> """<STR_LIT>""" <EOL> for i in self . images : <EOL> scale = self . scale / self . mm_per_unit <EOL> xmin , ymin = self . pos_to_pixel ( <EOL> i . xmin / self . mm_per_unit , i . ymin / self . mm_per_unit <EOL> ) <EOL> xmax , ymax = self . pos_to_pixel ( <EOL> i . xmax / self . mm_per_unit , i . ymax / self . mm_per_unit <EOL> ) <EOL> self . dc . SetPen ( wx . Pen ( ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ) ) ) <EOL> self . dc . SetBrush ( wx . TRANSPARENT_BRUSH ) <EOL> self . dc . DrawRectangle ( xmin , ymin , xmax - xmin , ymax - ymin ) <EOL> @ property <EOL> def xmin ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . center [ <NUM_LIT:0> ] - self . Size [ <NUM_LIT:0> ] / <NUM_LIT> / self . scale <EOL> @ property <EOL> def xmax ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . center [ <NUM_LIT:0> ] + self . Size [ <NUM_LIT:0> ] / <NUM_LIT> / self . scale <EOL> @ property <EOL> def ymin ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . center [ <NUM_LIT:1> ] - self . Size [ <NUM_LIT:1> ] / <NUM_LIT> / self . scale <EOL> @ property <EOL> def ymax ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . center [ <NUM_LIT:1> ] + self . Size [ <NUM_LIT:1> ] / <NUM_LIT> / self . scale <EOL> @ property <EOL> def view ( self ) : <EOL> """<STR_LIT>""" <EOL> return Struct ( xmin = self . xmin , xmax = self . xmax , <EOL> ymin = self . ymin , ymax = self . ymax , <EOL> alpha = self . alpha , beta = self . beta , <EOL> pixels_per_unit = self . scale ) <EOL> def load_image ( self , img , mm_per_unit = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> self . load_images ( [ img ] , mm_per_unit ) <EOL> def load_images ( self , imgs , mm_per_unit = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> merged = imgs [ <NUM_LIT:0> ] . merge ( imgs ) <EOL> wx . CallAfter ( self . _load_images , imgs , merged , mm_per_unit ) <EOL> def _load_images ( self , imgs , merged , mm_per_unit = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> self . images = imgs <EOL> self . image = merged <EOL> if self . snap : <EOL> self . snap_bounds ( ) <EOL> self . snap = False <EOL> self . mm_per_unit = mm_per_unit <EOL> self . Refresh ( ) <EOL> def snap_bounds ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . image : return <EOL> width , height = self . Size <EOL> try : <EOL> self . center = [ <EOL> ( self . image . xmin + self . image . dx / <NUM_LIT> ) / self . mm_per_unit , <EOL> ( self . image . ymin + self . image . dy / <NUM_LIT> ) / self . mm_per_unit <EOL> ] <EOL> self . scale = float ( <EOL> min ( width / ( self . image . dx / self . mm_per_unit ) , <EOL> height / ( self . image . dy / self . mm_per_unit ) ) <EOL> ) <EOL> self . alpha = self . beta = <NUM_LIT:0> <EOL> except TypeError : <EOL> pass <EOL> else : <EOL> self . mark_changed_view ( ) <EOL> self . Refresh ( ) <EOL> def snap_axis ( self , axis ) : <EOL> """<STR_LIT>""" <EOL> if axis == '<STR_LIT>' : <EOL> self . alpha , self . beta = pi / <NUM_LIT:2> , - pi / <NUM_LIT:2> <EOL> elif axis == '<STR_LIT>' : <EOL> self . alpha , self . beta = <NUM_LIT:0> , pi / <NUM_LIT:2> <EOL> elif axis == '<STR_LIT>' : <EOL> self . alpha , self . beta = <NUM_LIT:0> , <NUM_LIT:0> <EOL> elif axis == '<STR_LIT>' : <EOL> self . alpha , self . beta = - pi / <NUM_LIT:2> , - pi / <NUM_LIT:2> <EOL> elif axis == '<STR_LIT>' : <EOL> self . alpha , self . beta = <NUM_LIT:0> , - pi / <NUM_LIT:2> <EOL> elif axis == '<STR_LIT>' : <EOL> self . alpha , self . beta = <NUM_LIT:0> , pi <EOL> self . mark_changed_view ( ) <EOL> self . Refresh ( ) </s>
