diff options
author | Kurt B. Kaiser <kbk@shore.net> | 2005-11-18 22:05:48 (GMT) |
---|---|---|
committer | Kurt B. Kaiser <kbk@shore.net> | 2005-11-18 22:05:48 (GMT) |
commit | b17544551fc8dfd1304d5679c6e444cad4d34d97 (patch) | |
tree | 75cb5f0b7551a755354fc8fff5ae65449a3442ba /Lib/idlelib/CallTipWindow.py | |
parent | c85c74cd08f619b69a61a0290c660d642a15e9d3 (diff) | |
download | cpython-b17544551fc8dfd1304d5679c6e444cad4d34d97.zip cpython-b17544551fc8dfd1304d5679c6e444cad4d34d97.tar.gz cpython-b17544551fc8dfd1304d5679c6e444cad4d34d97.tar.bz2 |
Merge IDLE-syntax-branch r39668:41449 into trunk
A idlelib/AutoCompleteWindow.py
A idlelib/AutoComplete.py
A idlelib/HyperParser.py
M idlelib/PyShell.py
M idlelib/ParenMatch.py
M idlelib/configDialog.py
M idlelib/EditorWindow.py
M idlelib/PyParse.py
M idlelib/CallTips.py
M idlelib/CallTipWindow.py
M idlelib/run.py
M idlelib/config-extensions.def
A idlelib/MultiCall.py
Diffstat (limited to 'Lib/idlelib/CallTipWindow.py')
-rw-r--r-- | Lib/idlelib/CallTipWindow.py | 116 |
1 files changed, 99 insertions, 17 deletions
diff --git a/Lib/idlelib/CallTipWindow.py b/Lib/idlelib/CallTipWindow.py index 990d96e..09d6414 100644 --- a/Lib/idlelib/CallTipWindow.py +++ b/Lib/idlelib/CallTipWindow.py @@ -6,33 +6,65 @@ Used by the CallTips IDLE extension. """ from Tkinter import * +HIDE_VIRTUAL_EVENT_NAME = "<<caltipwindow-hide>>" +HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>") +CHECKHIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-checkhide>>" +CHECKHIDE_SEQUENCES = ("<KeyRelease>", "<ButtonRelease>") +CHECKHIDE_TIME = 100 # miliseconds + +MARK_RIGHT = "calltipwindowregion_right" + class CallTip: def __init__(self, widget): self.widget = widget - self.tipwindow = None - self.id = None - self.x = self.y = 0 + self.tipwindow = self.label = None + self.parenline = self.parencol = None + self.lastline = None + self.hideid = self.checkhideid = None + + def position_window(self): + """Check if needs to reposition the window, and if so - do it.""" + curline = int(self.widget.index("insert").split('.')[0]) + if curline == self.lastline: + return + self.lastline = curline + self.widget.see("insert") + if curline == self.parenline: + box = self.widget.bbox("%d.%d" % (self.parenline, + self.parencol)) + else: + box = self.widget.bbox("%d.0" % curline) + if not box: + box = list(self.widget.bbox("insert")) + # align to left of window + box[0] = 0 + box[2] = 0 + x = box[0] + self.widget.winfo_rootx() + 2 + y = box[1] + box[3] + self.widget.winfo_rooty() + self.tipwindow.wm_geometry("+%d+%d" % (x, y)) - def showtip(self, text): - " Display text in calltip window" + def showtip(self, text, parenleft, parenright): + """Show the calltip, bind events which will close it and reposition it. + """ # truncate overly long calltip if len(text) >= 79: text = text[:75] + ' ...' self.text = text if self.tipwindow or not self.text: return - self.widget.see("insert") - x, y, cx, cy = self.widget.bbox("insert") - x = x + self.widget.winfo_rootx() + 2 - y = y + cy + self.widget.winfo_rooty() + + self.widget.mark_set(MARK_RIGHT, parenright) + self.parenline, self.parencol = map( + int, self.widget.index(parenleft).split(".")) + self.tipwindow = tw = Toplevel(self.widget) + self.position_window() # XXX 12 Dec 2002 KBK The following command has two effects: It removes # the calltip window border (good) but also causes (at least on # Linux) the calltip to show as a top level window, burning through # any other window dragged over it. Also, shows on all viewports! tw.wm_overrideredirect(1) - tw.wm_geometry("+%d+%d" % (x, y)) try: # This command is only needed and available on Tk >= 8.4.0 for OSX # Without it, call tips intrude on the typing process by grabbing @@ -41,16 +73,66 @@ class CallTip: "help", "noActivates") except TclError: pass - label = Label(tw, text=self.text, justify=LEFT, - background="#ffffe0", relief=SOLID, borderwidth=1, - font = self.widget['font']) - label.pack() + self.label = Label(tw, text=self.text, justify=LEFT, + background="#ffffe0", relief=SOLID, borderwidth=1, + font = self.widget['font']) + self.label.pack() + + self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME, + self.checkhide_event) + for seq in CHECKHIDE_SEQUENCES: + self.widget.event_add(CHECKHIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, + self.hide_event) + for seq in HIDE_SEQUENCES: + self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) + + def checkhide_event(self, event=None): + if not self.tipwindow: + # If the event was triggered by the same event that unbinded + # this function, the function will be called nevertheless, + # so do nothing in this case. + return + curline, curcol = map(int, self.widget.index("insert").split('.')) + if curline < self.parenline or \ + (curline == self.parenline and curcol <= self.parencol) or \ + self.widget.compare("insert", ">", MARK_RIGHT): + self.hidetip() + else: + self.position_window() + self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + + def hide_event(self, event): + if not self.tipwindow: + # See the explanation in checkhide_event. + return + self.hidetip() def hidetip(self): - tw = self.tipwindow + if not self.tipwindow: + return + + for seq in CHECKHIDE_SEQUENCES: + self.widget.event_delete(CHECKHIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhideid) + self.checkhideid = None + for seq in HIDE_SEQUENCES: + self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid) + self.hideid = None + + self.label.destroy() + self.label = None + self.tipwindow.destroy() self.tipwindow = None - if tw: - tw.destroy() + + self.widget.mark_unset(MARK_RIGHT) + self.parenline = self.parencol = self.lastline = None + + def is_active(self): + return bool(self.tipwindow) + ############################### |