ToasterBox.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. # --------------------------------------------------------------------------- #
  2. # TOASTERBOX wxPython IMPLEMENTATION
  3. # Ported And Enhanced From wxWidgets Contribution (Aj Bommarito) By:
  4. #
  5. # Andrea Gavana, @ 16 September 2005
  6. # Latest Revision: 31 Oct 2007, 21.30 CET
  7. #
  8. #
  9. # TODO/Caveats List
  10. #
  11. # 1. Any Idea?
  12. #
  13. #
  14. # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
  15. # Write To Me At:
  16. #
  17. # [email protected]
  18. # [email protected]
  19. #
  20. # Or, Obviously, To The wxPython Mailing List!!!
  21. #
  22. #
  23. # End Of Comments
  24. # --------------------------------------------------------------------------- #
  25. """Description:
  26. ToasterBox Is A Cross-Platform Library To Make The Creation Of MSN Style "Toaster"
  27. Popups Easier. The Syntax Is Really Easy Especially If You Are Familiar With The
  28. Syntax Of wxPython.
  29. It Has 2 Main Styles:
  30. - TB_SIMPLE: Using This Style, You Will Be Able To Specify A Background Image For
  31. ToasterBox, Text Properties As Text Colour, Font And Label.
  32. - TB_COMPLEX: This Style Will Allow You To Put Almost Any Control Inside A
  33. ToasterBox. You Can Add A Panel In Which You Can Put All The Controls
  34. You Like.
  35. Both Styles Support The Setting Of ToasterBox Position (On Screen Coordinates),
  36. Size, The Time After Which The ToasterBox Is Destroyed (Linger), And The Scroll
  37. Speed Of ToasterBox.
  38. ToasterBox Has Been Tested On The Following Platforms:
  39. Windows (Verified on Windows XP, 2000)
  40. Latest Revision: Andrea Gavana @ 31 Oct 2007, 21.30 CET
  41. """
  42. import textwrap
  43. import wx
  44. import sys
  45. from wx.lib.statbmp import GenStaticBitmap as StaticBitmap
  46. # Define Window List, We Use It Globally
  47. winlist = []
  48. TB_SIMPLE = 1
  49. TB_COMPLEX = 2
  50. DEFAULT_TB_STYLE = wx.SIMPLE_BORDER | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR
  51. TB_CAPTION = DEFAULT_TB_STYLE | wx.CAPTION | wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.FRAME_TOOL_WINDOW
  52. TB_ONTIME = 1
  53. TB_ONCLICK = 2
  54. # scroll from up to down
  55. TB_SCR_TYPE_UD = 1
  56. # scroll from down to up
  57. TB_SCR_TYPE_DU = 2
  58. # ------------------------------------------------------------------------------ #
  59. # Class ToasterBox
  60. # Main Class Implementation. It Is Basically A wx.Timer. It Creates And
  61. # Displays Popups And Handles The "Stacking".
  62. # ------------------------------------------------------------------------------ #
  63. class ToasterBox(wx.Timer):
  64. def __init__(self, parent, tbstyle=TB_SIMPLE, windowstyle=DEFAULT_TB_STYLE,
  65. closingstyle=TB_ONTIME, scrollType=TB_SCR_TYPE_DU):
  66. """Deafult Class Constructor.
  67. ToasterBox.__init__(self, tbstyle=TB_SIMPLE, windowstyle=DEFAULT_TB_STYLE)
  68. Parameters:
  69. - tbstyle: This Parameter May Have 2 Values:
  70. (a) TB_SIMPLE: A Simple ToasterBox, With Background Image And Text
  71. Customization Can Be Created;
  72. (b) TB_COMPLEX: ToasterBoxes With Different Degree Of Complexity Can
  73. Be Created. You Can Add As Many Controls As You Want, Provided
  74. That You Call The AddPanel() Method And Pass To It A Dummy Frame
  75. And A wx.Panel. See The Demo For Details.
  76. - windowstyle: This Parameter Influences The Visual Appearance Of ToasterBox:
  77. (a) DEFAULT_TB_STYLE: Default Style, No Caption Nor Close Box;
  78. (b) TB_CAPTION: ToasterBox Will Have A Caption, With The Possibility To
  79. Set A Title For ToasterBox Frame, And A Close Box;
  80. - closingstyle: Set This Value To TB_ONCLICK If You Want To Be Able To Close
  81. ToasterBox By A Mouse Click Anywhere In The ToasterBox Frame.
  82. """
  83. self._parent = parent
  84. self._sleeptime = 10
  85. self._pausetime = 1700
  86. self._popuptext = "default"
  87. self._popupposition = wx.Point(100,100)
  88. self._popuptop = wx.Point(0,0)
  89. self._popupsize = wx.Size(150, 170)
  90. self._backgroundcolour = wx.WHITE
  91. self._foregroundcolour = wx.BLACK
  92. if sys.platform != "darwin":
  93. self._textfont = wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, "Verdana")
  94. else:
  95. self._textfont = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, "Monaco")
  96. self._bitmap = None
  97. self._tbstyle = tbstyle
  98. self._windowstyle = windowstyle
  99. self._closingstyle = closingstyle
  100. self._panel = None
  101. self._bottomright = wx.Point(wx.GetDisplaySize().GetWidth(),
  102. wx.GetDisplaySize().GetHeight())
  103. parent.Bind(wx.EVT_ICONIZE, lambda evt: [w.Hide() for w in winlist])
  104. self._tb = ToasterBoxWindow(self._parent, self, self._tbstyle, self._windowstyle,
  105. self._closingstyle, scrollType=scrollType)
  106. def SetPopupPosition(self, pos):
  107. """ Sets The ToasterBox Position On Screen. """
  108. self._popupposition = pos
  109. def SetPopupPositionByInt(self, pos):
  110. """ Sets The ToasterBox Position On Screen, At One Of The Screen Corners. """
  111. self._bottomright = wx.Point(wx.GetDisplaySize().GetWidth(),
  112. wx.GetDisplaySize().GetHeight())
  113. # top left
  114. if pos == 0:
  115. popupposition = wx.Point(0,0)
  116. # top right
  117. elif pos == 1:
  118. popupposition = wx.Point(wx.GetDisplaySize().GetWidth() -
  119. self._popupsize[0], 0)
  120. # bottom left
  121. elif pos == 2:
  122. popupposition = wxPoint(0, wx.GetDisplaySize().GetHeight() -
  123. self._popupsize[1])
  124. # bottom right
  125. elif pos == 3:
  126. popupposition = wx.Point(self._bottomright.x - self._popupsize[0],
  127. self._bottomright.y - self._popupsize[1])
  128. self._bottomright = wx.Point(popupposition.x + self._popupsize[0],
  129. popupposition.y + self._popupsize[1])
  130. def SetPopupBackgroundColor(self, colour=None):
  131. """ Sets The ToasterBox Background Colour. Use It Only For ToasterBoxes Created
  132. With TB_SIMPLE Style. """
  133. if colour is None:
  134. colour = wx.WHITE
  135. self._backgroundcolour = colour
  136. def SetPopupTextColor(self, colour=None):
  137. """ Sets The ToasterBox Foreground Colour. Use It Only For ToasterBoxes Created
  138. With TB_SIMPLE Style. """
  139. if colour is None:
  140. colour = wx.BLACK
  141. self._foregroundcolour = colour
  142. def SetPopupTextFont(self, font=None):
  143. """ Sets The ToasterBox Text Font. Use It Only For ToasterBoxes Created With
  144. TB_SIMPLE Style. """
  145. if font is None:
  146. if sys.platform != "darwin":
  147. font = wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, "Verdana")
  148. else:
  149. font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, "Monaco")
  150. self._textfont = font
  151. def SetPopupSize(self, size):
  152. """ Sets The ToasterBox Size. """
  153. self._popupsize = size
  154. def SetPopupPauseTime(self, pausetime):
  155. """ Sets The Time After Which The ToasterBox Is Destroyed (Linger). """
  156. self._pausetime = pausetime
  157. def SetPopupBitmap(self, bitmap=None):
  158. """ Sets The ToasterBox Background Image. Use It Only For ToasterBoxes
  159. Created With TB_SIMPLE Style. """
  160. if bitmap is not None:
  161. bitmap = wx.Bitmap(bitmap, wx.BITMAP_TYPE_BMP)
  162. self._bitmap = bitmap
  163. def SetPopupScrollSpeed(self, speed):
  164. """ Sets The ToasterBox Scroll Speed. The Speed Parameter Is The Pause
  165. Time (In ms) For Every Step In The ScrollUp() Method."""
  166. self._sleeptime = speed
  167. def SetPopupText(self, text):
  168. """ Sets The ToasterBox Text. Use It Only For ToasterBoxes Created With
  169. TB_SIMPLE Style. """
  170. self._popuptext = text
  171. def AddPanel(self, panel):
  172. """ Adds A Panel To The ToasterBox. Use It Only For ToasterBoxes Created
  173. With TB_COMPLEX Style. """
  174. if not self._tbstyle & TB_COMPLEX:
  175. raise "\nERROR: Panel Can Not Be Added When Using TB_SIMPLE ToasterBox Style"
  176. return
  177. self._panel = panel
  178. def Play(self):
  179. """ Creates The ToasterBoxWindow, That Does All The Job. """
  180. # create new window
  181. self._tb.SetPopupSize((self._popupsize[0], self._popupsize[1]))
  182. self._tb.SetPopupPosition((self._popupposition[0], self._popupposition[1]))
  183. self._tb.SetPopupPauseTime(self._pausetime)
  184. self._tb.SetPopupScrollSpeed(self._sleeptime)
  185. if self._tbstyle == TB_SIMPLE:
  186. self._tb.SetPopupTextColor(self._foregroundcolour)
  187. self._tb.SetPopupBackgroundColor(self._backgroundcolour)
  188. self._tb.SetPopupTextFont(self._textfont)
  189. if self._bitmap is not None:
  190. self._tb.SetPopupBitmap(self._bitmap)
  191. self._tb.SetPopupText(self._popuptext)
  192. if self._tbstyle == TB_COMPLEX:
  193. if self._panel is not None:
  194. self._tb.AddPanel(self._panel)
  195. # clean up the list
  196. self.CleanList()
  197. # check to see if there is already a window displayed
  198. # by looking at the linked list
  199. if len(winlist) > 0:
  200. # there ARE other windows displayed already
  201. # reclac where it should display
  202. self.MoveAbove(self._tb)
  203. # shift new window on to the list
  204. winlist.append(self._tb)
  205. if not self._tb.Play():
  206. # if we didn't show the window properly, remove it from the list
  207. winlist.remove(winlist[-1])
  208. # delete the object too
  209. self._tb.Destroy()
  210. return
  211. def MoveAbove(self, tb):
  212. """ If A ToasterBox Already Exists, Move The New One Above. """
  213. # recalc where to place this popup
  214. self._tb.SetPopupPosition((self._popupposition[0], self._popupposition[1] -
  215. self._popupsize[1]*len(winlist)))
  216. def GetToasterBoxWindow(self):
  217. """ Returns The ToasterBox Frame. """
  218. return self._tb
  219. def SetTitle(self, title):
  220. """ Sets The ToasterBox Title If It Was Created With TB_CAPTION Window Style. """
  221. self._tb.SetTitle(title)
  222. def Notify(self):
  223. """ It's Time To Hide A ToasterBox! """
  224. if len(winlist) == 0:
  225. return
  226. # clean the window list
  227. self.CleanList()
  228. # figure out how many blanks we have
  229. try:
  230. node = winlist[0]
  231. except:
  232. return
  233. if not node:
  234. return
  235. # move windows to fill in blank space
  236. for i in xrange(node.GetPosition()[1], self._popupposition[1], 4):
  237. if i > self._popupposition[1]:
  238. i = self._popupposition[1]
  239. # loop through all the windows
  240. for j in xrange(0, len(winlist)):
  241. ourNewHeight = i - (j*self._popupsize[1] - 8)
  242. tmpTb = winlist[j]
  243. # reset where the object THINKS its supposed to be
  244. tmpTb.SetPopupPosition((self._popupposition[0], ourNewHeight))
  245. # actually move it
  246. tmpTb.SetDimensions(self._popupposition[0], ourNewHeight, tmpTb.GetSize().GetWidth(),
  247. tmpTb.GetSize().GetHeight())
  248. wx.Usleep(self._sleeptime)
  249. def CleanList(self):
  250. """ Clean The Window List. """
  251. if len(winlist) == 0:
  252. return
  253. node = winlist[0]
  254. while node:
  255. if not node.IsShown():
  256. winlist.remove(node)
  257. try:
  258. node = winlist[0]
  259. except:
  260. node = 0
  261. else:
  262. indx = winlist.index(node)
  263. try:
  264. node = winlist[indx+1]
  265. except:
  266. node = 0
  267. # ------------------------------------------------------------------------------ #
  268. # Class ToasterBoxWindow
  269. # This Class Does All The Job, By Handling Background Images, Text Properties
  270. # And Panel Adding. Depending On The Style You Choose, ToasterBoxWindow Will
  271. # Behave Differently In Order To Handle Widgets Inside It.
  272. # ------------------------------------------------------------------------------ #
  273. class ToasterBoxWindow(wx.Frame):
  274. def __init__(self, parent, parent2, tbstyle, windowstyle,
  275. closingstyle, scrollType=TB_SCR_TYPE_DU):
  276. """Default Class Constructor.
  277. Used Internally. Do Not Call Directly This Class In Your Application!
  278. """
  279. wx.Frame.__init__(self, parent, wx.ID_ANY, "window", wx.DefaultPosition,
  280. wx.DefaultSize, style=windowstyle | wx.CLIP_CHILDREN)
  281. self._starttime = wx.GetLocalTime()
  282. self._parent2 = parent2
  283. self._parent = parent
  284. self._sleeptime = 10
  285. self._step = 4
  286. self._pausetime = 1700
  287. self._textcolour = wx.BLACK
  288. self._popuptext = "Change Me!"
  289. # the size we want the dialog to be
  290. framesize = wx.Size(150, 170)
  291. self._count = 1
  292. self._tbstyle = tbstyle
  293. self._windowstyle = windowstyle
  294. self._closingstyle = closingstyle
  295. self._scrollType = scrollType
  296. if tbstyle == TB_COMPLEX:
  297. self.sizer = wx.BoxSizer(wx.VERTICAL)
  298. else:
  299. self._staticbitmap = None
  300. if self._windowstyle == TB_CAPTION:
  301. self.Bind(wx.EVT_CLOSE, self.OnClose)
  302. self.SetTitle("")
  303. if self._closingstyle & TB_ONCLICK and self._windowstyle != TB_CAPTION:
  304. self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
  305. self._bottomright = wx.Point(wx.GetDisplaySize().GetWidth(),
  306. wx.GetDisplaySize().GetHeight())
  307. self.SetDimensions(self._bottomright.x, self._bottomright.y,
  308. framesize.GetWidth(), framesize.GetHeight())
  309. def OnClose(self, event):
  310. self.NotifyTimer(None)
  311. event.Skip()
  312. def OnMouseDown(self, event):
  313. self.NotifyTimer(None)
  314. event.Skip()
  315. def SetPopupBitmap(self, bitmap):
  316. """ Sets The ToasterBox Background Image. Use It Only For ToasterBoxes
  317. Created With TB_SIMPLE Style. """
  318. bitmap = bitmap.ConvertToImage()
  319. xsize, ysize = self.GetSize()
  320. bitmap = bitmap.Scale(xsize, ysize)
  321. bitmap = bitmap.ConvertToBitmap()
  322. self._staticbitmap = StaticBitmap(self, -1, bitmap, pos=(0,0))
  323. if self._closingstyle & TB_ONCLICK and self._windowstyle != TB_CAPTION:
  324. self._staticbitmap.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
  325. def SetPopupSize(self, size):
  326. """ Sets The ToasterBox Size. """
  327. self.SetDimensions(self._bottomright.x, self._bottomright.y, size[0], size[1])
  328. def SetPopupPosition(self, pos):
  329. """ Sets The ToasterBox Position On Screen. """
  330. self._bottomright = wx.Point(pos[0] + self.GetSize().GetWidth(),
  331. pos[1] + self.GetSize().GetHeight())
  332. self._dialogtop = pos
  333. def SetPopupPositionByInt(self, pos):
  334. """ Sets The ToasterBox Position On Screen, At One Of The Screen Corners. """
  335. self._bottomright = wx.Point(wx.GetDisplaySize().GetWidth(),
  336. wx.GetDisplaySize().GetHeight())
  337. # top left
  338. if pos == 0:
  339. popupposition = wx.Point(0,0)
  340. # top right
  341. elif pos == 1:
  342. popupposition = wx.Point(wx.GetDisplaySize().GetWidth() -
  343. self._popupsize[0], 0)
  344. # bottom left
  345. elif pos == 2:
  346. popupposition = wx.Point(0, wx.GetDisplaySize().GetHeight() -
  347. self._popupsize[1])
  348. # bottom right
  349. elif pos == 3:
  350. popupposition = wx.Point(self._bottomright.x - self._popupsize[0],
  351. self._bottomright.y - self._popupsize[1])
  352. self._bottomright = wx.Point(popupposition.x + self._popupsize[0],
  353. popupposition.y + self._popupsize[1])
  354. self._dialogtop = popupposition
  355. def SetPopupPauseTime(self, pausetime):
  356. """ Sets The Time After Which The ToasterBox Is Destroyed (Linger). """
  357. self._pausetime = pausetime
  358. def SetPopupScrollSpeed(self, speed):
  359. """ Sets The ToasterBox Scroll Speed. The Speed Parameter Is The Pause
  360. Time (In ms) For Every Step In The ScrollUp() Method."""
  361. self._sleeptime = speed
  362. def AddPanel(self, panel):
  363. """ Adds A Panel To The ToasterBox. Use It Only For ToasterBoxes Created
  364. With TB_COMPLEX Style. """
  365. if not self._tbstyle & TB_COMPLEX:
  366. raise "\nERROR: Panel Can Not Be Added When Using TB_SIMPLE ToasterBox Style"
  367. return
  368. self.sizer.Add(panel, 1, wx.EXPAND)
  369. self.sizer.Layout()
  370. self.SetSizer(self.sizer)
  371. if self._closingstyle & TB_ONCLICK and self._windowstyle != TB_CAPTION:
  372. panel.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
  373. def SetPopupText(self, text):
  374. """ Sets The ToasterBox Text. Use It Only For ToasterBoxes Created With
  375. TB_SIMPLE Style. """
  376. self._popuptext = text
  377. def SetPopupTextFont(self, font):
  378. """ Sets The ToasterBox Text Font. Use It Only For ToasterBoxes Created With
  379. TB_SIMPLE Style. """
  380. self._textfont = font
  381. def GetPopupText(self):
  382. """ Returns The ToasterBox Text. Use It Only For ToasterBoxes Created With
  383. TB_SIMPLE Style. """
  384. return self._popuptext
  385. def Play(self):
  386. """ Creates The ToasterBoxWindow, That Does All The Job. """
  387. # do some checks to make sure this window is valid
  388. if self._bottomright.x < 1 or self._bottomright.y < 1:
  389. return False
  390. if self.GetSize().GetWidth() < 50 or self.GetSize().GetWidth() < 50:
  391. # toasterbox launches into a endless loop for some reason
  392. # when you try to make the window too small.
  393. return False
  394. self.ScrollUp()
  395. timerid = wx.NewId()
  396. self.showtime = wx.Timer(self, timerid)
  397. self.showtime.Start(self._pausetime)
  398. self.Bind(wx.EVT_TIMER, self.NotifyTimer, id=timerid)
  399. return True
  400. def NotifyTimer(self, event):
  401. """ Hides Gradually The ToasterBoxWindow. """
  402. self.showtime.Stop()
  403. del self.showtime
  404. self.ScrollDown()
  405. def SetPopupBackgroundColor(self, colour):
  406. """ Sets The ToasterBox Background Colour. Use It Only For ToasterBoxes Created
  407. With TB_SIMPLE Style. """
  408. self.SetBackgroundColour(colour)
  409. def SetPopupTextColor(self, colour):
  410. """ Sets The ToasterBox Foreground Colour. Use It Only For ToasterBoxes Created
  411. With TB_SIMPLE Style. """
  412. self._textcolour = colour
  413. def ScrollUp(self):
  414. """ Scrolls The ToasterBox Up, Which Means Gradually Showing The ToasterBox. """
  415. self.Show(True)
  416. # walk the Y value up in a raise motion
  417. xpos = self.GetPosition().x
  418. ypos = self._bottomright[1]
  419. windowsize = 0
  420. # checking the type of the scroll (from up to down or from down to up)
  421. if self._scrollType == TB_SCR_TYPE_UD:
  422. start = self._dialogtop[1]
  423. stop = ypos
  424. step = self._step
  425. elif self._scrollType == TB_SCR_TYPE_DU:
  426. start = ypos
  427. stop = self._dialogtop[1]
  428. step = -self._step
  429. else:
  430. errMsg = ("scrollType not supported (in ToasterBoxWindow.ScrollUp): %s" %
  431. self._scrollType)
  432. raise ValueError(errMsg)
  433. for i in xrange(start, stop, step):
  434. if i < self._dialogtop[1]:
  435. i = self._dialogtop[1]
  436. windowsize = windowsize + self._step
  437. # checking the type of the scroll (from up to down or from down to up)
  438. if self._scrollType == TB_SCR_TYPE_UD:
  439. dimY = self._dialogtop[1]
  440. elif self._scrollType == TB_SCR_TYPE_DU:
  441. dimY = i
  442. else:
  443. errMsg = ("scrollType not supported (in ToasterBoxWindow.ScrollUp): %s" %
  444. self._scrollType)
  445. raise ValueError(errMsg)
  446. self.SetDimensions(self._dialogtop[0], dimY, self.GetSize().GetWidth(),
  447. windowsize)
  448. if self._tbstyle == TB_SIMPLE:
  449. self.DrawText()
  450. wx.Usleep(self._sleeptime)
  451. self.Update()
  452. self.Refresh()
  453. self.Update()
  454. if self._tbstyle == TB_SIMPLE:
  455. self.DrawText()
  456. # self.SetFocus()
  457. def ScrollDown(self):
  458. """ Scrolls The ToasterBox Down, Which Means Gradually Hiding The ToasterBox. """
  459. # walk down the Y value
  460. windowsize = self.GetSize().GetHeight()
  461. # checking the type of the scroll (from up to down or from down to up)
  462. if self._scrollType == TB_SCR_TYPE_UD:
  463. start = self._bottomright.y
  464. stop = self._dialogtop[1]
  465. step = -self._step
  466. elif self._scrollType == TB_SCR_TYPE_DU:
  467. start = self._dialogtop[1]
  468. stop = self._bottomright.y
  469. step = self._step
  470. else:
  471. errMsg = ("scrollType not supported (in ToasterBoxWindow.ScrollUp): %s" %
  472. self._scrollType)
  473. raise ValueError(errMsg)
  474. for i in xrange(start, stop, step):
  475. if i > self._bottomright.y:
  476. i = self._bottomright.y
  477. windowsize = windowsize - self._step
  478. # checking the type of the scroll (from up to down or from down to up)
  479. if self._scrollType == TB_SCR_TYPE_UD:
  480. dimY = self._dialogtop[1]
  481. elif self._scrollType == TB_SCR_TYPE_DU:
  482. dimY = i
  483. else:
  484. errMsg = ("scrollType not supported (in ToasterBoxWindow.ScrollUp): %s" %
  485. self._scrollType)
  486. raise ValueError(errMsg)
  487. self.SetDimensions(self._dialogtop[0], dimY,
  488. self.GetSize().GetWidth(), windowsize)
  489. wx.Usleep(self._sleeptime)
  490. self.Refresh()
  491. self.Hide()
  492. if self._parent2:
  493. self._parent2.Notify()
  494. def DrawText(self):
  495. if self._staticbitmap is not None:
  496. dc = wx.ClientDC(self._staticbitmap)
  497. else:
  498. dc = wx.ClientDC(self)
  499. dc.SetFont(self._textfont)
  500. if not hasattr(self, "text_coords"):
  501. self._getTextCoords(dc)
  502. dc.DrawTextList(*self.text_coords)
  503. def _getTextCoords(self, dc):
  504. """ Draw The User Specified Text Using The wx.DC. Use It Only For ToasterBoxes
  505. Created With TB_SIMPLE Style. """
  506. # border from sides and top to text (in pixels)
  507. border = 7
  508. # how much space between text lines
  509. textPadding = 2
  510. pText = self.GetPopupText()
  511. max_len = len(pText)
  512. tw, th = self._parent2._popupsize
  513. if self._windowstyle == TB_CAPTION:
  514. th = th - 20
  515. while 1:
  516. lines = textwrap.wrap(pText, max_len)
  517. for line in lines:
  518. w, h = dc.GetTextExtent(line)
  519. if w > tw - border * 2:
  520. max_len -= 1
  521. break
  522. else:
  523. break
  524. fh = 0
  525. for line in lines:
  526. w, h = dc.GetTextExtent(line)
  527. fh += h + textPadding
  528. y = (th - fh) / 2; coords = []
  529. for line in lines:
  530. w, h = dc.GetTextExtent(line)
  531. x = (tw - w) / 2
  532. coords.append((x, y))
  533. y += h + textPadding
  534. self.text_coords = (lines, coords)