NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

shortcuts.py (17432B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\shortcuts.py
      2 from collections import defaultdict
      3 from carbonui import uiconst
      4 from carbonui.control.button import Button
      5 from carbonui.control.combo import Combo
      6 from carbonui.control.window import Window
      7 from carbonui.primitives.container import Container
      8 from carbonui.primitives.fill import Fill
      9 from carbonui.primitives.frame import Frame
     10 from carbonui.primitives.layoutGrid import LayoutGrid
     11 from carbonui.primitives.sprite import Sprite
     12 from carbonui.services.command import GetKeyName, CommandMap
     13 from carbonui.uicore import uicore
     14 from eve.client.script.ui.control.eveLabel import EveLabelSmall
     15 KEYS = 49
     16 SHIFT_CTRL = 50
     17 SHIFT_ALT = 51
     18 CTRL_ALT = 52
     19 SHIFT_CTRL_ALT = 53
     20 CELL_SPACING = (5, 5)
     21 SHIFT_COLOR = (0.8,
     22  0.1,
     23  0.1,
     24  0.75)
     25 CTRL_COLOR = (0.1,
     26  0.8,
     27  0.1,
     28  0.75)
     29 ALT_COLOR = (0.1,
     30  0.85,
     31  0.9,
     32  0.75)
     33 OTHER_COLOR = (0.9,
     34  0.9,
     35  0.9,
     36  0.75)
     37 contextIncarna = 2
     38 
     39 class KeyboardWnd(Window):
     40     default_minSize = (1080, 440)
     41     default_height = 440
     42     default_width = 1080
     43     default_windowID = 'keyboardWnd'
     44     __notifyevents__ = ['OnMapShortcut', 'OnRestoreDefaultShortcuts']
     45 
     46     def DebugReload(self, *args):
     47         self.Close()
     48         KeyboardWnd.Open()
     49 
     50     def ApplyAttributes(self, attributes):
     51         Window.ApplyAttributes(self, attributes)
     52         self.topParent = Container(name='topParent', parent=self.content, align=uiconst.TOTOP, height=40, clipChildren=False, padding=(0, 8, 0, 0))
     53         self.keyboard_container = Container(parent=self.content, align=uiconst.TOALL, clipChildren=True)
     54         Button(parent=self.topParent, label='Reload', align=uiconst.TOPRIGHT, func=self.DebugReload, idx=0)
     55         leftDot = 6
     56         leftText = leftDot + 12
     57         top = 40
     58         Dot(parent=self.topParent, align=uiconst.TOPRIGHT, color=SHIFT_COLOR, left=leftDot, top=top)
     59         EveLabelSmall(parent=self.topParent, align=uiconst.TOPRIGHT, text='Shift', left=leftText, top=top)
     60         Dot(parent=self.topParent, align=uiconst.TOPRIGHT, color=CTRL_COLOR, left=leftDot, top=top + 12)
     61         EveLabelSmall(parent=self.topParent, align=uiconst.TOPRIGHT, text='Ctrl', left=leftText, top=top + 12)
     62         Dot(parent=self.topParent, align=uiconst.TOPRIGHT, color=ALT_COLOR, left=leftDot, top=top + 24)
     63         EveLabelSmall(parent=self.topParent, align=uiconst.TOPRIGHT, text='Alt', left=leftText, top=top + 24)
     64         Dot(parent=self.topParent, align=uiconst.TOPRIGHT, color=OTHER_COLOR, left=leftDot, top=top + 36)
     65         EveLabelSmall(parent=self.topParent, align=uiconst.TOPRIGHT, text='Shift, Ctrl & Alt combos', left=leftText, top=top + 36)
     66         options = [('All', None),
     67          ('Only keys', KEYS),
     68          ('Shift', uiconst.VK_SHIFT),
     69          ('Ctrl', uiconst.VK_CONTROL),
     70          ('Alt', uiconst.VK_MENU),
     71          ('Shift+Ctrl', SHIFT_CTRL),
     72          ('Shift+Alt', SHIFT_ALT),
     73          ('Ctrl+Alt', CTRL_ALT),
     74          ('Shift+Ctrl+Alt', SHIFT_CTRL_ALT)]
     75         self.displayCombo = Combo(parent=self.topParent, options=options, name='displayCombo', label='Show what?', callback=self.OnComboDisplayChanged, left=10)
     76         options = [('Default Settings', 0), ('Your Settings', 1)]
     77         self.settingsCombo = Combo(parent=self.topParent, options=options, name='settingsCombo', label='Settings', callback=self.OnSettingComboChanged, left=200)
     78         self.keyDownCookie = uicore.event.RegisterForTriuiEvents(uiconst.UI_KEYDOWN, self.OnGlobalKeyCallback)
     79         sm.RegisterNotify(self)
     80         self.RefreshKeyboard()
     81 
     82     def RefreshKeyboard(self):
     83         self.keyboard_container.Flush()
     84         self.keyToCont = defaultdict(list)
     85         self.BuildKeyBoard()
     86         self.MarkShortcutsByComboValue()
     87 
     88     def OnGlobalKeyCallback(self, wnd, eventID, param):
     89         vkey, flag = param
     90         conts = self.keyToCont.get(vkey, None)
     91         if conts:
     92             for eachCont in conts:
     93                 eachCont.BlinkBtn()
     94 
     95         return 1
     96 
     97     def OnComboDisplayChanged(self, *args):
     98         self.MarkShortcutsByComboValue()
     99 
    100     def MarkShortcutsByComboValue(self):
    101         value = self.displayCombo.GetValue()
    102         self.ClearAllDots()
    103         if value is None:
    104             self.MarkAllShortcuts()
    105         else:
    106             self._MarkKeyShortcuts()
    107             if value == KEYS:
    108                 pass
    109             elif value == uiconst.VK_SHIFT:
    110                 self._MarkShiftShortcuts()
    111             elif value == uiconst.VK_CONTROL:
    112                 self._MarkCtrlShortcuts()
    113             elif value == uiconst.VK_MENU:
    114                 self._MarkAltShortcuts()
    115             elif value == SHIFT_CTRL:
    116                 self._MarkOtherShortcutsWithModKeys({uiconst.VK_SHIFT, uiconst.VK_CONTROL})
    117             elif value == SHIFT_ALT:
    118                 self._MarkOtherShortcutsWithModKeys({uiconst.VK_SHIFT, uiconst.VK_MENU})
    119             elif value == CTRL_ALT:
    120                 self._MarkOtherShortcutsWithModKeys({uiconst.VK_CONTROL, uiconst.VK_MENU})
    121             elif value == SHIFT_CTRL_ALT:
    122                 self._MarkOtherShortcutsWithModKeys({uiconst.VK_SHIFT, uiconst.VK_CONTROL, uiconst.VK_MENU})
    123 
    124     def OnSettingComboChanged(self, *args):
    125         self.RefreshKeyboard()
    126 
    127     def BuildKeyBoard(self):
    128         rowCont = LayoutGrid(parent=self.keyboard_container, columns=1, cellSpacing=(0, 5), top=4, left=10)
    129         fRow = LayoutGrid(parent=rowCont, columns=16, cellSpacing=CELL_SPACING)
    130         self.AddBtnsToRow(fRow, F_ROW)
    131         space = LayoutGrid(parent=rowCont, columns=1, padTop=BTN_SIZE)
    132         row1 = LayoutGrid(parent=rowCont, columns=16, cellSpacing=CELL_SPACING)
    133         self.AddBtnsToRow(row1, ROW_1)
    134         row2 = LayoutGrid(parent=rowCont, columns=16, cellSpacing=CELL_SPACING)
    135         self.AddBtnsToRow(row2, ROW_2)
    136         row3 = LayoutGrid(parent=rowCont, columns=16, cellSpacing=CELL_SPACING)
    137         self.AddBtnsToRow(row3, ROW_3)
    138         row4 = LayoutGrid(parent=rowCont, columns=16, cellSpacing=CELL_SPACING)
    139         self.AddBtnsToRow(row4, ROW_4)
    140         row5 = LayoutGrid(parent=rowCont, columns=16, cellSpacing=CELL_SPACING)
    141         self.AddBtnsToRow(row5, ROW_5)
    142         self.BuildRightGrids()
    143 
    144     def BuildRightGrids(self):
    145         rightGrid1 = LayoutGrid(parent=self.keyboard_container, columns=3, cellSpacing=CELL_SPACING, left=700, top=4)
    146         self.AddBtnsToRow(rightGrid1, RIGHT_BTNS)
    147         numpadGrid = LayoutGrid(parent=self.keyboard_container, columns=4, cellSpacing=CELL_SPACING, left=860, top=96)
    148         self.AddBtnsToRow(numpadGrid, NUMPAD)
    149 
    150     def AddBtnsToRow(self, row, btns):
    151         for x, size in btns:
    152             w, h = size
    153             c = KeyboardKeys(parent=row, align=uiconst.CENTERLEFT, pos=(0,
    154              0,
    155              w,
    156              h))
    157             if x:
    158                 self.keyToCont[x].append(c)
    159                 keyName = GetKeyName(x)
    160                 keyName = keyName.lower() if len(keyName) == 1 else keyName
    161                 c.SetText(keyName)
    162                 Frame(parent=c, opacity=0.8)
    163 
    164     def FindKeysAndContForCmd(self, cmd):
    165         if cmd.shortcut is None:
    166             return (None, None, None)
    167         vkey = cmd.shortcut[-1]
    168         shortcutModKeys = cmd.shortcut[:-1]
    169         conts = self.keyToCont.get(vkey, None)
    170         return (vkey, shortcutModKeys, conts)
    171 
    172     def MarkAllShortcuts(self):
    173         self._MarkKeyShortcuts()
    174         self._MarkShiftShortcuts()
    175         self._MarkCtrlShortcuts()
    176         self._MarkAltShortcuts()
    177         self._MarkOtherShortcuts()
    178 
    179     def _MarkKeyShortcuts(self):
    180         for cmd in self.GetAllCommands():
    181             vkey, shortcutModKeys, conts = self.FindKeysAndContForCmd(cmd)
    182             if vkey is None or conts is None or shortcutModKeys:
    183                 continue
    184             for x in conts:
    185                 x.SetAsShortcut(cmd)
    186 
    187     def _MarkShiftShortcuts(self):
    188         for cmd in self.GetAllCommands():
    189             vkey, shortcutModKeys, conts = self.FindKeysAndContForCmd(cmd)
    190             if vkey is None or conts is None:
    191                 continue
    192             if shortcutModKeys == (uiconst.VK_SHIFT,):
    193                 for x in conts:
    194                     x.ShowShiftDot(cmd)
    195 
    196     def _MarkCtrlShortcuts(self):
    197         for cmd in self.GetAllCommands():
    198             vkey, shortcutModKeys, conts = self.FindKeysAndContForCmd(cmd)
    199             if vkey is None or conts is None:
    200                 continue
    201             if shortcutModKeys == (uiconst.VK_CONTROL,):
    202                 for x in conts:
    203                     x.ShowCtrlDot(cmd)
    204 
    205     def _MarkAltShortcuts(self):
    206         for cmd in self.GetAllCommands():
    207             vkey, shortcutModKeys, conts = self.FindKeysAndContForCmd(cmd)
    208             if vkey is None or conts is None:
    209                 continue
    210             if shortcutModKeys == (uiconst.VK_MENU,):
    211                 for x in conts:
    212                     x.ShowAltDot(cmd)
    213 
    214     def _MarkOtherShortcuts(self):
    215         for cmd in self.GetAllCommands():
    216             vkey, shortcutModKeys, conts = self.FindKeysAndContForCmd(cmd)
    217             if vkey is None or conts is None or not shortcutModKeys:
    218                 continue
    219             if len(shortcutModKeys) > 1:
    220                 for x in conts:
    221                     x.ShowOtherDot(cmd)
    222 
    223     def GetAllCommands(self):
    224         useDefault = self.settingsCombo.GetValue() == 0
    225         if useDefault:
    226             cmdSvc = sm.GetService('cmd')
    227             mapping = cmdSvc.SetDefaultShortcutMappingCORE()
    228             mapping.extend(cmdSvc.SetDefaultShortcutMappingGAME())
    229             mappingFis = [ x for x in mapping if cmdSvc.GetCategoryContext(x.category) != (contextIncarna,) ]
    230             cmdMap = CommandMap(defaultCmds=mappingFis)
    231             return cmdMap.GetAllCommands()
    232         else:
    233             return uicore.cmd.commandMap.GetAllCommands()
    234 
    235     def _MarkOtherShortcutsWithModKeys(self, modkeys):
    236         for cmd in self.GetAllCommands():
    237             vkey, shortcutModKeys, conts = self.FindKeysAndContForCmd(cmd)
    238             if vkey is None or conts is None or not shortcutModKeys:
    239                 continue
    240             if set(shortcutModKeys) == modkeys:
    241                 for x in conts:
    242                     x.ShowOtherDot(cmd)
    243 
    244     def Close(self, *args, **kwargs):
    245         try:
    246             uicore.event.UnregisterForTriuiEvents(self.keyDownCookie)
    247         except Exception:
    248             import log
    249             log.LogTraceback('error when unregistering cookie')
    250 
    251         Window.Close(self, *args, **kwargs)
    252 
    253     def ClearAllDots(self):
    254         for conts in self.keyToCont.itervalues():
    255             for c in conts:
    256                 c.ClearAllDots()
    257 
    258     def OnMapShortcut(self, *args):
    259         self.RefreshKeyboard()
    260 
    261     def OnRestoreDefaultShortcuts(self, *args):
    262         self.RefreshKeyboard()
    263 
    264 
    265 BTN_SIZE = 40
    266 NORMAL_BTN = (BTN_SIZE, BTN_SIZE)
    267 F_GAP = (0.6 * BTN_SIZE, BTN_SIZE)
    268 F_ROW = [(uiconst.VK_ESCAPE, NORMAL_BTN),
    269  (None, F_GAP),
    270  (uiconst.VK_F1, NORMAL_BTN),
    271  (uiconst.VK_F2, NORMAL_BTN),
    272  (uiconst.VK_F3, NORMAL_BTN),
    273  (uiconst.VK_F4, NORMAL_BTN),
    274  (None, F_GAP),
    275  (uiconst.VK_F5, NORMAL_BTN),
    276  (uiconst.VK_F6, NORMAL_BTN),
    277  (uiconst.VK_F7, NORMAL_BTN),
    278  (uiconst.VK_F8, NORMAL_BTN),
    279  (None, F_GAP),
    280  (uiconst.VK_F9, NORMAL_BTN),
    281  (uiconst.VK_F10, NORMAL_BTN),
    282  (uiconst.VK_F11, NORMAL_BTN),
    283  (uiconst.VK_F12, NORMAL_BTN)]
    284 ROW_1 = [(uiconst.VK_OEM_3, NORMAL_BTN),
    285  (uiconst.VK_1, NORMAL_BTN),
    286  (uiconst.VK_2, NORMAL_BTN),
    287  (uiconst.VK_3, NORMAL_BTN),
    288  (uiconst.VK_4, NORMAL_BTN),
    289  (uiconst.VK_5, NORMAL_BTN),
    290  (uiconst.VK_6, NORMAL_BTN),
    291  (uiconst.VK_7, NORMAL_BTN),
    292  (uiconst.VK_8, NORMAL_BTN),
    293  (uiconst.VK_9, NORMAL_BTN),
    294  (uiconst.VK_0, NORMAL_BTN),
    295  (uiconst.VK_OEM_MINUS, NORMAL_BTN),
    296  (uiconst.VK_OEM_PLUS, NORMAL_BTN),
    297  (uiconst.VK_BACK, (2 * BTN_SIZE, BTN_SIZE))]
    298 ROW_2 = [(uiconst.VK_TAB, (1.6 * BTN_SIZE, BTN_SIZE)),
    299  (uiconst.VK_Q, NORMAL_BTN),
    300  (uiconst.VK_W, NORMAL_BTN),
    301  (uiconst.VK_E, NORMAL_BTN),
    302  (uiconst.VK_R, NORMAL_BTN),
    303  (uiconst.VK_T, NORMAL_BTN),
    304  (uiconst.VK_Y, NORMAL_BTN),
    305  (uiconst.VK_U, NORMAL_BTN),
    306  (uiconst.VK_I, NORMAL_BTN),
    307  (uiconst.VK_O, NORMAL_BTN),
    308  (uiconst.VK_P, NORMAL_BTN),
    309  (uiconst.VK_OEM_4, NORMAL_BTN),
    310  (uiconst.VK_OEM_6, NORMAL_BTN),
    311  (uiconst.VK_OEM_5, (1.4 * BTN_SIZE, BTN_SIZE))]
    312 ROW_3 = [(uiconst.VK_CAPITAL, (1.9 * BTN_SIZE, BTN_SIZE)),
    313  (uiconst.VK_A, NORMAL_BTN),
    314  (uiconst.VK_S, NORMAL_BTN),
    315  (uiconst.VK_D, NORMAL_BTN),
    316  (uiconst.VK_F, NORMAL_BTN),
    317  (uiconst.VK_G, NORMAL_BTN),
    318  (uiconst.VK_H, NORMAL_BTN),
    319  (uiconst.VK_J, NORMAL_BTN),
    320  (uiconst.VK_K, NORMAL_BTN),
    321  (uiconst.VK_L, NORMAL_BTN),
    322  (uiconst.VK_OEM_1, NORMAL_BTN),
    323  (uiconst.VK_OEM_7, NORMAL_BTN),
    324  (uiconst.VK_RETURN, (2.2 * BTN_SIZE, BTN_SIZE))]
    325 ROW_4 = [(uiconst.VK_SHIFT, (2.5 * BTN_SIZE, BTN_SIZE)),
    326  (uiconst.VK_Z, NORMAL_BTN),
    327  (uiconst.VK_X, NORMAL_BTN),
    328  (uiconst.VK_C, NORMAL_BTN),
    329  (uiconst.VK_V, NORMAL_BTN),
    330  (uiconst.VK_B, NORMAL_BTN),
    331  (uiconst.VK_N, NORMAL_BTN),
    332  (uiconst.VK_M, NORMAL_BTN),
    333  (uiconst.VK_OEM_COMMA, NORMAL_BTN),
    334  (uiconst.VK_OEM_PERIOD, NORMAL_BTN),
    335  (uiconst.VK_OEM_2, NORMAL_BTN),
    336  (uiconst.VK_UP, NORMAL_BTN),
    337  (uiconst.VK_SHIFT, (1.6 * BTN_SIZE, BTN_SIZE))]
    338 ROW_5 = [(uiconst.VK_CONTROL, (1.5 * BTN_SIZE, BTN_SIZE)),
    339  (uiconst.VK_LWIN, (1.4 * BTN_SIZE, BTN_SIZE)),
    340  (uiconst.VK_MENU, (1.4 * BTN_SIZE, BTN_SIZE)),
    341  (uiconst.VK_SPACE, (6 * BTN_SIZE, BTN_SIZE)),
    342  (uiconst.VK_MENU, (1.4 * BTN_SIZE, BTN_SIZE)),
    343  (uiconst.VK_LWIN, (1.4 * BTN_SIZE, BTN_SIZE)),
    344  (uiconst.VK_APPS, NORMAL_BTN),
    345  (uiconst.VK_CONTROL, (1.5 * BTN_SIZE, BTN_SIZE))]
    346 shortcut = (44,)
    347 shortcut = (145,)
    348 shortcut = (19,)
    349 RIGHT_BTNS = [(uiconst.VK_SNAPSHOT, NORMAL_BTN),
    350  (uiconst.VK_SCROLL, NORMAL_BTN),
    351  (uiconst.VK_PAUSE, NORMAL_BTN),
    352  (None, NORMAL_BTN),
    353  (None, NORMAL_BTN),
    354  (None, NORMAL_BTN),
    355  (uiconst.VK_INSERT, NORMAL_BTN),
    356  (uiconst.VK_HOME, NORMAL_BTN),
    357  (uiconst.VK_PRIOR, NORMAL_BTN),
    358  (uiconst.VK_DELETE, NORMAL_BTN),
    359  (uiconst.VK_END, NORMAL_BTN),
    360  (uiconst.VK_NEXT, NORMAL_BTN),
    361  (None, NORMAL_BTN),
    362  (None, NORMAL_BTN),
    363  (None, NORMAL_BTN),
    364  (None, NORMAL_BTN),
    365  (uiconst.VK_UP, NORMAL_BTN),
    366  (None, NORMAL_BTN),
    367  (uiconst.VK_LEFT, NORMAL_BTN),
    368  (uiconst.VK_DOWN, NORMAL_BTN),
    369  (uiconst.VK_RIGHT, NORMAL_BTN)]
    370 NUMPAD = [(uiconst.VK_NUMLOCK, NORMAL_BTN),
    371  (uiconst.VK_DIVIDE, NORMAL_BTN),
    372  (uiconst.VK_MULTIPLY, NORMAL_BTN),
    373  (uiconst.VK_SUBTRACT, NORMAL_BTN),
    374  (uiconst.VK_NUMPAD7, NORMAL_BTN),
    375  (uiconst.VK_NUMPAD8, NORMAL_BTN),
    376  (uiconst.VK_NUMPAD9, NORMAL_BTN),
    377  (uiconst.VK_ADD, NORMAL_BTN),
    378  (uiconst.VK_NUMPAD4, NORMAL_BTN),
    379  (uiconst.VK_NUMPAD5, NORMAL_BTN),
    380  (uiconst.VK_NUMPAD6, NORMAL_BTN),
    381  (None, NORMAL_BTN),
    382  (uiconst.VK_NUMPAD1, NORMAL_BTN),
    383  (uiconst.VK_NUMPAD2, NORMAL_BTN),
    384  (uiconst.VK_NUMPAD3, NORMAL_BTN),
    385  (uiconst.VK_RETURN, NORMAL_BTN),
    386  (uiconst.VK_NUMPAD0, NORMAL_BTN),
    387  (None, NORMAL_BTN),
    388  (uiconst.VK_DECIMAL, NORMAL_BTN)]
    389 
    390 class KeyboardKeys(Container):
    391 
    392     def ApplyAttributes(self, attributes):
    393         Container.ApplyAttributes(self, attributes)
    394         self.bgFill = Fill(bgParent=self, opacity=0.0)
    395         self.shiftDot = Dot(parent=self, align=uiconst.TOPLEFT, color=SHIFT_COLOR)
    396         self.shiftDot.display = False
    397         self.ctrlDot = Dot(parent=self, align=uiconst.TOPRIGHT, color=CTRL_COLOR)
    398         self.ctrlDot.display = False
    399         self.altDot = Dot(parent=self, align=uiconst.BOTTOMLEFT, color=ALT_COLOR)
    400         self.altDot.display = False
    401         self.otherDotCmds = set()
    402         self.otherDot = Dot(parent=self, align=uiconst.BOTTOMRIGHT, color=OTHER_COLOR)
    403         self.otherDot.display = False
    404         self.label = EveLabelSmall(parent=self, text='', align=uiconst.CENTER)
    405 
    406     def SetText(self, text):
    407         self.label.SetText(text)
    408 
    409     def SetAsShortcut(self, cmd):
    410         self.label.SetTextColor((1, 0, 0, 1))
    411         self.label.SetState(uiconst.UI_NORMAL)
    412         self.SetHintOnObject(self.label, cmd)
    413 
    414     def ClearAllDots(self):
    415         self.shiftDot.display = False
    416         self.ctrlDot.display = False
    417         self.altDot.display = False
    418         self.otherDot.display = False
    419         self.otherDotCmds.clear()
    420 
    421     def BlinkBtn(self):
    422         uicore.animations.FadeTo(self.bgFill, startVal=0.5, endVal=0.0, duration=0.25)
    423 
    424     def ShowShiftDot(self, cmd):
    425         self.shiftDot.display = True
    426         self.SetHintOnObject(self.shiftDot, cmd)
    427 
    428     def ShowCtrlDot(self, cmd):
    429         self.ctrlDot.display = True
    430         self.SetHintOnObject(self.ctrlDot, cmd)
    431 
    432     def ShowAltDot(self, cmd):
    433         self.altDot.display = True
    434         self.SetHintOnObject(self.altDot, cmd)
    435 
    436     def ShowOtherDot(self, cmd):
    437         self.otherDotCmds.add(cmd)
    438         self.otherDot.display = True
    439         hintLabels = []
    440         for eachCmd in self.otherDotCmds:
    441             hintLabels.append(self._GetHintForCmd(eachCmd))
    442 
    443         self.otherDot.hint = '<br><br>'.join(hintLabels)
    444 
    445     def SetHintOnObject(self, obj, cmd):
    446         obj.hint = self._GetHintForCmd(cmd)
    447 
    448     def _GetHintForCmd(self, cmd):
    449         description = cmd.GetDescription()
    450         shortcutString = cmd.GetShortcutAsString()
    451         return '%s<br><b>%s</b>' % (description, shortcutString)
    452 
    453 
    454 class Dot(Container):
    455     default_height = 12
    456     default_width = 12
    457     default_state = uiconst.UI_NORMAL
    458 
    459     def ApplyAttributes(self, attributes):
    460         Container.ApplyAttributes(self, attributes)
    461         color = attributes.color or (1, 1, 1, 1)
    462         self.dot = Sprite(parent=self, align=uiconst.CENTER, pos=(0, 0, 8, 8), texturePath='res:/UI/Texture/Shared/smallDot.png', color=color, state=uiconst.UI_DISABLED)