From 4efa8d00fcae0fb5882ddbf5796008cc3374811b Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Wed, 4 May 2022 22:38:26 -0700 Subject: [PATCH] Fancy Mouse Cursors The gamepad mouse cursor has become THE mouse cursor. It is always visible and your real cursor is hidden, and this way the game can swap out other cursors for certain scenarios: * The Pencil Tool in the editor will use a pencil cursor over the level canvas. * The Flood Tool has a custom Flood cursor so you don't forget it's selected! Other improvements: * The Palette buttons in the editor now render using their swatch's pattern instead of only using its color. * If you have an ultra HD monitor and open a Bounded level in the editor which is too small to fill your screen, the editor canvas limits its size to fit the level (preferable over showing parts of the level you can't actually play as it's out of bounds). * The "brush size" box is only drawn around the cursor when a relevant tool is selected (Pencil, Line, Rect, Ellipse, Eraser) --- assets/sprites/flood-cursor.png | Bin 0 -> 7899 bytes assets/sprites/pencil.png | Bin 0 -> 8065 bytes cmd/doodle/main.go | 4 ++ pkg/balance/theme.go | 6 ++- pkg/cursor/cursor.go | 86 ++++++++++++++++++++++++++++++++ pkg/doodle.go | 5 +- pkg/editor_scene.go | 4 ++ pkg/editor_ui.go | 18 ++++++- pkg/editor_ui_palette.go | 18 ++++--- pkg/uix/canvas.go | 5 ++ pkg/uix/canvas_cursor.go | 53 +++++++++++++++----- 11 files changed, 176 insertions(+), 23 deletions(-) create mode 100644 assets/sprites/flood-cursor.png create mode 100644 assets/sprites/pencil.png create mode 100644 pkg/cursor/cursor.go diff --git a/assets/sprites/flood-cursor.png b/assets/sprites/flood-cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..74df9292f5d201e4d4b299756c30a4db29e59414 GIT binary patch literal 7899 zcmeHrc{r3^_&;UKk_bi0WX&>W#>|khlyxjwvMb7%g~7~VW*9`N2&q9$i=~oXA{B*f zA=$~2L6(xro_#64L%rMe`~LG@*YEq^J99nHJkNdZ`*Yv-=iKMaIValM5-Gqd!OO3mV|#M&t0%h=kP{G~DC`M`z! zIsRgU#I9ghQrr9f?$j13ty0`@v$!*TBK(nzM}he2eEC^uj9gY$#$>no%*m+RkJy{AH^%N4sq0t?`CeOGa!-AEsy0;3P+ zOpoW@?sY%yMsHB;3<+a~x)D}A_JQtRUoA7?tyc?U%VRZa?4C6b)Dsc53juw#9ew$E z{rjMnO2vDH-UO}Q!QN0NzC7W(aL{0oS?|((sCaS&v5L5PC^ECB{Vr2zQSjJ!mcaW2 z7d7KAS03NF&6vc9^$mw9e)Obq3QpLpvkm;|1hh?ULb~hL>97bBU3_u? zrb<0<#ZrfX*MDRnHqaZpFHuHk;^AvykP4go{I6X;dP~->fjI;!^^lYOe&?h zhyC2h);+U=MD{$yls;Xs_fdi?92M>WIC6j6Z!;sG_cL^&Z65zJVB>V z$|&EhRl%@Ku(68h0DU0q%z&p%yB73rkV@6- z48qd$<|UWb?(z>}H?4`tc?9sOimx*`4?YZg%#XPTyHj@;Y`iGLjL^MX^^6lC^z!hi zs6F_g8lhyPHhZYo`e#Gbv7*#9=iSY*&8O1OM=0hX-?ogIAGE%PBp33a2EC$3pRYk`UhJ|w|5KOmv2b*G1w0BsUB957K7v-fMsqbf#3 ze3^!*?#0EJL*;8OF2;mgd$dROfshzkOeAC6G1BgAT9Z{3wwc3t2jf||Kx1m+rzd<# zt0U6(=AN2!f=Aw>c`RQuFW#8nrBHt+fP=Hu&Fn#P#{gVnPbgje9bAGv;;9=r+nNi? z6t0ftp61}C}%R8)7*OR-f1%}k~N3c{YS-ms$CW5YIi?+{=wq( zsy6#Yt`50~jRrj2V9tatoHBc|BUNKxWU-S{T1a`ZX!$72BuPn>mMiOYM^8UDwKj%d zILX1|=1b%RYSQ@wFbap4iIoUE^6q$P?kBQi?l(c#jNZ(S2fM?|F5NVG<`d)V{S!lU zu#<;K41C3AeteK*BXYsmVXa*v+&WOqT4nOkC;#WMWXD(GiR-(2hOMb zm^yh_mQHFt)l}Z~N_9x`k*h$h*Jmf7)T7lWgfYeI9xm`VHr7-k{59XM15u$*<%0Kx z5DM4Eo_nHme1}I)7`~2sI}o6ST&0D0&@Xh0)5>PbzsoWNqXxKcQu+-qIf%(0UjM*p zH(TNsKm-^~pt{BLWdXpkC)17Wb}s=LqsOgUOm;iPBrdY+^UzLgfzRVm$Niuc9XiB_Ybiu{ z{K}jqE~vki`GlY_td>K-wCEi!&EyJ-nX*&h?7E#7lXer9=1iMVf!d20x{OM{9d*ja zCJ-MX6!db^Y3XmpGl5==8z*ZeR4gpSf=x<*c|sgy*$GG#=z6gJL%{)|L(fgzY%Vh_ znE*qp%EqkQmX)D{rKJfj7v>@xb|&nIw;9{mbFl0F@Q7|Es#)WZk5`qVmda&uYX|Y3 zaFMZ5wQx7Z{--y~nQ@ZXRtLdgu3Rdl7;pZ&-L&(W1SO(~Q_FxaJ@%#7a)F~|c?Slpz zwQyHTXxBA4DXEvYd3(|3a>vE=cvcXyDBZA!^~2Yzp59zs7wl8 zl@u-dcG9k^u5-vlg}q>>^#Se+S-An|3&)k7_r8oc5ntiINlI-r2oATD2i2JcFFM5!7YLXRoC0PWL=~RuFWx?u=^TQBY%kCebJ! z@H83V)%vbhBPok~NB8rfh815v4O+%s5zw%p&bink+2atn=G-%VDt+DH=5q)hClu6} zCzP!n|1oZlQm7a6@3xtrhx?nFlS6 z=ldS9Cpr*F=N?ohG6bSrSA}7-fxF`5e!TA+BU!h|f5XgDGe{GL&5s!}xpQ)&u zRc>>89#5fL2geD+C60_&9U&7Io$$@1Z+qWG26z{|5bb^+EF<-BGhvJ~MUpumD?i@J z)p9+=a3p%1hNP-U$^CrhX-CRE8Re%iGm`s6y+t!M7j*@G<;%MOB?;ksGTcd*%G1*w zM!XZ(5}YDte#)83t;%J2Y2`hRV*S_d`PN*RC=c^$lv-E~8#`DnP_#Pby>wt^hHxsu zwJWH`rx&bj83%NwTCYs>@6Wq+C0UbJcssD+?g2Fu{wz!JQ86B6&|>yQ3`pLXd9_10 z-k~7sjj_JmriD=EA^SUbjE>kR|BxNQw0$u-8uWSItTqQ^H$XQWs80*dnIm2c6dCLY zoEiO4k8t`BF^gm@m&C3*ahtuJd@`tJ#h6X<3_7SX9@sI5aO%2#>&M&JQmRI5afV~)o7F!=x`awj5-xiE{*? z<+a4q8|6ilT*ULw^Pu@oz*7z%^@`sf>pu0uwrl<4-0}hD)7x01a{dTyKl9>U?xv=6 z)tCzp=fjy*&1~AP8Xh3Nto0w9ut!7g^U9tMm33o+ucs3T7nu(SbjM5Ur?ScnkOf|hxsaTb9x1DSliph4J(xG(QKZ!p;zi4sUz8tbnH91n^XbUfN z5Aa$jm24emvPU&d99vyyPuYL;jIhAdUJ1i<+-wb=jEmMPckZ>AS8j6?{xPv-U#c6qi*#lnC~FD%C6wLaeywoIX|1PmF}w)SKU zP1YJkNP~*lL`wr;xwJNRoiZB=UzI%F2gOg<%S`gkbDEjP_|r@8*5 zl9QL4VryUjG}AH3V|r?-MA2L;P%o*NJT6tS77`5lcmy^${vBQDnq#V?TDLN&xOOTm z=k$3Ug4ItgP%6$0#CtoCYOWWRF7fkox`^HW;;tt1R8zI2PjdZrwz!b!k9pVkpRv0n z9hiWK=_Mh<9N}T_qtoNnzMXbSUT_fkW~`Sx@x-lBrZ*QI2Y2fTc{`lvQ1 zFkiL5jnFm2qFs1Pl-x$0jtfX&>IFBrD?_}+6ch&1eT8`{dY9^X_VjV~S@dt{7Edkh z8a~gJzmQ+qvjeAVN(v}i5dyyyaB&HQV+CIhus^h-GUE<5SeYLY3txt=Wom;ddC6(4_sbcni@*9+zeyeJ@0=$QGRlkb)q1FXPq24S)4$i zNd#3ChUAV_r4f8tCkt$B+Q(?VD6}`00&vHA;E6iYGi8<106a!V+7WI6w(vE;dg4uj z{js*emUif1Z?q;x`j{@SHVwf7AYdsd0FB^7BqL}#(%ZNQ*7KGaBn{YBp?K>^J6Tu* z3`qW108AC83I-a{@BwPly1W2we+&*`V`%&vg7u~&?Mb2dB0!+Pz(CbNs4B_d0|e33 z)C7UmKx%40mIja!fC#RrIn@&!Ru!5{(w^mhv~#VCLU@;jja)q-rtI)DM$V96w^KN@QkfF)97 z{tkgb|7q___4nCM2ZIJ-eXsgMly%41a5zmg{BKaEL^1_ML}Rz0Sm3I77LL0+%pD9yYXH?@ z7%0mS4gqSyU|=8?j)FmuKh zSR4wd2|0=dg57ayY7jWoT@w!7hQgo`#w33Niq)NX0?Gpm@+Ep~H*67((6ctxkycX$ z|0S{ZK~Zol10CrTcp{bdSA!j%fVHKdw%CNI!yy`KN7Xenp)d#puJMCf! z2v`;R3wNtq5UgZa#G-X#J*AVc*Z#Mw|+hvPDp?^6cqXMv)ZAUD-UrlIF6ww3A8sEPQ>JK^o zf9WikrY01HK|z3MEQ@B?Q5+74(!@c5U@#VpL1C~E32I0LJ$y5AXozd21|o}Ck)ye)qiBH4f=mL z(cV`0+cdzk`z2#dFRa-L^yhT-o3kw%{|`UE`{Mu50}J{;C;y7y|LFRUu7AbAzf%6M zy8ffe))|8I2h{bn@DYl%aW&93k>=kUHu{0oIDbvx3kS~a=Yya|f}P^s`$o|MS5 zRcx<=`uI;J^0oU#dkyPH9+@saDVWXuQm#K`Un$2RpLP-VdPTjExR2o^?JNS8?f_w%oHHHJw%qEoH7^_)8)Fn-llx#D%M#ZLD F{tv%sMl1jT literal 0 HcmV?d00001 diff --git a/assets/sprites/pencil.png b/assets/sprites/pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..7811e10fd5df6ed66627681fcbf7a38f50c24043 GIT binary patch literal 8065 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 0 { @@ -517,7 +518,22 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas { // _wanted_ to be smaller, as in Doodad Editing Mode. func (u *EditorUI) ExpandCanvas(e render.Engine) { if u.Scene.DrawingType == enum.LevelDrawing { - u.Canvas.Resize(u.Workspace.Size()) + var ( + workspaceSize = u.Workspace.Size() + maxSize = workspaceSize + ) + + // If the level is bounded make that the max canvas size. + if u.Scene.Level != nil && u.Scene.Level.PageType >= level.Bounded { + if u.Scene.Level.MaxWidth < int64(maxSize.W) { + maxSize.W = int(u.Scene.Level.MaxWidth) + } + if u.Scene.Level.MaxHeight < int64(maxSize.H) { + maxSize.H = int(u.Scene.Level.MaxHeight) + } + } + + u.Canvas.Resize(maxSize) } else { // Size is managed externally. } diff --git a/pkg/editor_ui_palette.go b/pkg/editor_ui_palette.go index 4c1c76d..d0fc456 100644 --- a/pkg/editor_ui_palette.go +++ b/pkg/editor_ui_palette.go @@ -4,8 +4,11 @@ import ( "fmt" "git.kirsle.net/apps/doodle/pkg/balance" + "git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/log" + "git.kirsle.net/apps/doodle/pkg/uix" "git.kirsle.net/apps/doodle/pkg/usercfg" + "git.kirsle.net/go/render" "git.kirsle.net/go/ui" ) @@ -94,12 +97,15 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame { frame.Pack(row, packConfig) } - colorbox := ui.NewFrame(swatch.Name) - colorbox.Configure(ui.Config{ - Width: width, - Height: width, - Background: swatch.Color, - }) + // Fancy colorbox: show the color AND the texture of each swatch. + var ( + colorbox = uix.NewCanvas(width, false) + chunker = level.NewChunker(width) + size = render.NewRect(width, width) + ) + chunker.SetRect(size, swatch) + colorbox.Resize(size) + colorbox.Load(u.Canvas.Palette, chunker) btn := ui.NewRadioButton("palette", &u.selectedSwatch, swatch.Name, colorbox) btn.Configure(ui.Config{ diff --git a/pkg/uix/canvas.go b/pkg/uix/canvas.go index ab3b4b4..0560711 100644 --- a/pkg/uix/canvas.go +++ b/pkg/uix/canvas.go @@ -7,6 +7,7 @@ import ( "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/collision" + "git.kirsle.net/apps/doodle/pkg/cursor" "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/drawtool" "git.kirsle.net/apps/doodle/pkg/filesystem" @@ -56,6 +57,10 @@ type Canvas struct { // NoLimitScroll suppresses the scroll limit for bounded levels. NoLimitScroll bool + // Show custom mouse cursors over this canvas (eg. editor tools) + FancyCursors bool + cursor *cursor.Cursor + // Underlying chunk data for the drawing. level *level.Level chunks *level.Chunker diff --git a/pkg/uix/canvas_cursor.go b/pkg/uix/canvas_cursor.go index 547b015..1dfdd5a 100644 --- a/pkg/uix/canvas_cursor.go +++ b/pkg/uix/canvas_cursor.go @@ -1,6 +1,8 @@ package uix import ( + "git.kirsle.net/apps/doodle/pkg/cursor" + "git.kirsle.net/apps/doodle/pkg/drawtool" "git.kirsle.net/apps/doodle/pkg/shmem" "git.kirsle.net/go/render" "git.kirsle.net/go/ui" @@ -27,24 +29,49 @@ func (w *Canvas) IsCursorOver() bool { // brush size, and draws a "preview rect" under the cursor of how big a click // will be at that size. func (w *Canvas) presentCursor(e render.Engine) { + // Are we to show a custom mouse cursor? + if w.FancyCursors { + switch w.Tool { + case drawtool.PencilTool: + w.cursor = cursor.NewPencil(e) + case drawtool.FloodTool: + w.cursor = cursor.NewFlood(e) + default: + w.cursor = nil + } + + if w.IsCursorOver() && w.cursor != nil { + cursor.Current = w.cursor + } else { + cursor.Current = cursor.NewPointer(e) + } + } + if !w.IsCursorOver() { return } // Are we editing with a thick brush? - if w.BrushSize > 0 { - var r = w.BrushSize - rect := render.Rect{ - X: shmem.Cursor.X - r, - Y: shmem.Cursor.Y - r, - W: r * 2, - H: r * 2, + if w.Tool == drawtool.LineTool || w.Tool == drawtool.RectTool || + w.Tool == drawtool.PencilTool || w.Tool == drawtool.EllipseTool || + w.Tool == drawtool.EraserTool { + + // Draw a box where the brush size is. + if w.BrushSize > 0 { + var r = w.BrushSize + rect := render.Rect{ + X: shmem.Cursor.X - r, + Y: shmem.Cursor.Y - r, + W: r * 2, + H: r * 2, + } + e.DrawRect(render.Black, rect) + rect.X++ + rect.Y++ + rect.W -= 2 + rect.H -= 2 + e.DrawRect(render.RGBA(153, 153, 153, 153), rect) } - e.DrawRect(render.Black, rect) - rect.X++ - rect.Y++ - rect.W -= 2 - rect.H -= 2 - e.DrawRect(render.RGBA(153, 153, 153, 153), rect) } + }