CraftLaunch APIリファレンス

clnch_widget.py

00001 import os
00002 import sys
00003 import math
00004 import struct
00005 import Image
00006 
00007 import pyauto
00008 import cterm
00009 from cterm.cterm_const import *
00010 
00011 import clnch_skin
00012 import clnch_misc
00013 import clnch_native
00014 import clnch_colortable
00015 
00016 # ----------------------------------------------------------------------------------------------------------------------------
00017 #
00018 # ----------------------------------------------------------------------------------------------------------------------------
00019 
00020 class Widget:
00021 
00022     def __init__( self, window, x, y, width, height ):
00023         self.window = window
00024         self.x = x
00025         self.y = y
00026         self.width = width
00027         self.height = height
00028         self.enable_cursor = False
00029         self.enable_ime = False
00030 
00031     def setPosSize( self, x, y, width, height ):
00032         self.x = x
00033         self.y = y
00034         self.width = width
00035         self.height = height
00036 
00037     def enableCursor( self, enable ):
00038         if not self.enable_cursor and enable:
00039             self.window.enableIme( self.enable_ime )
00040         self.enable_cursor = enable
00041 
00042     def enableIme( self, enable ):
00043         self.window.enableIme( self.enable_cursor )
00044         self.enable_ime = enable
00045 
00046 
00047 # ----------------------------------------------------------------------------------------------------------------------------
00048 #
00049 # ----------------------------------------------------------------------------------------------------------------------------
00050 
00051 class ButtonWidget(Widget):
00052 
00053     def __init__( self, window, x, y, width, height, message, handler=None ):
00054 
00055         Widget.__init__( self, window, x, y, width, height )
00056 
00057         self.message = message
00058         self.handler = handler
00059 
00060         self.paint()
00061 
00062     def onKeyDown( self, vk, mod ):
00063 
00064         #print "onKeyDown", vk
00065 
00066         if vk==VK_SPACE:
00067             self.onPush()
00068 
00069         elif vk==VK_RETURN:
00070             self.onPush()
00071 
00072         self.paint()
00073 
00074     def onPush(self):
00075         if self.handler:
00076             self.handler()
00077 
00078     def paint(self):
00079 
00080         if self.enable_cursor:
00081             attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00082             self.window.setCursorPos( -1, -1 )
00083         else:
00084             attr = cterm.Attribute( fg=clnch_colortable.fg )
00085 
00086         self.window.putString( self.x, self.y, self.width, 1, attr, self.message )
00087 
00088 
00089 # ----------------------------------------------------------------------------------------------------------------------------
00090 #
00091 # ----------------------------------------------------------------------------------------------------------------------------
00092 
00093 class CheckBoxWidget(Widget):
00094 
00095     def __init__( self, window, x, y, width, height, message, check ):
00096 
00097         Widget.__init__( self, window, x, y, width, height )
00098 
00099         def createImage(path):
00100             pil_img = Image.open(path)
00101             pil_img = pil_img.convert( "RGBA" )
00102             return cterm.Image.fromString( pil_img.size, pil_img.tostring() )
00103         self.img0 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/check0.png' ))
00104         self.img1 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/check1.png' ))
00105 
00106         self.plane_size = self.window.getCharSize()
00107         self.plane_size = ( self.plane_size[0]*2-1, self.plane_size[1]-1 )
00108 
00109         self.plane = cterm.Plane( self.window, (0,0), self.plane_size, 0 )
00110         self.plane.setImage(self.img0)
00111 
00112         self.message = message
00113         self.check = check
00114 
00115         self.paint()
00116 
00117     def onKeyDown( self, vk, mod ):
00118 
00119         #print "onKeyDown", vk
00120 
00121         if vk==VK_SPACE:
00122             self.check = not self.check
00123         self.paint()
00124 
00125     def paint(self):
00126 
00127         pos1 = self.window.charToClient( self.x, self.y )
00128         pos2 = self.window.charToClient( self.x+2, self.y+1 )
00129 
00130         self.plane.setPos( ( (pos1[0]+pos2[0]-self.plane_size[0])/2, (pos1[1]+pos2[1]-self.plane_size[1])/2 ) )
00131 
00132         if self.check:
00133             self.plane.setImage(self.img1)
00134         else:
00135             self.plane.setImage(self.img0)
00136 
00137         if self.enable_cursor:
00138             attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00139             self.window.setCursorPos( -1, -1 )
00140         else:
00141             attr = cterm.Attribute( fg=clnch_colortable.fg )
00142 
00143         self.window.putString( self.x+3, self.y, self.width-3, 1, attr, self.message )
00144 
00145     def getValue(self):
00146         return self.check
00147 
00148 
00149 
00150 # ----------------------------------------------------------------------------------------------------------------------------
00151 #
00152 # ----------------------------------------------------------------------------------------------------------------------------
00153 
00154 class ChoiceWidget(Widget):
00155 
00156     def __init__( self, window, x, y, width, height, message, item_list, initial_select ):
00157 
00158         Widget.__init__( self, window, x, y, width, height )
00159 
00160         self.message = message
00161         self.item_list = item_list
00162         self.select = initial_select
00163 
00164         self.paint()
00165 
00166     def onKeyDown( self, vk, mod ):
00167 
00168         #print "onKeyDown", vk
00169 
00170         if vk==VK_LEFT:
00171             self.select -= 1
00172             if self.select<0 : self.select=0
00173         elif vk==VK_RIGHT:
00174             self.select += 1
00175             if self.select>len(self.item_list)-1 : self.select=len(self.item_list)-1
00176         self.paint()
00177 
00178     def paint(self):
00179 
00180         x = self.x
00181 
00182         message_width = self.window.getStringWidth(self.message)
00183         self.window.putString( x, self.y, message_width, 1, cterm.Attribute( fg=clnch_colortable.fg ), self.message )
00184         x += message_width + 2
00185 
00186         for i in xrange(len(self.item_list)):
00187 
00188             item = self.item_list[i]
00189 
00190             if self.select==i :
00191                 if self.enable_cursor :
00192                     attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00193                     self.window.setCursorPos( -1, -1 )
00194                 else:
00195                     attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.choice_bg )
00196             else:
00197                 attr = cterm.Attribute( fg=clnch_colortable.fg )
00198 
00199             item_width = self.window.getStringWidth(item)
00200             self.window.putString( x, self.y, item_width, 1, attr, item )
00201             x += item_width + 2
00202 
00203     def getValue(self):
00204         return self.select
00205 
00206 
00207 # ----------------------------------------------------------------------------------------------------------------------------
00208 #
00209 # ----------------------------------------------------------------------------------------------------------------------------
00210 
00211 class ColorWidget(Widget):
00212 
00213     color_table = ( (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0) )
00214 
00215     def __init__( self, window, x, y, width, height, message, color ):
00216 
00217         Widget.__init__( self, window, x, y, width, height )
00218 
00219         self.frame_plane_size = self.window.getCharSize()
00220         self.frame_plane_size = ( self.frame_plane_size[0]*4-1, self.frame_plane_size[1]-1 )
00221         self.frame_plane = cterm.Plane( self.window, (0,0), self.frame_plane_size, 1 )
00222         self.color_plane_size = ( self.frame_plane_size[0]-2, self.frame_plane_size[1]-2 )
00223         self.color_plane = cterm.Plane( self.window, (0,0), self.color_plane_size, 0 )
00224 
00225         self.message = message
00226         self.color = color
00227 
00228         self.paint()
00229 
00230     def onKeyDown( self, vk, mod ):
00231 
00232         #print "onKeyDown", vk
00233 
00234         if vk==VK_SPACE or vk==VK_RETURN:
00235             result, color, ColorWidget.color_table = clnch_native.chooseColor( self.window.getHWND(), self.color, ColorWidget.color_table )
00236             if result:
00237                 self.color = color
00238         self.paint()
00239 
00240     def paint(self):
00241 
00242         pos1 = self.window.charToClient( self.x+0, self.y )
00243         pos2 = self.window.charToClient( self.x+4, self.y+1 )
00244 
00245         self.frame_plane.setPos( ( (pos1[0]+pos2[0]-self.color_plane_size[0])/2, (pos1[1]+pos2[1]-self.color_plane_size[1])/2 ) )
00246         self.frame_plane.setImage( cterm.Image.fromString( (1,1), struct.pack( "BBBB", clnch_colortable.bg[0]^0xff, clnch_colortable.bg[1]^0xff, clnch_colortable.bg[2]^0xff, 0xff ) ) )
00247 
00248         self.color_plane.setPos( ( (pos1[0]+pos2[0]-self.color_plane_size[0])/2+1, (pos1[1]+pos2[1]-self.color_plane_size[1])/2+1 ) )
00249         self.color_plane.setImage( cterm.Image.fromString( (1,1), struct.pack( "BBBB", self.color[0], self.color[1], self.color[2], 0xff ) ) )
00250 
00251         if self.enable_cursor:
00252             attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00253             self.window.setCursorPos( -1, -1 )
00254         else:
00255             attr = cterm.Attribute( fg=clnch_colortable.fg )
00256 
00257         self.window.putString( self.x+5, self.y, self.width-3, 1, attr, self.message )
00258 
00259     def getValue(self):
00260         return self.color
00261 
00262 
00263 # ----------------------------------------------------------------------------------------------------------------------------
00264 #
00265 # ----------------------------------------------------------------------------------------------------------------------------
00266 
00267 class HotKeyWidget(Widget):
00268 
00269     def __init__( self, window, x, y, width, height, vk, mod ):
00270 
00271         Widget.__init__( self, window, x, y, width, height )
00272 
00273         self.vk = vk
00274         self.mod = mod
00275 
00276         self.paint()
00277 
00278     def onKeyDown( self, vk, mod ):
00279 
00280         #print "onKeyDown", vk, mod
00281 
00282         if vk==VK_LCONTROL or vk==VK_RCONTROL or vk==VK_CONTROL:
00283             mod &= ~MODKEY_CTRL
00284         elif vk==VK_LMENU or vk==VK_RMENU or vk==VK_MENU:
00285             mod &= ~MODKEY_ALT
00286         elif vk==VK_LSHIFT or vk==VK_RSHIFT or vk==VK_SHIFT:
00287             mod &= ~MODKEY_SHIFT
00288         elif vk==VK_LWIN or vk==VK_RWIN:
00289             mod &= ~MODKEY_WIN
00290 
00291         self.vk = vk
00292         self.mod = mod
00293 
00294         self.paint()
00295 
00296     def paint(self):
00297 
00298         if self.enable_cursor:
00299             attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00300             self.window.setCursorPos( -1, -1 )
00301         else:
00302             attr = cterm.Attribute( fg=clnch_colortable.fg )
00303 
00304         _vk_name_table = {
00305 
00306             VK_A : "A",
00307             VK_B : "B",
00308             VK_C : "C",
00309             VK_D : "D",
00310             VK_E : "E",
00311             VK_F : "F",
00312             VK_G : "G",
00313             VK_H : "H",
00314             VK_I : "I",
00315             VK_J : "J",
00316             VK_K : "K",
00317             VK_L : "L",
00318             VK_M : "M",
00319             VK_N : "N",
00320             VK_O : "O",
00321             VK_P : "P",
00322             VK_Q : "Q",
00323             VK_R : "R",
00324             VK_S : "S",
00325             VK_T : "T",
00326             VK_U : "U",
00327             VK_V : "V",
00328             VK_W : "W",
00329             VK_X : "X",
00330             VK_Y : "Y",
00331             VK_Z : "Z",
00332 
00333             VK_0 : "0",
00334             VK_1 : "1",
00335             VK_2 : "2",
00336             VK_3 : "3",
00337             VK_4 : "4",
00338             VK_5 : "5",
00339             VK_6 : "6",
00340             VK_7 : "7",
00341             VK_8 : "8",
00342             VK_9 : "9",
00343 
00344             VK_OEM_MINUS  : "Minus",
00345             VK_OEM_PLUS   : "Plus",
00346             VK_OEM_COMMA  : "Comma",
00347             VK_OEM_PERIOD : "Period",
00348 
00349             VK_NUMLOCK  : "NumLock",
00350             VK_DIVIDE   : "Divide",
00351             VK_MULTIPLY : "Multiply",
00352             VK_SUBTRACT : "Subtract",
00353             VK_ADD      : "Add",
00354             VK_DECIMAL  : "Decimal",
00355 
00356             VK_NUMPAD0 : "Num0",
00357             VK_NUMPAD1 : "Num1",
00358             VK_NUMPAD2 : "Num2",
00359             VK_NUMPAD3 : "Num3",
00360             VK_NUMPAD4 : "Num4",
00361             VK_NUMPAD5 : "Num5",
00362             VK_NUMPAD6 : "Num6",
00363             VK_NUMPAD7 : "Num7",
00364             VK_NUMPAD8 : "Num8",
00365             VK_NUMPAD9 : "Num9",
00366     
00367             VK_F1  : "F1",
00368             VK_F2  : "F2",
00369             VK_F3  : "F3",
00370             VK_F4  : "F4",
00371             VK_F5  : "F5",
00372             VK_F6  : "F6",
00373             VK_F7  : "F7",
00374             VK_F8  : "F8",
00375             VK_F9  : "F9",
00376             VK_F10 : "F10",
00377             VK_F11 : "F11",
00378             VK_F12 : "F12",
00379 
00380             VK_LEFT     : "Left",
00381             VK_RIGHT    : "Right",
00382             VK_UP       : "Up",
00383             VK_DOWN     : "Down",
00384             VK_SPACE    : "Space",
00385             VK_TAB      : "Tab",
00386             VK_BACK     : "Back",
00387             VK_RETURN   : "Return",
00388             VK_ESCAPE   : "Escape",
00389             VK_CAPITAL  : "CapsLock",
00390             VK_APPS     : "Apps",
00391     
00392             VK_INSERT   : "Insert",
00393             VK_DELETE   : "Delete",
00394             VK_HOME     : "Home",
00395             VK_END      : "End",
00396             VK_NEXT     : "PageDown",
00397             VK_PRIOR    : "PageUp",
00398 
00399             VK_MENU     : "Alt",
00400             VK_LMENU    : "LAlt",
00401             VK_RMENU    : "RAlt",
00402             VK_CONTROL  : "Ctrl",
00403             VK_LCONTROL : "LCtrl",
00404             VK_RCONTROL : "RCtrl",
00405             VK_SHIFT    : "Shift",
00406             VK_LSHIFT   : "LShift",
00407             VK_RSHIFT   : "RShift",
00408             VK_LWIN     : "LWin",
00409             VK_RWIN     : "RWin",
00410 
00411             VK_SNAPSHOT : "PrintScreen",
00412             VK_SCROLL   : "ScrollLock",
00413             VK_PAUSE    : "Pause",
00414         }
00415 
00416         str_mod = ""
00417         if self.mod & MODKEY_ALT:
00418             str_mod += "A-"
00419         if self.mod & MODKEY_CTRL:
00420             str_mod += "C-"
00421         if self.mod & MODKEY_SHIFT:
00422             str_mod += "S-"
00423         if self.mod & MODKEY_WIN:
00424             str_mod += "W-"
00425 
00426         try:
00427             str_vk = _vk_name_table[self.vk]
00428         except KeyError:
00429             str_vk = "(%d)" % self.vk
00430 
00431         s = str_mod + str_vk
00432         
00433         s = clnch_misc.adjustStringWidth( self.window, s, self.width, clnch_misc.ALIGN_CENTER )
00434 
00435         self.window.putString( self.x, self.y, self.width, 1, attr, s )
00436 
00437     def getValue(self):
00438         return [ self.vk, self.mod ]
00439 
00440 # ----------------------------------------------------------------------------------------------------------------------------
00441 #
00442 # ----------------------------------------------------------------------------------------------------------------------------
00443 
00444 class action_Insert:
00445     def __init__( self, pos, text ):
00446         self.pos = pos
00447         self.text = text
00448 
00449 class action_Delete:
00450     def __init__( self, pos, text ):
00451         self.pos = pos
00452         self.text = text
00453 
00454 class action_Back:
00455     def __init__( self, pos, text ):
00456         self.pos = pos
00457         self.text = text
00458 
00459 class EditWidget(Widget):
00460 
00461     class UpdateInfo:
00462         def __init__( self, text, selection ):
00463             self.text = text
00464             self.selection = selection
00465 
00466     def __init__( self, window, x, y, width, height, text, selection=None, margin1=1, margin2=12, auto_complete=False, no_bg=False, autofix_list=None, update_handler=None, candidate_handler=None, word_break_handler=None ):
00467 
00468         Widget.__init__( self, window, x, y, width, height )
00469 
00470         self.enableIme(True)
00471 
00472         self.text = text
00473         if selection==None : selection=[ len(text), len(text) ]
00474         self.selection = selection
00475         if margin1 > self.width/2 : margin1 = self.width/2
00476         if margin2 > self.width/2 : margin2 = self.width/2
00477         self.margin1 = margin1
00478         self.margin2 = margin2
00479         self.auto_complete = auto_complete
00480         self.scroll_pos = -self.margin1
00481         self.autofix_list = autofix_list
00482         self.update_handler = update_handler
00483         self.candidate_handler = candidate_handler
00484         if word_break_handler:
00485             sekf.word_break_handler = word_break_handler
00486         else:
00487             self.word_break_handler = clnch_misc.wordbreak_Filename
00488 
00489         self.undo_list = []
00490         self.redo_list = []
00491         self.last_action = None
00492 
00493         if not no_bg:
00494             pos1 = self.window.charToClient(x,y)
00495             pos2 = self.window.charToClient(x+width,y+1)
00496             self.skin_edit = clnch_skin.SkinPlane( self.window, os.path.join( os.path.split(sys.argv[0])[0], 'skin/edit_active.png' ) )
00497             self.skin_edit.adjust( (pos1[0],pos1[1],pos2[0]-pos1[0],pos2[1]-pos1[1]) )
00498         else:
00499             self.skin_edit = None
00500 
00501         if candidate_handler:
00502             self.list_window = CandidateWindow( x, y, 10, 1, 80, 16, window, selchange_handler=self.onListSelChange )
00503             self.list_window_pos = 0
00504         else:
00505             self.list_window = None
00506 
00507         self.makeVisible( self.selection[1] )
00508 
00509         self.paint()
00510 
00511     def destroy(self):
00512         if self.skin_edit:
00513             self.skin_edit.destroy()
00514         if self.list_window:
00515             self.list_window.destroy()
00516 
00517     def setPosSize( self, x, y, width, height ):
00518         Widget.setPosSize( self, x, y, width, height )
00519         if self.skin_edit:
00520             pos1 = self.window.charToClient(x,y)
00521             pos2 = self.window.charToClient(x+width,y+1)
00522             self.skin_edit.adjust( (pos1[0],pos1[1],pos2[0]-pos1[0],pos2[1]-pos1[1]) )
00523 
00524     def setAutoComplete( self, auto_complete ):
00525         self.auto_complete = auto_complete
00526 
00527     def getAutoComplete(self):
00528         return self.auto_complete
00529 
00530     def appendUndo( self, action ):
00531         if self.last_action != None :
00532             self.undo_list.append(self.last_action)
00533             self.redo_list = []
00534         self.last_action = action
00535 
00536     def undo(self):
00537 
00538         self.appendUndo(None)
00539 
00540         if len(self.undo_list)==0 : return
00541 
00542         action = self.undo_list[-1]
00543 
00544         if isinstance( action, action_Insert ):
00545 
00546             update_info = EditWidget.UpdateInfo(
00547                 self.text[ : action.pos ] + self.text[ action.pos + len(action.text) : ],
00548                 [ action.pos, action.pos ]
00549                 )
00550 
00551         elif isinstance( action, action_Delete ) or isinstance( action, action_Back ):
00552 
00553             update_info = EditWidget.UpdateInfo(
00554                 self.text[ : action.pos ] + action.text + self.text[ action.pos : ],
00555                 [ action.pos+len(action.text), action.pos+len(action.text) ]
00556                 )
00557 
00558         else:
00559             assert(0)
00560 
00561         self.closeList()
00562 
00563         if self.update_handler:
00564             if self.update_handler(update_info)==False:
00565                 return
00566 
00567         self.undo_list = self.undo_list[:-1]
00568         self.redo_list.append(action)
00569 
00570         self.text = update_info.text
00571         self.selection = update_info.selection
00572         self.makeVisible( self.selection[1] )
00573         self.paint()
00574 
00575     def redo(self):
00576 
00577         if len(self.redo_list)==0 : return
00578 
00579         action = self.redo_list[-1]
00580 
00581         if isinstance( action, action_Insert ):
00582 
00583             update_info = EditWidget.UpdateInfo(
00584                 self.text[ : action.pos ] + action.text + self.text[ action.pos : ],
00585                 [ action.pos + len(action.text), action.pos + len(action.text) ]
00586                 )
00587 
00588         elif isinstance( action, action_Delete ) or isinstance( action, action_Back ):
00589 
00590             update_info = EditWidget.UpdateInfo(
00591                 self.text[ : action.pos ] + self.text[ action.pos + len(action.text) : ],
00592                 [ action.pos, action.pos ]
00593                 )
00594 
00595         else:
00596             assert(0)
00597 
00598         self.closeList()
00599 
00600         if self.update_handler:
00601             if self.update_handler(update_info)==False:
00602                 return
00603 
00604         self.undo_list.append(action)
00605         self.redo_list = self.redo_list[:-1]
00606 
00607         self.text = update_info.text
00608         self.selection = update_info.selection
00609         self.makeVisible( self.selection[1] )
00610         self.paint()
00611 
00612     def onKeyDown( self, vk, mod ):
00613 
00614         #print "onKeyDown", vk, mod
00615 
00616         if mod==MODKEY_SHIFT:
00617 
00618             if vk==VK_SPACE:
00619                 if self.candidate_handler:
00620                     self.window.removeKeyMessage()
00621                     if self.list_window.numItems()==0:
00622                         self.insertText(u"")
00623                         return True
00624                     return self.list_window.onKeyDown( vk, mod )
00625 
00626             elif vk==VK_LEFT:
00627                 self.appendUndo(None)
00628                 self.selection[1] = max( self.selection[1]-1, 0 )
00629             elif vk==VK_RIGHT:
00630                 self.appendUndo(None)
00631                 self.selection[1] = min( self.selection[1]+1, len(self.text) )
00632             elif vk==VK_HOME:
00633                 self.appendUndo(None)
00634                 self.selection[1] = 0
00635             elif vk==VK_END:
00636                 self.appendUndo(None)
00637                 self.selection[1] = len(self.text)
00638             self.makeVisible( self.selection[1] )
00639             self.paint()
00640 
00641         elif mod==MODKEY_CTRL:
00642 
00643             if vk==VK_LEFT:
00644                 self.appendUndo(None)
00645                 new_caret_pos = self.word_break_handler( self.text, self.selection[1]-1, -1 )
00646                 self.selection = [ new_caret_pos, new_caret_pos ]
00647                 self.makeVisible( self.selection[1] )
00648                 self.paint()
00649 
00650             elif vk==VK_RIGHT:
00651                 self.appendUndo(None)
00652                 new_caret_pos = self.word_break_handler( self.text, self.selection[1]+1, +1 )
00653                 self.selection = [ new_caret_pos, new_caret_pos ]
00654                 self.makeVisible( self.selection[1] )
00655                 self.paint()
00656 
00657             elif vk==VK_BACK:
00658                 if self.selection[0]==self.selection[1] and self.selection[0]>0:
00659                     selection_left = self.word_break_handler( self.text, self.selection[1]-1, -1 )
00660                     selection_right = self.selection[1]
00661                     update_info = EditWidget.UpdateInfo(
00662                         self.text[ : selection_left ] + self.text[ selection_right : ],
00663                         [ selection_left, selection_left ]
00664                         )
00665                 else:
00666                     selection_left = min( self.selection[0], self.selection[1] )
00667                     selection_right = max( self.selection[0], self.selection[1] )
00668                     update_info = EditWidget.UpdateInfo(
00669                         self.text[ : selection_left ] + self.text[ selection_right : ],
00670                         [ selection_left, selection_left ]
00671                         )
00672 
00673                 if self.candidate_handler:
00674                     self.popupList( update_info, False )
00675 
00676                 if self.update_handler:
00677                     if self.update_handler(update_info)==False:
00678                         return
00679 
00680                 self.appendUndo( action_Delete( update_info.selection[0], self.text[ selection_left : selection_right ] ) )
00681                 self.appendUndo(None)
00682 
00683                 self.text = update_info.text
00684                 self.selection = update_info.selection
00685                 self.makeVisible( self.selection[1] )
00686                 self.paint()
00687 
00688             elif vk==VK_A:
00689                 self.appendUndo(None)
00690                 self.selection = [ 0, len(self.text) ]
00691                 self.makeVisible( self.selection[1] )
00692                 self.paint()
00693 
00694             elif vk==VK_X:
00695                 self.appendUndo(None)
00696                 if self.selection[0]==self.selection[1] : return
00697 
00698                 selection_left = min( self.selection[0], self.selection[1] )
00699                 selection_right = max( self.selection[0], self.selection[1] )
00700 
00701                 update_info = EditWidget.UpdateInfo(
00702                     self.text[ : selection_left ] + self.text[ selection_right : ],
00703                     [ selection_left, selection_left ]
00704                     )
00705 
00706                 self.closeList()
00707 
00708                 if self.update_handler:
00709                     if self.update_handler(update_info)==False:
00710                         return
00711 
00712                 self.appendUndo( action_Delete( selection_left, self.text[ selection_left : selection_right ] ) )
00713                 self.appendUndo(None)
00714 
00715                 clnch_misc.setClipboardText( self.text[ selection_left : selection_right ] )
00716 
00717                 self.text = update_info.text
00718                 self.selection = update_info.selection
00719                 self.makeVisible( self.selection[1] )
00720                 self.paint()
00721 
00722             elif vk==VK_C:
00723                 self.appendUndo(None)
00724                 if self.selection[0]==self.selection[1] : return
00725 
00726                 selection_left = min( self.selection[0], self.selection[1] )
00727                 selection_right = max( self.selection[0], self.selection[1] )
00728 
00729                 update_info = EditWidget.UpdateInfo(
00730                     self.text,
00731                     [ self.selection[1], self.selection[1] ]
00732                     )
00733 
00734                 self.closeList()
00735 
00736                 if self.update_handler:
00737                     if self.update_handler(update_info)==False:
00738                         return
00739 
00740                 clnch_misc.setClipboardText( self.text[ selection_left : selection_right ] )
00741 
00742                 self.text = update_info.text
00743                 self.selection = update_info.selection
00744                 self.makeVisible( self.selection[1] )
00745                 self.paint()
00746 
00747             elif vk==VK_V:
00748                 self.appendUndo(None)
00749                 selection_left = min( self.selection[0], self.selection[1] )
00750                 selection_right = max( self.selection[0], self.selection[1] )
00751 
00752                 clipboard_text = clnch_misc.getClipboardText()
00753 
00754                 update_info = EditWidget.UpdateInfo(
00755                     self.text[ : selection_left ] + clipboard_text + self.text[ selection_right : ],
00756                     [ selection_left+len(clipboard_text), selection_left+len(clipboard_text) ]
00757                     )
00758 
00759                 self.closeList()
00760 
00761                 if self.update_handler:
00762                     if self.update_handler(update_info)==False:
00763                         return
00764 
00765                 self.appendUndo( action_Insert( selection_left, clipboard_text ) )
00766                 self.appendUndo(None)
00767 
00768                 self.text = update_info.text
00769                 self.selection = update_info.selection
00770                 self.makeVisible( self.selection[1] )
00771                 self.paint()
00772 
00773             elif vk==VK_Z:
00774                 self.appendUndo(None)
00775                 self.undo()
00776 
00777             elif vk==VK_Y:
00778                 self.redo()
00779 
00780         elif mod==MODKEY_SHIFT|MODKEY_CTRL:
00781 
00782             if vk==VK_LEFT:
00783                 self.appendUndo(None)
00784                 self.selection[1] = self.word_break_handler( self.text, self.selection[1]-1, -1 )
00785                 self.makeVisible( self.selection[1] )
00786                 self.paint()
00787 
00788             elif vk==VK_RIGHT:
00789                 self.appendUndo(None)
00790                 self.selection[1] = self.word_break_handler( self.text, self.selection[1]+1, +1 )
00791                 self.makeVisible( self.selection[1] )
00792                 self.paint()
00793 
00794         elif mod==0:
00795 
00796             if vk in (VK_SPACE,VK_UP,VK_DOWN,VK_PRIOR,VK_NEXT):
00797                 if self.candidate_handler:
00798                     self.window.removeKeyMessage()
00799                     if self.list_window.numItems()==0:
00800                         self.insertText(u"")
00801                         return True
00802                     return self.list_window.onKeyDown( vk, mod )
00803 
00804             elif vk==VK_TAB:
00805                 if self.candidate_handler:
00806                     if self.list_window.numItems()!=0:
00807                         self.window.removeKeyMessage()
00808                         common_prefix = self.list_window.commonPrefix()
00809                         selection_left = min( self.selection[0], self.selection[1] )
00810                         self.insertText(self.text[ selection_left : self.list_window_pos + len(common_prefix) ] )
00811                         return True
00812 
00813             elif vk==VK_ESCAPE:
00814                 if self.candidate_handler:
00815                     if self.list_window.numItems()>0:
00816                         self.closeList()
00817                         return True
00818 
00819             elif self.selection[0]==self.selection[1]:
00820                 if vk==VK_LEFT:
00821                     self.appendUndo(None)
00822                     new_caret_pos = max( self.selection[1]-1, 0 )
00823                     self.selection = [ new_caret_pos, new_caret_pos ]
00824                 elif vk==VK_RIGHT:
00825                     self.appendUndo(None)
00826                     new_caret_pos = min( self.selection[1]+1, len(self.text) )
00827                     self.selection = [ new_caret_pos, new_caret_pos ]
00828                 elif vk==VK_HOME:
00829                     self.appendUndo(None)
00830                     self.selection = [ 0, 0 ]
00831                 elif vk==VK_END:
00832                     self.appendUndo(None)
00833                     self.selection = [ len(self.text), len(self.text) ]
00834                 elif vk==VK_DELETE:
00835                     update_info = EditWidget.UpdateInfo(
00836                         self.text[ : self.selection[0] ] + self.text[ self.selection[1]+1 : ],
00837                         [ self.selection[0], self.selection[0] ]
00838                         )
00839 
00840                     self.closeList()
00841 
00842                     if self.update_handler:
00843                         if self.update_handler(update_info)==False:
00844                             return
00845 
00846                     if isinstance( self.last_action, action_Delete ):
00847                         self.last_action.text += self.text[ self.selection[0] : self.selection[0]+1 ]
00848                     else:
00849                         self.appendUndo( action_Delete( self.selection[0], self.text[ self.selection[0] : self.selection[0]+1 ] ) )
00850 
00851                     self.text = update_info.text
00852                     self.selection = update_info.selection
00853                 elif vk==VK_BACK:
00854                     remove_left = max( self.selection[1]-1, 0 )
00855                     update_info = EditWidget.UpdateInfo(
00856                         self.text[ : remove_left ] + self.text[ self.selection[1] : ],
00857                         [ remove_left, remove_left ]
00858                         )
00859 
00860                     self.closeList()
00861 
00862                     if self.update_handler:
00863                         if self.update_handler(update_info)==False:
00864                             return
00865 
00866                     if isinstance( self.last_action, action_Back ):
00867                         self.last_action.text = self.text[ remove_left : self.selection[1] ] + self.last_action.text
00868                         self.last_action.pos -= 1
00869                     else:
00870                         self.appendUndo( action_Back( remove_left, self.text[ remove_left : self.selection[1] ] ) )
00871 
00872                     self.text = update_info.text
00873                     self.selection = update_info.selection
00874                 self.makeVisible( self.selection[1] )
00875                 self.paint()
00876             else:
00877                 if vk==VK_LEFT:
00878                     self.appendUndo(None)
00879                     new_caret_pos = min( self.selection[0], self.selection[1] )
00880                     self.selection = [ new_caret_pos, new_caret_pos ]
00881                 elif vk==VK_RIGHT:
00882                     self.appendUndo(None)
00883                     new_caret_pos = max( self.selection[0], self.selection[1] )
00884                     self.selection = [ new_caret_pos, new_caret_pos ]
00885                 elif vk==VK_HOME:
00886                     self.appendUndo(None)
00887                     self.selection = [ 0, 0 ]
00888                 elif vk==VK_END:
00889                     self.appendUndo(None)
00890                     self.selection = [ len(self.text), len(self.text) ]
00891                 elif vk==VK_DELETE or vk==VK_BACK:
00892                     selection_left = min( self.selection[0], self.selection[1] )
00893                     selection_right = max( self.selection[0], self.selection[1] )
00894                     update_info = EditWidget.UpdateInfo(
00895                         self.text[ : selection_left ] + self.text[ selection_right : ],
00896                         [ selection_left, selection_left ]
00897                         )
00898 
00899                     self.closeList()
00900 
00901                     if self.update_handler:
00902                         if self.update_handler(update_info)==False:
00903                             return
00904                     self.appendUndo( action_Delete( selection_left, self.text[ selection_left : selection_right ] ) )
00905                     self.appendUndo(None)
00906                     self.text = update_info.text
00907                     self.selection = update_info.selection
00908                 self.makeVisible( self.selection[1] )
00909                 self.paint()
00910 
00911     def onChar( self, ch, mod ):
00912 
00913         #print "onChar", ch
00914 
00915         if self.autofix_list:
00916             for autofix_string in self.autofix_list:
00917                 if unichr(ch) in autofix_string:
00918 
00919                     selection_left = min( self.selection[0], self.selection[1] )
00920                     selection_right = max( self.selection[0], self.selection[1] )
00921 
00922                     min_pos = -1
00923                     for autofix_char in autofix_string:
00924                         pos = self.text.find( autofix_char, selection_left, selection_right )
00925                         if pos>=0:
00926                             if min_pos<0 or pos<min_pos : min_pos=pos
00927 
00928                     if min_pos>=0:
00929                         self.selection = [ min_pos, selection_right ]
00930                     else:
00931                         self.selection = [ selection_right, selection_right ]
00932 
00933         if ch<=0xff and ( ch<0x20 or ch==0x7f ):
00934             return
00935         else:
00936             self.insertText( unichr(ch) )
00937 
00938     def onWindowMove( self ):
00939         self.closeList()
00940 
00941     def popupList( self, update_info=None, complete=True ):
00942 
00943         if self.candidate_handler:
00944 
00945             if update_info==None:
00946                 update_info = EditWidget.UpdateInfo(
00947                     self.text,
00948                     self.selection
00949                     )
00950 
00951             selection_right = max( update_info.selection[0], update_info.selection[1] )
00952 
00953             candidate_list, base_len = self.candidate_handler(update_info)
00954             #print self.scroll_pos, base_len
00955 
00956             if complete:
00957                 try:
00958                     select = candidate_list.index(update_info.text[base_len:selection_right])
00959                 except:
00960                     select = 0
00961             else:
00962                 select = -1
00963             
00964             x, y1 = self.window.charToScreen( self.x+self.window.getStringWidth(update_info.text[:base_len])-self.scroll_pos, self.y )
00965             x, y2 = self.window.charToScreen( self.x+self.window.getStringWidth(update_info.text[:base_len])-self.scroll_pos, self.y+1 )
00966             self.list_window_pos = base_len
00967             self.list_window.setItems( x, y1, y2, candidate_list, select )
00968 
00969             if complete and len(candidate_list)>0:
00970 
00971                 left = update_info.text[:base_len]
00972                 mid = candidate_list[select]
00973                 right = update_info.text[selection_right:]
00974 
00975                 update_info.text = left + mid + right
00976                 update_info.selection = [ update_info.selection[0], len(left)+len(mid) ]
00977 
00978     def closeList(self):
00979         if self.candidate_handler:
00980             x, y = self.window.charToScreen( 0, 0 )
00981             self.list_window_pos = 0
00982             self.list_window.setItems( x, y, y, [], 0 )
00983 
00984     def onListSelChange( self, select, text ):
00985         
00986         selection_left = min( self.selection[0], self.selection[1] )
00987         selection_right = max( self.selection[0], self.selection[1] )
00988 
00989         left = self.text[:self.list_window_pos]
00990         mid = text
00991         right = self.text[selection_right:]
00992 
00993         update_info = EditWidget.UpdateInfo(
00994             left + mid + right,
00995             [ selection_left, len(left)+len(mid) ]
00996             )
00997 
00998         if self.update_handler:
00999             if self.update_handler(update_info)==False:
01000                 return
01001 
01002         self.text = update_info.text
01003         self.selection = update_info.selection
01004         self.makeVisible( self.selection[1] )
01005         self.paint()
01006 
01007     def insertText( self, text ):
01008         selection_left = min( self.selection[0], self.selection[1] )
01009         selection_right = max( self.selection[0], self.selection[1] )
01010 
01011         new_caret_pos = selection_left + len(text)
01012         update_info = EditWidget.UpdateInfo(
01013             self.text[ : selection_left ] + text + self.text[ selection_right : ],
01014             [ new_caret_pos, new_caret_pos ]
01015             )
01016 
01017         if self.candidate_handler:
01018             self.popupList( update_info, self.auto_complete )
01019 
01020         if self.update_handler:
01021             if self.update_handler(update_info)==False:
01022                 return
01023 
01024         inserted_text = text + update_info.text[ update_info.selection[0] : update_info.selection[1] ]
01025 
01026         if selection_left==selection_right:
01027             if isinstance( self.last_action, action_Insert ):
01028                 self.last_action.text += inserted_text
01029             else:
01030                 self.appendUndo( action_Insert( selection_left, inserted_text ) )
01031         else:
01032             self.appendUndo( action_Delete( selection_left, self.text[selection_left:selection_right] ) )
01033             self.appendUndo( action_Insert( selection_left, inserted_text ) )
01034 
01035         self.text = update_info.text
01036         self.selection = update_info.selection
01037         self.makeVisible( self.selection[1] )
01038         self.paint()
01039 
01040     def selectAll(self):
01041         self.selection = [ 0, len(self.text) ]
01042         self.paint()
01043 
01044     def clear(self):
01045 
01046         update_info = EditWidget.UpdateInfo(
01047             u"",
01048             [ 0, 0 ]
01049             )
01050 
01051         if self.update_handler:
01052             if self.update_handler(update_info)==False:
01053                 return
01054 
01055         self.text = update_info.text
01056         self.selection = update_info.selection
01057         self.makeVisible( self.selection[1] )
01058         self.paint()
01059 
01060     def makeVisible( self, pos ):
01061 
01062         def countStringWidthRight( text, pos, width ):
01063             while True:
01064                 if pos<0 or pos>len(text)-1 :
01065                     width -= 1
01066                 else:
01067                     width -= self.window.getStringWidth(text[pos])
01068                 if width < 0 : break
01069                 pos += 1
01070             return pos
01071 
01072         def countStringWidthLeft( text, pos, width ):
01073             while True:
01074                 pos -= 1
01075                 if pos<0 or pos>len(text)-1 :
01076                     width -= 1
01077                 else:
01078                     width -= self.window.getStringWidth(text[pos])
01079                 if width < 0 : break
01080             return pos + 1
01081 
01082         if pos < countStringWidthRight( self.text, self.scroll_pos+1, self.margin1-1 ) :
01083             self.scroll_pos = max( countStringWidthLeft( self.text, pos, self.margin2 ), -self.margin1 )
01084         elif pos > countStringWidthRight( self.text, self.scroll_pos, self.width-self.margin1 ) :
01085             pos1 = countStringWidthLeft( self.text, pos, self.width-self.margin2 )
01086             pos2 = countStringWidthLeft( self.text, len(self.text), self.width-self.margin1 )
01087             self.scroll_pos = min( pos1, pos2 )
01088 
01089     def paint(self):
01090 
01091         selection_left = min( self.selection[0], self.selection[1] )
01092         selection_right = max( self.selection[0], self.selection[1] )
01093 
01094         x = self.x
01095         width = self.width
01096 
01097         attribute_edit = cterm.Attribute( fg=clnch_colortable.edit_fg )
01098         attribute_edit_selected = cterm.Attribute( fg=clnch_colortable.edit_select_fg, bg=clnch_colortable.edit_select_bg )
01099 
01100         self.window.putString( x, self.y, width, 1, attribute_edit, u" " * width )
01101 
01102         if self.scroll_pos < selection_left:
01103 
01104             if self.scroll_pos<0:
01105                 left_string = self.text[ 0 : selection_left ]
01106                 x += 1
01107                 width -= 1
01108             else:
01109                 left_string = self.text[ self.scroll_pos : selection_left ]
01110 
01111             self.window.putString( x, self.y, width, 1, attribute_edit, left_string )
01112             left_string_width = self.window.getStringWidth(left_string)
01113             x += left_string_width
01114             width -= left_string_width
01115 
01116         if selection_left < selection_right:
01117 
01118             if self.scroll_pos<selection_left:
01119                 mid_string = self.text[ selection_left : selection_right ]
01120             else:
01121                 mid_string = self.text[ self.scroll_pos : selection_right ]
01122 
01123             if self.enable_cursor:
01124                 attr = attribute_edit_selected
01125             else:
01126                 attr = attribute_edit
01127 
01128             self.window.putString( x, self.y, width, 1, attr, mid_string )
01129             mid_string_width = self.window.getStringWidth(mid_string)
01130             x += mid_string_width
01131             width -= mid_string_width
01132 
01133         if selection_right < self.scroll_pos + self.width:
01134 
01135             right_string = self.text[ selection_right : ]
01136 
01137             self.window.putString( x, self.y, width, 1, attribute_edit, right_string )
01138             right_string_width = self.window.getStringWidth(right_string)
01139             x += right_string_width
01140             width -= right_string_width
01141 
01142         if self.enable_cursor:
01143             if self.scroll_pos<0:
01144                 left_string = self.text[ 0 : self.selection[1] ]
01145                 offset = 1
01146             else:
01147                 left_string = self.text[ self.scroll_pos : self.selection[1] ]
01148                 offset = 0
01149             self.window.setCursorPos( self.x + offset + self.window.getStringWidth(left_string), self.y )
01150 
01151     def getText(self):
01152         return self.text
01153 
01154     def setText(self,text):
01155         self.text = text
01156 
01157     def getSelection(self):
01158         return self.selection
01159 
01160     def setSelection(self,selection):
01161         self.selection = selection
01162 
01163 class CandidateWindow( cterm.Window ):
01164 
01165     def __init__( self, x, y, min_width, min_height, max_width, max_height, parent_window, keydown_hook=None, selchange_handler=None ):
01166 
01167         cterm.Window.__init__(
01168             self,
01169             x=x,
01170             y=y,
01171             width=5,
01172             height=5,
01173             origin= ORIGIN_X_LEFT | ORIGIN_Y_TOP,
01174             parent_window=parent_window,
01175             bg_color = clnch_colortable.candlist_bg,
01176             show = False,
01177             resizable = False,
01178             title_bar = False,
01179             minimizebox = False,
01180             maximizebox = False,
01181             activate_handler = self.onActivate,
01182             keydown_handler = self.onKeyDown,
01183             char_handler = self.onChar,
01184             )
01185 
01186         self.parent_window = parent_window
01187 
01188         self.min_width = min_width
01189         self.min_height = min_height
01190         self.max_width = max_width
01191         self.max_height = max_height
01192 
01193         self.keydown_hook = keydown_hook
01194         self.selchange_handler = selchange_handler
01195 
01196         self.setItems( x, y, y, [], 0 )
01197 
01198     def setItems( self, x, y1, y2, items, select=0 ):
01199 
01200         max_item_width = 0
01201         for item in items:
01202             if isinstance(item,list) or isinstance(item,tuple):
01203                 item = item[0]
01204             item_width = self.getStringWidth(item)
01205             if item_width>max_item_width:
01206                 max_item_width=item_width
01207 
01208         window_width = max_item_width
01209         window_height = len(items)
01210 
01211         window_width = max(window_width,self.min_width)
01212         window_height = max(window_height,self.min_height)
01213 
01214         window_width = min(window_width,self.max_width)
01215         window_height = min(window_height,self.max_height)
01216 
01217         # 画面に収まらない場合は上方向に配置する
01218         y = y2
01219         monitor_info_list = pyauto.Window.getMonitorInfo()
01220         for monitor_info in monitor_info_list:
01221             if monitor_info[0][0] <= x < monitor_info[0][2] and monitor_info[0][1] <= y1 < monitor_info[0][3]:
01222                 window_rect = self.getWindowRect()
01223                 char_w, char_h = self.getCharSize()
01224                 if y2 + (window_rect[3]-window_rect[1]) + (self.max_height-self.height())*char_h >= monitor_info[1][3]:
01225                     y = y1 - ((window_rect[3]-window_rect[1]) + (window_height-self.height())*char_h)
01226                 break
01227         
01228         if not len(items):
01229             self.show( False, False )
01230 
01231         self.setPosSize(
01232             x=x,
01233             y=y,
01234             width=window_width,
01235             height=window_height,
01236             origin= ORIGIN_X_LEFT | ORIGIN_Y_TOP
01237             )
01238 
01239         if len(items):
01240             self.show( True, False )
01241 
01242         self.items = items
01243         self.scroll_info = clnch_misc.ScrollInfo()
01244         self.select = select
01245         self.scroll_info.makeVisible( self.select, self.height() )
01246 
01247         #if self.selchange_handler:
01248         #    if len(self.items):
01249         #        self.selchange_handler( self.select, self.items[self.select] )
01250 
01251         self.paint()
01252 
01253     def onActivate( self, active ):
01254         if active:
01255             self.parent_window.activate()
01256 
01257     def onKeyDown( self, vk, mod ):
01258 
01259         if self.keydown_hook:
01260             if self.keydown_hook( vk, mod ):
01261                 return True
01262 
01263         if mod==MODKEY_SHIFT:
01264             if vk==VK_SPACE:
01265                 if not len(self.items) : return True
01266                 self.select -= 1
01267                 if self.select<0 : self.select=len(self.items)-1
01268                 self.scroll_info.makeVisible( self.select, self.height() )
01269 
01270                 if self.selchange_handler:
01271                     self.selchange_handler( self.select, self.items[self.select] )
01272 
01273                 self.paint()
01274                 return True
01275 
01276         elif mod==0:
01277             if vk==VK_SPACE:
01278                 if not len(self.items) : return True
01279                 self.select += 1
01280                 if self.select>len(self.items)-1 : self.select=0
01281                 self.scroll_info.makeVisible( self.select, self.height() )
01282 
01283                 if self.selchange_handler:
01284                     self.selchange_handler( self.select, self.items[self.select] )
01285 
01286                 self.paint()
01287                 return True
01288 
01289             elif vk==VK_UP:
01290                 if not len(self.items) : return True
01291                 if self.select>=0:
01292                     self.select -= 1
01293                     if self.select<0 : self.select=0
01294                 else:
01295                     self.select=len(self.items)-1
01296                 self.scroll_info.makeVisible( self.select, self.height() )
01297 
01298                 if self.selchange_handler:
01299                     self.selchange_handler( self.select, self.items[self.select] )
01300 
01301                 self.paint()
01302                 return True
01303 
01304             elif vk==VK_DOWN:
01305                 if not len(self.items) : return True
01306                 self.select += 1
01307                 if self.select>len(self.items)-1 : self.select=len(self.items)-1
01308                 self.scroll_info.makeVisible( self.select, self.height() )
01309 
01310                 if self.selchange_handler:
01311                     self.selchange_handler( self.select, self.items[self.select] )
01312 
01313                 self.paint()
01314                 return True
01315 
01316             elif vk==VK_PRIOR:
01317                 if not len(self.items) : return True
01318 
01319                 if self.select>=0:
01320                     if self.select>self.scroll_info.pos :
01321                         self.select = self.scroll_info.pos
01322                     else:
01323                         self.select -= self.height()
01324                         if self.select<0 : self.select=0
01325                 else:
01326                     self.select=len(self.items)-1
01327 
01328                 self.scroll_info.makeVisible( self.select, self.height() )
01329 
01330                 if self.selchange_handler:
01331                     self.selchange_handler( self.select, self.items[self.select] )
01332 
01333                 self.paint()
01334                 return True
01335 
01336             elif vk==VK_NEXT:
01337                 if not len(self.items) : return True
01338                 if self.select<self.scroll_info.pos+self.height()-1:
01339                     self.select = self.scroll_info.pos+self.height()-1
01340                 else:
01341                     self.select += self.height()
01342                 if self.select>len(self.items)-1 : self.select=len(self.items)-1
01343                 self.scroll_info.makeVisible( self.select, self.height() )
01344 
01345                 if self.selchange_handler:
01346                     self.selchange_handler( self.select, self.items[self.select] )
01347 
01348                 self.paint()
01349                 return True
01350 
01351     def onChar( self, ch, mod ):
01352         pass
01353 
01354     def paint(self):
01355 
01356         x=0
01357         y=0
01358         width=self.width()
01359         height=self.height()
01360 
01361         attribute_normal = cterm.Attribute( fg=clnch_colortable.fg )
01362         attribute_candidate = cterm.Attribute( fg=clnch_colortable.candlist_fg, bg=clnch_colortable.candlist_bg )
01363         attribute_candidate_selected = cterm.Attribute( fg=clnch_colortable.candlist_select_fg, bg=clnch_colortable.candlist_select_bg )
01364 
01365         for i in xrange(height):
01366             index = self.scroll_info.pos+i
01367             if index < len(self.items):
01368 
01369                 item = self.items[index]
01370                 if isinstance(item,list) or isinstance(item,tuple):
01371                     item = item[0]
01372 
01373                 if self.select==index:
01374                     attr=attribute_candidate_selected
01375                 else:
01376                     attr=attribute_candidate
01377                 self.putString( x, y+i, width, 1, attr, u" " * width )
01378                 self.putString( x, y+i, width, 1, attr, item )
01379             else:
01380                 self.putString( x, y+i, width, 1, attribute_normal, u" " * width )
01381 
01382     def getSelection(self):
01383         return self.select
01384 
01385     def numItems(self):
01386         return len(self.items)
01387 
01388     def commonPrefix(self):
01389         if len(self.items)==0 : return u""
01390         common_prefix = self.items[0].lower()
01391         for item in self.items:
01392             name = item.lower()
01393             while 1:
01394                 if name.startswith(common_prefix): break
01395                 common_prefix = common_prefix[:-1]
01396                 if not common_prefix : return u""
01397         return common_prefix
01398 
01399 # ----------------------------------------------------------------------------------------------------------------------------
01400 #
01401 # ----------------------------------------------------------------------------------------------------------------------------
01402 
01403 class TimeWidget(Widget):
01404 
01405     FOCUS_YEAR = 0
01406     FOCUS_MONTH = 1
01407     FOCUS_DAY = 2
01408     FOCUS_HOUR = 3
01409     FOCUS_MINUTE = 4
01410     FOCUS_SECOND = 5
01411 
01412     def __init__( self, window, x, y, timestamp ):
01413 
01414         Widget.__init__( self, window, x, y, 22, 1 )
01415 
01416         pos1 = self.window.charToClient(x,y)
01417         pos2 = self.window.charToClient(x+22,y+1)
01418         self.skin_edit = clnch_skin.SkinPlane( self.window, os.path.join( os.path.split(sys.argv[0])[0], 'skin/edit_active.png' ) )
01419         self.skin_edit.adjust( (pos1[0],pos1[1],pos2[0]-pos1[0],pos2[1]-pos1[1]) )
01420 
01421         self.year_edit   = EditWidget( window, x+1,  y, 4, 1, "%04d"%timestamp[0], None, 0, 1, update_handler=self.onYearUpdate )
01422         self.month_edit  = EditWidget( window, x+6,  y, 2, 1, "%02d"%timestamp[1], None, 0, 1, update_handler=self.onMonthUpdate )
01423         self.day_edit    = EditWidget( window, x+9,  y, 2, 1, "%02d"%timestamp[2], None, 0, 1, update_handler=self.onDayUpdate )
01424         self.hour_edit   = EditWidget( window, x+13, y, 2, 1, "%02d"%timestamp[3], None, 0, 1, update_handler=self.onHourUpdate )
01425         self.minute_edit = EditWidget( window, x+16, y, 2, 1, "%02d"%timestamp[4], None, 0, 1, update_handler=self.onMinuteUpdate )
01426         self.second_edit = EditWidget( window, x+19, y, 2, 1, "%02d"%timestamp[5], None, 0, 1, update_handler=self.onSecondUpdate )
01427 
01428         self.year_edit.enableIme(False)
01429         self.month_edit.enableIme(False)
01430         self.day_edit.enableIme(False)
01431         self.hour_edit.enableIme(False)
01432         self.minute_edit.enableIme(False)
01433         self.second_edit.enableIme(False)
01434 
01435         self.year_edit.selectAll()
01436         self.month_edit.selectAll()
01437         self.day_edit.selectAll()
01438         self.hour_edit.selectAll()
01439         self.minute_edit.selectAll()
01440         self.second_edit.selectAll()
01441 
01442         self.focus = TimeWidget.FOCUS_YEAR
01443 
01444         self.paint()
01445 
01446     def onYearUpdate( self, info ):
01447         if len(info.text.strip())==0 :
01448             i=0
01449         else:
01450             i = int(info.text)
01451         if i>9999 : return False
01452         info.text = u"%04d"%i
01453         info.selection = [4,4]
01454         return True
01455 
01456     def onMonthUpdate( self, info ):
01457         if len(info.text.strip())==0 :
01458             i=0
01459         else:
01460             i = int(info.text)
01461         if i>12 : return False
01462         info.text = u"%02d"%i
01463         info.selection = [2,2]
01464         return True
01465 
01466     def onDayUpdate( self, info ):
01467         if len(info.text.strip())==0 :
01468             i=0
01469         else:
01470             i = int(info.text)
01471         if i>31 : return False
01472         info.text = u"%02d"%i
01473         info.selection = [2,2]
01474         return True
01475 
01476     def onHourUpdate( self, info ):
01477         if len(info.text.strip())==0 :
01478             i=0
01479         else:
01480             i = int(info.text)
01481         if i>23 : return False
01482         info.text = u"%02d"%i
01483         info.selection = [2,2]
01484         return True
01485 
01486     def onMinuteUpdate( self, info ):
01487         if len(info.text.strip())==0 :
01488             i=0
01489         else:
01490             i = int(info.text)
01491         if i>59 : return False
01492         info.text = u"%02d"%i
01493         info.selection = [2,2]
01494         return True
01495 
01496     def onSecondUpdate( self, info ):
01497         if len(info.text.strip())==0 :
01498             i=0
01499         else:
01500             i = int(info.text)
01501         if i>59 : return False
01502         info.text = u"%02d"%i
01503         info.selection = [2,2]
01504         return True
01505 
01506     def onKeyDown( self, vk, mod ):
01507 
01508         #print "onKeyDown", vk
01509 
01510         if vk==VK_LEFT:
01511             if self.focus==TimeWidget.FOCUS_MONTH:
01512                 self.focus=TimeWidget.FOCUS_YEAR
01513                 self.year_edit.selectAll()
01514             elif self.focus==TimeWidget.FOCUS_DAY:
01515                 self.focus=TimeWidget.FOCUS_MONTH
01516                 self.month_edit.selectAll()
01517             elif self.focus==TimeWidget.FOCUS_HOUR:
01518                 self.focus=TimeWidget.FOCUS_DAY
01519                 self.hour_edit.selectAll()
01520             elif self.focus==TimeWidget.FOCUS_MINUTE:
01521                 self.focus=TimeWidget.FOCUS_HOUR
01522                 self.minute_edit.selectAll()
01523             elif self.focus==TimeWidget.FOCUS_SECOND:
01524                 self.focus=TimeWidget.FOCUS_MINUTE
01525                 self.second_edit.selectAll()
01526             self.paint()
01527 
01528         elif vk==VK_RIGHT:
01529             if self.focus==TimeWidget.FOCUS_YEAR:
01530                 self.focus=TimeWidget.FOCUS_MONTH
01531                 self.month_edit.selectAll()
01532             elif self.focus==TimeWidget.FOCUS_MONTH:
01533                 self.focus=TimeWidget.FOCUS_DAY
01534                 self.day_edit.selectAll()
01535             elif self.focus==TimeWidget.FOCUS_DAY:
01536                 self.focus=TimeWidget.FOCUS_HOUR
01537                 self.hour_edit.selectAll()
01538             elif self.focus==TimeWidget.FOCUS_HOUR:
01539                 self.focus=TimeWidget.FOCUS_MINUTE
01540                 self.minute_edit.selectAll()
01541             elif self.focus==TimeWidget.FOCUS_MINUTE:
01542                 self.focus=TimeWidget.FOCUS_SECOND
01543                 self.second_edit.selectAll()
01544             self.paint()
01545 
01546         else:
01547             if self.focus==TimeWidget.FOCUS_YEAR:
01548                 self.year_edit.onKeyDown( vk, mod )
01549             elif self.focus==TimeWidget.FOCUS_MONTH:
01550                 self.month_edit.onKeyDown( vk, mod )
01551             elif self.focus==TimeWidget.FOCUS_DAY:
01552                 self.day_edit.onKeyDown( vk, mod )
01553             elif self.focus==TimeWidget.FOCUS_HOUR:
01554                 self.hour_edit.onKeyDown( vk, mod )
01555             elif self.focus==TimeWidget.FOCUS_MINUTE:
01556                 self.minute_edit.onKeyDown( vk, mod )
01557             elif self.focus==TimeWidget.FOCUS_SECOND:
01558                 self.second_edit.onKeyDown( vk, mod )
01559 
01560     def onChar( self, ch, mod ):
01561 
01562         #print "onChar", ch
01563 
01564         if u"0123456789\b".find(unichr(ch)) >= 0:
01565 
01566             if self.focus==TimeWidget.FOCUS_YEAR:
01567                 self.year_edit.onChar( ch, mod )
01568             elif self.focus==TimeWidget.FOCUS_MONTH:
01569                 self.month_edit.onChar( ch, mod )
01570             elif self.focus==TimeWidget.FOCUS_DAY:
01571                 self.day_edit.onChar( ch, mod )
01572             elif self.focus==TimeWidget.FOCUS_HOUR:
01573                 self.hour_edit.onChar( ch, mod )
01574             elif self.focus==TimeWidget.FOCUS_MINUTE:
01575                 self.minute_edit.onChar( ch, mod )
01576             elif self.focus==TimeWidget.FOCUS_SECOND:
01577                 self.second_edit.onChar( ch, mod )
01578 
01579     def paint(self):
01580 
01581         attribute_edit = cterm.Attribute( fg=clnch_colortable.edit_fg )
01582 
01583         self.window.putString( self.x, self.y, self.width, 1, attribute_edit, u"     /  /      :  :   " )
01584 
01585         self.year_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_YEAR )
01586         self.year_edit.paint()
01587 
01588         self.month_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_MONTH )
01589         self.month_edit.paint()
01590 
01591         self.day_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_DAY )
01592         self.day_edit.paint()
01593 
01594         self.hour_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_HOUR )
01595         self.hour_edit.paint()
01596 
01597         self.minute_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_MINUTE )
01598         self.minute_edit.paint()
01599 
01600         self.second_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_SECOND )
01601         self.second_edit.paint()
01602 
01603     def getValue(self):
01604         return (
01605                 int(self.year_edit.getText()),
01606                 int(self.month_edit.getText()),
01607                 int(self.day_edit.getText()),
01608                 int(self.hour_edit.getText()),
01609                 int(self.minute_edit.getText()),
01610                 int(self.second_edit.getText())
01611             )
01612 
01613 
01614 # ----------------------------------------------------------------------------------------------------------------------------
01615 #
01616 # ----------------------------------------------------------------------------------------------------------------------------
01617 
01618 class ProgressBarWidget(Widget):
01619 
01620     busy_anim_speed = 0.4
01621 
01622     def __init__( self, window, x, y, width, height ):
01623 
01624         Widget.__init__( self, window, x, y, width, height )
01625 
01626         def createImage(path):
01627             pil_img = Image.open(path)
01628             pil_img = pil_img.convert( "RGBA" )
01629             return cterm.Image.fromString( pil_img.size, pil_img.tostring(), (0,0,0) )
01630         img0 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/progress0.png' ))
01631         img1 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/progress1.png' ))
01632 
01633         self.frame_plane = cterm.Plane( self.window, (0,0), (0,0), 1 )
01634         self.frame_plane.setImage(img0)
01635         self.bar_plane = cterm.Plane( self.window, (0,0), (0,0), 0 )
01636         self.bar_plane.setImage(img1)
01637         
01638         self.busy_mode = False
01639         self.busy_anim_phase = 0
01640         self.busy_anim_theta = 0
01641         self.busy_anim_chase = 0
01642         self.value = [ 0, 0 ]
01643 
01644         self.paint()
01645 
01646     def destroy(self):
01647         self.window.killTimer(self._onTimer)
01648         self.frame_plane.destroy()
01649         self.bar_plane.destroy()
01650 
01651     def show(self,visible):
01652         self.frame_plane.show(visible)
01653         self.bar_plane.show(visible)
01654 
01655     def paint(self):
01656 
01657         pos1 = self.window.charToClient( self.x, self.y )
01658         pos2 = self.window.charToClient( self.x+self.width, self.y+self.height )
01659         margin_y = 2
01660 
01661         self.frame_plane.setPos( ( pos1[0], pos1[1]+margin_y ) )
01662         self.frame_plane.setSize( ( pos2[0]-pos1[0], pos2[1]-pos1[1]-margin_y ) )
01663 
01664         self.bar_plane.setPos( ( pos1[0] + int((pos2[0]-pos1[0])*self.value[0]), pos1[1]+margin_y ) )
01665         self.bar_plane.setSize( ( int((pos2[0]-pos1[0])*(self.value[1]-self.value[0])), pos2[1]-pos1[1]-margin_y ) )
01666 
01667         attr = cterm.Attribute( fg=clnch_colortable.edit_fg )
01668         self.window.putString( self.x, self.y, self.width, 1, attr, u" " * self.width )
01669 
01670     def setValue( self, value ):
01671         if value!=None:
01672             value = max( value, 0.0 )
01673             value = min( value, 1.0 )
01674     
01675             if self.value[1] != value:
01676                 self.value[0] = 0.0
01677                 self.value[1] = value
01678                 self.paint()
01679         else:
01680             if not self.busy_mode:
01681                 self.busy_mode = True
01682                 self.busy_anim_phase = 0
01683                 self.busy_anim_theta = 0
01684                 self.busy_anim_chase = 0
01685                 self.window.setTimer( self._onTimer, 50 )
01686 
01687     def getValue(self):
01688         return self.value[1]
01689 
01690     def _onTimer(self):
01691     
01692         if self.busy_anim_phase==0:
01693             self.busy_anim_theta += ProgressBarWidget.busy_anim_speed
01694             if self.busy_anim_theta > math.pi*0.5:
01695                 self.busy_anim_phase = 1
01696 
01697         elif self.busy_anim_phase==1:
01698             self.busy_anim_theta += ProgressBarWidget.busy_anim_speed
01699             self.busy_anim_chase += ProgressBarWidget.busy_anim_speed
01700             if self.busy_anim_theta > math.pi:
01701                 self.busy_anim_theta = math.pi
01702                 self.busy_anim_phase = 2
01703 
01704         elif self.busy_anim_phase==2:
01705             self.busy_anim_chase += ProgressBarWidget.busy_anim_speed
01706             if self.busy_anim_chase > math.pi:
01707                 self.busy_anim_chase = math.pi
01708                 self.busy_anim_phase = 3
01709 
01710         elif self.busy_anim_phase==3:
01711             self.busy_anim_theta -= ProgressBarWidget.busy_anim_speed
01712             if self.busy_anim_theta < math.pi*0.5:
01713                 self.busy_anim_phase = 4
01714 
01715         elif self.busy_anim_phase==4:
01716             self.busy_anim_theta -= ProgressBarWidget.busy_anim_speed
01717             self.busy_anim_chase -= ProgressBarWidget.busy_anim_speed
01718             if self.busy_anim_theta < 0:
01719                 self.busy_anim_theta = 0
01720                 self.busy_anim_phase = 5
01721 
01722         elif self.busy_anim_phase==5:
01723             self.busy_anim_chase -= ProgressBarWidget.busy_anim_speed
01724             if self.busy_anim_chase < 0:
01725                 self.busy_anim_chase = 0
01726                 self.busy_anim_phase = 0
01727 
01728         value1 = math.cos(self.busy_anim_theta) * 0.5 + 0.5
01729         value2 = math.cos(self.busy_anim_chase) * 0.5 + 0.5
01730         
01731         self.value = [ min(value1,value2), max(value1,value2) ]
01732             
01733         self.paint()

Copyright © 2009 craftware. All rights reserved.