From 6861fdf482e990e5c1b15b1650fd020e1968a94a Mon Sep 17 00:00:00 2001 From: Metallicow Date: Tue, 4 Oct 2016 12:40:59 -0500 Subject: [PATCH] Update Cursor Demo Add an example of all cursor options and a IcoFX-like widget test area. --- demo/Cursor.py | 297 +++++++++++++++--- demo/cursors/paperairplane_arrow_blue.cur | Bin 0 -> 4286 bytes .../paperairplane_arrow_blue_fadeout80.cur | Bin 0 -> 4286 bytes .../paperairplane_arrow_colorshift.ani | Bin 0 -> 120300 bytes demo/cursors/paperairplane_arrow_dark.cur | Bin 0 -> 4286 bytes demo/cursors/paperairplane_arrow_grey.cur | Bin 0 -> 4286 bytes demo/cursors/paperairplane_arrow_red.cur | Bin 0 -> 4286 bytes demo/cursors/paperairplane_arrow_white.cur | Bin 0 -> 4286 bytes demo/cursors/paperairplane_arrow_white24.png | Bin 0 -> 371 bytes 9 files changed, 246 insertions(+), 51 deletions(-) create mode 100644 demo/cursors/paperairplane_arrow_blue.cur create mode 100644 demo/cursors/paperairplane_arrow_blue_fadeout80.cur create mode 100644 demo/cursors/paperairplane_arrow_colorshift.ani create mode 100644 demo/cursors/paperairplane_arrow_dark.cur create mode 100644 demo/cursors/paperairplane_arrow_grey.cur create mode 100644 demo/cursors/paperairplane_arrow_red.cur create mode 100644 demo/cursors/paperairplane_arrow_white.cur create mode 100644 demo/cursors/paperairplane_arrow_white24.png diff --git a/demo/Cursor.py b/demo/Cursor.py index 0ad2818c..1af8483a 100644 --- a/demo/Cursor.py +++ b/demo/Cursor.py @@ -1,14 +1,76 @@ #!/usr/bin/env python -# Tags: phoenix-port, py3-port +#-Imports---------------------------------------------------------------------- + +#--Python Imports. +import os +import sys + +#--wxPython Imports. import wx -import images +from wx.lib.embeddedimage import PyEmbeddedImage -#---------------------------------------------------------------------- +#-Globals---------------------------------------------------------------------- -CUSTOMID = 1111 +paperairplane_arrow_blue24 = PyEmbeddedImage( + "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACpUlEQVR42q3VC0hTYRgG4M6m" + "m8uRmGaVV8SQSrDMbJ6azpZ40qXLXM05y2GikFdKS4PUrEINUygVQ0FalmU3soiIhEohbEGS" + "RlQkRChUUAVBCL19/zBBNNDT+eBh8AO87LtsC6h+ExNRE45IWwo3d9DHBNETleQhfqEahMVa" + "WMhPEkaUkgYErtHCWNSOkAgBnEz+mZ4CiKtkAaFRBmxNPwJDbj2Cw7eA42Tv6NmHuEgSEKY1" + "wZjXgJiUYtiqLmNZcDjouZ94SxISrtsNS2kHNPG5EDKqkXe8G55LA1nIJeJJ5ER8rYszI6vC" + "Dk1CgVNqXhMKTnVjoYc3C6kjHkQmOiBSn46cym5oth2ckl1uR9FJO5QqNbuRbKIWHbIxPgP5" + "J65DY6iYpvT0Lew/2gq5q/L/boQXrDhQ34vo5GPT8Ck1qOvoQ1ZhDWRyF/E3EpOYiYqm+4je" + "UTuDztwA+53nSDJls/UVdyO67XtQ3dKH6J2NsxJsbbj75BUieT0b+vxvJN64F7XtA+BNrf+U" + "X30bjx2v4eamYiH3iNec11dItaHRPgje3DErU3EPHMMfoNE6v8E3kkaC5jwPQ5oNzVdegLdc" + "nGGztQuOkTHssu7DAo5jgzaS9fNqU1KqFed7hsBbr86QU/UQff0OtkXsHkpIFFlOFHNeWSEx" + "BeNfvuPZ8Bh6H42irWcElrIH2JR5Ew2dQzhUWft3uLFTrZlnwcvbBzp9AvJLDqOz6xrejI6j" + "7MwgLvS+hZBsZgEtJIJ4ijm2QnKDvCSfqNe/fANCMPDUgfcffyAoZBULsJKVzmsWUWriT1aT" + "tWQDKXdVKCfOnmuGr58/67+WrBD7yyojCuJOFk22YQmJI1/JBOHZm5T/1zKimhzq4GT/FxNJ" + "iyMK4kP8nK0UUX8Azg5aSnmghYAAAAAASUVORK5CYII=") + +paperairplane_arrow_white24 = PyEmbeddedImage( + "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAB2ElEQVR4Aa3VsatSYRiA8Twd" + "y5Pa5SoXi0RpErQuQehQIEREi+ka5KSLew4uDaKLgy26C7bkpIHgaOlgSINIEjgo0f0HqiFo" + "eXve4UxO174PfogqPpzj971eYf3EQ/jggdnl8/mEh+84xzXjgUQiIdlsViNfEYfXeKDZbEoy" + "mdTIR0RgGw30+31pt9sSjUY18h4hXDUWGAwGsl6vpV6vSzgc1shbnMAyFtjv97JYLKRarYrf" + "79fIawRhGQuo6XQqlUpFvF7vX95+BT88xgJqPB5LsVgUy7J+85En7hkxFlD6Wj6f11v1wz0j" + "RgO73U56vd7hGTEVUNvtVrrdrqRSqcMzYiKgNpuNtFqtwzNiKqBms5luX91ZGqnjJiwjgdVq" + "JY1Gw72CL3iKW7D/O6A/dKfTcefUNzzHPZwauYLlcimlUkm//A+KeIAz2JeeprpbdOiNRiPR" + "26KByWQimUxGAx/wCHeO2ariOI7E43FJp9NSKBSkVqvJfD6X4XAosVjMnUtJBI450c/wBu/w" + "CXsNlstl0fsfCAQ08AKxY/+MHERwFwncx0vm0EUul5NgMPiL548ROXayemDjOm4giBDO8RkX" + "yCAEY8sDDd5GF0mcwPiycYozOLj0+gej7JQuh90YaAAAAABJRU5ErkJggg==") + + +gFileDir = os.path.dirname(os.path.abspath(__file__)) + +ID_PAPERAIRPLANE_ARROW_BLUE = 2001 +ID_PAPERAIRPLANE_ARROW_RED = 2002 +ID_PAPERAIRPLANE_ARROW_GREY = 2003 +ID_PAPERAIRPLANE_ARROW_DARK = 2004 +ID_PAPERAIRPLANE_ARROW_BLUE_FADEOUT80 = 2005 +ID_PAPERAIRPLANE_ARROW_COLORSHIFT = 2006 +ID_PAPERAIRPLANE_ARROW_WHITE = 2006 + +ID_PAPERAIRPLANE_ARROW_WHITE_PNG = 2007 + +ID_PAPERAIRPLANE_ARROW_BLUE_PY = 2008 +ID_PAPERAIRPLANE_ARROW_WHITE_PY = 2009 cursors = { + # .cur, .ani loose files. + "paperairplane_arrow_blue.cur" : ID_PAPERAIRPLANE_ARROW_BLUE, + "paperairplane_arrow_red.cur" : ID_PAPERAIRPLANE_ARROW_RED, + "paperairplane_arrow_grey.cur" : ID_PAPERAIRPLANE_ARROW_GREY, + "paperairplane_arrow_dark.cur" : ID_PAPERAIRPLANE_ARROW_DARK, + "paperairplane_arrow_blue_fadeout80.cur" : ID_PAPERAIRPLANE_ARROW_BLUE_FADEOUT80, + "paperairplane_arrow_white.cur" : ID_PAPERAIRPLANE_ARROW_WHITE, + "paperairplane_arrow_colorshift.ani" : ID_PAPERAIRPLANE_ARROW_COLORSHIFT, + # .png loose files. + "paperairplane_arrow_white24.png" : ID_PAPERAIRPLANE_ARROW_WHITE_PNG, + # PyEmbeddedImages + "paperairplane_arrow_blue24 [PyEmbeddedImage]" : ID_PAPERAIRPLANE_ARROW_BLUE_PY, + "paperairplane_arrow_white24 [PyEmbeddedImage]" : ID_PAPERAIRPLANE_ARROW_WHITE_PY, + # wxPython Stock Cursors. "wx.CURSOR_ARROW" : wx.CURSOR_ARROW, "wx.CURSOR_RIGHT_ARROW" : wx.CURSOR_RIGHT_ARROW, "wx.CURSOR_BULLSEYE" : wx.CURSOR_BULLSEYE, @@ -38,90 +100,224 @@ cursors = { "wx.CURSOR_DEFAULT" : wx.CURSOR_DEFAULT, "wx.CURSOR_COPY_ARROW" : wx.CURSOR_COPY_ARROW, "wx.CURSOR_ARROWWAIT" : wx.CURSOR_ARROWWAIT, - - "zz [custom cursor]" : CUSTOMID, } +#-Classes---------------------------------------------------------------------- + + +class DrawWindow(wx.Window): + def __init__(self, parent, log, id=wx.ID_ANY, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0): + wx.Window.__init__(self, parent, id, pos, size, style) + self.log = log + self.SetBackgroundColour(wx.WHITE) + self.lines = [] + self.x = self.y = 0 + + self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) + self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) + self.Bind(wx.EVT_MOTION, self.OnMotion) + self.Bind(wx.EVT_PAINT, self.OnPaint) + + def OnPaint(self, event): + dc = wx.PaintDC(self) + self.DrawSavedLines(dc) + + def DrawSavedLines(self, dc): + dc.SetPen(wx.Pen(wx.BLUE, 1)) + for line in self.lines: + for coords in line: + dc.DrawLine(*coords) + + def OnLeftDown(self, event): + self.curLine = [] + self.x, self.y = event.GetPosition() + self.CaptureMouse() + + def OnLeftUp(self, event): + if self.HasCapture(): + self.lines.append(self.curLine) + self.curLine = [] + self.ReleaseMouse() + + def OnMotion(self, event): + if self.HasCapture() and event.Dragging(): + dc = wx.ClientDC(self) + dc.SetPen(wx.Pen(wx.BLUE, 1)) + evtPos = event.GetPosition() + coords = (self.x, self.y) + (evtPos.x, evtPos.y) + self.curLine.append(coords) + dc.DrawLine(*coords) + self.x, self.y = event.GetPosition() + + +class CursorTestPanel(wx.Panel): + """ + Cursor Test Panel inspired by AniFX cursor test panel. + """ + def __init__(self, parent, log): + self.log = log + wx.Panel.__init__(self, parent, -1, style=wx.BORDER_SUNKEN) + + # Create all the widgets for the test panel. + pnl = wx.Panel(self, -1, style=wx.BORDER_SIMPLE) + pnl.SetBackgroundColour(wx.BLACK) + + self.win = wx.Window(pnl, -1, size=(200, 100)) + self.win.SetBackgroundColour("white") + self.win.Bind(wx.EVT_LEFT_DOWN, self.OnDrawDot) + + self.drawWin = DrawWindow(pnl, log, size=(200, 100)) + + vbSizer0 = wx.BoxSizer(wx.VERTICAL) + vbSizer0.Add(self.win, 1, wx.EXPAND | wx.BOTTOM, 1) + vbSizer0.Add(self.drawWin, 1, wx.EXPAND) + pnl.SetSizer(vbSizer0) + + b = wx.Button(self, -1, 'Button') + tc = wx.TextCtrl(self, -1, 'Text Ctrl') + rb1 = wx.RadioButton(self, -1, 'Radio Button 1') + rb2 = wx.RadioButton(self, -1, 'Radio Button 2') + cb = wx.CheckBox(self, -1, 'Check Box') + combo = wx.ComboBox(self, -1, 'One', choices=('One', 'Two', 'Three', 'Four', 'Five')) + sl = wx.Slider(self, -1) + sc = wx.SpinCtrl(self, -1) + + # Add all the widgets to a tuple that we will access when changing cursors. + self.allWidgets = (self, pnl, self.win, self.drawWin, b, tc, rb1, rb2, cb, combo, sl, sc) + + # Do the panel layout. + vbSizer = wx.BoxSizer(wx.VERTICAL) + hbSizer = wx.BoxSizer(wx.HORIZONTAL) + + gSizer = wx.GridSizer(rows=4, cols=2, vgap=5, hgap=5) + gSizer.AddMany((b, tc, rb1, rb2, cb, combo, sl, sc)) + + hbSizer.Add(pnl, 0, wx.EXPAND | wx.ALL, 10) + hbSizer.Add(gSizer, 0, wx.EXPAND | wx.ALL, 10) + + vbSizer.Add(hbSizer, 0, wx.ALL, 10) + + self.SetSizer(vbSizer) + + def OnDrawDot(self, event): + # Draw a dot so the user can see where the hotspot is. + dc = wx.ClientDC(self.win) + dc.SetPen(wx.Pen("RED")) + dc.SetBrush(wx.Brush("RED")) + pos = event.GetPosition() + dc.DrawCircle(pos.x, pos.y, 4) + + class TestPanel(wx.Panel): def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) - # create a list of choices from the dictionary above - choices = sorted(cursors.keys()) + # Create a list of choices from the dictionary above. + choices = cursors.keys() + choices = sorted(choices) - # create the controls + # Create the controls. self.cb = wx.ComboBox(self, -1, "wx.CURSOR_DEFAULT", choices=choices, style=wx.CB_READONLY) - self.tx = wx.StaticText(self, -1, - "This sample allows you to see all the stock cursors \n" - "available to wxPython. Simply select a name from the \n" - "wx.Choice and then move the mouse into the window \n" - "below to see the cursor. NOTE: not all stock cursors \n" - "have a specific representaion on all platforms.") - - self.win = wx.Window(self, -1, size=(200,200), style=wx.SIMPLE_BORDER) - self.win.SetBackgroundColour("white") + self.tx = wx.StaticText(self, -1, + "This sample allows you to see all the stock cursors available to wxPython,\n" + "and also custom cursors loaded from images, .cur, or .ani files.\n" + "Simply select a name from the wx.Choice and then move the mouse into the window \n" + "below to see the cursor.\n" + "NOTE: not all stock cursors have a specific representaion on all platforms.") - # bind an event or two + self.testPanel = CursorTestPanel(self, log) + + # Bind events. self.Bind(wx.EVT_COMBOBOX, self.OnChooseCursor, self.cb) - self.win.Bind(wx.EVT_LEFT_DOWN, self.OnDrawDot) - - # Setup the layout - gbs = wx.GridBagSizer() - gbs.Add(self.cb, (2,1)) - gbs.Add(self.tx, (2,3)) - gbs.Add(self.win, (5,0), (1, 6), wx.ALIGN_CENTER) - self.SetSizer(gbs) + # Setup the layout. + vbSizer = wx.BoxSizer(wx.VERTICAL) + vbSizer.Add(self.tx, 0, wx.ALL, 10) + vbSizer.Add(self.cb, 0, wx.LEFT | wx.BOTTOM, 10) + gbs = wx.GridBagSizer(8, 8) + gbs.Add(self.testPanel, (0, 1), (1, 4), wx.ALIGN_LEFT) + vbSizer.Add(gbs, 0, wx.ALL) + + self.SetSizer(vbSizer) + + wx.CallAfter(self.cb.SetFocus) # Convienience start for mousewheel switching. def OnChooseCursor(self, evt): - # clear the dots - self.win.Refresh() + # Clear the dots. + self.testPanel.win.Refresh() + self.testPanel.drawWin.lines = [] + self.testPanel.drawWin.Refresh() choice = self.cb.GetStringSelection() - self.log.write("Selecting the %s cursor\n" % choice) + + self.log.WriteText("Selecting the %s cursor\n" % choice) cnum = cursors[choice] - - if cnum == CUSTOMID: - image = images.Pointy.GetImage() - # since this image didn't come from a .cur file, tell it where the hotspot is - image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 1) - image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 1) + if cnum in (ID_PAPERAIRPLANE_ARROW_BLUE, + ID_PAPERAIRPLANE_ARROW_RED, + ID_PAPERAIRPLANE_ARROW_GREY, + ID_PAPERAIRPLANE_ARROW_DARK, + ID_PAPERAIRPLANE_ARROW_BLUE_FADEOUT80, + ID_PAPERAIRPLANE_ARROW_WHITE, + ID_PAPERAIRPLANE_ARROW_COLORSHIFT): # .cur or .ani loose files. - # make the image into a cursor + if choice.endswith('.ani'): + cursor = wx.Cursor(gFileDir + os.sep + 'cursors' + os.sep + choice, wx.BITMAP_TYPE_ANI) + if choice.endswith('.cur'): + cursor = wx.Cursor(gFileDir + os.sep + 'cursors' + os.sep + choice, wx.BITMAP_TYPE_CUR) + + elif cnum == ID_PAPERAIRPLANE_ARROW_WHITE_PNG: # .png loose files. + image = wx.Image(gFileDir + os.sep + 'cursors' + os.sep + choice, wx.BITMAP_TYPE_PNG) + + # Since these image didn't come from a .cur or .ani file, + # tell it where the hotspot is. + image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 0) + image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 0) + # Make the image into a cursor. + cursor = wx.Cursor(image) + + elif cnum in (ID_PAPERAIRPLANE_ARROW_BLUE_PY, + ID_PAPERAIRPLANE_ARROW_WHITE_PY): # PyEmbeddedImages + if cnum == ID_PAPERAIRPLANE_ARROW_BLUE_PY: + image = paperairplane_arrow_blue24.GetImage() + elif cnum == ID_PAPERAIRPLANE_ARROW_WHITE_PY: + image = paperairplane_arrow_white24.GetImage() + + # Since these image didn't come from a .cur or .ani file, + # tell it where the hotspot is. + image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 0) + image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 0) + # Make the image into a cursor. cursor = wx.Cursor(image) else: - # create one of the stock (built-in) cursors + # Create one of the stock (built-in) cursors. cursor = wx.Cursor(cnum) - # set the cursor for the window - self.win.SetCursor(cursor) - + # Set the cursors for all the testPanels widgets. + [widget.SetCursor(cursor) for widget in self.testPanel.allWidgets] def OnDrawDot(self, evt): - # Draw a dot so the user can see where the hotspot is + # Draw a dot so the user can see where the hotspot is. dc = wx.ClientDC(self.win) dc.SetPen(wx.Pen("RED")) dc.SetBrush(wx.Brush("RED")) pos = evt.GetPosition() - dc.DrawCircle(pos.x, pos.y, 4) - + dc.DrawCircle(pos.x, pos.y, 3) -#---------------------------------------------------------------------- + +#-wxPython Demo---------------------------------------------------------------- def runTest(frame, nb, log): win = TestPanel(nb, log) return win -#---------------------------------------------------------------------- - - overview = """

wx.Cursor

@@ -132,9 +328,8 @@ This demo shows the stock mouse cursors that are available to wxPython. """ - if __name__ == '__main__': - import sys,os + import os + import sys import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) - diff --git a/demo/cursors/paperairplane_arrow_blue.cur b/demo/cursors/paperairplane_arrow_blue.cur new file mode 100644 index 0000000000000000000000000000000000000000..0654738f801a757c7ca26f459bd6861944e84f69 GIT binary patch literal 4286 zcmeI!ZAep590u^aWi~75O)S!!$;hI}6sftgmL@GVHOum4mSUo$X3@JrYOh#fMrC3s zNK3RVimVS23B5tsf&`5)$cWM}6&O*V`1Jh6qSE&1-spoDe!IKd*?G=6_ndR5D0)Sw z`1vUVNBu-a@#4GL z(&s>WPLX8PDxY=hN%}g4d`SA7Kt0q)$z;+ZpY=*VjTB5)ilvk8quu%{&Ygvi_w;^V zr;=9r`KMp*WhOW*air#o+nn3S3ID3{hua zg06NaHrv-r{x{l3Hu9xWYK%ihf(a?~VQhSj(&5pUa^hzK)F8@^C3%_3Fi;->gW zJgzQ9WuoP;ZkFWXrSkzi3)jTIh zgrK1)3p-bte{$^0gyU!d#u?mY@86BwJc9&kD*0S(9U;W=Tf%(rqH zuV#P$tZRcc5H-6}kR548NvaJEhjU<@I!Ur+&-Wz#pTAM_Ix%b>%5vhdEp935i!%`D zKTWb*Xa;HipDSiz0QM)Zz=`Y_ga`V|I#Yd(yBe>sxkgkM#KRVBf?lW18h4d%4)8(B zvUxJ*nyqnH`CMa?-AkISaaZ}wl{Fqun(QyGvIoE8=`V*7=%+p^Ciw@hOc=zcfII;e b-7n-?K9@35b{Q270>Gk>hbD`FMPQ`w=^fwP literal 0 HcmV?d00001 diff --git a/demo/cursors/paperairplane_arrow_blue_fadeout80.cur b/demo/cursors/paperairplane_arrow_blue_fadeout80.cur new file mode 100644 index 0000000000000000000000000000000000000000..e4962500a1ca4434ff1dd8b1e9aec6e23927b303 GIT binary patch literal 4286 zcmeIzZ%7ki90%~*G}EliwEy9j7#0dck(w)YHN{KKnYL@rvy^2zvRqWFjHTAHoS_cN ziQz%Ci8hN`78cRKQV3g+pb-TL5&EV#^)|Y`kGQb3UfqnqAAI)go_o0O-E+^~QIwbx zQBo;2SzXI0Y9;<{0x2i~d+|G8^D{6%1OMR+h;YtgAnjZi$z3=laE`-Cb|@qO-fENQ zfyOW8o8tvII=S8uSOKZ916Bd)^G5~Xpyb#~VL42`zJnG7(yiC7((Bi)rO~$*7J)x1 z8VB79>5v7vF;VN(-WP-Fub)1sH^)fT=-UWkK<Qw7E2cKn0L_A@@emQfJZZm(LUI_{d9ktiP8X?P+J9m~`yj;%)5kjV89C z<`j#-0wD85?hmAeFUeSlb`M_@8YfIJI=okQu~9K-8d ztp=w~F+(T2-7r4tH5_Ca12PXmB1FMr5afMSnok>t94$sptC&@fQDgi#;x(#L)s`$=+R4W?VK&K?z4sI?#A*Q_fA=~8_!t> z_OAiK*ZTBa-~W_2Nnb}*ULTzp(4)v$*R}qK>ls47@*ibW{NGB#^WWhc)B;6>O<9OG07TP}ZPHK1kg;h{Gll1Q P4COI|#}FPvcnSOf1j}D( literal 0 HcmV?d00001 diff --git a/demo/cursors/paperairplane_arrow_colorshift.ani b/demo/cursors/paperairplane_arrow_colorshift.ani new file mode 100644 index 0000000000000000000000000000000000000000..8475c0b73b243df9f5892737109f7a9642f24b24 GIT binary patch literal 120300 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 literal 0 HcmV?d00001 diff --git a/demo/cursors/paperairplane_arrow_red.cur b/demo/cursors/paperairplane_arrow_red.cur new file mode 100644 index 0000000000000000000000000000000000000000..544a16a51184c4c349bae4efea756e28b5d639b0 GIT binary patch literal 4286 zcmeI!TSyd990u@ly`&;kwj`*zDq0z$CYri=S#POZ54@H_mDS8%* z_X}ufF{6KQ4jJhNk^h*ING*51UY~=nUlw7WTEMfhc|7QyMN!!+#HNhmR@V%go7zPF zXF5%X$yv@mWF0TY!`>Nab;DLFt0yoqZibzmz34+1d8& z=>-%PREYdvbcOWfL-ul9hje`zI`5d7-M69q!eLCAKOrVMN%Y|d)zE&D> z#xEhh7*|_fLL1*^MVHb6)8I6+GcDu)jkzJTLymD@Ya>oujE4F##KgB+X>XfAS!t`d z|9>)9OR~;A(TA9*Vi;>j5FOk6kH-2@7;AcBOR zQf!Xf%4e>aCeXE2 Q0C+0ILzAa~r$9r$0S<)MdH?_b literal 0 HcmV?d00001 diff --git a/demo/cursors/paperairplane_arrow_white.cur b/demo/cursors/paperairplane_arrow_white.cur new file mode 100644 index 0000000000000000000000000000000000000000..cb390949dd93966fc7e209626a03c3f0bacb324f GIT binary patch literal 4286 zcmeH|Kd4es9LMi{DNoUOg%v^Kl_D&ShCmA-!ah2;Y0>-fOkIAAJ0CJf6?F=lp)>Xxf&hYr&wljOWKR z?G!#;06}mI;8(n^4-wH0`G0G$epfcvdeGi(&a{4{L;wD{wSLt$*J^Y99hk`uI1aY0 z%*uwJzO&#NxC~AL(_zxj=RFEegB#!__ykhG0H#C1@5Z2Kz9Tm=twUH_O!B*g3W ze!=(q;2ba=3jRA7^fBmwF?jEGyCs{=O08C-U(l8VA)o_Oq2L$#48xFUG%Bf7N(zO7 z42MH$x7!j31n7SXt^toJIXWNY4~0TfE|;ZVuS>JpluoB3lgUJOcXy@N>q#sYqkjmP z1KcAgP!1J;tJPZi==`1Wcr2MrhW@YMA-D~gE6h`+u;X7W7Rww6hr^u1JHR}+4tO3Y zg&jZFf_qUamBjD&a}KY-J;3@@3cG&JVK5j-KA#t-)5$qJ0bV6JI@$HlW;3Z&D!-n; zjUi8ft$*R4&*#g!h(scM?iU~clyi@BwEFzay+)%U@pzo>*We;BReR`f+0U9xCX;l3 z06csC%KgXl=g<1@cDs^Jrv-Na&;Gl>1uTWx_3!ullFQ}9;c$F|FbjA;Sq?M)(P*@+ zGmpo^buR#0ZcbX&Kb=mcSS*Uq=cBt0lxv)xy+Xy$d#75hTCVZE+-z6z^Zr|%@s?`b zuHSBr+wr?xF7EeRV7bQa`0?M*;0mx@<97VWkA35ZA@Uu(0UFs^v5og5YhXM3uMh$ISo$ literal 0 HcmV?d00001 diff --git a/demo/cursors/paperairplane_arrow_white24.png b/demo/cursors/paperairplane_arrow_white24.png new file mode 100644 index 0000000000000000000000000000000000000000..9e91534c2946a4b855502901614148a6d010ec76 GIT binary patch literal 371 zcmV-(0gV2MP)#W zrHTa@ozpZ`h{bp*bpUs?RB3U8KEx^iFL?E7+LJ$s3Asy z1~g-2>HDGbe54C8O0lkla;m7sLy+cN;XUmM;