From 9efa891d743996264948af26b39a3f652a536238 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 10 Sep 2017 16:56:18 -0500 Subject: [PATCH 01/77] Remove from git --- .vs/SpriteLibrary/v14/.suo | Bin 61440 -> 0 bytes .vs/SpriteLibrary/v15/.suo | Bin 64512 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .vs/SpriteLibrary/v14/.suo delete mode 100644 .vs/SpriteLibrary/v15/.suo diff --git a/.vs/SpriteLibrary/v14/.suo b/.vs/SpriteLibrary/v14/.suo deleted file mode 100644 index 65beebbfd2cdbb3706bfc40b3f0a8fdbab80b810..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61440 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 B7s&ts diff --git a/.vs/SpriteLibrary/v15/.suo b/.vs/SpriteLibrary/v15/.suo deleted file mode 100644 index 3b0f24b8f34e69b41c3e5a84ce1e39eafd46377a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64512 zcmeHQ4Uk*ab$)BFjSZMT6Y~>dgzEqSOK4Zp{@7s9YIp6$yLgS(#$Xv+t9`qcS1T=& z*7ky(kTy*z#UxM~(gvD@{4^vPQrb?T>CX_-PSYd<3~e*hG?^x}onbnqCDWOM@A39Z08YKoL^W`ylEbg4_>?{+i(_7yWmCEi8W~B*_jY_D>J~7QPL<8QpxCd|mz_z>>KwP8xQQ}SEn(ab*%UGVt zI6O|_*?pGh#9zR@B47q^3~)cd_}(eQ^@nl(5dhz7X#cDdML-D?1w0KWv- z4EP}6S^(#g>j57EaH_Zwum#`;1OROSndUabxx8n0yhV>E^TYnncs)4A0KI@dKtEsy zU?*Sza64cZU=m=LZmstY>FFHCF$oyguZ`(U;NB5H8gLZAJZEu~adJ4H1{^oslh5Rl zGbv~D2lO~6ag=43aXyNBzYO>lz{dc;3ivqSHvkU-ejV^IfbTtm<7vQ?fKLEE33v?f zIDpTe!11>LpVF^CjpOg==bypxDZtZ!-vxXY@I}Dq0nY%w0ALzl!tu+1-_x&oPXbQ8 zQ0E%(+P}^f+GNQ|{#R8};2(Oye-tq0On?(57hFB~z<;(Nnw%r5zo95!K_t#E3{LYO zd2;e{PJ#UIwTQs^fmQDmS3V;T^`?HYUzq~GHH>jMh4DR!lB>wmH0mM^Ss;tra1O-J zc}X_Ab8PYSb2z-KN32$U^07{V_=%hICy!2X<+ESI$$#q?Jt$=kC7(js^EkSddt_Qy z>G&_j4Y&AHhKj%{&JyM&|Xr8jee8Ty9`x7^Vn>1MV#7YsfA5vH! zN)X0>3|yUG3E`>@_29>U8%Cs%a%iqD%Bd6O*XUnhcZc5x)Zf`u3;q%0X9)RAVq_@Q zJyYla{`cc}HNb88S#;U{ccHzrkoff2PA&KkBL4UF3BU>eUSMZU^rGa{ z#@K}b>i=9kpj_g%{*Ck>M;SBPNF&C3(a*+F>IvLsoy*eOVW&*8qJ{F$g*D)(Zs2}4 z0>W;LI!Dp+6ToHd{QqyB)wzW-AX&RVF>31a-Ix%@-GOMZ#L-2X;^cLudyoYRNrHO{Q^7=-b+g}ls_ z0Jr5g)<1jvC~!{T#}>a!8}U-$!pMVE58(f6F8?5smF2hM??E0^V?wVa`A;i;@_+0Dq)W~})p$_gZ`lB(mjjpw zH~4*s^f)JN1k!>LR^i@iz&QZsks9Lb7Ne%TE8Ab|4RbpXz59|Ev{Q@*2|AS| zIA8?8`}_3cejM)x+ygiONC3$D+zU7aI1Di2;W;Iaali!N2p|nO4wwYY0PX`&510c? z1NaW*boN!A&*FGYKRZ56pkMTd_=#lCV#R%odV>~n(3c<$T##vtKnz6 zI)(Y*&mh77&=akOpETtZD1Vb?NxP`t_nhL&XGNU2#ZTIH3dB!&g8jrT{-cQdLp@PX z{y)3r{}{L&YG4XjwM=8)J6m1KIZ&oZ`x7wUnRy!7uCRd2G;^6R7I@MF>$X-C*k5w)S%t=Mm5>QU!EJ9vpMGJYgTFU=b#Bb%x2$lKI zSx6q#h;p{99OlFS8tLDPe+cED0#@1~8Ff*WMuPd!|3(yNL@$yRzrFln%!#=!!t>~V zA3ze7_d|ih??)p&z35mzp@?s? ze;*!E9&%g$-$q=%!*Dk0|H)H(`hTtYL4S?c|5Fb3^#7v%7hC`D>3{9ke?0xKr~j2Y zcPH+Ly2{$+ubt@nmH0nT|Lf_08>#=b%0JQ`g=-Mh$5dMnq5Z=q&@*K!xBTZ01O4N4 z!9nugZt*V|p(TN4#$QeU;_3e_jcvK4{;8Su|DOKWS^w@A@{7{9hqd)pRYY$j8j$*Z?y)tO>Gnc3nSo*B)gQ@hmJ zk=&%3y=62Q8jp;3j<>aqMS{stauw6xs3p5E-gly?W|?F_yAfB5#dLO}z$jPWd{;U< zmOC!*ZJ#`Js3)14#Pj~Nni*U9*oydUp{Py;V!2F4O%;(!A+STus`+#((3{q7B=fU} z+YcPjBgTt)yuHOYRY>LXne=F>K;b~JCl((*a9isyzIEewdp>s27cTtFH+E&d4uS6W zo_LIMXbjd<3G8YXme>WHbH!!~c1<~)TeZi0PCJ4ERw%if!H0FsBF@LOy7yr{mA3s6 z#ImmQClHhCuw3I(wcQ}2xZ<9aS;U^-vjA3A3RTWt zggMPdJTX@iu_Gja+Toft*NY0E<)irLDxnN$*%&SKxVpq0C5){qC$XZPMV_7YnLTjk&oG>iCxxRE!fA9W@**i4u@Pl zmDuEwJ$OgY;J`IF3JRY_opU!6ZEM&&m=Cs-wC!Zekp~j1tzy@mpj)Ox%Mv5)bD!EQ z@+RzMO7U1%l}gGU%Qbb{)5;#T19t>2;p2k)OT@mTLulJhv~efewIBZ>SX>5i)`eX9 zF>dz2qOu2PJ?O<9i0j7_z7fP7uGIE`IwFW0Lb=%cSc*$6rI7m^gpD<6lNJv$_PLhW zr6+sw#JRVM)of`up3rP2xUQW+&C6Oy0N4EHiU8_G^f+2ZuunwMvRo@51#-6<+p(12 zdbUag^&Ub!CsFIHZMKSvbDo9q--#dFg2z#ujpNvkUmN;x5^vJRKZ&bS?$|23kj5PM z+Kbv~H9hIaQnV?Br%y?uiNq+xZA_5>d8SKxju zpI%?AK_9FkP9V1(u*MWUeO#+WY0u!Z(2pDwhCn|lq{rP>IpnU0x6An$C%R3Tcp8qa zvq+0=IE8YszvZ$K@%EUvApDB&#&T$ZRh89T=gDDCJK47hR50%}m$UmaaY~H`i!oE+6-B zat?Mw#oWu(to^q%D$BFDM%Se^bE#u;*P{6eKZfxhUIE4x&ENhqvhIhE~-H{O&}G)I3l_DKuya$ib`&YB%W*gPIyr1hG@T z5cV+gJ@#5m_qYOPvxy*FH2AhRV{7{;uu5o)rMPHlC@DSu3c?3*9>pw->mZV z`KSZ?7`K|pvW~qBPyZ0cQj_wHvc6p{G&4U{Ny6nCnYkXUG3{!iar9udzbTDKg5Tk_ zlRp&C{kQBSr;@FxXa7TAwdIz4CEF@@7G|FPkFX!}?0*(&=TuD(E4k0*WARi? z5AUYL_2C@NmUWGyWw~xu(ydjpWLr);Qz!auoUW+;vZ7fh=!SNew@m2N&dX6d>Qvrl zrfaJtzuZPEbNM{`AMp(r;WLl>WtzwSXDQ6$^et}Igo#<+PV3doqoCwntTs30Yed$V zb~RBS{-*L?80S3&)kieX{%a}k36T`msQ&LfV{jG7K8BU@r43r?7?1T~4{I~*!;y8q zl={ClFO@j5Qhg5&c=mtn*~`QJFAxj_UF>G>>`X>dk&d?RP*@FibsyYvKN>Ikc$$iai$6ug!n zL1^V)oj1rYhYDh~oTGa&SQE=lO(*kee$CEg;Yi%P@6faVtiG3UdD(xa?^l(T%9;(j zuZZ3Gv2-?>nWGU9jDd1TS+qdNUHwr&dAews>sp|N=>V$ZwimyM@ea!sU>0*q}JrUOOV>ecv+4d>V5BD~cRvvA5KeFb9`?#`bDbZ?*a;7C%pXSlTIMPYn zl48>EVnRAs6 z_^nt9W%O|;tk=13k2A;&MoC&8(H56a2n;f=W}dEh)|EBR@nf9A_r<;bj&@PJqcUe=>;E z1wUO^a{9=D+s^5u*?^hv3HOX5yPSkdj{KaTF`qgG+m)4`;uvM8wIh@|hx3{BJ*1^| zs|E0Sw98_NW=Fj#&wCPX!zP|PEQ=k5y6Le3C5Ldd! zFMavlmp2Z6@#(SWp4|AK-IZcO|Ka+5%56ia?2Oh#l(x!g)JVx;#D4&uXXt$`j9*aq zz}BvL?h_u^+VRv#qkde45VK$N{TIcNegNsg?G#3+G5GH>2$5{Kf);&L^{d-o=p4IYlF7gsZKFK*8L#blO z`-GO;HQI>cT+(gYSHW4o{6_VB-k;8=i|XM1SD6p^8r81Sqj~tQ4WtUw`P|WysjZ0_ zEF}~Y#q`u{E-{u%&2WjKkT{kuK+WYV6lcaZqn7E{VG`U2DSr|}3Uw^(!1Q*=e+H(T zC`={uNDE69KymWq1JRBcvHvB?-b`L@?Yw}BueN^|?a7k3AG)QNWarg>Z~woWo%_;$ z(cAxT^gbzf_siPhTEE%aN5?&X&w;?n5<{H_T;1LCd!d+Yz+`oFe* z;;sKzw$CVd>;I5O6VS4F>;KmEDQlfj8|SV6OG_tf?Re||)omoa_5W&p%v=9=w^}Z( zZoKt>OyJ)7KV~MmYHXFPp|(_NS-+%Si@+e$^49;csOYW#d+Yx$>}S07e}4aN{?-@X z`oFjS&o5`rcm4nSFd$lwx6e_sy<3C$JrLA`pGV7|e0J*O&GB4jh94i^ell*f-GEg^ zFx=A>?dfXwM{&0U^zrQ;Y>+?t2+uOt8a8E~1NBGpqAGGNB`eVUxI2h^ixA(-_ z{NeUk)ZZ0u3;Ls>V1IW{v>z|TPMMJ;OekwH7fI)Q?ZLK4g7zi&cyb{DOB0x(;H${O zK*W4iZZ6Up4oAEE!M<=51&ej~ySh4}{$NMAy(<)qggZLJr+(A~<4P|PA9y_VdPN{_g4A;ifnPN>X_7Bc2=Cyw_jM!(c{g=c% ztIbE#$=OUUIaWi*eZ!fwmqO9NXH2WGIaLdZyjsZ3G{t-(CnYNdC1502}1sk1|3VC|O!>zEs} zg=r7|GNW_={rMRC#k?ThRc-}iw}t_@Hhx)hB-kDDMG}pk;PpvlnXIU zJl5YGi)~HNt5qQ}lAgLdm*}0_in32^MTui8iX_@$sap^U4eGiDyQ{_{aWf}Wp@}_W zS0pImqL*&P`Q@aE!hbHVHXUjOHu;Prp|t%!2` zcc)u!j{d)PuJGZO?vVaYguMn`cL@J6(vHgPy2I(&E?C*m z!e<42C>NAJYFXU9_up9{{+Ac{zEAU=VP`B=zZy5ThShgK6x^@%4nW=^6>J) zQoIv7p1=P1r|u|>{_m#mt@z{%cBP<~8}s`M9sjw@g(lU;F_yb_jgG90&qQ9=O#Jwj z&%OB0V{iZd;8Qyv&A(xnSGVK;1ZL8HV5A2qy6X}c;0zy$*6t6cR(_xn?QiB7lJHVw zSK`N>9l0j*)N||ZdF>xRKJZp{*se~?7s39lDdunC+o-4vXkLz3e$mQbd-{qm@BH3h z2Y^qshP@}I~5ElmI5@qcHYe$69>$Nzc!pWOA^uKD+jK>l(o zEmfD+&MyA15%ODYHF{ZS-IL$!{lr^^3x4`;ckp@5hqly0$fLen2YM9ud`AotauS?< zLGueM_Dpd#;|Gf>lf1D&{(YhCx6t?9%zsO}{r}>uZhtrJC&t!k$ikF))4EJt-m3KR zN!d9K`8cb^7FvoQpZ@dDKKPSe|GNJdfo;1_-|#j%U73DSwKbE|SK=HzLI2$%_n-RK zUtX)f6UxCIyHEe=o^88Vf8(z%|MrH--F7u5j1cph*X!yU$VwU{Vb(GKG4QR(f3-jU z2d4*LXnmvOs()Mg+{Ko_oI8aXbLCdXAcbc|7aX46gb9N?^+0N4zR@gnkS|hOYs9Q5sTsLi!iDa|)8e}4VvX8%nRm7yzHs1jCYVM{VYR{c zt)HH0)jqJ`-m3j;SHHMt_@8%dI4An-&xa!SzS4@_^tD*E)2Pt+zP>HrWbR|$?yq0z SNUZoP?{uo7 Date: Sun, 10 Sep 2017 16:56:52 -0500 Subject: [PATCH 02/77] Add things to ignore to git --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac7b446 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +/.vs/SpriteLibrary From 1dc3b5e9f11440abb9a6054ceb16f24488e03801 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 10 Sep 2017 16:57:31 -0500 Subject: [PATCH 03/77] initial sprite sharing functions --- SpriteLibrary/SpriteController.cs | 100 ++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/SpriteLibrary/SpriteController.cs b/SpriteLibrary/SpriteController.cs index 6092469..04fbb24 100644 --- a/SpriteLibrary/SpriteController.cs +++ b/SpriteLibrary/SpriteController.cs @@ -116,6 +116,7 @@ namespace SpriteLibrary Image MyOriginalImage; //The untainted background PictureBox DrawingArea; //The PictureBox we draw ourselves on List Sprites = new List(); + List LinkedControllers = new List(); //Other sprite controllers that we share sprites with /// /// Since everything needs a random number generator, we make one that should be accessible throughout your program. @@ -638,6 +639,21 @@ namespace SpriteLibrary return newList; } + /// + /// Get a list of all your named sprites. These should just be your template sprites. + /// + /// A list containing all the named sprites + public List AllNamedSprites() + { + List tList = new List(); + foreach(Sprite one in Sprites) + { + if (one.SpriteName != "") + tList.Add(one); + } + return tList; + } + /// /// Return an adjustment ratio. This is the image-size to picture-box ratio. /// It is used for calculating precise pixels or picture-box locations. @@ -959,9 +975,35 @@ namespace SpriteLibrary public void AddSprite(Sprite SpriteToAdd) { Sprites.Add(SpriteToAdd); + AddSpriteToLinkedControllers(SpriteToAdd); SortSprites(); } + /// + /// This internal function is for adding named sprites from other controllers to keep them in sync + /// + /// The sprite to add if it does not exist yet on this controller + internal void AddSpriteIfNotExists(Sprite SpriteToAdd) + { + if (SpriteToAdd.SpriteName == "") return; //We only add named sprites + Sprite found = SpriteFromName(SpriteToAdd.SpriteName); + if(found == null) + Sprites.Add(SpriteToAdd); + } + + /// + /// If we are linked to other controllers, add this sprite template to the other controllers also + /// + /// The sprite we are trying to add + internal void AddSpriteToLinkedControllers(Sprite SpriteToAdd) + { + if (SpriteToAdd.SpriteName == "") return; //We only add named sprites + foreach (SpriteController one in LinkedControllers) + { + one.AddSpriteIfNotExists(SpriteToAdd); + } + } + /// /// Tell a sprite to destroy itself. The sprite will have Destroying property set to true from /// the time you destroy it until it vanishes. Whe you destroy a sprite, it will erase itself @@ -1000,6 +1042,64 @@ namespace SpriteLibrary What.SetName(Name); } + + /// + /// Link up a sprite controller so that it shares sprites with this other sprite controller. If one sprite controller + /// does not have the named sprite, it will query any linked controllers for that named sprite and copy it to the + /// controller that did not have it. This means you only need to create a sprite once, and you can use it on multiple + /// sprite controllers. In many games, you will want to have a sprite appear on different PictureBoxes, and this is + /// a way to do that. For example, you may want to have a bad-guy running around on the screen, but also have his sprite + /// appear in a bad-guy summary, along with his stats, on the side. Loading sprites can be slow, so this makes things a bit + /// faster by only needing to load them once. + /// + /// The sprite-controller to link. You only need to link it one direction, + /// the sprite controller will automatically create a bi-directional link + public void LinkControllersForSpriteTemplateSharing(SpriteController ControllerToLinkToThis) + { + if (ControllerToLinkToThis == null) return; + if(!LinkedControllers.Contains(ControllerToLinkToThis)) + { + LinkedControllers.Add(ControllerToLinkToThis); + } + ControllerToLinkToThis.LinkControllersForSpriteTemplateSharing(this); //link the other direction also + } + + /// + /// Unlink a previously linked controller. If you have linked a controller from a different window and are trying to + /// kill off the controller in a window you are closing, you want to unlink them as the window closes. We take a brief + /// moment to copy over any templates that have not yet been copied over. + /// + /// The + public void UnlinkControllersForSpriteTemplateSharing(SpriteController ControllerToUnlink) + { + if (ControllerToUnlink == null) return; //nothing to do. + if (LinkedControllers.Contains(ControllerToUnlink)) + { + LinkedControllers.Remove(ControllerToUnlink); + } + ControllerToUnlink.UnlinkControllersForSpriteTemplateSharingInternal(this); + List MySpriteTemplates = AllNamedSprites(); + List TheirSpriteTemplates = ControllerToUnlink.AllNamedSprites(); + foreach (Sprite one in MySpriteTemplates) + ControllerToUnlink.AddSpriteIfNotExists(one); + foreach (Sprite one in TheirSpriteTemplates) + AddSpriteIfNotExists(one); + } + + /// + /// This unlinks the second half. This is an internal function so people using SpriteController cannot accidentally + /// unlink half a controller. + /// + /// + internal void UnlinkControllersForSpriteTemplateSharingInternal(SpriteController ControllerToUnlink) + { + if (ControllerToUnlink == null) return; //nothing to do. + if (LinkedControllers.Contains(ControllerToUnlink)) + { + LinkedControllers.Remove(ControllerToUnlink); + } + } + /// /// This takes a point, as given by the mouse-click args, and returns the sprites at that point. Different /// functions use different coordinates, whether based off the background image, or based off the picturebox. From ed0529deae2fd20841aa7fdf80b6b6844492a6b3 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 10 Sep 2017 17:00:59 -0500 Subject: [PATCH 04/77] Get Sprites from linked controllers also --- SpriteLibrary/SpriteController.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/SpriteLibrary/SpriteController.cs b/SpriteLibrary/SpriteController.cs index 04fbb24..2e613bc 100644 --- a/SpriteLibrary/SpriteController.cs +++ b/SpriteLibrary/SpriteController.cs @@ -964,9 +964,34 @@ namespace SpriteLibrary if (OneSprite.SpriteName == Name) { return OneSprite; } } + //If we have not found one on this controller, get it from another controller + foreach(SpriteController SC in LinkedControllers) + { + Sprite Found = SC.SpriteFromNameInternal(Name); + if (Found != null) + { + //If we get here, we do not have it in our list. Add it to this controller and then return it + AddSprite(Found); + return Found; + } + } return null; } + /// + /// The internal SpriteFromName does not check the linked controllers. Keeps us from entering into an endless loop + /// + /// + /// + internal Sprite SpriteFromNameInternal(string Name) + { + foreach (Sprite OneSprite in Sprites) + { + if (OneSprite.SpriteName == Name) + { return OneSprite; } + } + return null; + } /// /// Add the specified sprite to the list of sprites we know about. You usually do not need to do this. /// Sprites add themselves to the controller when you create a new sprite. From 527f2b4ffdcd9ba2e8675f7a536fa916b024838b Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 10 Sep 2017 17:06:06 -0500 Subject: [PATCH 05/77] Add some documentation --- SpriteLibrary/SpriteController.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteController.cs b/SpriteLibrary/SpriteController.cs index 2e613bc..4db792e 100644 --- a/SpriteLibrary/SpriteController.cs +++ b/SpriteLibrary/SpriteController.cs @@ -921,7 +921,11 @@ namespace SpriteLibrary } /// - /// Find a sprite that has been named with the specified name. Then duplicate that sprite + /// Find a sprite that has been named with the specified name. Then duplicate that sprite. If you have + /// SpriteControllers which are linked (see + /// + /// SpriteController.LinkControllersForSpriteTemplateSharing for how to do this), if the Sprite template is + /// not contained in this controller, it is looked up in any linked controllers. /// /// /// Below is a function that creates a sprite based off a name, and puts it at the designated coordinates. From ed0a4bcfc64bda95f8399a46e14350627e96f698 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 11 Sep 2017 20:34:14 -0500 Subject: [PATCH 06/77] removing files --- SpriteLibrary/bin/Release/SpriteLibrary.XML | 1766 ----------------- SpriteLibrary/bin/Release/SpriteLibrary.dll | Bin 66048 -> 0 bytes SpriteLibrary/bin/Release/SpriteLibrary.pdb | Bin 138752 -> 0 bytes .../obj/Release/CoreCompileInputs.cache | 1 - .../DesignTimeResolveAssemblyReferences.cache | Bin 713 -> 0 bytes ...gnTimeResolveAssemblyReferencesInput.cache | Bin 7437 -> 0 bytes ...riteLibrary.Properties.Resources.resources | Bin 8537 -> 0 bytes .../SpriteLibrary.csproj.FileListAbsolute.txt | 8 - ...priteLibrary.csproj.GenerateResource.Cache | Bin 997 -> 0 bytes ...brary.csprojResolveAssemblyReference.cache | Bin 2682 -> 0 bytes SpriteLibrary/obj/Release/SpriteLibrary.dll | Bin 66048 -> 0 bytes SpriteLibrary/obj/Release/SpriteLibrary.pdb | Bin 138752 -> 0 bytes .../Properties.Resources.Designer.cs.dll | Bin 3072 -> 0 bytes ...le_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs | 0 ...le_5937a670-0e60-4077-877b-f7221da3dda1.cs | 0 ...le_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs | 0 16 files changed, 1775 deletions(-) delete mode 100644 SpriteLibrary/bin/Release/SpriteLibrary.XML delete mode 100644 SpriteLibrary/bin/Release/SpriteLibrary.dll delete mode 100644 SpriteLibrary/bin/Release/SpriteLibrary.pdb delete mode 100644 SpriteLibrary/obj/Release/CoreCompileInputs.cache delete mode 100644 SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferences.cache delete mode 100644 SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.Properties.Resources.resources delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csproj.FileListAbsolute.txt delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csproj.GenerateResource.Cache delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.dll delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.pdb delete mode 100644 SpriteLibrary/obj/Release/TempPE/Properties.Resources.Designer.cs.dll delete mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs delete mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs delete mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs diff --git a/SpriteLibrary/bin/Release/SpriteLibrary.XML b/SpriteLibrary/bin/Release/SpriteLibrary.XML deleted file mode 100644 index 5c53934..0000000 --- a/SpriteLibrary/bin/Release/SpriteLibrary.XML +++ /dev/null @@ -1,1766 +0,0 @@ - - - - SpriteLibrary - - - - - This is a delegate for a keypress event. - - - - - - - This is a system that can be used to check for any keypress on a form. It is usually used through - - - You want to define a variable on your form, something like: - - private KeyMessageFilter the_filter = new KeyMessageFilter(); - - When the form loads (in the - event of the form), set the filter with: - - Application.AddMessageFilter(the_filter); - - And then, to use it, do something like: - - bool Up = m_filter.IsKeyPressed(Keys.W); - bool Down = m_filter.IsKeyPressed(Keys.S); - - Much of this code was found here: - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} - {\colortbl ;\red0\green0\blue255;} - {\*\generator Riched20 10.0.10586}\viewkind4\uc1 - \pard\sa200\sl276\slmult1\f0\fs22\lang9 This is the Running Demo, which was created to test out the SpriteController: {{\field{\*\fldinst{HYPERLINK http://www.codeproject.com/Articles/1085446/Using-Sprites-Inside-Windows-Forms }}{\fldrslt{http://www.codeproject.com/Articles/1085446/Using-Sprites-Inside-Windows-Forms\ul0\cf0}}}}\f0 [rest of string was truncated]";. - - - - - A single frame of an animation - - - - - One animation. A series of images. - - - - - Create an image from an image that has a bunch of frames in the one image. - Start at the specified position (Start), and grab Count items (if we can find them) - - The number of frames to grab - A point in the image where we start capturing frames - The smart image this is part of - the image we use for the sprite. Should have lots of images as a part of it. - the width of each frame - the height of each frame - The duration in miliseconds for this frame - - - - Create an image from an image that has a bunch of frames in the one image. - Start at (0,0) with the specified height and width. Pull out as many images as we can - - The smart image this is part of - the image we use for the sprite. Should have lots of images as a part of it. - the width of each frame - the height of each frame - The duration in miliseconds for this frame - - - - This is the holder and parser for images within the AnimatedSprite world - It allows you to store and access animations. A smart image might be a "troll" - that has a series of animations for up, down, left, right, and die. - - - - - Make an animated image from an image that contains multiple frames - - The sprite controller this is attached to - The image we use to draw the animation from - The width of the image to cut out of the main image - The height of the image to cut out of the main image - The duration in miliseconds - - - - Return true if the specified animation and frame for that animation needs - to be changed due to the time passing. - - The animation index - the frame index - The time that has passed since the last frame was displayed. - - - - - Check to see if the animation is in the last frame. Only works if animateonce is set to true - - The animateOnce value of the sprite - The animation we think we are on - The frame we think we are on - - - - - Return the number of frames that the specified animation has. - - What animation to check - The number of animation frames found in that animation - - - - An EventArgs that contains information about Sprites. Most of the Sprite events use - this SpriteEventArgs. - - - - - If another Sprite is involved in the event (Collision), than that Sprite is included here. - It will be null if no other Sprite is involved. - - - - - The CollisionMethod used in the event. Currently, only rectangle collisions are used - - - - - For the CheckBeforeMove event, newlocation will be the location the sprite is trying - to move to. You can adjust the point (move it left, right, up, down) and it will affect - the placement of the sprite. - - - - - Used primarily in the CheckBeforeMove event. If you set cancel to true, then the move fails. - You can use this to keep a Sprite from going places where it ought not to go. - - - - - A Sprite is an animated image that has a size, position, rotation, and possible vector - It tracks where in the animation sequence it is, can report colisions, etc. This SpriteController - draws, moves, and deals with most graphical aspects of the sprites for you. - - - - - The Sprite ID as specified by the sprite controller. - - - - - The name of the sprite. Use SetSpriteName(Name) to change this name. Most Named sprites - are used to define what a sprite is. Once you have created a named sprite, you usually use - to clone the sprite for use. The basic rule of thumb is - to load your sprites from images once, and name the initial sprites. Then, when you go to use - those sprites, get duplicates of them. The reason for this is because it takes more processing time to initially - create the sprites than it takes to duplicate them. - - - - - Set the opacity of the sprite. The value should be between 0 and 1. 1 is solid, 0 is transparent. - Sometimes you want to drag a sprite around the map, or show a sprite that "could be there." Setting - the sprite opacity is usually how you do that. One warning, however. The opacity value takes effect the - next time it is drawn. If the sprite is animating rapidly, it will take effect nearly emmediately. If - it is not animating, not moving, or just sitting there, then it may not take effect for quite some time. - - - - - Return the name of the sprite that this was duplicated from. A duplicated sprite will have - no name, but will have a SpriteOriginName. - - - - - This is the frame of the current animation sequence. You can use this if you need to figure out what frame index - to resume something at, or something like that. - - - - - The final frame is the one that gets displayed once the animation has finished. - - - - - Report whether or not the animation has been completed. When you tell a Sprite to AnimateOnce, - this will report "false" until the animation sequence has been finished. At that time, the value - will be "True." The tricky bit is that this is a boolean. If you have not told a sprite to - animate once, it will always return "false." If a sprite is paused, this returns "false." The only - time this returns "true" is when you tell a sprite to animate once, or animate a few times, and those - times have completed. At that time, this will report "True". If you have a sprite with only one frame, - it may not look like it is "animating", but it is. It is simply animating that one frame over and over. - So, AnimationDone reports false, unless you have told it to animate_once. - - - - - The movement speed of the sprite. To make a Sprite move, you need to set the MovementSpeed, - the direction (using - , - , - , - or ), and the - property. - The speed is calculated in pixels per amount of time. A higher number is faster than a lower number. - - - - - Tells us if we are in the process of doing a MoveTo operation. This boolean should be the - opposite of SpriteReachedEndpoint, but that boolean is poorly named. This is usually the easier - one to use. - - - - - If we are trying to collide with a sprite, we store that sprite here. - - - - - Determine if the sprite automatically moves (you need to give it a direction [using one of the - SetSpriteDirection functions] and speed [MovementSpeed = X] also) - - - - - A number from 0 to 100. Default = 50. Higher numbers print on top of lower numbers. If you want a sprite to - always be drawn on top of other sprites, give it a number higher than 50. If you want a sprite to go under - other sprites, make its number lower than 50. - - - - - Determine if the sprite will automatically move outside the box. If not, it will hit the side of the box and stick - - - - - Get or set the animation nimber. It is best to change the animation using ChangeAnimation. - It is safer. - - - - - The number of animations this sprite has - - - - - Report whether or not this Sprite has been drawn. If it has, then it needs to be erased at - some point in time. - - - - - The sprite location as found on the base image. This is usually the easiest location to use. - - - - - The sprite location as found on the picture-box that this sprite is associated with. Used when dealing with mouse-clicks - - - - - Return the size of the sprite in reference to the image on which it is drawn. To get the - size of the Sprite in relation to the PictureBox, use GetVisibleSize - - - - - Return the relative size of the Sprite in relation to the PictureBox. If the box has been - stretched or shrunk, that affects the visible size of the sprite. - - - - - Change the rotation of the sprite, using degrees. 0 degrees is to the right. 90 is up. - 180 left, 270 down. But, if your sprite was drawn facing up, then rotating it 90 degrees - will have it pointing left. The angle goes counter-clockwise. The image will be scaled - such that it continues to fit within the rectangle that it was originally in. This results - in a little bit of shrinking at times, but you should rarely notice that. - - - - - Flip the image when it gets printed. If your sprite is walking left, flipping it will - make it look like it is going right. - This works great for many things. But, if your program is gobbling memory or CPU, you may need to - consider using Sprite.AddAnimation - - - - - Flip the image when it gets printed. If your sprite looks like it is facing up, doing - this will make it look like it faces down. - This works great for many things. But, if your program is gobbling memory or CPU, you may need to - consider using Sprite.AddAnimation - - - - - If the Sprite is in the middle of being Destroyed, this is set to true. When a Sprite is - Destroyed, it needs to erase itself and do some house-cleaning before it actually vanishes. - During this time, you may not want to use it. It is always a good thing to verify a Sprite - is not in the middle of being destroyed before you do something important with it. To Destroy - a Sprite, use the Sprite.Destroy() function. - - - - - This is true unless we are using MoveTo(point) or MoveTo(list of points) to tell the sprite to move - from one place to the next. This boolean tells us if it has finished or not. - - - - - The visible Height as seen in the PictureBox. It may be stretched, or shrunk from the actual - image size. - - - - - The visible width as seen in the PictureBox. The Sprite may be stretched or shrunk from the - actual image size. - - - - - A Sprite can hold a payload. Use this to store extra information about the various Sprites. Health, Armor, - Shoot time, etc. But, to store information in the payload, you need to make a new class of SpritePayload. The syntax - for doing so is: - - public class TankPayload : SpritePayload { public int Armor; public int Speed; } - - You can access the payload and retrieve the various values. - - - - - A delegate that has a SpriteEventArgs instead of EventArgs. Used for most - of the Sprite events. This allows us to pass more information from sprite events than - a basic EventArgs allows for - - The Sprite that triggers the event - A SpriteEventArgs class which contains Sprite Event values - - - - This event happens right after the sprite is created. Use this to immediately set a - sprite to animate once or something like that. - - - - - This happens when the sprite hits the border of the picture-box. - Useful for when you want to have shots explode when they hit the side. - - - - - This happens when the sprite has exited the picture box. Useful when you want to - keep sprites from traveling on forever after exiting. - - - - - Only used when you tell an animation to animate once. At the end of the animation, - this function fires off. - - - - - This happens when two sprites hit each-other. The SpriteEventArgs that is returned - contains the sprite that this sprite hits. - - - - - This event fires off before a sprite is drawn. Use it if you have constraints. You - can change the location or cancel the move entirely. - - - - - This event happens when someone clicks on the sprite (on the rectangle in which the sprite is). - If you want the event to fire off only when someone clicks on the visible part of the sprite, - use ClickTransparent instead. - - - - - This event happens when someone clicks on the sprite (on the sprite image itself). - If the sprite is sometimes hidden, but you want the click to work even if it is not - visible at that instant, use Click instead. - - - - - This event happens when the mouse moves over the sprite, and then pauses. We use the hover timing from the - parent form. - - - - - When the mouse moves over the sprite. Use this for a menu, when you want the menu item to glow when the - mouse is over the menu item sprite. - - - - - When the mouse moves off the sprite. Use this for a menu, when you want the menu item to stop glowing when - the mouse moves away from the menu item sprite. - - - - - This event happens when the mouse moves over a non-transparent portion of the sprite, and then pauses. - We use the hover timing from the parent form. - - - - - When the mouse moves over a non-transparent portoin of the sprite. Use this for a menu, when you want the - menu item to glow when the mouse is over the menu item sprite. - - - - - When the mouse moves off the non-transparent portion of the sprite. Use this for a menu, when you want the - menu item to stop glowing when - the mouse moves away from the menu item sprite. - - - - - When the frame of an animation changes. If you want to have something happen every time - the foot of your monster comes down, when the swing of your sword is at certain points, etc. - Check to see that the Animaton and FrameIndex are what you expect them to be. - - - - - An event for when you tell a Sprite to MoveTo(Point) a specific point, or, when you - tell the Sprite to MoveTo(list of points). When the Sprite has reached the final destination, - the Sprite fires off this event. - - - - - When you tell a sprite to MoveTo(list of points), this fires off every time it gets to - one of the points. When it gets to the final point, only the SpriteAtEndPoint event fires off. - - - - - The Sprite has just been told to be destroyed. You might want to do some cleanup. - If you need to destroy some payload data, or tell something to cleanup after the sprite - this is where to do that. - - - - - Generate a new sprite. It takes the image and the width and height. If there are multiple images of that width - and height in the image, an animation is created. - - The sprite controller that manages this sprite - The image we pull the animation from - The width of one animation frame - The height of one animation frame - - - - Generate a new sprite. It takes the image and the width and height. If there are multiple images of that width - and height in the image, an animation is created. - - The sprite controller that manages this sprite - The image we pull the animation from - The size of the animation frame - - - - Generate a new single-frame sprite from the specified image. - - The sprite controller that manages this sprite - The image we pull the animation from - - - - Generate a new sprite. It takes a width, height, and the duration in Milliseconds for each frame - - The sprite controller - The image we pull the animations from - The width of one animation frame - the height of one animation frame - The number of milliseconds each frame is shown for as it animates. - - - - Create a Sprite from an animation image, specifying the number of consecutive - frames to grab. - - A point on the specified image where we begin grabbing frames - The Sprite controller we are associating the sprite with - An image that we grab the frames from - The width of one frame - The height of one frame - The number of milliseconds each frame is displayed for - The number of frames to grab as a part of this animation - - - - Create a Sprite that is based off of the specified sprite. Clone the Sprite except that - we set SpriteName = "" and OrigSpriteName = the OldSprite.SpriteName. That way we know that - the sprite was duplicated from the original, and we can still distinguish the original from - the duplicate. - - The Sprite to make a copy of - If we want to set this sprite name to be that of the original. This is a terrible idea. Never do it. - - - - Give this sprite a name. This way we can make a duplicate of it by specifying the name - - A string that represents the new name of the sprite - - - - Add another animation to an existing Sprite. After you add animations, you can use - ChangeAnimation to select which animation you want the specified sprite to show. - For example, you may want to have Animation 0 be a guy walking left, and animation 1 is - that same guy walking right. Because we do not specify the number of frames, it starts - at the top-left corner and grabs as many frames as it can from the image. - - The animation image to grab the frames from - The width of each frame - The height of each frame - - - - Add another animation to an existing Sprite. After you add animations, you can use - ChangeAnimation to select which animation you want the specified sprite to show. - For example, you may want to have Animation 0 be a guy walking left, and animation 1 is - that same guy walking right. Because we do not specify the number of frames, it starts - at the top-left corner and grabs as many frames as it can from the image. - - The animation image to grab the frames from - The size of each frame - - - - Add another animation to an existing Sprite. After you add animations, you can use - ChangeAnimation to select which animation you want the specified sprite to show. - For example, you may want to have Animation 0 be a guy walking left, and animation 1 is - that same guy walking right. Because we do not specify the number of frames, it starts - at the top-left corner and grabs as many frames as it can from the image. - - The animation image to grab the frames from - - - - Add another animation to an existing Sprite. After you add animations, you can use - ChangeAnimation to select which animation you want the specified sprite to show. - For example, you may want to have Animation 0 be a guy walking left, and animation 1 is - that same guy walking right. Because we do not specify the number of frames, it starts - at the top-left corner and grabs as many frames as it can from the image. - - The animation image to grab the frames from - The duration the single frame uses before refreshing. 1000 is a good number. - - - - Add another animation to an existing Sprite. After you add animations, you can use - ChangeAnimation to select which animation you want the specified sprite to show. - For example, you may want to have Animation 0 be a guy walking left, and animation 1 is - that same guy walking right. Because we do not specify the number of frames, it starts - at the top-left corner and grabs as many frames as it can from the image. - - The animation image to grab the frames from - The width of each frame - The height of each frame - The time in milliseconds we use for each frame - - - - Add another animation to an existing Sprite. After you add animations, you can use - ChangeAnimation to select which animation you want the specified sprite to show. - For example, you may want to have Animation 0 be a guy walking left, and animation 1 is - that same guy walking right. Because we do not specify the number of frames, it starts - at the top-left corner and grabs as many frames as it can from the image. - - The animation image to grab the frames from - The width of each frame - The height of each frame - The time in milliseconds we use for each frame - The number of frames we grab from the image - The starting position on the Image where we grab the first frame - - - - Duplicate an animation, except rotated by the specified number of degrees. For example, if you have - a single animation (0), and you want to rotate it by 90 degrees, it will create animation 1 with that - rotation to it. In the long haul, generating a few rotated animations is less memory intensive than - rotating it on demand. - - An integer value specifying the animation to duplicate - The amount of counter-clockwise rotation to add - - - - Duplicate an animation, except rotated by the specified number of degrees. For example, if you have - a single animation (0), and you want to rotate it by 90 degrees, it will create animation 1 with that - rotation to it. In the long haul, generating a few rotated animations is less memory intensive than - rotating it on demand using the or booleans. - - An integer value specifying the animation to duplicate - A boolean, stating if we should mirror horizontally - A boolean, stating if we should mirror vertically - - - - Start a new animation, but do it just once. You can use AnimateJustAFewTimes(1) to the same effect. - Or, you can use AnimateJustAFewTimes with a different number. The SpriteAnimationComplete event will - fire off when the animation completes. The variable, Sprite.AnimationDone will be true once the - animation finishes animating. - - Once the animation has finished, display this animation frame. - -1, or any number that is not an actual frame, will show the last frame of the animation. - The animation index you want to use - - - - Start a new animation. It will complete the animation the number of times you specify. - For example, if your sprite is walking, and one animation is one step, specifying 4 here - will result in your sprite taking 4 steps and then the animation stops. You will want - to make sure you are checking for when the animation stops, using the SpriteAnimationComplete event, - checking the Sprite.AnimationDone flag. - - The animation index you want to use - The number of animations to do before it stops - Once the animation has finished, display this animation frame. - -1, or any number that is not an actual frame, will show the last frame of the animation. - - - - Start a new animation index from scratch - - The animation index you want to use - The first frame you want to start the animation at. - - - - Change the animation speed of a particular animation. This looks at the first frame - and compares that frame to the speed specified. It adjusts all the animations by the - same percentage. - - The integer representing the animation to change - The speed in milliseconds for the new animation - - - - Change the animation speed of a specific frame. Beware. This affects every sprite using this frame - - The index of the animation - The index of the frame within the animation - The new frame duration in milliseconds - - - - Get the animation speed of a single frame. - - The animation we are looking at - The index of the frame we wish to get the speed of - -1 if either index is out of range. Otherwise, return the total milliseconds of the specified frame. - - - - Return the animation speed of this particualar animation of the sprite. - - The animation we are looking at - The speed which was set. The speed is calculated in pixels per amount of time. A higher number is faster than a lower number - - - - Actually draw the Sprite. Never use this. It is used by the SpriteController - - - - - Put the Sprite at a specified location, using the dimentions of the BackgroundImage. - Unless you are using coordinates you have gotten from a mouse-click, this is how you want - to place a Sprite somewhere. It is the easiest way to track things. But, if you are - doing something using mouse-click coordinates, you want to use PutPictureBoxLocation - - The new point on the Image - - - - Put the Sprite at a specified location, using the dimentions of the BackgroundImage. - Unless you are using coordinates you have gotten from a mouse-click, this is how you want - to place a Sprite somewhere. It is the easiest way to track things. But, if you are - doing something using mouse-click coordinates, you want to use PutPictureBoxLocation - - The X location on the background image - the Y location on the background image - - - - Put the Sprite at a specified location, using the dimentions of the PictureBox. - You want to use this if you got your X/Y position from a mouse-click. Otherwise, - this is the harder way to track things, particularly if your window can resize. Use - PutBaseImageLocation instead. - - A point on the PictureBox - - - - Done when the box resizes. We need to recompute the picturebox location. The resize function - automatically calls this. You should never need to do so. - - - - - This is run from the sprite controller every 10 miliseconds. You should never - need to call this yourself. - - - - - Return the point that this sprite needs to be shooting for, for the center of this sprite to - hit the center of the destination sprite. - - The sprite we are shooting for trying to hit - A point which allows the moving sprite to collide with the destination sprite. - - - - Resize the sprite using the base image coordinates. The width and height specified - are relative to the size of the background image, not the picturebox. - - The size (width, height) to make the sprite - - - - Tell the sprite to kill itself. It will erase itself and then - be removed from the spritelist. Then it will be gone forever. - - - - - Remove the sprite from the field. This does not destroy the sprite. It simply removes it from action. - Use UnhideSprite to show it again. - - - - - Make the sprite reappear. If you have not positioned it yet, it will show up at the top corner. It is best to only - use this when you have hidden it using HideSprite - - - - - Return true or false, asking if the specifiec sprite is at the point on the picturebox. - You can use this with a mouse-click to see if you are clicking on a sprite. Use the - SpriteCollisionMethod "transparent" to see if you have clicked on an actual pixel of the - sprite instead of just within the sprite rectangle. - - The x and y location in ImageBox coordinates. - The method of determining if the sprite is at that position - True if the sprite is at the specified location, false if it is not - - - - Because sprites are scaled (shrunk or stretched), this function finds the point - within the sprite that is specified by the location. this function is used by - a number of internal processes, but may be useful to you. But probably not. - - A point given in Image coordinates - A point within the pixel that can be used to find a particular pixel in a sprite. - - - - Check to see if the sprite exists at the point specified. The point given is - in coordinates used by the image (not the PictureBox, use SpriteAtPictureBox for that) - - An imagebox location - the method to use to determine if the image is there - true if the sprite is at that position, false if it is not - - - - return the current image frame. Warning: If you write to this image, it will - affect all sprites using this frame. - - An image that is the current sprite frame for the current animation - - - - return the frame for the given index. Warning: If you write to this image, it will - affect all sprites using this frame. - - The Animation index we are trying to find - The Frame index we are trying to find - An image that is the current sprite frame for the current animation - - - - Replace a sprite image. It will replace the current frame unless you specify both an animation - and the frame within the animation you wish to replace. Warning: This replaces the image_frame - for every sprite that uses that is based off the same image. - - The new image to use - The animation you want to change - The frame within the animation you want to change - - - - Taking into consideration how the sprite is stretched or shrunk, it - returns a SpriteAdjustmentRatio that can be used to work with the sprite - itself. - - The current SpriteAdjustmentRatio used to display this sprite - - - - Return true if the sprite can go to this point and still be on the drawing-board. - - The point, given in pixels and corresponding to pixels on the picturebox - true or false - - - - Return true if the sprite can go to this point and still be on the drawing-board. - - The point, given in pixels and corresponding to pixels on the background image - true or false - - - - Move to where the destination sprite currently is at. This is a dumb move. It does not take into - consideration the movement direction of the destination sprite. So the moving sprite does need to be - moving a bit faster than the sprite you are trying to hit for it to do so. - - The sprite we are trying to hit - - - - Tell the Sprite to move towards a destination. You need to give the sprite a MovementSpeed - and tell the sprite that it can automatically move. But the sprite will begin a journey towards - that point at the MovementSpeed you have set. When it gets to the point, the SpriteArrivedAtEndPoint event - will fire off. Also, the SpriteReachedEnd bool will be true. - - An image-point that the sprite will move to. - - - - Tell the sprite to move towards each point in turn. The sprite will move in a straight line until the first point. - From there it moves to the next point, until it has reached the last point. Every time it reaches a point, the - SpriteArrivedAtWaypoint event is triggered. When it reaches the final point in the list, the SpriteArrivedAtEndPoint - event is triggered. While the sprite is moving, the SpriteReachedEndPoint attribute is set to false. When it has - arrived, it is set to true. - - A list of Image-Points that the sprite will follow, one after the other - - - - Sets the Sprite Moving towards a given point. You are responsible to do something with it once it gets there. - If you want it to automatically stop upon reaching it, use MoveTo instead. Actually, the MoveTo function works - a lot better than this one. Because of integer rounding and a few other things, this function is a little - bit imprecise. If you send it towards a point, it will go in that general direction. The MoveTo function - will perpetually recalculate its way to the destination point and actually reach that point. SetSpriteDirectionToPoint - will sort-of head in the direction of the point. But MoveTo will go to that point. - - The destination, based off a point on the background image, that we send the sprite towards. - - - - Cancel a MoveTo command. The sprite will stop moving, and all the waypoints will be removed. - - - - - Given a "degree" (from 0 to 360, set the direction - that the sprite moves automatically. 0 is right, 90 is up, 180 is left - and 270 is down. - - the degrees to use - - - - Set the sprite direction using Radians. Most people do not want to use this. - Use SetSpriteDirectionDegrees instead unless you like math and know what you - are doing with Radians. - - The angle in radians - - - - Set the sprite direction using a vector. The vector may contain - a speed as well as the movement delta (amount of x shift, and amount - of y shift.) If so, this function may also affect the movement speed - Most people prefer to use SetSpriteDirectionDegrees instead of using - vectors. - - A vector - - - - Convert a number from degrees to radians. - - The number from 0 to 360 in degrees - The corresponding number converted to radians - - - - Convert a number from radians to degrees. - - The number of radians - The corresponding number in degrees - - - - Return the current vector that the sprite is moving along - - The current sprite vector - - - - Returns the direction the sprite is currently traveling, using Radians. - - The direction in radians that the sprite is traveling in - - - - Get the direction that the sprite is traveling in in degrees. You may want to - use Math.Round on the results. The value returned is usually just a tiny bit off - from what you set it with. For example, if you set the sprite movement direction - to be 270 degrees (down), this function may return it as 269.999992. Rounding the - number will give it back to you at probably the same direction you set it as. - - A double (it has a decimal place) that represents the direction in degrees - - - - Return the centerpoint of the sprite, as found on the background image - - a point with the x and y based off the background image location - - - - Return the centerpoint of the sprite, as found on the picturebox - - A point with the x and y found on the picturebox - - - - Check to see if the specified rectangle overlaps with the sprite. - - The rectangle we are looking to see if we hit - True if the rectangle overlaps the sprite rectabgle - - - - Check to see if two sprites hit each-other. The sprite collision methods are - not all programmed in. - - The Sprite we are checking to see if we hit - The method we use to determine if they hit - - - - This is used when two sprites hit each-other. - - The sprite it hits - the method for checking - - - - Make the sprite show up in front of all other sprites. - - - - - Make the sprite go behind all other sprites - - - - - Pause the sprite. We can pause just the animation (and still let it move), pause movement (and let it animate), or pause everything. - - Which aspects of the sprite you want to pause. - - - - unpause the sprite. - - Which aspects of the sprite you want to unpause. - - - - Ask if the sprite is paused using the specified sprite type (default is PauseAll) - - The spritePauseType to see if the sprite is paused with - True if the sprite is set to pause the specified item, false if not - - - - SpriteLibrary is a .net graphical library for creating and controlling sprites on a PictureBox. - - A sprite is an animated image that can be moved around on a - picturebox. You can give the sprite an initial location, and either move it around manually or give it - specific movement controls. - - To use this library, you will need to add a reference to it in your project. You will also need a reference to - "Windows Base." - In the solution explorer, if you right-click your project and go to "add", and then "reference" and click - "WindowsBase" towards the bottom. - On that same window, on the left, click "browse." Then, click the "Browse..." button and find the sprite-library dll. - The main places to find the SpriteLibrary and sample programs using this SpriteLibrary are here: - - and - - - - - - The various types of collisions a sprite can have. Currently only rectangle works. The other types were added when I - thought the different types of collision types were needed. Someday we may add these if we find they are useful, or if - someone else decides they want to help program the SpriteLibrary. These values are primarily used in Sprite Events - - - - - Checks if the two rectangles that contain the sprites overlap. Each rectangle is the starting location of the sprite - (top left) with the sprite width, and height marking the other sides of the rectangle. - - - - - Draws a circle (ellipse) inside the sprite rectangles and see if those ellipses overlap - - - - - Check to see if nontransparent portions of a sprite collide. Not working. - - - - - A structure that contains the width and height adjustment ratio. Use this if you need to manually calculate positions - between the PictureBox that the sprite is in, and the Background Image itself. - - - - - Divide a picturebox ratio by this to get the image location. Multiply an image location by this to get the picturebox location. - - - - - Divide a picturebox ratio by this to get the image location. Multiply an image location by this to get the picturebox location. - - - - - The type of pause signals you can give a sprite or the sprite controller - - - - - Pause the animating. Animation resumes from the current frame when we unpause. A paused animation will continue - to display the same image frame until it is unpaused. - - - - - Pause any automatic movement. Movement resumes where it was left off if you unpause. The sprite will - just sit there until unpaused. - - - - - Pause events. Sprite collisions, movement checks, etc are stopped until the unpause. - - - - - All pausable things are paused. PauseAnimation, PauseMovement, and PauseEvents. - - - - - A sprite controller is the main heart of the sprite class. Each SpriteController manages one picturebox. - If at all possible, try to keep each game in one picturebox, and try to avoid making and destroying - new forms with SpriteController/pictureboxes in them. It is hard to destroy them completely. - - - A sprite controller controls animations and - can help you check for key-presses. To make a sprite controller, - you need to have one defined for your main form: - - SpriteController MySpriteController; - - And then, when the form is created, after the InitializeComponents() function, you - need to configure the drawing area and create the sprite controller: - - MainDrawingArea.BackgroundImage = Properties.Resources.Background; - MainDrawingArea.BackgroundImageLayout = ImageLayout.Stretch; - MySpriteController = new SpriteController(MainDrawingArea); - - In this case, MainDrawingArea is the picturebox where all the sprites will be displayed. - - - - - Since everything needs a random number generator, we make one that should be accessible throughout your program. - - - - - This is only used by the SpriteController. It allows us to queue up invalidation requests. - - - - - The count of all the sprites the controller knows about. This includes named - sprites, which may not be visible. - - - - - If your sprite images need substantial growing or shrinking when displayed, you can try setting this to "true" - to see if it makes it run any faster. What it does is to resize the image once, and keep a cached copy of that - image at that size. If you use the same sprite, but with different sizes, setting this to "True" may actually slow - down the game instead of speeding it up. - - - - - Create a sprite controller, specifying the picturebox on which the sprites - will be displayed. You want to have the PictureBox already defined, and a background image - already set for the PictureBox. - - - This is an example of a Form class that defines a SpriteController. The MainDrawingArea is a - PictureBox. - - public partial class ShootingFieldForm : Form - { - public ShootingFieldForm() - { - InitializeComponent(); - MainDrawingArea.BackgroundImage = Properties.Resources.Background; - MainDrawingArea.BackgroundImageLayout = ImageLayout.Stretch; - MySpriteController = new SpriteController(MainDrawingArea); - } - } - - - The PictureBox. - that the sprites will be drawn in - - - - Create a sprite controller, specifying the picturebox on which the sprites - will be displayed. - - - This is an example of a Form class that defines a SpriteController. The MainDrawingArea is a - PictureBox. While defining the SpriteController, we - are also setting a function used for the DoTick. event. - - public partial class ShootingFieldForm : Form - { - public ShootingFieldForm() - { - InitializeComponent(); - MainDrawingArea.BackgroundImage = Properties.Resources.Background; - MainDrawingArea.BackgroundImageLayout = ImageLayout.Stretch; - MySpriteController = new SpriteController(MainDrawingArea, CheckForKeyPress); - } - - private void CheckForKeyPress(object sender, EventArgs e) - { - //Do stuff here - } - } - - - - The picturebox that the sprites will be drawn in - A function on the form that you want to have run every tick - - - - Define some things and set up some things that need defining at instantiation - - - - - Change the Tick Interval. By default, the spritecontroller does a tick every 10ms, which - is very fast. Some people may prefer it to happen less regularly. Must be > 5, and less than 1001 - - The new tick interval - - - - Allow the sprite sort-method to be overridden. - - - The default sprite sort method is: - - SpriteComparisonDelegate = delegate (Sprite first, Sprite second) { return first.Zvalue.CompareTo(second.Zvalue); }; - - Which compares just the Zvalues of the two sprites. Often you will want to have a more refined sort. The sort - order determines which sprites appear on top of other sprites. In the default state, if two sprites have the - same Zvalue, it is very uncleaer which one will draw on top of the other one. By overridding this sort function, - you can specify a very precise order of which sprite is on top and which is behind. - - - - - This is what happens when someone clicks on the PictureBox. We want to pass any Click events to the Sprite - - - - - - - Check to see if we are hovering over anything - - - - - - - Replace the image on which the sprites are drawn. Use this when you move to a new playing field, - or want to have a different background - - Replacing the background image is actually a lot more complex than you might imagine. Once you use the - below code, it can be done without any problem. But you need to do it this way, or it just goofs up in - a number of small ways. - You need to tell the sprite controller that you are replacing the background image, - and you need to change the image to that image as well.Because the Images are actually - pointers to memory where the image sets, changes to one image will affect the other image.This goofs - things up, so what we do is duplicate the image twice, and tell the sprite controller to use one of the - copies and then set the background to be the other one of the two copies.Finally, we tell the picturebox - to invalidate itself.That does everything that is needed. - - void ReplaceBackground(Image NewBackground) - { - if (MyController == null) return; - if (NewBackground == null) return; - - Image OneImage = new Bitmap(NewBackground); - MyController.ReplaceOriginalImage(OneImage); - - Image TwoImage = new Bitmap(NewBackground); - pb_map.BackgroundImage = TwoImage; - pb_map.Invalidate(); - } - - - - The new image that all sprites will be drawn on - - - - Notify the sprite controller that you have changed the background image on the - PictureBox. Whatever background is on the picturebox is now used to draw all the sprites on. - - - - - The function called by the timer every 10 millisecods We also call do_tick, which - is the function defined by the user. This is usually where they will do the majority of the work. - - - - - - - The function called by the timer every 10 millisecods This is usually where you will do the majority of the work. - You can define this manually, or when you instantiate the SpriteController - - - The Sprite controller uses a System.Windows.Forms.Timer. This timer is notoriously un-precise, but it is very - easy to set up initially. It tries to fire off every 10 milliseconds, but it can fire off incredibly - slowly if you have long pieces of code; the DoTick function needs to finish before it can start again. You want all your - functions to run as quickly as possible to avoid things looking jerky. - Most programs you will make using the sprite library will begin by tapping into the DoTick Event. - Every time the sprite controller is ready to pass control back to your program, it will call - the DoTick event. You want to see if you should be doing anything, and then exiting the do-tick function. - - public partial class ShootingFieldForm : Form - { - public ShootingFieldForm() - { - InitializeComponent(); - MainDrawingArea.BackgroundImage = Properties.Resources.Background; - MainDrawingArea.BackgroundImageLayout = ImageLayout.Stretch; - MySpriteController = new SpriteController(MainDrawingArea, CheckForKeyPress); - } - - private void CheckForKeyPress(object sender, EventArgs e) - { - bool left = false; - bool right = false; - bool space = false; - bool didsomething = false; - TimeSpan duration = DateTime.Now - LastMovement; - if (duration.TotalMilliseconds < 100) - return; - LastMovement = DateTime.Now; - if (MySpriteController.IsKeyPressed(Keys.A) || MySpriteController.IsKeyPressed(Keys.Left)) - { - left = true; - } - if (MySpriteController.IsKeyPressed(Keys.D)||MySpriteController.IsKeyPressed(Keys.Right)) - { - right = true; - } - if (left && right) return; //do nothing if we conflict - if (left) - { - if (LastDirection != MyDir.left) - { - Spaceship.SetSpriteDirectionDegrees(180); - //We want to only change animation once. Every time we change - //the animation, it starts at the first frame again. - Spaceship.ChangeAnimation(0); - LastDirection = MyDir.left; - } - didsomething = true; - Spaceship.MovementSpeed = 15; - Spaceship.AutomaticallyMoves = true; - } - if (right) - { - if (LastDirection != MyDir.right) - { - Spaceship.SetSpriteDirectionDegrees(0); - Spaceship.ChangeAnimation(0); - LastDirection = MyDir.right; - } - didsomething = true; - Spaceship.AutomaticallyMoves = true; - Spaceship.MovementSpeed = 15; - } - if(!didsomething) - { - LastDirection = MyDir.stopped; - //No keys pressed. Stop moving - Spaceship.MovementSpeed = 0; - } - } - - - - - - Process a form resize by recalculating all the picturebox locations for all sprites. - - The form - Form event args - - - - Count the number of sprites that were duplicated from the sprite with the specified name. When you use a - SpriteController.DuplicateSprite(string) - command, it creates a new sprite that is based off the named sprite. This function will count those duplicated sprites. - - The name to look for - The count of sprites that are duplicates of the specified name - - - - Return a list of all sprites - - A list of all sprites - - - - Return all sprites that were based off a particular sprite name. - When you use a - SpriteController.DuplicateSprite(string) - command, it creates a new sprite that is based off the named sprite. This function returns a list of those - duplicated sprites. - - The sprite name to find - A list of sprites that were based off the named sprite - - - - Return a list of all sprites which have been drawn on the image - - A list of sprites that have been drawn - - - - Return a list of all sprites which are not master sprites (which are duplicates of something) - - A list of sprites - - - - Return an adjustment ratio. This is the image-size to picture-box ratio. - It is used for calculating precise pixels or picture-box locations. - - A SpriteAdjustmentRatio containing the current ratio of picture-box pixels to image-box pixels - - - - This takes a point, the location on a picturebox, and returns the corresponding point on the BackgroundImage. - Picturebox locations are "sloppy"; the background image locations are very precise. Since this takes a "sloppy" - number and returns a precise number, it does some rounding to figure out where the specified location is. - - A point on the picturebox that you want the corresponding image pixel location for. - A point (x,y) on the background image which corresponds to the picture-box coordinates you sent into the function. - - - - Return the height of an object in picture-box terms. It is basically the virtual height - of the sprite or other item. - - The image-box heigh (or sprite height) - An integer that corresponds to the hight as displayed in the picturebox - - - - Return the width of an object in picture-box terms. It takes the width of a sprite or other - item that is being displayed on the screen, and calculates the width as displayed in the - picture-box (taking into consideration stretching or shrinking) - - An integer width of the drawn item - An integer that contains the number of pixels wide it is on the picturebox - - - - This does the reverse of an adjusted point. It takes a point on the image and - transforms it to one on the PictureBox - - A point on the image, using the x and y pixels on the image - A location that can be used on the picture-box, taking into consideration the image being stretched. - - - - Adjust a rectangle that is based on the image, according to the stretch of the picturebox - - A rectangle using coordinates from the image - a rectangle that is adjusted for the PictureBox - - - - Adjust an image point so that it conforms to the picturebox. - - The image location - the corresponding point on the PictuerBox - - - - Invalidate a rectangle that is specified in image coordinates - - A rectangle based on the image coordinates - Whether to do it now, or to queue it up for another time. - - - - Invalidate the entire image on which the sprites are drawn - - Whether to do it now, or to queue it up for another time. - - - - The Background Image on which the sprites are drawn. This image ends up having - sprite parts on it. The OriginalImage is the version that is clean. Use - ReplaceOriginalImage to replace the background Image. - - - - - The Image from which the background is taken when we erase sprites. The BackgroundImage - is the image that contains images of the sprites as well as the background image. Use - ReplaceOriginalImage to replace this and the BackgroundImage. - - - - - Make a duplicate of the specified sprite. The duplicate does not yet have a location. - - The sprite to duplicate - A new sprite. If What is null, returns null - - - - Find a sprite that has been named with the specified name. Then duplicate that sprite - - - Below is a function that creates a sprite based off a name, and puts it at the designated coordinates. - - public void AddSprite(string name, int startx, int starty) - { - Sprite NewSprite = MySpriteController.DuplicateSprite(What.ToString()); - if(NewSprite != null) - { - NewSprite.AutomaticallyMoves = true; - NewSprite.CannotMoveOutsideBox = true; - NewSprite.SetSpriteDirectionDegrees(180); //left - NewSprite.PutBaseImageLocation(new Point(startx, starty)); - NewSprite.MovementSpeed = 5; - } - } - - - The name of a sprite - A duplicate of the specified sprite. It has no location, and does not retain the sprite name. - - - - Find a sprite that has a specified name. This returns the actual sprite with that name. - You usually want to use DuplicateSprite(Name) to clone the sprite and get one you can - destroy. If you destroy a named sprite without duplicating it, you may end up losing - it for the remainder of the program. - - A string that matches something added to a sprite with Sprite.SetName - A sprite that has the specified name, or null if no such sprite exists. - - - - Add the specified sprite to the list of sprites we know about. You usually do not need to do this. - Sprites add themselves to the controller when you create a new sprite. - - The sprite to add to the sprite-controller - - - - Tell a sprite to destroy itself. The sprite will have Destroying property set to true from - the time you destroy it until it vanishes. Whe you destroy a sprite, it will erase itself - and remove itself from the controller. After it is destroyed, it is completely gone. - - The Sprite to destroy - - - - Remove all sprites (even named sprites that have not yet been displayed) - - - - - Find the specified Sprite in the controller and change its name to the specified string. - You can do the same thing with Sprite.SetName(Name) - - The Sprite to find - The string to change the name to - - - - This takes a point, as given by the mouse-click args, and returns the sprites at that point. Different - functions use different coordinates, whether based off the background image, or based off the picturebox. - This one uses the picturebox coordinates. So you can use this directly from a MouseDown or MouseUp function. - - The picture-box point being clicked on - A list of sprites that are all at the specified point. - - - - This takes a point, as as specified on the image, and returns the sprites at that point. Different - functions use different coordinates, whether based off the background image, or based off the picturebox. - This one uses the background image coordinates. Use SpritesAdPoint() if you are doing something based off - a MouseUp or MouseDown function. This is used for functions based on sprite location or based off the absoloute - location (using the background image location is much more precise than the visible location in the picturebox) - - The point being looked at - A list of sprites that are all at the specified image point - - - - Return a list of all the sprites that intersect with the given background-image-based rectangle - - The rectangle on the image we are trying to find - A list of the sprites that have any portion of it inside the rectangle - - - - Check to see if any keys are pressed. There is a small glitch with the - key-pressed system. If the form loses focus, and someone releases a key, the key-up is never - triggered. It is a good thing to ResetKeypressState() occasionally if you think your form may have - lost focus. - - True if a key is pressed, false if no keys are pressed. - - - - Return a list of all the keys that are currently pressed. There is a small glitch with the - key-pressed system. If the form loses focus, and someone releases a key, the key-up is never - triggered. It is a good thing to ResetKeypressState() occasionally if you think your form may have - lost focus. - - A List of Keys which are currently considered to be pressed. - - - - Check to see if the given key is pressed. There is a small glitch with the - key-pressed system. If the form loses focus, and someone releases a key, the key-up is never - triggered. It is a good thing to ResetKeypressState() occasionally if you think your form may have - lost focus. - - The key to check to see if it is pressed - True if the key is pressed, false if that key is not pressed - - - - If you want to have a KeyDown function that is triggered by a keypress function, add the event here. - The event should have the parameters (object sender, KeyEventArgs e) - - The function to set - - - - If you want to have a KeyUp function that is triggered by a keypress function, add the event here. - The event should have the parameters (object sender, KeyEventArgs e) - - The function to set - - - - Reset the keypress status. Sometimes the sprite controller misses a key being released (usually - because a window has taken priority, or something has changed). Calling this function will reset - the stored memory of whether a key has been pressed. - - - - - Change the display order of the specified sprite so it goes in front of all other sprites. - - The sprite we want to show up in front - - - - Change the display order of the specified sprite so it goes behind all other sprites. - - The sprite to send behind all other sprites - - - - Change the display order of the specified sprite so it is more likely to go behind all other sprites. - - The sprite to send behind all other sprites - - - - Change the display order of the specified sprite so it is more likely to go in front of other sprites - - The sprite to send behind all other sprites - - - - Change the display order of the sprites such that the specified sprite appears behind the other sprite. - - The sprite we are changing the display order of - The sprite we want to go behind - - - - Make the sprite go in front of the specified sprite. - - The sprite to change the display order of - The sprite we want to make sure we display in front of - - - - Play a sound that we can check to see if it has completed. - - The sound to play - The name, which we can use to determine if it has finished. - - - - Play a sound bit in a separate thread. When the thread is done, set a bool saying that - - The sound to play - The string that we can use to track the status of the sound - A function that gets called when the sound is complete - - - - Check to see if the specified sound has finished playing - - The name of the sound - True if the sound is not currently playing. False if it is currently playing. - - - - Pause everything. It loops through all the sprites in the SpriteController and sends the specified - SpritePauseType to each one. Look at the documentation for SpritePauseType to determine which pause - type to use. - - The SpritePauseType to send all sprites - - - - un-Pause everything. This will send the specified SpritePauseType unpause command - to all sprites. - - The SpritePauseType to unpause for all sprites - - - - The SpritePayload is a stub of a class, for storing user-defined data and functions along with a sprite. - - - Basically, you want to "override" this class. You do this by making your - own class that looks something like: - - public class TankPayload : SpritePayload - { - public int Armor = 20; - public int FireTime = 100; - } - - And then you add that to your sprite: - TankSprite.Payload = new TankPayload(); - If there is no payload, then the payload - property is null. If you have multiple types of SpritePayloads, you may need to do something like: - - if(TankSprite.payload != null and TankSprite.payload is TankPayload) - { - TankPayload tPayload = (TankPayload)TankSprite.payload; tPayload.Armor--; - } - - - - - diff --git a/SpriteLibrary/bin/Release/SpriteLibrary.dll b/SpriteLibrary/bin/Release/SpriteLibrary.dll deleted file mode 100644 index eaa3011a0e5fb89f3c1a8c96598374ae658603d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66048 zcmeFad3YSfwLV&4TC5pKBUzSh$(HP~EP2P+U~J2~jl5vXyNNAJV_WuEEzd~U zLdcPV*_VVRgpiP!5JJM5l>iA_NJtpPR znx3w1-qW6`>P*|a(=Gd}T3b3g?5?Vv$*OdBM^$@A)uPqws`lG$$w>tTks4L>n#Dpi zX#p|fYlk*xwH*^mYxke5L=Re8D005%uKy+2L;OwGCzC z4yTbgZbmg>W)KFE+J53BV8_J6=*C`|7|D!c8R8^hQYL(Cg>8ysdtGV_QE+jOxBcA>>+z1C;`)kT_)NvD82(pbk8Al7_N?CTB08LBDgl-nitQX z*cS_!p+ciDn3x1guxkv$xY&pq;izFx2F1pZ95Gzeih~jIe1IA9(7VlE>PS{Eb(Mn5bhx3|2-aIsqr#p6 zq|l&rC8wj_{!tv1bqjN!$nkzac|TOPDKBJlcd<`HY10PC?h)|uaD)T8?#b;gk0{IY z;svvQi<|)?%*NBzu|1z{FE%Xpmc^aa|2V@u_XAyFbo|%hlA5rwo zJW7&eHp2TbL}9E*V01L=zV|Q5qEjOtM^lDhoHT~iKzv#_pwp~k zPSs25q_qKiKADTU(U^oePeiB>1TvVWO-wUnziBr*GUz9ci~$W9WEn~>B+$RPtbk5( zg~38IQ!=!yAuxnX+4y9wPT7dDK@S+g4Cc*23TSLcZ#zMr3?|e;Sx`Sy{0eyxR#789 z@25x_o)(+)5D3Bey!+@P=?448?FMsh0&fs2XfJ>vy>OdBL+3u(B`kX(Q4vr^X!<%I zjiNhZHel%EP)IC-puHGC;(>VF<(jQF&vs>-t2-KtG4my#a3!S$*uk$pqX*O-#fHw>DXO|CHwV71bUkXvJOdV!Z# z$Aga7)~8V_jqAg)Y{1MFjpqg8^9q4@4W9D>MkKV<-{~^QJRZH~{0_W9ENMC0mycoU zHkP623%e#-^DoaObGzuh6q&s#fCenqh6NH!;eSe+_A;c3jhMltlwzeeXA@f!aD7Bh z&*JTQo5xP)-!JFQ)XVZbxmQ4na`TmPbK<1AL$iN}7L5g!s;tJbH+`CZPtM!YzDbpn zEzZkIoDGfA{mKKFpN#s^gGgLMjL=Pxuixxt$AVmGT*z1+%XxtlGvjeTk0)Ml)?QM^ zJ>A6cx^gH}>dZPGa%DCiP3NsR{^5sC-`j!Oqg|rt(}mtHGA)8tU@68#&8$Q39)5yu z;uSklZ=u+uKs}LOuuh=w0@9aQ4K=F6 zVD%4aHS!D!L!M9*Yam_^sd(MB!3I5kBDH0ksi=6}J%ikZJcI1vKvH#WL`;yMgArpz zd~(2uH&cC049V`)HVwG3V(4P#-3~_~R0eU46>^m1TAzbzL=0m^*`{VJX11KDuxay8 z;MTIu&8N_?mNcB$%xP3J+)9x9Ph_gwK&MYRwT#n<^RajGp;@<9FD=ciL-Bo>M=|R+ zBUy)gM9h}*rjZjMV5*V?PJn>rzEQU`fE9QDywir!Rfy9=xVvBm1Tg=~9Gn0F6Rjk0 z0tDod1Wtf3Axq!{2os603WZWaPpl_H#}f@a+zS|WzXFdE5{*v|>2VJ}x^1eZk8V>G zEN%?j!o3pZ#)8JE+Z!mIT8ch{TUU9Xf&76!W?_-!Q0vaud$GKQ60B#&65 z>SwR>72Zf!y3OYV)KPWyUb52uJ#}`6L`v;rMB;fEz7|+LVebPIym#*dcWkuxK~(HT z1c%!D$jyh|66yMv^I(FhdE!F`Mmm0oe!&( zA@mXT_xOb>T_NK1(P}|Ie7;|3q$@<6KAPh7!@Yi? zQLYei`e4!h+7aHRV z5vPyl8vSs;Uudi=M4UdFAoRlnexVvyh&X*Ts_Tb8<`=4Ug^1HfL$QANLch>BSBN-$ zG=A!bkNAbgyF$e2qd`wUe34%W&)u>OOq@O%sr17a`-LXBLd5B#;YB}uiC?JB6(UX_ zjS2eUOZ`F|Wy+n&Ao&N5$^7 zexcJ`A>ydmz0NN*(-k6)irwq|LZ`bz#8I*PNx#r6SBN+&c5mydmz0ogprYl4o6}zAI3(awbh@)cnCcn^Gt`Kol?0&{CG}jd(&c717Y9~`hu-d!) z*TR_N_}l;I;`p zexZe~5OGu--{Kcqv{zU-AnrcZG=!!Q6(Wv`E{X%P8A>#ZiaV(#U%P^J?#Q&uzre|{B_&*oJ_xRm; zj_Xe1s2IN2FSOPbB94mTulj}7xkAKIG5j^ZP_rvU92LV~_Y19eg@~hK_#1wq4XzMz zR1AO9FSOAWB94mTZ~28bxkAKIF?^q2XtOIs92LXg_6u!sg@~hK_lfPY3K2)e@I!u~9j*{@R181t7iw{Z zh@)co5x>w*SBNLZj^=0gbm(lT#dPr$OWgl|E`A^NyRy}FC2>^zKIRu{bA^bb z;`e)gp`?97s9iR?37O&6~9mTh1y*q;;8uj zpzd!N|?Q?~QqvH2Tzfj5*B94mRr~E?uT_NJA`2De8sKXT^j*8!(_=Rj& zh&U>KpY{uNx#qe`}p+l|^aa0Wd$}iO83K2)e@UQ(s=et70Q8D}* zzfi9$L>v{vzx4}U;0h5(#qjU^LVd0faa0WdhhONhD?}U>!_WJLKI#e)N5$|9exZI> zh&U>SU-SzNxI)BHG5mYK(8pXM;;0xt<`=rq6(Wv`;g|eEM_eJ|s2Ki(U+5xNh&U>S zU-k=K>-_u1udz>FqMTmeTuW8fuJ$Ez`}E zJ|NRjX(Tc-y^_+cGTlV!7MWf}=_JxdeSWqIQ;Fr>uET@(1QF}#EKX3AW0WeQXX^39 z<)B97VFH{IH0{wOMKU!*%M8=`1QRZ(Si~bgW@z~UpTP_889XJuSE=)|45@gDV@aW+ zZ17O%@S|Nt240TyG<3qzJp?fo#~c~M!CIJN)?IxvkszIuH|v(@fwI!XMM&bjISQ8V z9q97?71RgkFIIS!OrC@Ne&nR%>2Q<*|6!^?Z%H)LB~Hh)=rw||#Pd9^2&%&AY$&<{ z`yOR)@|C>;XG6H`Aq$mtqqEdz1V^;;3=_vK_&nGU3en8GuhWie6#qk4n@?BPt8sfg z6{ybe&B@0sk>dokn~^@!uLK1%6ji7TK+wvQpoPT*f7@o|UCB@l^5 zz`z6$!MT4W;=BQXYEoh9Re`J^y&<3^-IoQxjGD2Kd|e=%O@y-V3q;VbBC3yt(KF5Z z85SE5HN)|^vOpCYMHjSpv#Y4jNmr|m7w7hW5q;J)W#3d?g8D)u_bt>LEeux+tTtuG zLR!Zk+FyJFv>)Oxf;9awt#IG6^mtj~YE%{l6;Cn5XTU3U;xS;q1eR*`JaiWszk5&) znu^Ysn+>+S*5e=__s(p<%BRUHZ2MrMp<__3N7g>9Cm3lU1YN<%=1IxN%PLcY$PvwY}CbM*oYWaV_U$+8WX-W6W5TS3Nu-7)=T6IdBzVl z_v9UPI#IPt*6u+L<@L&|Xzz09=V@2(twiAo%zyNbA3Sf=&r=Mn@gyS;w|*oQO6;YU zp`@C#Sp;h@WOa*CbL2QV@Q;PX_`N-EQi)Q zb-2LUkHS!?q9GiXiRoi}CCd?trEP?UIUD0UhEJOIyki(I7BJ4?6*N9WO;JH(TSE(6 z$u@76%OZ(PUV#q6>!aQ(loX#c|Z7%}CXeh_XKnZy|)SH3h6-(m8C!tJF+z5z%VhD`9+}8p&R?%j?r4AU^1?+DC zr=<`@t(YEin6)qBRv|YbTQx? zTT>BJbr>;!hI3MVenfRitiiHfvUd{FPG7}{EgAXn6-imLuToO=RThzb)hz~N*J>DT zF8o`7EJBkS^{2@z*SaC0_a;EJQ&cs{NMMjLF|#lOONISlO{`RzOFWq|_LcNek$U0` z@?e!Js{_TfP|gt6pQM~2tXI-eqkWK}Gz?7di3SIADAV-q*$f$AGHp``G{j|Z z(0egW8#D-y@pc<5eyuwFrA+lDNyI@e+)#(D6Np7XcK^Ds@xgfwB zmA&)Hyonf=DUn?z^~ext*Mn# zX73i1zqLIN1a48Y7q>kipDRf2y3RS*ksxtmpSgSn(+ zvs{NIZbiX)YT8JJlqG7~04@!Y(+15MlM(7zRYZN7v#U*7!cmPT;|-&e3P_VE8#U#o zsZyTIaygrTQGrBN1)f;I%|@LdTOiruaL>EGYm z%HCi#xTz$bx@<|&z0{ViKuJVhK*eqPmaUuA82a|SGUF{yyfKaz!0b>|FAU{h!<(zZ4P>s8L#GntYgNZq5{0xBwul69EE!d zq`rJkwmiIrdn)^k(&<<(&WA-sdXUq!bSzRfVDFJWSOLdh1qgF_{91`C7QKkmD+2a;C?_(JZgCDGg*y|P%;nk;v_qgZyevNJLHwrooDKykjMVg$RB zS{**LVQmdrTNCGlrH2!DbIr*&^HDbaU>5t0s~{J?Sx=k+Vd}wg`5eG0H*qI9I?is# zy@Sr5JsLwk3?%LWi(GscDWbWy3ObOJ?$HyyFk)XSkhp-Z$&@t8ltxiG+aOy5*#OlL z4HMyYqSA|d%2F>mPY<=TVIUrcEH1QiPJ9%gp%56Yl^ClJm_-_1v7^;>-L$c@Z(jR_ zCBMIBUSNxiC!N0!K=zM)@3Gd3=WlD8AJ`HJIMtnzuZFn(^XB6#9rPL^mqf9s3;0}c z-R1Jqzd&0sd~f-ms|ozpIDOH#bKnj`qqX2Men)LFaEF!7SW! zeN8pNy}0JN1M&>DJ&js~@R1H#cS9g3udsh%=@TnYLt<1SNAul(M`~ z{cyENMB$4`!rcrAai2VyZl%y;LUugM>h?>J3E9ysM>iZgST}|-{sr{u82tiVU-?9C zldL=qsFIxB@R^Nrc;yk`y31#FkS5hqTKd7`4H{XEvT@^#@^RzJxXx`#F9Kr#y$qKf zxOj9b#vrAje@td*kr}dT6(jq4Ek+AzWm(#l7(J$&N@r@4qL8OSnSKdMo z*cYNe*$)E(bG5)iJ<3_R!7yO=MNz0}^u=(|dzS&$m#VhKO*7%TypO0`peOEwh6Zc_ ze+$=f^tqIU;M+$?2VT6NN5b|$z;m(p34>mWW89VSPi~7f3=h;Bf#K6Jlk$8pg>skm zp~J(DNq`L%fwDJiHNUs}rC<4T@{X}}VxoI$I^?*el9y02$;l#go4#F~yp*WBDM@dd zMEdqHbt5HllZkAc+{*&50rHuVSCKewUPh1aFNb7pKXLjxNGOAD66v!ksXo@#x08{l zsjHHm_x%5E=j%}DvGa1*PU8FvcIv3zm8b{TF7ccUGCGS}s7d4XUaAy5EsHdu-3Y0w z3Sb?!Nf&~@{$XDYo=1!ym(T-%Nahm&@wi8R5(xG+B=5-}9~@!Ps`X*mLI_ZMC9Wl@ zUTUw=5&Jp^(T|(Y!b-N+zTP3*pX4Mrz;W|uByj^M_NTn$XPk^TddWX`q(AMD?VBih z-2AnZM#T-LNYL0}*yyH_#M>yqeE=DmSc_Tu zBVgp=Gj`ttFC^v4?VEwrheG8{h0t~gHT*)ZO!J(TX`NhqmWgT0<=T^Uc0=a`9W=NOQeQd=3JV3;?D{tZ`+$fS=`Ih}SEU`>w5jN|e01hr2^jjFD z`Ja?#*TZLuiMw2za9T;gC0RenX!H0a!r_+3FrQ%oHf|{p?V~UQTcvxmX+@^lK~X7* zr^vEy#X*mQi_MAK@i3WcQXGN^J)=`K$t%NiXY2}J2p&C1z6I9?N_-#n!$V~3hkA%V zl*BL*zW~W`B*_UB&#t%;t}wl>2)X`*8TrZ#`v>Gcm4_ZQ`|?;r=lRje@<@M}>?i4v zFsEP4w{L}|i7x`YNX~C;!#xA~#sU1%TIL1(72=P6M1K!|!|_MYA-#0GdB=3Tl;O}J z#y=d$6!e!5466%`#tJx)e|m2V+N`1KB*8rkLjv}VNluOvi(o8&^2$TR14N0b?QW8m z&xCpWz@#&Hyz!K?lf-GjVh#U#VYeX*#%+_&w@`&teJW2QWyjKp_C=|qMQs9KbV55KOF?r`SO z7Q$#o;h$CbyTJ;jzL=<+eYasH47q7Y}TU*yGPzNtPE=Tn21ROe;K?FV4C`ZyvL%Xd4|K1-t`V#%S*Yr;3h zB?W5y$Mll-n4i6nD|8V;z=r11_Mo?{LpaG8x0`biG)K}!50_I6^ z8uj}?;?JPstDF!q9TD^$T`Y#oOpZlv5IIj)plg!v^Fn;~Iy!#IxcTv5hq}y`+2aS55ro{&4x%Z>&68}x7qV3H3shH1kGbn)y{!hdoGv} zG^b>8KNyO?N%GSH0~>wRn+*J+?J0XU^UzF{^9CH!4x%sCkHDrN?uoVRE<-{f1!jOc z>Z_S6aj6aT{Rx$=4fY|5j9R1bO}g|FExy? zYXbs<9!uyDLvJcALEy(UvkwEi5!1^0{)nsIYXgStZ=wL1e|6R`^#uXBLi!STbO+3$ z_P2mhKunOhY2ODzFO{hx76;X+Ow;~07%E79Da$?!WzQnp29+If_{`cPff#D_+@=hobS<- z=0ookXFy*`!obrN4<1qD)Gr3JEW-{Lg z3$LjB0GAgdCJqzJv&nidg;zaVg06ZmMcLseAjCJ5R91Fwu}b6`c)_|A_@o0SLHsZf ziSuSmnlfqnl<8B^f#_c!NC9@DlaDKVXoFTj=nD(23@?bO{c@Zqo%3nBba(X_eOUoWc-Y>-ob}?mZ*^9$XQCm8v(iGabIh7Id zUo}RpDGnoTidQO#@@y4Ru85P~c<|>15%Jqvqc$SG6(#zufu9%b6ZclL?Lo>Ff=r>f zIht2tiu)?(R2GV}CgfEViton=Myd#=#t|GfhG4^Rl6=30@;+HSrxKlK%oDYRqI%-J z!wbc}8iJp%CYke4nkiBx1TU!~+q8PJVIk-d@l&?*h5)61!?lQxrnFs0GG^tGg19(R z{cXT+#;>n3#gE}bQ!KCg0Pvd8yGF&u>7@^hh>L&59~fbZN$ivF6@Cu>DIPPYvH}l} z>yhhH)OWl1>?o>lWsGX~pS5J+c_mbrJq2XvPWa6fd1F2YdR@_Yc;k}cBy&;8y(le# zToG}6gn>G4te{-m03+h@O7iMv)FL8Qar(AuvivuYH-*7vzFR@|{B;DuPp}_mGIwh| zwfH7u4(=6k(z<{k#RMiaak%PeeIsMkxBmugF)-?VMdDyFVIej5euc3J_r@ae`bgsC z(>pPcJQO9Y5U02`V6W92t^YJ~H86H0PP|fDWr1fD61G7+$=cr-cC`L$z@8Fe1nxbf zkJf)nYyn1=Z7U((Ho}na9=5DSVNoun6S=s|u}_X&jHk5`El^z~o<{u^i!{!MVI~#( zs<0m@4vJC_?;!rAhdk0(FT}URE8-Fl?^VLUI|F$ai$94gwR8G21zqMj{Z|8O;+2o@Y>z$)_-Y+l zXiX&e&IE!#9!apYh)OuKgy1!G1fyL3vFaZ{;}wM@^Uydd;iB570AEXx%$ucm0)DcF z(ifDI%vB>PeRLeb&(#wAMKS9IG)2QiqKt`>TQbPr$XTu&-j4u2o(yMBI4fsUO?*Sj3Nbv6ruPUYV_Bhka z38qF6Trr+tPc^|23~yrYkC=V|!*YfZE;ExLNqYjpiNk(xn&z!&g$?~bjok}4nc;$Z zYN_9iehBbYf=cG@kuO8$-f;x)tR?uH5ig^hV?~z$-dXS(U@Po5#e>yvA|0=L2k^hD z-Us|i6&9G{>xpv=P5ilp>iD~H1aBT42$|xpvE+gL(ohKPIHCyfhB2j~sQ66fNWe!* z#)M{yJ^AB9adERY5%9FYY{2ho=bLfS95~-3?lMrG(|!-i{s6&08U**51iup^m=`9v zHA3*tJc29p3I3JgwSv;u=mgK?yblH`UB-ELTa^Abmk{E-_p290 zf0pHISpEryDb}TNUcq_qU~4CE-iz7VUvUZJIPZCE?NcoOB+K`(t`Av$HA{Y;b-l&% z^H|GE3@>3_qd4zK&ig~wwS@ED%DVo_B`oB;*Rd{xefSE?U(dQKSaL5*KFGQvEV+fX z{FC7qSl5}X>kQ8O3hQcRU5|1JMVxmB>-s8}Fq(CJ$ny8HuG3iZBG&aB%h$4GH)|8653f;1zYtL%dcU{qpa&~mY>g(pI}|nSj%r1 zcC)T7)-{Ur-psn*=Mq+M-kVt0pHPA+j>WzK_yNXJ>X}XGnQOEnz#|O*C_?D-XV$L) z99dEX*i`%tTKr&jbaDAJ)z@N1kk}L2AEWC-v}PjS6WX!pwh+x-68lwjcPK2@R1to$ zwSDydP()m+uzkSt#G?xPE3ka=p29u=Rv;Rxkq!CYjAlZG;xxtvtbauNfX$UW@w>u> z+Ay)q!7dFA6Dh`C)$WR39V!y}W4ILY)51?8Qd0`sUW$=kJR>pGh_G2$uR$NM&p~p% zgWVP?7AXh2D^x0;VeCRkelt`iZmgkvggqV_B^K3Yv7h2x)ju8V*P-!Z#(3ggY~49w zFCLRMD(pqZR!Iz{{617C&UdiaLiOTK2YWX(RUDI;_~S^;!h$)$Ws3fhcWARkje~`( zGenbv68LoUSN9}8?crZXuvXx_ovv)#!f-!ON2lVi4}>R z;)vq?pnjj#Dy~%6&+A{(TE%S&8&mwU(I)Oz`A#n`5^dr>#e24HFW!-SSn*!2(}4X@ z@y3-b)OLxVDc-D-Qn5??M)7`;Sg7q5#}x0CM5)*<-cY>WnuXdP@s7f-ttl0IL~sh% z*6JwVi+2tR6xLIYHHBEHuyh*=8zcm-ii3j0cpZFPtv3VQ^Y zExxO;qZ4hbQ~XU~4*)wL>haisqUt$dY0;*zw}55DXBD=$)V8|BvkJQyShvWhtsmt3 zZ(!$%MG7m5+txvGfx>Ppx2;3sn+kgXSdVy9VND}!>wHmzja@2b1F&APO<|M9+tvl* zdW9_n)+c_Vu-0nZIxGxq`cl3$u#bv43JU`37hMV~0X87+QrHn_|Co41Vb=k>P*l#8 zrQ8k;M?|y29s_ofxKd$Tfn6-Vudr@lmxzBV?7zm@)}>+wHo(Z1D0r8Nl*0Zn*0wGe zUsPBC?Qn&7USVqzwsoZ_!SF-*QoybfO$uw8U|Uy1t;`0D&D_WRJMMHk)l^9cP~=rdx*vMly)=%{$_>@0S< zb-VcF8pgzC#PnChQHAx7tg-G8-*>QUth>eE9PAG5UNPnznXiB3=R#iy95ebGV*_{z0JD)OZzf5?Znu6eX04al z*Kn`Y z*!x9qSZ|0*>^YHNE+752^(WEkU=Le=7S}u2->o;rl-*MD?}>-4zlbXpc4V|E{-5}b z!ps;)gGDej!|a#ZE>l>*47q;-w`(|?E0|<;djMT3VWeC7XGVv zR$;?yZT+ueTe~b}#aP0wSJ=4f`++^9uz8H-?ABd6;seLon z49CTIg;g48_C$kjM2D6l2=R2`YGnyu~VpNvltr?`SokVx^|bsdaBPg3~hc|=6kk$ zZP?W6yJWr}7u}&*+CLr4#GXsCTS_h%ajp^8E@13pYr=^0jXdp}3Y!5eUwf0W3&ot_ z=NbjtobzOv>ET<#!?e#TY+=pzaFO;!g&iEe2Uz|=DOodmdpN3fD(s2jguS9Lij}DL z%pobcD0;UM)$)5JmKZkz&rs?WcA#Q}S*$fF>^LH|M7vaB_r%iSQtds3jh=9~5!Ytn z`6#utR@xgb)9!JwQtTUjPh!@xqNGuw{Y+sGF!me926*hL(2iXoOL@NZ!f=K5wu4Mj`)L;ihdsSgSFa1P#wDz{biY9z2 zT&-=x4mMf+xx}Z!W3(SBY)kCc@K|leMTOEJk-(#CwV*ud^0c{VY63`@6z!FL@5w2MYT}$$tO~UP$_`vl=V@5I##A!PqtB zzp8!}m{-GD+IZ$&C~nvO1l|;d%?tczc&;{EVNYo5L-QQ$BZ2jyMvcnP-WM-a7~L0Z z5jw}1y)U*ROC5~vi_g~1^w`qmv!%(=a7@!8E_NuOMOHbyw+$__#=*`rwa8irdm^Mo znjI`2)*>4mY*$2!Y;v&s^0den2iugdMYcKEabO>Du+QP~=ne+hA zf?8ykgN=nPdmJodX_37S_Bbp{Iao1l>2R* zU>}FR^BwH>(074@O@_Y14)$|k{SI~zb^n-y6~LAw4wesFE_Sf{&?=WY*lDokatFH> zt#YM<{Q;I;?O@Yj%O@P{V`!CY9qc*iyWYW`g}xgc>Z`Z2KJPLEk)gb;$TZ)%TFEbZPfi42eVQ4UpUxLVA-<{ zRtZ~v@3u_$iZF)7IUxx)V;*P`ce0|gVn*7atHeg>R#bsCTyv6unn+fl!JW2IozKPhz~39D4!)YaRuZxak%_suyX`)dnyUizbmeb^;~|kfYP&3nkMEj zow#^PhkZkxDR`e66hj<^Oi*lwE>ld!6WfrWcL%(=0xV;&Ops-=+)vcgyxI+D;CYps zOVXQBnkF9Ono8|%dZ;p`Z6tFl+sY?W$+Ap>I$IcE3k_wVERDE>b(yM;WT!3$;KP7O zvnM5G?^r7T)+lk`9ZB5Bi-|&M{iJDp>5SXdE7?%!&l^w{x-tP#!L9Q;%J*s^$)X}d zaZlb8{>_yh7`l&n`(Z%jaT~dkelA5swzqeWp%(eqd*;2RMMb(Ob|ol0u~&;gQ6p2NY!(B1;pW;W6qKKuv7ph>o!b>bP}UximRiwsKr} zDfja@b{Cg_Ym{`o3;ArEF2s`)O-N{RnG()o`G0b0TRFxj;K>kn1h|#I$dsK-iDNv} z#g|#0(s)XpLm@8J^fma2GN9sh3x-g zw$PjY-_6C|68@bY?A3q!dc2MIOf}Bi0h)NX_?hYm zPLw}`Q;Jg=&Su!ia5=+s7;a|R0$7UY@FahLVGqNv0h;15?V0Kd@g$%r-T`jq(KFS5hvaj$`C3?CR#&doh`XvMY4zg8@pA!t>lSL&`hS$*TpA=z zaT&uI4F4h8#;n(7h{=UpHBI{z&Q56B&46Lpc|dzdyi?nwMYRnjA4PgMY$$a@Q(bP(lfty+7#=$C-&D*pp;SLI8PxpK^_NM9IzTbsj@ixebF=CBQm zM0sU_zKCs@!Ra{+H)~Ig8?9Gsv#M$VFO1gf6EtbVTR3UZs8@_x3kumYfwfQ2-mTxr zk}diiF6|#;)fijCNohZS31^?AtI~6=qA8bD7JvUk6{(&f)Yq+NgKVw64b<&H?fzR*bj|p7h7*cy8!Ax7`7JHzF3RC zs{L%lvw_W8b;0wtMbXuU^&rkYwX9ouVMroUX(Wn89Ri>F+dX%?P6U8b3M+IJ0Pt`!IL))529 z+gg1-;4|fvUQu}|;1>$dH$KhnqG_+fd$;KSHR^WIuN`-{(JUT{{#`VSy|phO{d)Ne z#%1EY;V&Cs(f?8W8e}v)1^Jr(YJD{LHT_+{1A0r{e88J<1}4QdC7JeMGkZJ5p1goP zc>#Me#eVpjW{kcy_yF7am|j=;T>d&dE_3e&t^Y$}ffuCAY}y`-N%dW87^xZ?odDZsu5yxm}0xa(U9 zXo_0pc!a zxRT*H3^y}87tj)YkhH{Q3_s0zZ)W&LU>E3rVfYT9E?SHelxD)hsOxen?RXh&LKJgd8jCemXAaIVxJj(DE zhL18l#!zU)4d@q&WqASp3QiMctWL0%;jIiGXZRAs>Hu-S61WZ)KFLs+M5$uf&+sV2 z0XoHF-oo%PhA%PH!bGoT*vPPj;Q+&17(T}EC5Bpr%V${4a6ZFEhC3LxFzjbI!0;%; zTNpmd@EAjp$E7ix&u|CBeuhUGKFaVILy^z&4Cgc4!LXm zXLyw1qYNKoc#NSa>+!5>yUK6|_cyI7q!3TrC2v(T^+>M2?dr-)4^rS~y z0{bgf1fQr`2KeYif`4atRVk&n$C+MEFg1eUitz+{stJx@coTDf#PkaomNSfSnVAGh z+7k#)97gcW5f8uy>{8%9G>k|u#Mc6f=-Zs)gJ@Mmh{q??0setuvVhVb#3lhgS3eE# z%wkHvR!8(XB{KnEPY}GJhG1Vg(Zdtn622EZ1C+I+iTj_G^8we4Bv>(g3E)4=37$KO zME=mxob0AeD*0Sty@GZo?1xhoZj)R|J#Lk;i9m4V)h zn$bzoa?s~uO{s}_fR;#dyY2#{FK3Pby%EsD`Oiwo?*Y`s0<^n@73C;U_5#v3OGbmT zPgH@D0@TGKQH{Kd0WF-E90Pg>pe~kRWVM8ibzu>XnACu>RMdiUK#T(=4XBG{_&%P6 zQ8WQc7a)DRZ2~CIVQale{0fl%g`tTke+3|Y$)o{rC0YP)b^y}5ol^nVz{fh?^*Igj zRrpUAufbco$kWaQ%-7C>d;y@2_u}WFbuSX%!5j0ZYpb*mHB-M)KdK+sO=G#S!MH5= ztSQ9KTNFJvh8|dqzY-oR3eo0;@Y{0qgs-7>Uq)+8&?boM^u^*I`ULTw zu~lXHMBZb&8lXskO^a&)w+~By(ymQxYU|S}s!(By)N$QxYU|MlMql zn0eal9Ht`3oKv>v8Vg*qrsl91C)O-Zt+Ufz>pIizUC9j9Qxav)X*oF=m#pbIEXL=y zZr{GBJ=2+L=~Q!7v|-amP*{3ub0>!6+Y#ahZ!agWDyWbCy3N zqfXttMN-wo^2Ht9`;+OGovGxGsbZnMzq2LXp0PWCG__~CaB%~5nm0E!9SG7Q)Yi|G z1j$5w{Y*)aOw`!Vlmy8{o&8KnU?y4bV@ksEj;`q-%luQe`y^np!A5#%z&MDh{Jopp1WKGRsF)mrta#)N@*7O_} z2r}oC?LHp-30$(K=CBx-tZ6wc#wBZd z4vTTgnvug|oLMl*XNJUOF8K5GTz`TfnQ)(K2 zYo(tx-DSlzlMw5#Bj4Xj}|7|w+p4bF`aD5W?7kRYi|+zGp%+y)xHz{Xw7mK+Nl&& zLV0G=(qu<6-QFr_ts`jtzYfcPPBhYufLH}{Go3B1$wm10Oy$kdnwFlF-O?sH)m2iP z?Z&n?v2YJ6l5{G!t}~g;61nC%oTbUG6OeNRSK8+#_a{4WdqxFzBoE3&OIzFab?xUT zrP?;J&hGALTb^0c-qD`f13|1blj)S*x({j3Y8<`=rf!+U{_Xo*WO-&yOE+$$#Ilym zf@HFTTmp<0@vY&4B-(LNGSii|iIGn3hiTiT4{~^th=P`Pw0E_)q+n>9Xm1m9B!gT# zci;By3tC$Dq0A-i$&|xeoo?UV-Z7-a#yu@v&Gx!vM;kR$Yci{PPdg~h_ELL6l9QQa zs}0IpatXTFZrmv()9fJ8+>YCc=JwWoE0bM&Y`BeUM%|)4gI=Mi`z3R6x+RlbndB~p z%eo}A%hpM*?r2TQ?oEE~v{T%p5gicQ-;zeR-`}!3$z7EyxjW6x!!!ztT-w@XCsjyh zk~Yco!ad2>eM{{0vi7bncxrLm?&RuSe%9hcaB;_OSE2M^OG;8y(SG8}9zVV$ZSR-j z${{Ts)bCbzNaCvG!6v(vtC%GnT4QIR*Y3y?dU6SClU?2Ejx~0BM^|Ip-fpx(8!93T zMDLf0rj|_C+9X_}w3F{-lHyvXR-xl(V1mR}_Q)$Dp`HDS&b*{Og;rRJeE@PgqH!(7 zqPky9EujZc44F(9}!>0TEnnUy^*p3aW4@JL6-hFu&C6l2^&r8Y*Xb9zvjB=ebzCT)?i>B;8? zEPGF8@es2C$R!|#_=+~-;Sb@Np}|2S?$C!0t!51Jp=SaS8~3!g?vdi)I5{L`T^IU~ zOzxuTMl5RSN>a=VIkq|C9$I#QWzt6418ZvU;Lfv?u37WhWs7W3HttDwaDx2ol*klv zpP!<}W#%qSQFiGdwukzL;5%$it+l&g?vhk{C!-jZ?6hoK#-TTj>~hXsXd_JqEbLAp z&ScNcrm-Vtcc)vES$rb~Nc&)B0fsZdB0iuE0Af-)zwzM~BhWMcvl>-M#GA~rB; zx4|4|h|KQ2EJ~)5yNR(9n%i3uzz$_`TRV127o?$!!UL@VF%ECUR41&;ct|qoPA`t% zXqzXML{8rfGnkD&Bz-AXr?RPK?QLpWKn3@>2z5Foyr{b~1+%-dINBe*4f6_51)lj1 zV{S$feU^CWtL$ts9wLv~G*2a$?~?g*nS-d!Eoro+Ql_R@g^@SfQ^_7_DbWU?FB9S7=dkXZP;i$@D6_V|^x>9*RkAhw+x4zZfQ$mOyB30BCE?VWz6^dRS0n@qJF;#6jE*=y2R+_rWNW-PQjd$20mGb9UP(b41PQF8$4gr1%4 zsrD`pmjagKT{NeAmL|Jony6b4Z{0GARgxlu1F|XEa-I_m9tsI?Ut5seh0%b7%=juhy`R^40&Z+Yq^tQY zLuGhYYs)(@n{;%o-o*=w)HgA3YsXNSP% zJy`R%A$GHb?0pESX0m*uku9#Vqo)h&Lq}XS)g;x~h=Zu*4^;A`BUAo+99jf+cVZo* zbg{=&z)}IQu*t@iTqT$0O}4~VW}w){n7Sa{o!KK$t352WvAqo`wOGOiE5`B#_Mz;G zNph())h3c~kTVgvDcP}`^S5EWv=a9pZH=kaa$eB3B{#N%MeF5en^v5vEfvCdISX4- zshz~y*wWtRAgx&{^&46(3toe%IyZJrJ(@9{F%}F&zDvV}RUTE`xiWLhAQ4$hy zx}-!`wx`o}8cjh{N=is{nVoJwAH4+xnpydt263Y9wMeT=YQc&;mF)=>ewb@Jx@bk7 zqSjo~eh3Mk^57uliKh0QY3ycCY6C^~rZqPH6+{d&xW|D|7dqH}*-C3#u%6)La@_Jt zb0~36cd|Q41M5Z%X3UZuMqmlrX79(ku7j4n`w{Rh9U0svBsqbA-H#g-njl@A7MX(G zf$rbo-YD~6*=&>7JK#h)x36sJ5O(MGr7#hz#Ad8;1^Ij(h9kP+7LA>9n!`BBW@i`h zj8I5$fI8GQ-Ccu;T@KrG2fziaaeAsFg7s!gs&xnkiXMWRQa2RJgYJrh3~p>|bLRWp zrCaWuwrbSuu7X@3y1BQb1zJ+W*xJZkWpZ&tOEfm+tOtXn-^Q6(87Ivr8 z=w6G|OeET}35rQ>SIR`4)ALQnUFjCyrpR{a zwaHy-?`ZCgF+VNi8GyS zw#7n@Xqu)7k*nP09lLA+d+BzPHbvHw&y*#(R5_&PQhDUu&g%!UCrOjKLX=JGJ3STw zS^rYB+d{Z$IDp_ywxr=XT1>MyvH0bcIHI)$i!i~{ z_u}(ly1XAuE8~YC!6SZZcH!TK9jX13?2#QnjapbLg5*PZEEdbv{jt1RrV#TJ zpwCYrk4SszJ~ZnV4+U``RXZccLR1W*4nxKLPWzDJEJJgqSL2VT1ulz8zS1Ry@0@rO zO1g4Ua#ss_0ZnAQEt>73PL^2Tb<#AQ%uLGm?#!g@tdtS*egkVEntI`@Y#&j> zA7(Y&*)Q+NqS?VPiw_>pvK(}2^c#dcHg`KR&32Z)8pF|ktTIvkCc2H1&frn}#HM?0 z^W-uu<4grSRb;XqQkHfC8JQ=!0;5sm5^DJUsIgiNVwEBDW@s5Jw->Vn&v6^UhC25T zva>XHciFT@PV2B98UZsr8V^CH7*!Q^c3N|6ceh~CgXjjIN0r7jzQQhZx_EZTkxbc( z)ZW1)TEuvo6U~5D$hM|xlp$uLEJwATYP4qCL#I8Z46U3oNcK3*K*q|QZ_hMLzRaiv z0h_H5mCo*#Dpbv{ssZ%H2MUhhuE!-9#qV-vOmou8IM*|Al%oWQU=>Y_S3&S1y zAzyew(rjaOh#^*aAnPEBIvDM#ItZD-D@>f6p`5A;dj4lmIui@9Eo*WN))@`+l&DSu>dx7f=kY*opn+|r9{ zlP#@y)`E4pUur@*+}Y`fO_DTBw}tgNF^W|i)e>8yS35?|6W5q8qvzh|U%>b|k1NAiZQyTg{Z zuDoHO8mifr7&jqp8E`c6kj*;?IX6v`=C+uNJL61FHo0<;MBYutO?w()a{$2I6s5yw za=eA(5WhCDyGldfZ{a~=XUwe;BCT|DZoN*?MGjo1sI@t@Yv0>e^k za&5AW(o~)GU9GF^gJKWD0!%!$4VZm8&9;g z>S6dgR1VM0M5F8pbLBF5JmO(&bqCcfd&BEg3aeZBK!p~o*h1n<7v1jjnA_UJErywg zui2eUwZ)O$@ksRy+VcQOttH%c#SDPWNabC%B9qE7oThu!)F#u^q^t1&8#|D^e8{G^ z+lolD&;j%@52~o-rortAEjQr4rkKSIN9EXbMQ^L?gZ9?zaE_NUxTX+J~ke~ zZ^tzQ>RP_q_*aC}I8#qFQM?f6#B%)D53km4KDqSlqG>O{(jui^TEc!1G|BzGvKji=UMOpx-??>VA{V4n+ zK3dEQgfu-=8ar2yw&)iA4cTH*RIHgHJ+?fy96Cr(xgj*GJcPoFMX^-cl3yA-pqECw zDI4ppEH5w8^wQWsSQ{mr%K;sy{KFAVNfvl=MO%g!=_-Tf%P>mIi)71=wwR@{b}iZx zL9JM-82^qixcfniw&Ycjt^!zHtl_H!kZ5<+qkhpA3lb167N*Q&RN<&QDy35$i((~Q ze5@oWv}j)eIkZ>|3xzDpiuPX=>%WXdLRE$af)%V1(Sg#uD!B79aFH&=KRoIYM8;UT z6)TDM#d;_s6&LH__81sm8VX1IuZoq&daNuz)_)B(nPr89hIFilu>5>#%lvSa79AK_ zge-+nAL{`^|My=d4K9+Ga;U&t97afsm78er9$1Mp{rz{#PH=a)Du}#fyb;nZs|W`6 z;2Q1!B>#UARjL1zXy1Z@u+Vi$M>ima{THFwXdir4fR}glXkWAsFRjoe+Q&+6rY^RO z{-d6>47~^q)juFDt3k)IU=qAq5JWlsQrAFvC=BON>9BRM%yF1IyaM7D z6cog&khg#=8K9a^v8;lSLB&l$fw&H*E;E*u1gfbc3^bBA;Q!cqYMWU91AG}+j=mEcSgC?BRuii!VE4(^ zjMZ=#8L-fe+1_y>i~2{bW-z37aB@{?2xhpUkea*@Edqt|{~(&b{{ai`;QkUuhn6YS zPA@Dh3I$Zr%#PKRh4N$l4^eH&|IfhzaMMN6Dct9uW5_*xiWM>o3aDcQLjg*V-f1*fQjqL6$#6;IXXOMPTI<b=YiwYp)PE&_sb(yMr>u}|JUC6{K#=!cYJm!St~|bhzlVJ z5+2G71I!Y$!~Z7{~~8HIRdmOAhfZ zzQvc^ltYdIl1onU{~-A6OOns`RaMWAU7AV)2tIfu?#y&oy?XWP{i;{*^1%5zO`C=IRF#>I`3bte`0BYhO3otIh; zpQYU|uC1=VA)R#*?o*fR8zM9KL03zWb&|v+>UhPd<4l@T}Yh zQ?5W|a6tu(&4VeMbFfOAb3$^}>vt(U!}+q8v7Z1!THr!W2!l7=e4!!Ia?udD>Sh0?DBWj{;pU9B;*UzZl8T2=3xRTy?>MV ztcR7{xQqq%3WZA`i$*Y*ylE0rcmUnFjK9V7FR%YjY!1qEp93CVhEgjg=A z5#_N4$ADz7@L+B#Aobdy9MW%bqqkk*mrHs5-b!VoObl@U@-yeQ8>F36PFT5|w;Q{= zjlI^^cB|do+TCuaTi17+jjeR2k>6;g`EKi4n;%W2a=6KFCN}DOmC6GiwpIV=!+qP5 zDKVnP&OkX3xA|Sgy*iH**k6CQycr7Yl-2UCdb#qBv(|q~DQ$>;&0@6soNX3$4mCNT zCS!x#qfWf}?P<5ik;NPO2}l0Z{3=hsS*iT{zy9){HQT@8U+)ya*qb;Aoog;;+}2#g zJ;1BEaDH=pkWJYc^=j@BiF4gHo1%U4@dmeB@4c7qwfC+yZ|v-5jq5l5==5Mdxh{^$ z9#jitOTqi2J9qW}8=tqf_*VH3{%xGS% ztJb)C>jjOPN!}+OJ|0*rzRg-$N?uyrdhz1z^UssEQXT;8ZYATa(@1n?IA|m-l0&xl z_D)}H*d=cHmijQ?c6Y~LZ|?f*&G+_h**I5{1D`K69J`OnsLMLr4cFA_H+Oe#?11x? zq)#OD@XcA_*A7^yz^@hi8TDZy3vD|KQn7M4A zbQG5>_0Xj{ZFa|eu%qS7Rgaar818n4x+TIAG;qhH6k1bI?vS{!>AC~w2Pb&a7K~2( zzHr)5PQwOE-FzZ(&2=ZP+wW%_m`t+X2{1{Xu%te)2HnE)V+{5<+fr<)pi8}k*%38K zZQ!WK4RhzC>a{@Ax-HQ|j%4QIu8TL9BfK>m$}frUzPyxm=k^at2X-)I`^b=-1yUxC z5O!*)fR@MIh@ZJ`?g*agKFh8krz7e#7WT@xaq##u7)>ZbVN~L4tfc{hGJxq8-0lr0 zYL_V*VuM3M1-QzdenuLa^&|-9j?)3GFl4x{lJ00YNOp zXtm`Yp4BKPC-0_vjv`a4zH~$0gVl@4^Y1==^x?oB7kU1;b(H6DhW6(gy^`D=~&-5I29wD z7)!R(fjcBU!nINVjzBOChdI0_{sLVN`KF*4`5Crr399R4g|D+H#nF#GA?Xc8qoImh zp1JINBj`pGInR~GcqU-rq?~1&V_zqL5)#RDkP$CRxugUxvS792Of@qF(izfH*Jq3z z;i13;$mXLKUMA1zWmtHuqNW?E)?_9K%Uy%q*wji2cm?m9x)8*a2pInLaKYVn^}Smz zN>EPTR|hqKLdHf?MR#9!gz8XBH}-jmzOVQpHqS{3@EwlfkL=lqQ^%~c zH2*MN#ntzRRsU_18NyHgixbcJvr6zCf>>m)fOAlhe#+1TF&K@>K_ZWr`GOFWZIzld zMXyX;&Y>c3CghnJH;6w&ZdA#;x!qZWen_%_*+??3F@DpLr~jgvVaV^qJb`b=)HI(l zVvAGW43YjapG27Ecpo-!8=1()TXwP}%FkHxObYr;BRx$Z=C9YROX`z$1zG|!mcBPo z_+?lUoH$pFcH6#gYA{dC$Q9(J#I|Xkvx=~t8UH|Ycm$>eT^1jD4o4B+`PC9It9B5} z&@Mxfcu_n=yF!1#AVU({1U#XrHmneaax@|l2}V2vIE^Bj__s=_fq6=Ffn?4Sn6*xB zIyCHdqTx(8?wBK6G;f&WCPz51+-X|QIyD?337qEa(hlm)7ZC`)b5-7U11NvRlu%9G z7O(r1noXBHH;`^@MMiUd>OOng(xY$(kPzP`T;D`9ytw7u43~!26w!pp|M2vPuA(ct z)FYgrz*PYelwlafxjWv^)XiS@%&}71w7I_QA3}5!)EeH+_2WbjdFCH4Qsy*;|No>4 zw%skhz^sYmWVEXqy#tNhH*e$hwJD*CMEk$e`qcxwFmfsN@pP^JbPkO(?!p4X|MdEw z(e^YmoY83W)~~_#s|@q$R~hEhI85Y&SL~D)mJH54&9~yO#qHD;=M81l{c=T6W?T$g zh+w{+;FO@vy||-iXU5Gd5mZ4svv26Ql>G|YOnD@;wkRn%&)Kt75>Q)odSrJk=f1Rc ztrNGqCx`q-10`S?v88tQMi+ZCJ@8h-`))zCdZha45qb_~CtHN0gujGSd*s*dN~w-4 zftyrFrKn{S!VI(Oqw1!kSWnuKbR!rDhn_P~cNE%~l?H3&axp|E(})w^N2IBBDbz0d zXa*BSDgR-NLc?-(%*0BG&W7ldZZtme?oWYT#u&(;%GOh@BC{AMAlH94&IHFrPMCZ_ zb6h+{tp8T&g)rLv31*>Ver$_Sf%c**2Q}2ocFy{lQ&& zTWn*?n96mBeC_eD;0^bow0_biGafDNh4YCB7NzprT6oa%A!e4uU6m7XRui#!X@i!y zJ(A1MM(Z_azrEPnjM_>T(L73;XmwerV3B27gELhxF|;(0&BY<2mqq=!&%ddb5Nn=5 z=8WMROSr&*?K3{Ic&)&n>*n1yoAUG^i(u2RtMG`_r&hKWuqthkS@qHtFC9kaqbaM< zZK+4O%m|gWIiPm4bY5*y1zd_@j!NvWdoE>KKvzBkop66%_VwkiLS27=jrD!(#Ma0_=>*10+7{J!UZVR}N&Fe49 zP4yhUFzhKtAk3mLO2jmBa$NHHxXGyne;HH1B+-73rKK6>TFuh#(FVAL8KM(hI-XU4 zDxzq`B1nFJXYL!+Mdh#o$G45j1(732ZK_ra5Mm8MAKDHpRVTTHXX+>>^i?G)EeSlw zDiZnGvP+QgIpxk;wX)Y#sXHLiO%f0u@vyi+sr%mS*==)U2$E+=S)U$xRwlGzKvTZn zlUA&!?W-_w&cZY!_dxU!&#aPecElpI^B|z6P@7aEDfy&RL(In^ZpT)eLLXluDc8t4bHf*u#r0+;%^1@M1h@AA;5ych3 z=AP2w)|?Tg?%DL%a~|r6g>*1{Q#O%!@!G{Nm`zR7L}gBjmKfUox)ka;ZoUnxO|z?c z+GCq*+eTT>zYNu3X`c-c&Yl-o>L z*ZdakH;L{6OgmFpjcDr+rp#SF1UqC&*j#_xUE5Nq%Ynr%hGCf5o>R)j7Gh@nyl%!( z5-u{*T5i)4WpI`l>O9*E6{3FgepB6?(&)kyebX6-h|PvW-s%sB-H!k2?O|zXv;o2y zN9$T++x3+I6+hq@php>~q?as3*OvkGPL;x?lOe0m z3PHorvlQKzU}i!q1mFufP$(M$FD4{BT;t$yPFr~S_70aOWm?3WAo*txP9!DD-6g2X z*4xjb#g!xO`jruXq#>9$I4WxHNveV`6E6!e_>oaoy^byKA9W%GODmw$eiDt%gp99ZjE=Z@?k zLYbP8(qc=@eP67{(?TZ}P*i;Tk{4pFwc_e{wKep1%?qP8A`y&Q*j>@W5Rx4{5^1C; z%_lakY7Tb@PDx8zOi&!@83liRB%D-2!weKeF+WHQtX764S_x%F$OLT`rWHt7OmX8R z2tIs!nD+85DX`!qYYB1o<)G6Ko1yavob6Zz3G_Q?7o7gNc%PR9&oosf62JdQ8P(s~ z6t`%$^1}O5__&4B&yI-Aq`yV9kx2|4PM-#|;0?HGooAG*mO(#l^Dv3xY1?afR`Jvn z^`W)glePqcfzuu{V`OcJ{A$ld18EXPh$R3AB8f%T%ZZ;D2nLz)(|rYJgU%P@Yvt9) zq&CaNt8$_(m{RRb5e#%L^+zM2%EEMTsIjl;1I{8ih1Rt=m1v8@ZrGgtuuBt5v6a)Q z25jI)*^sTP`Rn#@0XCRZ$SWSuwjgK@;y|+3hMG9lADo1_NVjfB-FgR&DolOHpy1?J zn9p0bGQZ!i?$R}@g=UKWvS2r3iwE5Syz3#eW4Vh(-4}O~4eqwS<;w3qLA<1aUlJh| zo?#^p)RNu|zC-{LkqSEqFADS{GATxN zt+5XG=armS8KHf2BL^IpmJ#?6D78JU1wKuJL%`K`3@WMC`p52Z*dUNZQ@48J9T<)$ zV!*t54iN*SOn)E_i5*PJgC`<3w{sdBjzu=Yh^o-SEL`+T7kbaSm@88XuhxvfXQ;i3 z`4FC7oWCnaL9ajj`Lm~bS1Q9rav2(Al{9`;seJtS?&F{T_-`Nn;@bLm{$YCi-u-|2 ztMf{A_~2&p=N!lu32XjznDAsWI}9ums*DuGcs!YQx?M!JL)9=9$z$`(!ol0p zHwv5*9*UvR#p0d%sM8W=zj?38@5iK%O6AA;?9RsVv$=LW|NjG?+0g4fpw`Sk87|AL z>|cHV`;URauVw!B_4QC-#fZ(1(0;Z!o>H=qfiteFoqloQQ^)Vbp3^t~djH%mA3mu( z=2`!rR6eYH%%}U6hdlBAFL?imC+k17hF`q)%m4DpLMs*0(RlgyKe5j~K~yq0|GLYU z6`-ot;U2XOJt`OOQ^Al^y`b0S%4_`H=dS7+3ht*?12N>AfBoZYe+SSNaH5P42&#TK z4e6P+X)tg9-!2sv%E0;qdam#*0z-Z)pwHL?pioI+uS;|HMmGKlv*nqGw2QC1Jn4R= z9Pci73aT-L$7li1m)Cb_ElANVVSEA%s@s7O=h&p$qY?g*#8$b>^Y&MaN~#tagL4X9 zW|+NvtUABD(BnU?vtWFm{s-1u6c|x$BFqn{BAL+U^fg!c8A9y%9f?MzSs@RPUqlf7 zW^nvUb%5Ik?wDU@h}5jmN@G3@V`!y>cU&ud^OXH6_`h#-_mwdnYGB%6JflDbZg^Qe zO@&{(5WN@sE>nG(=GU#y9cEM5+*)9M0wrG64-$QSFMiMTEk^tM>tElHza8l}hXVft D^PJ%7 diff --git a/SpriteLibrary/bin/Release/SpriteLibrary.pdb b/SpriteLibrary/bin/Release/SpriteLibrary.pdb deleted file mode 100644 index 67db46b73121f4a9963ef5dc49e5edc735203a93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138752 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 diff --git a/SpriteLibrary/obj/Release/CoreCompileInputs.cache b/SpriteLibrary/obj/Release/CoreCompileInputs.cache deleted file mode 100644 index e8c1fbc..0000000 --- a/SpriteLibrary/obj/Release/CoreCompileInputs.cache +++ /dev/null @@ -1 +0,0 @@ -a8cf27034d92fac0fcc617c33163b8923a432866 diff --git a/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferences.cache b/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferences.cache deleted file mode 100644 index cbb9a6fdcc194b91ed2939af6fd8df48884d5226..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713 zcmaKq-*3|}5XZB$>Dnwq70-JJ5)YtNR-#fEld1_Ks!gzI&}vT+k{e&ZsuNGPvr+y# zB>n*Y5dH%m;I8|LsPMzrIs0<=xjTCsp6C6>MLVs?NBMXx3!|+r9edqKCD@GHg=LvG zFo@5B3(J{aKs}x(!*W!2OR8z+tkXNsi3RYHY=jsY6l!C$`f@O!?es+AWfT(*dls3tKT{qDoe5bjX z@WN@cd0kI8)73dQVEPm^(*jP7zK{Y;mky@#E3~m9+d1Q^0qc3KmKOwD-F3N+Zel%N z!+i8l{Gadl4yf2LB=}yNBtYrY7hQBZC_LNG5$TiRRXoA2*!anpz2{H!4^V=Ex`6nV zwNPQ_!REKk%_ry&m)b0HcJgL+XI(sFIKaHJg*HmgnNX@vNmpH`9t9-3w}Jk83HPS7 zODwAi5oDyeb;nxBQi6#170~ho5h4NSPzwY_zQ`8bIWVg_9+;+fvV!YDY?n90^qc4V h{)WFz^Yy+x{Qe7m9EM@o>7p582?-k}!}Mji^#^_p*ZKee diff --git a/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache b/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache deleted file mode 100644 index c8ba4b315d63e27d110283c4dd1360975050ccaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7437 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 E1ufnjXaE2J diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache b/SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache deleted file mode 100644 index 1c0912018623e9fd733dd5e85338ca5397f319f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2682 zcmcJQ?M@Rx6o!|UmUbyv@mozQ+5U|$-^Bc_5LJsxTQ>cq*pGlBq8niBa*p%Xc`ydPSMU#JpL0pl_Z?mui%CfRq zE0-HC^z&Lh8Edl7oLB!D|L42;*B5D4_5;-7AW06TOjo1$&gW5h{Z$L6v?E#MG_Wel znL3((KHYi`0Z52FaNZ~d5mp{l>$JG72J&zyrZ?4*4zegslar2b2pM(PHHMby^nK53k*V(4aS5GLJs3AY zyDM5J$8ec4fZDQnndAz|Rg!BY*GX=W+$6b0GEQ=v9-!6Ig#U)_n-EpQgeFah zs%1iyv*+xnnkMwngs9pk^vHy0H%w^CglM-+XxfBmH%;iV3DItw(2NODH<(bxgs59g U=!pqAeIVC_sN2kuo*K~bAH>ljZ2$lO diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.dll b/SpriteLibrary/obj/Release/SpriteLibrary.dll deleted file mode 100644 index eaa3011a0e5fb89f3c1a8c96598374ae658603d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66048 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 D^PJ%7 diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.pdb b/SpriteLibrary/obj/Release/SpriteLibrary.pdb deleted file mode 100644 index 67db46b73121f4a9963ef5dc49e5edc735203a93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138752 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 diff --git a/SpriteLibrary/obj/Release/TempPE/Properties.Resources.Designer.cs.dll b/SpriteLibrary/obj/Release/TempPE/Properties.Resources.Designer.cs.dll deleted file mode 100644 index b8a9f2840d3f251a0467148d2fdac2dbef36bb5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 zcmeHJUu;uV82`>~*Omf>bwEUoUKkU`Z&xeie?1Gnv=yXN+ua_{Y+ zn2;rCqKSzl_@IdohG2Zq2Q?BGH9i@`3yDw02aLR$kQg6)QRDo5_YWO^Ley71?fL$n z?|k2P&Uf0W=g(7uh?1Dg%S21SJPHB4H&}!^_weUA`gGORElXnZ>XzAg%hOw~YPe=o zubGace7!1lx9#Ybqn8d>^rosyW9{1Pw#fDLIMJlg=+vS2pNn_9PFwZWVwflci55z~ z+YYQ_7BGp{2Q+jXH;)+8aWK)E1QlLkQ~q{w#IgwEW%xZDl6Qv%qBVEd+*_)L;m1Z9 z@CRcC*zo0PANX1tK*wB>E4X0jM8^$R+Nu`CP=J_o%VMq=1){MP>^~xxxULu+n?^l! zLnnGGMI>1GFUBL<4rGD=cM|mtYcvWU@YPFa0h1g46xr0HTge5}`WC5ZJ66G3!9MG) z23Vb5WV_IM%@Aea27UxV$*IE+U@|*IshwL%TV!Tu-*AHNhaUI1mv%sua?9`^SSlP| zHZVt#Do>4xC^J6Og+0cwF)}=|n}bB|HsA&|e#o2zkFn(1pE&8KbRl0RTY>AmW!hsFAAhc^qUx=O<`Tvg*w(_*HFgs@D<=*LHxP9~jxGy5^AXUMA9dSi5ALJxx1hv_&v3K^h88AzOfa_^@AQ=sy3Al+41hhp1 zw2dr!R~w=UNQMDNMFFcGr(ejxJvjr|N9O<^po>(bepIALLv#ah1aKm-d=T01Llm6v zvfz`SqmzJTu>h%t`t$68J_*R3k*4G#3~m|cvHa%C15G(<&0A%c!=e)Hn^N_*EuWyK zS5vNSRcWT}_*PTSc3SeF>C|mWW$82bq^p{dgjs4x|5&kY`)yZ}w}N)1r`m2!#=7yk zOuHS_By7X54D+VbkdvxG zm5%4jron5KBOM>*l{QVgswG|DlAbXWRmU?*(z6=K-l%y--L`rDEyHLJit9XOI`Ot; zbh>FWhdu2=ajE$!68= z1lN4LLM?L9Z9Ykw1g?TJF+1q4X3mR@IV`==W!mB^M^of6A={-v7LSzy;i5?KWy*;`na=C!sl};zL{6KyHuTB23-qEB^ z`TZ%@=l3VmB0rc&iyZh|EV%p?i}%Nb*MR3RBp+(r%cNU k-xDc=Tg}?#0r&|1_1x*@Hi;hoxA=bVZSw!w|3n4;0%>~AYXATM diff --git a/SpriteLibrary/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/SpriteLibrary/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs deleted file mode 100644 index e69de29..0000000 diff --git a/SpriteLibrary/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/SpriteLibrary/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs deleted file mode 100644 index e69de29..0000000 diff --git a/SpriteLibrary/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/SpriteLibrary/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs deleted file mode 100644 index e69de29..0000000 From e0a9fb8c675d33d5cf6ba7b2d0e98db72533de60 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 11 Sep 2017 20:35:19 -0500 Subject: [PATCH 07/77] ignore bin and obj --- .gitignore | 2 ++ SpriteLibrary/SpriteController.cs | 10 +++++++++- .../obj/Release/CoreCompileInputs.cache | 1 + ...ignTimeResolveAssemblyReferencesInput.cache | Bin 0 -> 7437 bytes ...priteLibrary.Properties.Resources.resources | Bin 0 -> 8537 bytes .../SpriteLibrary.csproj.FileListAbsolute.txt | 8 ++++++++ ...SpriteLibrary.csproj.GenerateResource.Cache | Bin 0 -> 997 bytes ...ibrary.csprojResolveAssemblyReference.cache | Bin 0 -> 2682 bytes SpriteLibrary/obj/Release/SpriteLibrary.dll | Bin 0 -> 67072 bytes SpriteLibrary/obj/Release/SpriteLibrary.pdb | Bin 0 -> 142848 bytes ...ile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs | 0 ...ile_5937a670-0e60-4077-877b-f7221da3dda1.cs | 0 ...ile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs | 0 13 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 SpriteLibrary/obj/Release/CoreCompileInputs.cache create mode 100644 SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache create mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.Properties.Resources.resources create mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csproj.FileListAbsolute.txt create mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csproj.GenerateResource.Cache create mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache create mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.dll create mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.pdb create mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs create mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs create mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs diff --git a/.gitignore b/.gitignore index ac7b446..ea3bf65 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ ################################################################################ /.vs/SpriteLibrary +/SpriteLibrary/bin/Release +/SpriteLibrary/obj/Release diff --git a/SpriteLibrary/SpriteController.cs b/SpriteLibrary/SpriteController.cs index 4db792e..4b39f93 100644 --- a/SpriteLibrary/SpriteController.cs +++ b/SpriteLibrary/SpriteController.cs @@ -1090,7 +1090,15 @@ namespace SpriteLibrary { LinkedControllers.Add(ControllerToLinkToThis); } - ControllerToLinkToThis.LinkControllersForSpriteTemplateSharing(this); //link the other direction also + ControllerToLinkToThis.LinkControllersForSpriteTemplateSharingInternal(this); //link the other direction also + } + internal void LinkControllersForSpriteTemplateSharingInternal(SpriteController ControllerToLinkToThis) + { + if (ControllerToLinkToThis == null) return; + if (!LinkedControllers.Contains(ControllerToLinkToThis)) + { + LinkedControllers.Add(ControllerToLinkToThis); + } } /// diff --git a/SpriteLibrary/obj/Release/CoreCompileInputs.cache b/SpriteLibrary/obj/Release/CoreCompileInputs.cache new file mode 100644 index 0000000..e8c1fbc --- /dev/null +++ b/SpriteLibrary/obj/Release/CoreCompileInputs.cache @@ -0,0 +1 @@ +a8cf27034d92fac0fcc617c33163b8923a432866 diff --git a/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache b/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000000000000000000000000000000000000..c8ba4b315d63e27d110283c4dd1360975050ccaa GIT binary patch literal 7437 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 E1ufnjXaE2J literal 0 HcmV?d00001 diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache b/SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..1c0912018623e9fd733dd5e85338ca5397f319f8 GIT binary patch literal 2682 zcmcJQ?M@Rx6o!|UmUbyv@mozQ+5U|$-^Bc_5LJsxTQ>cq*pGlBq8niBa*p%Xc`ydPSMU#JpL0pl_Z?mui%CfRq zE0-HC^z&Lh8Edl7oLB!D|L42;*B5D4_5;-7AW06TOjo1$&gW5h{Z$L6v?E#MG_Wel znL3((KHYi`0Z52FaNZ~d5mp{l>$JG72J&zyrZ?4*4zegslar2b2pM(PHHMby^nK53k*V(4aS5GLJs3AY zyDM5J$8ec4fZDQnndAz|Rg!BY*GX=W+$6b0GEQ=v9-!6Ig#U)_n-EpQgeFah zs%1iyv*+xnnkMwngs9pk^vHy0H%w^CglM-+XxfBmH%;iV3DItw(2NODH<(bxgs59g U=!pqAeIVC_sN2kuo*K~bAH>ljZ2$lO literal 0 HcmV?d00001 diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.dll b/SpriteLibrary/obj/Release/SpriteLibrary.dll new file mode 100644 index 0000000000000000000000000000000000000000..2eb8bb8fba9a237bef50bc176d174da6f63f1bc6 GIT binary patch literal 67072 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 QpVxnSUH*ShKRX!sZ%WPlIRF3v literal 0 HcmV?d00001 diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.pdb b/SpriteLibrary/obj/Release/SpriteLibrary.pdb new file mode 100644 index 0000000000000000000000000000000000000000..966e8ecf8f03855746790877c52e068a7460fb97 GIT binary patch literal 142848 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 Date: Mon, 11 Sep 2017 20:36:39 -0500 Subject: [PATCH 08/77] remove files --- .../obj/Release/CoreCompileInputs.cache | 1 - ...ignTimeResolveAssemblyReferencesInput.cache | Bin 7437 -> 0 bytes ...priteLibrary.Properties.Resources.resources | Bin 8537 -> 0 bytes .../SpriteLibrary.csproj.FileListAbsolute.txt | 8 -------- ...SpriteLibrary.csproj.GenerateResource.Cache | Bin 997 -> 0 bytes ...ibrary.csprojResolveAssemblyReference.cache | Bin 2682 -> 0 bytes SpriteLibrary/obj/Release/SpriteLibrary.dll | Bin 67072 -> 0 bytes SpriteLibrary/obj/Release/SpriteLibrary.pdb | Bin 142848 -> 0 bytes ...ile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs | 0 ...ile_5937a670-0e60-4077-877b-f7221da3dda1.cs | 0 ...ile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs | 0 11 files changed, 9 deletions(-) delete mode 100644 SpriteLibrary/obj/Release/CoreCompileInputs.cache delete mode 100644 SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.Properties.Resources.resources delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csproj.FileListAbsolute.txt delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csproj.GenerateResource.Cache delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.dll delete mode 100644 SpriteLibrary/obj/Release/SpriteLibrary.pdb delete mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs delete mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs delete mode 100644 SpriteLibrary/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs diff --git a/SpriteLibrary/obj/Release/CoreCompileInputs.cache b/SpriteLibrary/obj/Release/CoreCompileInputs.cache deleted file mode 100644 index e8c1fbc..0000000 --- a/SpriteLibrary/obj/Release/CoreCompileInputs.cache +++ /dev/null @@ -1 +0,0 @@ -a8cf27034d92fac0fcc617c33163b8923a432866 diff --git a/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache b/SpriteLibrary/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache deleted file mode 100644 index c8ba4b315d63e27d110283c4dd1360975050ccaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7437 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 E1ufnjXaE2J diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache b/SpriteLibrary/obj/Release/SpriteLibrary.csprojResolveAssemblyReference.cache deleted file mode 100644 index 1c0912018623e9fd733dd5e85338ca5397f319f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2682 zcmcJQ?M@Rx6o!|UmUbyv@mozQ+5U|$-^Bc_5LJsxTQ>cq*pGlBq8niBa*p%Xc`ydPSMU#JpL0pl_Z?mui%CfRq zE0-HC^z&Lh8Edl7oLB!D|L42;*B5D4_5;-7AW06TOjo1$&gW5h{Z$L6v?E#MG_Wel znL3((KHYi`0Z52FaNZ~d5mp{l>$JG72J&zyrZ?4*4zegslar2b2pM(PHHMby^nK53k*V(4aS5GLJs3AY zyDM5J$8ec4fZDQnndAz|Rg!BY*GX=W+$6b0GEQ=v9-!6Ig#U)_n-EpQgeFah zs%1iyv*+xnnkMwngs9pk^vHy0H%w^CglM-+XxfBmH%;iV3DItw(2NODH<(bxgs59g U=!pqAeIVC_sN2kuo*K~bAH>ljZ2$lO diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.dll b/SpriteLibrary/obj/Release/SpriteLibrary.dll deleted file mode 100644 index 2eb8bb8fba9a237bef50bc176d174da6f63f1bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67072 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 QpVxnSUH*ShKRX!sZ%WPlIRF3v diff --git a/SpriteLibrary/obj/Release/SpriteLibrary.pdb b/SpriteLibrary/obj/Release/SpriteLibrary.pdb deleted file mode 100644 index 966e8ecf8f03855746790877c52e068a7460fb97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142848 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 Date: Tue, 12 Sep 2017 07:45:04 -0500 Subject: [PATCH 09/77] Debug sprite sharing --- SpriteLibrary/Sprite.cs | 2 +- SpriteLibrary/SpriteController.cs | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SpriteLibrary/Sprite.cs b/SpriteLibrary/Sprite.cs index a810874..749caba 100644 --- a/SpriteLibrary/Sprite.cs +++ b/SpriteLibrary/Sprite.cs @@ -252,7 +252,7 @@ namespace SpriteLibrary /// public bool MirrorVertically = false; - SpriteController MySpriteController; + internal SpriteController MySpriteController; private bool _Destroying = false; /// /// If the Sprite is in the middle of being Destroyed, this is set to true. When a Sprite is diff --git a/SpriteLibrary/SpriteController.cs b/SpriteLibrary/SpriteController.cs index 4b39f93..de1d7c1 100644 --- a/SpriteLibrary/SpriteController.cs +++ b/SpriteLibrary/SpriteController.cs @@ -976,6 +976,7 @@ namespace SpriteLibrary { //If we get here, we do not have it in our list. Add it to this controller and then return it AddSprite(Found); + //Console.WriteLine("Found A Sprite in another controller:" + Found.SpriteName); return Found; } } @@ -1003,6 +1004,7 @@ namespace SpriteLibrary /// The sprite to add to the sprite-controller public void AddSprite(Sprite SpriteToAdd) { + SpriteToAdd.MySpriteController = this; Sprites.Add(SpriteToAdd); AddSpriteToLinkedControllers(SpriteToAdd); SortSprites(); @@ -1016,8 +1018,12 @@ namespace SpriteLibrary { if (SpriteToAdd.SpriteName == "") return; //We only add named sprites Sprite found = SpriteFromName(SpriteToAdd.SpriteName); - if(found == null) - Sprites.Add(SpriteToAdd); + if (found == null) + { + Sprite Clone = new Sprite(SpriteToAdd,true); + Clone.MySpriteController = this; + Sprites.Add(Clone); + } } /// From 846d4b569f25e700842361b15e8f4d5308bfd94e Mon Sep 17 00:00:00 2001 From: Tim Young Date: Fri, 15 Sep 2017 15:52:59 -0500 Subject: [PATCH 10/77] Adding initial sprite database and sprite entry form --- SpriteLibrary/SpriteDatabase.cs | 224 ++++++++++++++++++ SpriteLibrary/SpriteEntryForm.Designer.cs | 276 ++++++++++++++++++++++ SpriteLibrary/SpriteEntryForm.cs | 83 +++++++ SpriteLibrary/SpriteInfo.cs | 21 ++ SpriteLibrary/SpriteLibrary.csproj | 8 + 5 files changed, 612 insertions(+) create mode 100644 SpriteLibrary/SpriteDatabase.cs create mode 100644 SpriteLibrary/SpriteEntryForm.Designer.cs create mode 100644 SpriteLibrary/SpriteEntryForm.cs create mode 100644 SpriteLibrary/SpriteInfo.cs diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs new file mode 100644 index 0000000..278d5a1 --- /dev/null +++ b/SpriteLibrary/SpriteDatabase.cs @@ -0,0 +1,224 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; +using System.Xml; +using System.Xml.Serialization; +using System.Resources; +using System.IO; + +namespace SpriteLibrary +{ + internal struct ImageStruct + { + internal Image TheImage; + internal string ImageName; + } + + /// + /// Store of all the types of things in the ADVDemo + /// + public class SpriteDatabase + { + List SpriteInfoList = new List(); + List TheImages = new List(); + ResourceManager myResourceManager = null; + string Filename = ""; + + public SpriteDatabase(ResourceManager theResourceManager, string filename) + { + myResourceManager = theResourceManager; + Filename = filename; + Load(); + } + + internal void Load() + { + LoadSpriteInfo(); + } + + + //******************************* + //**** Sprite Info Functions *** + //******************************* + #region SpriteInfo Functions + void LoadSpriteInfo() + { + if (DoesResourceExist(Filename)) + { + //This clears out the old list, as it gets replaced. + SpriteInfoList = LoadObjectFromXmlFile>(Filename, myResourceManager); + } + else + { + //try loading it from an actual filename + if (File.Exists(Filename)) + SpriteInfoList = ReadFromXmlFile>(Filename); + } + //If neither works, we end up with an empty file. + //If it fails, SpriteInfoList is null and things explode. + if (SpriteInfoList == null) + SpriteInfoList = new List(); //make an empty one so things do not explode. + } + + public List SpriteNames() + { + List theNames = new List(); + foreach (SpriteInfo si in SpriteInfoList) + { + theNames.Add(si.SpriteName); + } + return theNames; + } + + internal bool DoesResourceExist(string resourcename) + { + if (myResourceManager == null) return false; + if (myResourceManager.GetObject(resourcename) != null) + return true; + return false; + } + + public Image GetImageFromName(string Name, bool UseSmartImages) + { + Image MyImage = null; + if (UseSmartImages) + { + foreach (ImageStruct IS in TheImages) + { + if (IS.ImageName.Equals(Name, StringComparison.InvariantCultureIgnoreCase)) + { + MyImage = IS.TheImage; + break; + } + } + } + if (MyImage == null) + { + ResourceManager rm = myResourceManager; + MyImage = (Bitmap)rm.GetObject(Name); + if (UseSmartImages) + { + ImageStruct NewIS = new ImageStruct(); + NewIS.ImageName = Name; + NewIS.TheImage = MyImage; + TheImages.Add(NewIS); + } + } + return MyImage; + } + + public Sprite SmartDuplicateSprite(SpriteController theController, string SpriteName, bool UseSmartImages = true) + { + Sprite DestSprite = theController.DuplicateSprite(SpriteName); + if (DestSprite != null) return DestSprite; + + //If it does not exist, make it + foreach (SpriteInfo SI in SpriteInfoList) + { + if (SI.SpriteName == SpriteName) + { + //This is the sprite. Pull out the image resource. then pull out the sprite. + ResourceManager rm = myResourceManager; + Image myImage = (Bitmap)rm.GetObject(SI.ImageName); + if (myImage == null) return null; //break out if we do not have the image defined for this + DestSprite = new Sprite(SI.StartPoint, theController, myImage, SI.Width, SI.Height, SI.AnimSpeed, SI.NumAnimations); + int sizepercent = SI.ViewPercent; + if (sizepercent < 5) sizepercent = 100; + if (sizepercent > 300) sizepercent = 100; + double delta = (double)sizepercent / 100.0; //turn it into a double, and into something we can multiply. + DestSprite.SetSize(new Size((int)(DestSprite.GetSize.Width * delta), (int)(DestSprite.GetSize.Height * delta))); + DestSprite.SetName(SpriteName); + //We have created a new sprite. Now, return a duplicate of that sprite. + return theController.DuplicateSprite(SpriteName); + } + } + return null; + } + #endregion + + #region Generic XML Funcs + + /// + /// Load in an XML serialized item from the specified ResourceManager. You will usually make one of these by + /// creating an object and using SpriteDatabase.WriteToXmlFile to + /// save it to a file on your desktop. Then you can drag and drop that file into your project and then use this + /// LoadObjectFromXmlFile function. + /// + /// The type of object to load. It could be something as simple as an int, a class, or a list of classes. + /// The resource item to load. If you would access it like: properties.resources.myFile, + /// the correct value to put here would be "myFile" + /// The resource manager. Usually Properties.Resources.ResourceManager + /// An object of the value you specified. Or null if it fails. + public static T LoadObjectFromXmlFile(string XMLResourceToLoad, ResourceManager MyManager) where T : new() + { + //Load in the sprite data + XmlSerializer serializer = new XmlSerializer(typeof(T)); + + // Retrieves String and Image resources. + object titem = MyManager.GetObject(XMLResourceToLoad); + byte[] item = (byte[])System.Text.Encoding.UTF8.GetBytes((string)titem); + + try + { + return (T)serializer.Deserialize(new MemoryStream(item)); + } + finally + { + + } + } + + /// + /// Writes the given object instance to an XML file. + /// Only Public properties and variables will be written to the file. These can be any type though, even other classes. + /// If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute. + /// Object type must have a parameterless constructor. + /// + /// The type of object being written to the file. + /// The file path to write the object instance to. + /// The object instance to write to the file. + internal static void WriteToXmlFile(string filePath, T objectToWrite) where T : new() + { + TextWriter writer = null; + try + { + var serializer = new XmlSerializer(typeof(T)); + writer = new StreamWriter(filePath); + serializer.Serialize(writer, objectToWrite); + } + finally + { + if (writer != null) + writer.Close(); + } + } + + /// + /// Reads an object instance from an XML file. + /// Object type must have a parameterless constructor. + /// + /// The type of object to read from the file. + /// The file path to read the object instance from. + /// Returns a new instance of the object read from the XML file. + public static T ReadFromXmlFile(string filePath) where T : new() + { + TextReader reader = null; + try + { + var serializer = new XmlSerializer(typeof(T)); + reader = new StreamReader(filePath); + return (T)serializer.Deserialize(reader); + } + finally + { + if (reader != null) + reader.Close(); + } + } + #endregion + } + +} diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs new file mode 100644 index 0000000..ff299c1 --- /dev/null +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -0,0 +1,276 @@ +namespace SpriteLibrary +{ + partial class SpriteEntryForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pbImageField = new System.Windows.Forms.PictureBox(); + this.cbStartingImage = new System.Windows.Forms.ComboBox(); + this.lblStartingImage = new System.Windows.Forms.Label(); + this.lblChosenArea = new System.Windows.Forms.Label(); + this.tbNumFrames = new System.Windows.Forms.TextBox(); + this.lblFrames = new System.Windows.Forms.Label(); + this.tbSpriteName = new System.Windows.Forms.TextBox(); + this.lblSpriteName = new System.Windows.Forms.Label(); + this.btnDone = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnApply = new System.Windows.Forms.Button(); + this.btnNew = new System.Windows.Forms.Button(); + this.tbAmimationSpeed = new System.Windows.Forms.TextBox(); + this.lblAnimationSpeed = new System.Windows.Forms.Label(); + this.lblDefaultSize = new System.Windows.Forms.Label(); + this.tbDefaultSize = new System.Windows.Forms.TextBox(); + this.btnBack = new System.Windows.Forms.Button(); + this.btnFwd = new System.Windows.Forms.Button(); + this.lblCountSprites = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); + this.SuspendLayout(); + // + // pbImageField + // + this.pbImageField.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.pbImageField.Location = new System.Drawing.Point(5, 10); + this.pbImageField.Name = "pbImageField"; + this.pbImageField.Size = new System.Drawing.Size(213, 253); + this.pbImageField.TabIndex = 0; + this.pbImageField.TabStop = false; + // + // cbStartingImage + // + this.cbStartingImage.FormattingEnabled = true; + this.cbStartingImage.Location = new System.Drawing.Point(349, 40); + this.cbStartingImage.Name = "cbStartingImage"; + this.cbStartingImage.Size = new System.Drawing.Size(131, 24); + this.cbStartingImage.TabIndex = 1; + this.cbStartingImage.SelectedIndexChanged += new System.EventHandler(this.cbStartingImage_SelectedIndexChanged); + // + // lblStartingImage + // + this.lblStartingImage.AutoSize = true; + this.lblStartingImage.Location = new System.Drawing.Point(244, 43); + this.lblStartingImage.Name = "lblStartingImage"; + this.lblStartingImage.Size = new System.Drawing.Size(99, 17); + this.lblStartingImage.TabIndex = 2; + this.lblStartingImage.Text = "Starting Image"; + // + // lblChosenArea + // + this.lblChosenArea.AutoSize = true; + this.lblChosenArea.Location = new System.Drawing.Point(350, 77); + this.lblChosenArea.Name = "lblChosenArea"; + this.lblChosenArea.Size = new System.Drawing.Size(46, 17); + this.lblChosenArea.TabIndex = 3; + this.lblChosenArea.Text = "label2"; + // + // tbNumFrames + // + this.tbNumFrames.Location = new System.Drawing.Point(349, 109); + this.tbNumFrames.Name = "tbNumFrames"; + this.tbNumFrames.Size = new System.Drawing.Size(47, 22); + this.tbNumFrames.TabIndex = 4; + // + // lblFrames + // + this.lblFrames.AutoSize = true; + this.lblFrames.Location = new System.Drawing.Point(288, 109); + this.lblFrames.Name = "lblFrames"; + this.lblFrames.Size = new System.Drawing.Size(55, 17); + this.lblFrames.TabIndex = 5; + this.lblFrames.Text = "Frames"; + // + // tbSpriteName + // + this.tbSpriteName.Location = new System.Drawing.Point(349, 10); + this.tbSpriteName.Name = "tbSpriteName"; + this.tbSpriteName.Size = new System.Drawing.Size(100, 22); + this.tbSpriteName.TabIndex = 6; + // + // lblSpriteName + // + this.lblSpriteName.AutoSize = true; + this.lblSpriteName.Location = new System.Drawing.Point(251, 14); + this.lblSpriteName.Name = "lblSpriteName"; + this.lblSpriteName.Size = new System.Drawing.Size(86, 17); + this.lblSpriteName.TabIndex = 7; + this.lblSpriteName.Text = "Sprite Name"; + // + // btnDone + // + this.btnDone.Location = new System.Drawing.Point(434, 259); + this.btnDone.Name = "btnDone"; + this.btnDone.Size = new System.Drawing.Size(75, 23); + this.btnDone.TabIndex = 8; + this.btnDone.Text = "Done"; + this.btnDone.UseVisualStyleBackColor = true; + // + // btnCancel + // + this.btnCancel.Location = new System.Drawing.Point(353, 259); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 9; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnApply + // + this.btnApply.Location = new System.Drawing.Point(434, 230); + this.btnApply.Name = "btnApply"; + this.btnApply.Size = new System.Drawing.Size(75, 23); + this.btnApply.TabIndex = 10; + this.btnApply.Text = "Apply"; + this.btnApply.UseVisualStyleBackColor = true; + // + // btnNew + // + this.btnNew.Location = new System.Drawing.Point(353, 230); + this.btnNew.Name = "btnNew"; + this.btnNew.Size = new System.Drawing.Size(75, 23); + this.btnNew.TabIndex = 11; + this.btnNew.Text = "New"; + this.btnNew.UseVisualStyleBackColor = true; + // + // tbAmimationSpeed + // + this.tbAmimationSpeed.Location = new System.Drawing.Point(349, 145); + this.tbAmimationSpeed.Name = "tbAmimationSpeed"; + this.tbAmimationSpeed.Size = new System.Drawing.Size(100, 22); + this.tbAmimationSpeed.TabIndex = 12; + // + // lblAnimationSpeed + // + this.lblAnimationSpeed.AutoSize = true; + this.lblAnimationSpeed.Location = new System.Drawing.Point(228, 148); + this.lblAnimationSpeed.Name = "lblAnimationSpeed"; + this.lblAnimationSpeed.Size = new System.Drawing.Size(115, 17); + this.lblAnimationSpeed.TabIndex = 13; + this.lblAnimationSpeed.Text = "Animation Speed"; + // + // lblDefaultSize + // + this.lblDefaultSize.AutoSize = true; + this.lblDefaultSize.Location = new System.Drawing.Point(261, 188); + this.lblDefaultSize.Name = "lblDefaultSize"; + this.lblDefaultSize.Size = new System.Drawing.Size(84, 17); + this.lblDefaultSize.TabIndex = 14; + this.lblDefaultSize.Text = "Default Size"; + // + // tbDefaultSize + // + this.tbDefaultSize.Location = new System.Drawing.Point(349, 185); + this.tbDefaultSize.Name = "tbDefaultSize"; + this.tbDefaultSize.Size = new System.Drawing.Size(100, 22); + this.tbDefaultSize.TabIndex = 15; + // + // btnBack + // + this.btnBack.Location = new System.Drawing.Point(43, 269); + this.btnBack.Name = "btnBack"; + this.btnBack.Size = new System.Drawing.Size(29, 23); + this.btnBack.TabIndex = 16; + this.btnBack.Text = "<"; + this.btnBack.UseVisualStyleBackColor = true; + // + // btnFwd + // + this.btnFwd.Location = new System.Drawing.Point(125, 269); + this.btnFwd.Name = "btnFwd"; + this.btnFwd.Size = new System.Drawing.Size(29, 23); + this.btnFwd.TabIndex = 17; + this.btnFwd.Text = ">"; + this.btnFwd.UseVisualStyleBackColor = true; + // + // lblCountSprites + // + this.lblCountSprites.AutoSize = true; + this.lblCountSprites.Location = new System.Drawing.Point(89, 272); + this.lblCountSprites.Name = "lblCountSprites"; + this.lblCountSprites.Size = new System.Drawing.Size(16, 17); + this.lblCountSprites.TabIndex = 18; + this.lblCountSprites.Text = "0"; + // + // SpriteEntryForm + // + this.AcceptButton = this.btnApply; + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(524, 294); + this.Controls.Add(this.lblCountSprites); + this.Controls.Add(this.btnFwd); + this.Controls.Add(this.btnBack); + this.Controls.Add(this.tbDefaultSize); + this.Controls.Add(this.lblDefaultSize); + this.Controls.Add(this.lblAnimationSpeed); + this.Controls.Add(this.tbAmimationSpeed); + this.Controls.Add(this.btnNew); + this.Controls.Add(this.btnApply); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnDone); + this.Controls.Add(this.lblSpriteName); + this.Controls.Add(this.tbSpriteName); + this.Controls.Add(this.lblFrames); + this.Controls.Add(this.tbNumFrames); + this.Controls.Add(this.lblChosenArea); + this.Controls.Add(this.lblStartingImage); + this.Controls.Add(this.cbStartingImage); + this.Controls.Add(this.pbImageField); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SpriteEntryForm"; + this.Text = "SpriteEntryForm"; + ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox pbImageField; + private System.Windows.Forms.ComboBox cbStartingImage; + private System.Windows.Forms.Label lblStartingImage; + private System.Windows.Forms.Label lblChosenArea; + private System.Windows.Forms.TextBox tbNumFrames; + private System.Windows.Forms.Label lblFrames; + private System.Windows.Forms.TextBox tbSpriteName; + private System.Windows.Forms.Label lblSpriteName; + private System.Windows.Forms.Button btnDone; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnApply; + private System.Windows.Forms.Button btnNew; + private System.Windows.Forms.TextBox tbAmimationSpeed; + private System.Windows.Forms.Label lblAnimationSpeed; + private System.Windows.Forms.Label lblDefaultSize; + private System.Windows.Forms.TextBox tbDefaultSize; + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.Button btnFwd; + private System.Windows.Forms.Label lblCountSprites; + } +} \ No newline at end of file diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs new file mode 100644 index 0000000..a5514ad --- /dev/null +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Serialization; +using System.IO; +using System.Resources; +using System.Windows.Forms; +using System.Windows; +using System.Collections; + + + +namespace SpriteLibrary +{ + public partial class SpriteEntryForm : Form + { + SpriteController MyController; + ResourceManager myResources = null; + + public SpriteEntryForm(ResourceManager theResourceManager) + { + InitializeComponent(); + myResources = theResourceManager; + LocalSetup(); + } + + public void LocalSetup() + { + pbImageField.BackgroundImageLayout = ImageLayout.Stretch; + MyController = new SpriteController(pbImageField); + PopulateMenu(); + } + + public void PopulateMenu() + { + ResourceManager rm = Properties.Resources.ResourceManager; + if (myResources != null) rm = myResources; + PopulateMenu(rm); + + } + public void PopulateMenu(ResourceManager rm) + { + if (myResources == null) myResources = rm; + ResourceSet RS = rm.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true); + cbStartingImage.Items.Clear(); + foreach (DictionaryEntry entry in RS) + { + string resourceKey = entry.Key.ToString(); + object resource = entry.Value; + if (resource is Image) + { + cbStartingImage.Items.Add(resourceKey); + } + } + cbStartingImage.SelectedIndex = 0; + } + + private void cbStartingImage_SelectedIndexChanged(object sender, EventArgs e) + { + ResourceManager rm; + if (myResources != null) rm = myResources; + else rm = Properties.Resources.ResourceManager; + //We have a selected item + if (cbStartingImage.SelectedIndex >= 0) + { + //Load in a new image into our background + Image NewImage = (Bitmap)rm.GetObject(cbStartingImage.SelectedItem.ToString()); + if (NewImage != null) + { + MyController.ReplaceOriginalImage(new Bitmap(NewImage)); + pbImageField.BackgroundImage = new Bitmap(NewImage); + pbImageField.Invalidate(); + } + } + } + } +} diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs new file mode 100644 index 0000000..a727c30 --- /dev/null +++ b/SpriteLibrary/SpriteInfo.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; + +namespace SpriteLibrary +{ + internal class SpriteInfo + { + public string SpriteName = ""; + public Point StartPoint = new Point(-1, -1); + public string ImageName = ""; + public int Width = -1; + public int Height = -1; + public int AnimSpeed = 200; + public int NumAnimations = 1; + public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + } +} diff --git a/SpriteLibrary/SpriteLibrary.csproj b/SpriteLibrary/SpriteLibrary.csproj index c9b2631..a3eb328 100644 --- a/SpriteLibrary/SpriteLibrary.csproj +++ b/SpriteLibrary/SpriteLibrary.csproj @@ -62,6 +62,14 @@ + + + Form + + + SpriteEntryForm.cs + + From 23814be473d7b81ca2c2480f8e63b74bf03c1532 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Fri, 15 Sep 2017 19:15:37 -0500 Subject: [PATCH 11/77] Return a spriteinfo list from the entry form --- SpriteLibrary/SpriteDatabase.cs | 11 +++++++++++ SpriteLibrary/SpriteEntryForm.cs | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 278d5a1..aca30d7 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -81,6 +81,17 @@ namespace SpriteLibrary return false; } + public void OpenEditWindow(int FirstItemIndex=-1) + { + SpriteEntryForm SEF = new SpriteEntryForm(myResourceManager, SpriteInfoList); + SEF.ShowDialog(); + //Use the updated list returned from the form. + SpriteInfoList.Clear(); + SpriteInfoList.AddRange(SEF.GetUpdatedList()); + } + #endregion + + #region General Functions public Image GetImageFromName(string Name, bool UseSmartImages) { Image MyImage = null; diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index a5514ad..e3d3349 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -18,33 +18,41 @@ using System.Collections; namespace SpriteLibrary { - public partial class SpriteEntryForm : Form + internal partial class SpriteEntryForm : Form { SpriteController MyController; ResourceManager myResources = null; + List SpriteInformation = new List(); - public SpriteEntryForm(ResourceManager theResourceManager) + internal SpriteEntryForm(ResourceManager theResourceManager, List ListToWorkOn) { InitializeComponent(); + if (theResourceManager == null) throw new Exception("NullException: The ResourceManager passed to the SpriteEntryForm cannot be null. Pass it Properties.Resources.ResourceManager"); myResources = theResourceManager; LocalSetup(); + SpriteInformation.AddRange(ListToWorkOn); } - public void LocalSetup() + private void LocalSetup() { pbImageField.BackgroundImageLayout = ImageLayout.Stretch; MyController = new SpriteController(pbImageField); PopulateMenu(); } - public void PopulateMenu() + internal List GetUpdatedList() { - ResourceManager rm = Properties.Resources.ResourceManager; - if (myResources != null) rm = myResources; + return SpriteInformation; + } + + private void PopulateMenu() + { + ResourceManager rm = myResources; PopulateMenu(rm); } - public void PopulateMenu(ResourceManager rm) + + private void PopulateMenu(ResourceManager rm) { if (myResources == null) myResources = rm; ResourceSet RS = rm.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true); From 72f1c3ac791a8bad3d60e46640726a01d51a8d20 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Fri, 15 Sep 2017 19:21:46 -0500 Subject: [PATCH 12/77] Define a grid size to snap onto. A grid of 1x1 gives us a pixel by pixel grid. But we usually want to have 5, 10, 50, 100 or something like that. --- SpriteLibrary/SpriteDatabase.cs | 11 ++++++++++- SpriteLibrary/SpriteEntryForm.cs | 6 +++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index aca30d7..0e89309 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -26,6 +26,7 @@ namespace SpriteLibrary List TheImages = new List(); ResourceManager myResourceManager = null; string Filename = ""; + Size SnapGridSize = new Size(5, 5); public SpriteDatabase(ResourceManager theResourceManager, string filename) { @@ -39,6 +40,14 @@ namespace SpriteLibrary LoadSpriteInfo(); } + public void SetSnapGridSize(Size GridSize) + { + if (GridSize.Width <= 0) return; + if (GridSize.Height <= 0) return; + if (GridSize.Width > 500) return; + if (GridSize.Height > 500) return; + SnapGridSize = GridSize; + } //******************************* //**** Sprite Info Functions *** @@ -83,7 +92,7 @@ namespace SpriteLibrary public void OpenEditWindow(int FirstItemIndex=-1) { - SpriteEntryForm SEF = new SpriteEntryForm(myResourceManager, SpriteInfoList); + SpriteEntryForm SEF = new SpriteEntryForm(myResourceManager, SpriteInfoList, SnapGridSize); SEF.ShowDialog(); //Use the updated list returned from the form. SpriteInfoList.Clear(); diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index e3d3349..26bafcc 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -11,11 +11,9 @@ using System.Xml.Serialization; using System.IO; using System.Resources; using System.Windows.Forms; -using System.Windows; using System.Collections; - namespace SpriteLibrary { internal partial class SpriteEntryForm : Form @@ -23,12 +21,14 @@ namespace SpriteLibrary SpriteController MyController; ResourceManager myResources = null; List SpriteInformation = new List(); + Size SnapGridSize = new Size(5,5); - internal SpriteEntryForm(ResourceManager theResourceManager, List ListToWorkOn) + internal SpriteEntryForm(ResourceManager theResourceManager, List ListToWorkOn, Size GridSize) { InitializeComponent(); if (theResourceManager == null) throw new Exception("NullException: The ResourceManager passed to the SpriteEntryForm cannot be null. Pass it Properties.Resources.ResourceManager"); myResources = theResourceManager; + SnapGridSize = GridSize; LocalSetup(); SpriteInformation.AddRange(ListToWorkOn); } From b881985b1b22bdbd0ab3de0200bc5284dc13d310 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Fri, 15 Sep 2017 20:16:26 -0500 Subject: [PATCH 13/77] Cloning infrastructure and breaking up spriteInfo to be able to hold multiple animations for one sprite --- SpriteLibrary/SpriteDatabase.cs | 31 +++++++++++++++++++++++++++++++ SpriteLibrary/SpriteInfo.cs | 30 +++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 0e89309..ba93380 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -238,6 +238,37 @@ namespace SpriteLibrary reader.Close(); } } + + public static string WriteToXMLString(T toSerialize) + { + XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType()); + + using (StringWriter textWriter = new StringWriter()) + { + xmlSerializer.Serialize(textWriter, toSerialize); + return textWriter.ToString(); + } + } + public static T ReadFromXmlString(string toDeserialize) where T : new() + { + XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); + using (StringReader textReader = new StringReader(toDeserialize)) + return (T)xmlSerializer.Deserialize(textReader); + } + + public static T CloneByXMLSerializing(T ObjectToClone) + { + XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); + string dest; + using (StringWriter textWriter = new StringWriter()) + { + xmlSerializer.Serialize(textWriter, ObjectToClone); + dest = textWriter.ToString(); + } + + using (StringReader textReader = new StringReader(dest)) + return (T)xmlSerializer.Deserialize(textReader); + } #endregion } diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index a727c30..89550b8 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -7,15 +7,39 @@ using System.Drawing; namespace SpriteLibrary { - internal class SpriteInfo + internal class AnimationInfo { - public string SpriteName = ""; public Point StartPoint = new Point(-1, -1); public string ImageName = ""; public int Width = -1; public int Height = -1; public int AnimSpeed = 200; - public int NumAnimations = 1; + public int NumFrames = 1; public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + + /// + /// A generic cloning method that works when everything is public + /// + /// + public AnimationInfo Clone() + { + return SpriteDatabase.CloneByXMLSerializing(this); + } + } + + internal class SpriteInfo + { + public string SpriteName = ""; + public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + public List Animations = new List(); + + /// + /// A generic cloning method that works when everything is public + /// + /// + public SpriteInfo Clone() + { + return SpriteDatabase.CloneByXMLSerializing(this); + } } } From 84e15883fde16c1e12db7c6c0a49e44813f60693 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sat, 16 Sep 2017 08:03:58 -0500 Subject: [PATCH 14/77] SpriteDatabase creates sprites --- SpriteLibrary/SpriteDatabase.cs | 13 +-- SpriteLibrary/SpriteEntryForm.Designer.cs | 4 +- SpriteLibrary/SpriteEntryForm.resx | 120 ++++++++++++++++++++++ SpriteLibrary/SpriteInfo.cs | 48 +++++++++ SpriteLibrary/SpriteLibrary.csproj | 3 + 5 files changed, 175 insertions(+), 13 deletions(-) create mode 100644 SpriteLibrary/SpriteEntryForm.resx diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index ba93380..90b0bc3 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -140,18 +140,7 @@ namespace SpriteLibrary { if (SI.SpriteName == SpriteName) { - //This is the sprite. Pull out the image resource. then pull out the sprite. - ResourceManager rm = myResourceManager; - Image myImage = (Bitmap)rm.GetObject(SI.ImageName); - if (myImage == null) return null; //break out if we do not have the image defined for this - DestSprite = new Sprite(SI.StartPoint, theController, myImage, SI.Width, SI.Height, SI.AnimSpeed, SI.NumAnimations); - int sizepercent = SI.ViewPercent; - if (sizepercent < 5) sizepercent = 100; - if (sizepercent > 300) sizepercent = 100; - double delta = (double)sizepercent / 100.0; //turn it into a double, and into something we can multiply. - DestSprite.SetSize(new Size((int)(DestSprite.GetSize.Width * delta), (int)(DestSprite.GetSize.Height * delta))); - DestSprite.SetName(SpriteName); - //We have created a new sprite. Now, return a duplicate of that sprite. + SI.CreateSprite(theController, this); return theController.DuplicateSprite(SpriteName); } } diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index ff299c1..0759e7d 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -52,8 +52,9 @@ // // pbImageField // - this.pbImageField.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + this.pbImageField.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); + this.pbImageField.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbImageField.Location = new System.Drawing.Point(5, 10); this.pbImageField.Name = "pbImageField"; this.pbImageField.Size = new System.Drawing.Size(213, 253); @@ -130,6 +131,7 @@ // // btnCancel // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Location = new System.Drawing.Point(353, 259); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); diff --git a/SpriteLibrary/SpriteEntryForm.resx b/SpriteLibrary/SpriteEntryForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/SpriteLibrary/SpriteEntryForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index 89550b8..eea3962 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -4,11 +4,19 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; +using System.Resources; + namespace SpriteLibrary { + internal enum AnimationType { SpriteDefinition=0, Rotation=1, Mirror=2 } internal class AnimationInfo { + public AnimationType FieldsToUse = AnimationType.SpriteDefinition; + public int AnimationToUse = 0; + public int RotationDegrees=0; + public bool MirrorHorizontally = false; + public bool MirrorVertically = false; public Point StartPoint = new Point(-1, -1); public string ImageName = ""; public int Width = -1; @@ -41,5 +49,45 @@ namespace SpriteLibrary { return SpriteDatabase.CloneByXMLSerializing(this); } + + public Sprite CreateSprite(SpriteController ControllerToUse, SpriteDatabase TheDatabaseToUse) + { + Sprite DestSprite = null; + for (int index = 0; index < Animations.Count; index++) + { + AnimationInfo CurrentAnimation = Animations[index]; + Image myImage = TheDatabaseToUse.GetImageFromName(CurrentAnimation.ImageName, true); + if (myImage == null) return null; //break out if we do not have the image defined for this + AnimationType AT = CurrentAnimation.FieldsToUse; + if (index == 0) AT = AnimationType.SpriteDefinition; //the first one MUST be this. + switch(AT) + { + case AnimationType.SpriteDefinition: + if(DestSprite == null)//Creating the sprite from scratch + { + DestSprite = new Sprite(CurrentAnimation.StartPoint, ControllerToUse, myImage, CurrentAnimation.Width, CurrentAnimation.Height, CurrentAnimation.AnimSpeed, CurrentAnimation.NumFrames); + } + else + { + DestSprite.AddAnimation(CurrentAnimation.StartPoint, myImage, CurrentAnimation.Width, CurrentAnimation.Height, CurrentAnimation.AnimSpeed, CurrentAnimation.NumFrames); + } + break; + case AnimationType.Rotation: + DestSprite.AddAnimation(CurrentAnimation.AnimationToUse, CurrentAnimation.RotationDegrees); + break; + case AnimationType.Mirror: + DestSprite.AddAnimation(CurrentAnimation.AnimationToUse, CurrentAnimation.MirrorHorizontally,CurrentAnimation.MirrorVertically); + break; + } + } + int sizepercent = ViewPercent; + if (sizepercent < 5) sizepercent = 100; + if (sizepercent > 300) sizepercent = 100; + double delta = (double)sizepercent / 100.0; //turn it into a double, and into something we can multiply. + DestSprite.SetSize(new Size((int)(DestSprite.GetSize.Width * delta), (int)(DestSprite.GetSize.Height * delta))); + DestSprite.SetName(SpriteName); + //We have created a new sprite. Now, return a duplicate of that sprite. + return DestSprite; + } } } diff --git a/SpriteLibrary/SpriteLibrary.csproj b/SpriteLibrary/SpriteLibrary.csproj index a3eb328..eda7b56 100644 --- a/SpriteLibrary/SpriteLibrary.csproj +++ b/SpriteLibrary/SpriteLibrary.csproj @@ -78,6 +78,9 @@ Resources.Designer.cs Designer + + SpriteEntryForm.cs + From 7d1883b7651fb2cec87c6648ae00a3bf16a57dba Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sat, 16 Sep 2017 08:11:35 -0500 Subject: [PATCH 15/77] Add a save function --- SpriteLibrary/SpriteDatabase.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 90b0bc3..5e3475f 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -40,6 +40,22 @@ namespace SpriteLibrary LoadSpriteInfo(); } + internal void Save() + { + if(!DoesResourceExist(Filename)) + { + //we will try to save it as a file + try + { + WriteToXmlFile>(Filename, SpriteInfoList); + } + catch (Exception e) + { + throw new Exception("SpriteDatabase failed to save: Filename:" + Filename +"\n" + "ERROR: " + e.ToString(), e); + } + } + } + public void SetSnapGridSize(Size GridSize) { if (GridSize.Width <= 0) return; From 4f2d190b6c24b4cda24ec6d98bdcc19183a03483 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sat, 16 Sep 2017 08:14:46 -0500 Subject: [PATCH 16/77] comment on save function --- SpriteLibrary/SpriteDatabase.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 5e3475f..2872998 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -40,7 +40,14 @@ namespace SpriteLibrary LoadSpriteInfo(); } - internal void Save() + /// + /// Tell the database to save the sprite definitions. Use this while you are creating your game. + /// When you are done, you will usually want to take your sprite definition file and add it to the + /// resources of your game. The resources cannot be saved to, so you cannot continue to add new sprites + /// once you are loading and saving them from a resources file. But, the resources file is included with + /// the program when you build it. + /// + public void Save() { if(!DoesResourceExist(Filename)) { From e9f1a9a3edde1a8cd4665948845aadc20edbbbee Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sat, 16 Sep 2017 08:23:47 -0500 Subject: [PATCH 17/77] initial saving working (possibly) --- SpriteLibrary/SpriteDatabase.cs | 10 ++++++++-- SpriteLibrary/SpriteEntryForm.Designer.cs | 1 + SpriteLibrary/SpriteEntryForm.cs | 12 +++++++++--- SpriteLibrary/SpriteInfo.cs | 8 ++++---- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 2872998..86f7df9 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -22,11 +22,12 @@ namespace SpriteLibrary /// public class SpriteDatabase { - List SpriteInfoList = new List(); + public List SpriteInfoList = new List(); List TheImages = new List(); ResourceManager myResourceManager = null; string Filename = ""; Size SnapGridSize = new Size(5, 5); + int CurrentSIIndex = -1; //The information item we are editing. -1 means it is a new one. public SpriteDatabase(ResourceManager theResourceManager, string filename) { @@ -40,6 +41,11 @@ namespace SpriteLibrary LoadSpriteInfo(); } + internal ResourceManager GetResourceManager() + { + return myResourceManager; + } + /// /// Tell the database to save the sprite definitions. Use this while you are creating your game. /// When you are done, you will usually want to take your sprite definition file and add it to the @@ -115,7 +121,7 @@ namespace SpriteLibrary public void OpenEditWindow(int FirstItemIndex=-1) { - SpriteEntryForm SEF = new SpriteEntryForm(myResourceManager, SpriteInfoList, SnapGridSize); + SpriteEntryForm SEF = new SpriteEntryForm(this, SpriteInfoList, SnapGridSize); SEF.ShowDialog(); //Use the updated list returned from the form. SpriteInfoList.Clear(); diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 0759e7d..28400bb 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -247,6 +247,7 @@ this.MinimizeBox = false; this.Name = "SpriteEntryForm"; this.Text = "SpriteEntryForm"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SpriteEntryForm_FormClosing); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 26bafcc..8ece2de 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -22,12 +22,13 @@ namespace SpriteLibrary ResourceManager myResources = null; List SpriteInformation = new List(); Size SnapGridSize = new Size(5,5); + SpriteDatabase myDatabase = null; - internal SpriteEntryForm(ResourceManager theResourceManager, List ListToWorkOn, Size GridSize) + internal SpriteEntryForm(SpriteDatabase theDatabase, List ListToWorkOn, Size GridSize) { InitializeComponent(); - if (theResourceManager == null) throw new Exception("NullException: The ResourceManager passed to the SpriteEntryForm cannot be null. Pass it Properties.Resources.ResourceManager"); - myResources = theResourceManager; + myDatabase = theDatabase; + myResources = myDatabase.GetResourceManager(); SnapGridSize = GridSize; LocalSetup(); SpriteInformation.AddRange(ListToWorkOn); @@ -87,5 +88,10 @@ namespace SpriteLibrary } } } + + private void SpriteEntryForm_FormClosing(object sender, FormClosingEventArgs e) + { + myDatabase.Save(); //try saving the file + } } } diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index eea3962..6e313c1 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -35,11 +35,11 @@ namespace SpriteLibrary } } - internal class SpriteInfo + public class SpriteInfo { - public string SpriteName = ""; - public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size - public List Animations = new List(); + internal string SpriteName = ""; + internal int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + internal List Animations = new List(); /// /// A generic cloning method that works when everything is public From 7e22a57ca578714beef005a2f0babbad19330300 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sat, 16 Sep 2017 15:18:49 -0500 Subject: [PATCH 18/77] move values to the correct place --- SpriteLibrary/SpriteDatabase.cs | 1 - SpriteLibrary/SpriteEntryForm.cs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 86f7df9..361d22e 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -27,7 +27,6 @@ namespace SpriteLibrary ResourceManager myResourceManager = null; string Filename = ""; Size SnapGridSize = new Size(5, 5); - int CurrentSIIndex = -1; //The information item we are editing. -1 means it is a new one. public SpriteDatabase(ResourceManager theResourceManager, string filename) { diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 8ece2de..01c1c51 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -23,6 +23,8 @@ namespace SpriteLibrary List SpriteInformation = new List(); Size SnapGridSize = new Size(5,5); SpriteDatabase myDatabase = null; + int CurrentSIIndex = -1; //The information item we are editing. -1 means it is a new one. + int CurrentSIAnimation = -1; internal SpriteEntryForm(SpriteDatabase theDatabase, List ListToWorkOn, Size GridSize) { From c438320a5ede949c8df5f91bf064e1c99fbb20f2 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sat, 16 Sep 2017 19:08:46 -0500 Subject: [PATCH 19/77] Set up an initial spriteinfo --- SpriteLibrary/SpriteEntryForm.Designer.cs | 279 +++++++++++++++++++--- SpriteLibrary/SpriteEntryForm.cs | 23 ++ 2 files changed, 268 insertions(+), 34 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 28400bb..0263fdc 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -39,7 +39,7 @@ this.btnDone = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.btnApply = new System.Windows.Forms.Button(); - this.btnNew = new System.Windows.Forms.Button(); + this.btnNewSprite = new System.Windows.Forms.Button(); this.tbAmimationSpeed = new System.Windows.Forms.TextBox(); this.lblAnimationSpeed = new System.Windows.Forms.Label(); this.lblDefaultSize = new System.Windows.Forms.Label(); @@ -47,7 +47,28 @@ this.btnBack = new System.Windows.Forms.Button(); this.btnFwd = new System.Windows.Forms.Button(); this.lblCountSprites = new System.Windows.Forms.Label(); + this.tpRotateMirror = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.panel1 = new System.Windows.Forms.Panel(); + this.rbFromImage = new System.Windows.Forms.RadioButton(); + this.rbRotation = new System.Windows.Forms.RadioButton(); + this.rbMirror = new System.Windows.Forms.RadioButton(); + this.btnNewAnimation = new System.Windows.Forms.Button(); + this.pbPreview = new System.Windows.Forms.PictureBox(); + this.btnPreview = new System.Windows.Forms.Button(); + this.cbAnimation = new System.Windows.Forms.ComboBox(); + this.lblWhichAnim = new System.Windows.Forms.Label(); + this.tbRotation = new System.Windows.Forms.TextBox(); + this.lblRotationDegrees = new System.Windows.Forms.Label(); + this.cbMirrorV = new System.Windows.Forms.CheckBox(); + this.cbMirrorH = new System.Windows.Forms.CheckBox(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); + this.tpRotateMirror.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).BeginInit(); this.SuspendLayout(); // // pbImageField @@ -57,14 +78,14 @@ this.pbImageField.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbImageField.Location = new System.Drawing.Point(5, 10); this.pbImageField.Name = "pbImageField"; - this.pbImageField.Size = new System.Drawing.Size(213, 253); + this.pbImageField.Size = new System.Drawing.Size(213, 306); this.pbImageField.TabIndex = 0; this.pbImageField.TabStop = false; // // cbStartingImage // this.cbStartingImage.FormattingEnabled = true; - this.cbStartingImage.Location = new System.Drawing.Point(349, 40); + this.cbStartingImage.Location = new System.Drawing.Point(128, 6); this.cbStartingImage.Name = "cbStartingImage"; this.cbStartingImage.Size = new System.Drawing.Size(131, 24); this.cbStartingImage.TabIndex = 1; @@ -73,7 +94,7 @@ // lblStartingImage // this.lblStartingImage.AutoSize = true; - this.lblStartingImage.Location = new System.Drawing.Point(244, 43); + this.lblStartingImage.Location = new System.Drawing.Point(23, 9); this.lblStartingImage.Name = "lblStartingImage"; this.lblStartingImage.Size = new System.Drawing.Size(99, 17); this.lblStartingImage.TabIndex = 2; @@ -82,7 +103,7 @@ // lblChosenArea // this.lblChosenArea.AutoSize = true; - this.lblChosenArea.Location = new System.Drawing.Point(350, 77); + this.lblChosenArea.Location = new System.Drawing.Point(129, 44); this.lblChosenArea.Name = "lblChosenArea"; this.lblChosenArea.Size = new System.Drawing.Size(46, 17); this.lblChosenArea.TabIndex = 3; @@ -90,7 +111,7 @@ // // tbNumFrames // - this.tbNumFrames.Location = new System.Drawing.Point(349, 109); + this.tbNumFrames.Location = new System.Drawing.Point(128, 75); this.tbNumFrames.Name = "tbNumFrames"; this.tbNumFrames.Size = new System.Drawing.Size(47, 22); this.tbNumFrames.TabIndex = 4; @@ -98,7 +119,7 @@ // lblFrames // this.lblFrames.AutoSize = true; - this.lblFrames.Location = new System.Drawing.Point(288, 109); + this.lblFrames.Location = new System.Drawing.Point(67, 75); this.lblFrames.Name = "lblFrames"; this.lblFrames.Size = new System.Drawing.Size(55, 17); this.lblFrames.TabIndex = 5; @@ -106,7 +127,7 @@ // // tbSpriteName // - this.tbSpriteName.Location = new System.Drawing.Point(349, 10); + this.tbSpriteName.Location = new System.Drawing.Point(356, 10); this.tbSpriteName.Name = "tbSpriteName"; this.tbSpriteName.Size = new System.Drawing.Size(100, 22); this.tbSpriteName.TabIndex = 6; @@ -114,7 +135,7 @@ // lblSpriteName // this.lblSpriteName.AutoSize = true; - this.lblSpriteName.Location = new System.Drawing.Point(251, 14); + this.lblSpriteName.Location = new System.Drawing.Point(258, 14); this.lblSpriteName.Name = "lblSpriteName"; this.lblSpriteName.Size = new System.Drawing.Size(86, 17); this.lblSpriteName.TabIndex = 7; @@ -122,7 +143,7 @@ // // btnDone // - this.btnDone.Location = new System.Drawing.Point(434, 259); + this.btnDone.Location = new System.Drawing.Point(421, 309); this.btnDone.Name = "btnDone"; this.btnDone.Size = new System.Drawing.Size(75, 23); this.btnDone.TabIndex = 8; @@ -132,7 +153,7 @@ // btnCancel // this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(353, 259); + this.btnCancel.Location = new System.Drawing.Point(340, 309); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 9; @@ -141,25 +162,25 @@ // // btnApply // - this.btnApply.Location = new System.Drawing.Point(434, 230); + this.btnApply.Location = new System.Drawing.Point(340, 280); this.btnApply.Name = "btnApply"; this.btnApply.Size = new System.Drawing.Size(75, 23); this.btnApply.TabIndex = 10; this.btnApply.Text = "Apply"; this.btnApply.UseVisualStyleBackColor = true; // - // btnNew + // btnNewSprite // - this.btnNew.Location = new System.Drawing.Point(353, 230); - this.btnNew.Name = "btnNew"; - this.btnNew.Size = new System.Drawing.Size(75, 23); - this.btnNew.TabIndex = 11; - this.btnNew.Text = "New"; - this.btnNew.UseVisualStyleBackColor = true; + this.btnNewSprite.Location = new System.Drawing.Point(238, 280); + this.btnNewSprite.Name = "btnNewSprite"; + this.btnNewSprite.Size = new System.Drawing.Size(92, 23); + this.btnNewSprite.TabIndex = 11; + this.btnNewSprite.Text = "New Sprite"; + this.btnNewSprite.UseVisualStyleBackColor = true; // // tbAmimationSpeed // - this.tbAmimationSpeed.Location = new System.Drawing.Point(349, 145); + this.tbAmimationSpeed.Location = new System.Drawing.Point(356, 207); this.tbAmimationSpeed.Name = "tbAmimationSpeed"; this.tbAmimationSpeed.Size = new System.Drawing.Size(100, 22); this.tbAmimationSpeed.TabIndex = 12; @@ -167,7 +188,7 @@ // lblAnimationSpeed // this.lblAnimationSpeed.AutoSize = true; - this.lblAnimationSpeed.Location = new System.Drawing.Point(228, 148); + this.lblAnimationSpeed.Location = new System.Drawing.Point(235, 210); this.lblAnimationSpeed.Name = "lblAnimationSpeed"; this.lblAnimationSpeed.Size = new System.Drawing.Size(115, 17); this.lblAnimationSpeed.TabIndex = 13; @@ -176,7 +197,7 @@ // lblDefaultSize // this.lblDefaultSize.AutoSize = true; - this.lblDefaultSize.Location = new System.Drawing.Point(261, 188); + this.lblDefaultSize.Location = new System.Drawing.Point(268, 249); this.lblDefaultSize.Name = "lblDefaultSize"; this.lblDefaultSize.Size = new System.Drawing.Size(84, 17); this.lblDefaultSize.TabIndex = 14; @@ -184,14 +205,15 @@ // // tbDefaultSize // - this.tbDefaultSize.Location = new System.Drawing.Point(349, 185); + this.tbDefaultSize.Location = new System.Drawing.Point(356, 246); this.tbDefaultSize.Name = "tbDefaultSize"; this.tbDefaultSize.Size = new System.Drawing.Size(100, 22); this.tbDefaultSize.TabIndex = 15; // // btnBack // - this.btnBack.Location = new System.Drawing.Point(43, 269); + this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnBack.Location = new System.Drawing.Point(49, 322); this.btnBack.Name = "btnBack"; this.btnBack.Size = new System.Drawing.Size(29, 23); this.btnBack.TabIndex = 16; @@ -200,7 +222,8 @@ // // btnFwd // - this.btnFwd.Location = new System.Drawing.Point(125, 269); + this.btnFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnFwd.Location = new System.Drawing.Point(131, 322); this.btnFwd.Name = "btnFwd"; this.btnFwd.Size = new System.Drawing.Size(29, 23); this.btnFwd.TabIndex = 17; @@ -209,20 +232,189 @@ // // lblCountSprites // + this.lblCountSprites.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblCountSprites.AutoSize = true; - this.lblCountSprites.Location = new System.Drawing.Point(89, 272); + this.lblCountSprites.Location = new System.Drawing.Point(95, 325); this.lblCountSprites.Name = "lblCountSprites"; this.lblCountSprites.Size = new System.Drawing.Size(16, 17); this.lblCountSprites.TabIndex = 18; this.lblCountSprites.Text = "0"; // + // tpRotateMirror + // + this.tpRotateMirror.Controls.Add(this.tabPage1); + this.tpRotateMirror.Controls.Add(this.tabPage2); + this.tpRotateMirror.Location = new System.Drawing.Point(224, 58); + this.tpRotateMirror.Name = "tpRotateMirror"; + this.tpRotateMirror.SelectedIndex = 0; + this.tpRotateMirror.Size = new System.Drawing.Size(282, 143); + this.tpRotateMirror.TabIndex = 19; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.cbStartingImage); + this.tabPage1.Controls.Add(this.lblStartingImage); + this.tabPage1.Controls.Add(this.lblChosenArea); + this.tabPage1.Controls.Add(this.tbNumFrames); + this.tabPage1.Controls.Add(this.lblFrames); + this.tabPage1.Location = new System.Drawing.Point(4, 25); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(274, 114); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "tpFromImage"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.cbMirrorH); + this.tabPage2.Controls.Add(this.cbMirrorV); + this.tabPage2.Controls.Add(this.lblRotationDegrees); + this.tabPage2.Controls.Add(this.tbRotation); + this.tabPage2.Controls.Add(this.lblWhichAnim); + this.tabPage2.Controls.Add(this.cbAnimation); + this.tabPage2.Location = new System.Drawing.Point(4, 25); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(274, 114); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "tabPage2"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // panel1 + // + this.panel1.Controls.Add(this.rbMirror); + this.panel1.Controls.Add(this.rbRotation); + this.panel1.Controls.Add(this.rbFromImage); + this.panel1.Location = new System.Drawing.Point(224, 31); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(277, 27); + this.panel1.TabIndex = 20; + // + // rbFromImage + // + this.rbFromImage.AutoSize = true; + this.rbFromImage.Location = new System.Drawing.Point(14, 3); + this.rbFromImage.Name = "rbFromImage"; + this.rbFromImage.Size = new System.Drawing.Size(103, 21); + this.rbFromImage.TabIndex = 0; + this.rbFromImage.TabStop = true; + this.rbFromImage.Text = "From Image"; + this.rbFromImage.UseVisualStyleBackColor = true; + // + // rbRotation + // + this.rbRotation.AutoSize = true; + this.rbRotation.Location = new System.Drawing.Point(120, 3); + this.rbRotation.Name = "rbRotation"; + this.rbRotation.Size = new System.Drawing.Size(71, 21); + this.rbRotation.TabIndex = 1; + this.rbRotation.TabStop = true; + this.rbRotation.Text = "Rotate"; + this.rbRotation.UseVisualStyleBackColor = true; + // + // rbMirror + // + this.rbMirror.AutoSize = true; + this.rbMirror.Location = new System.Drawing.Point(197, 3); + this.rbMirror.Name = "rbMirror"; + this.rbMirror.Size = new System.Drawing.Size(66, 21); + this.rbMirror.TabIndex = 2; + this.rbMirror.TabStop = true; + this.rbMirror.Text = "Mirror"; + this.rbMirror.UseVisualStyleBackColor = true; + // + // btnNewAnimation + // + this.btnNewAnimation.Location = new System.Drawing.Point(238, 309); + this.btnNewAnimation.Name = "btnNewAnimation"; + this.btnNewAnimation.Size = new System.Drawing.Size(92, 23); + this.btnNewAnimation.TabIndex = 21; + this.btnNewAnimation.Text = "New Anim"; + this.btnNewAnimation.UseVisualStyleBackColor = true; + // + // pbPreview + // + this.pbPreview.Location = new System.Drawing.Point(512, 31); + this.pbPreview.Name = "pbPreview"; + this.pbPreview.Size = new System.Drawing.Size(91, 77); + this.pbPreview.TabIndex = 22; + this.pbPreview.TabStop = false; + // + // btnPreview + // + this.btnPreview.Location = new System.Drawing.Point(527, 114); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(75, 23); + this.btnPreview.TabIndex = 23; + this.btnPreview.Text = "Preview"; + this.btnPreview.UseVisualStyleBackColor = true; + // + // cbAnimation + // + this.cbAnimation.FormattingEnabled = true; + this.cbAnimation.Location = new System.Drawing.Point(128, 18); + this.cbAnimation.Name = "cbAnimation"; + this.cbAnimation.Size = new System.Drawing.Size(100, 24); + this.cbAnimation.TabIndex = 0; + // + // lblWhichAnim + // + this.lblWhichAnim.AutoSize = true; + this.lblWhichAnim.Location = new System.Drawing.Point(38, 8); + this.lblWhichAnim.Name = "lblWhichAnim"; + this.lblWhichAnim.Size = new System.Drawing.Size(78, 34); + this.lblWhichAnim.TabIndex = 1; + this.lblWhichAnim.Text = "Based Off\r\nAnimation#"; + // + // tbRotation + // + this.tbRotation.Location = new System.Drawing.Point(128, 58); + this.tbRotation.Name = "tbRotation"; + this.tbRotation.Size = new System.Drawing.Size(100, 22); + this.tbRotation.TabIndex = 2; + // + // lblRotationDegrees + // + this.lblRotationDegrees.AutoSize = true; + this.lblRotationDegrees.Location = new System.Drawing.Point(54, 61); + this.lblRotationDegrees.Name = "lblRotationDegrees"; + this.lblRotationDegrees.Size = new System.Drawing.Size(62, 17); + this.lblRotationDegrees.TabIndex = 3; + this.lblRotationDegrees.Text = "Degrees"; + // + // cbMirrorV + // + this.cbMirrorV.AutoSize = true; + this.cbMirrorV.Location = new System.Drawing.Point(148, 87); + this.cbMirrorV.Name = "cbMirrorV"; + this.cbMirrorV.Size = new System.Drawing.Size(80, 21); + this.cbMirrorV.TabIndex = 4; + this.cbMirrorV.Text = "Mirror V"; + this.cbMirrorV.UseVisualStyleBackColor = true; + // + // cbMirrorH + // + this.cbMirrorH.AutoSize = true; + this.cbMirrorH.Location = new System.Drawing.Point(35, 87); + this.cbMirrorH.Name = "cbMirrorH"; + this.cbMirrorH.Size = new System.Drawing.Size(81, 21); + this.cbMirrorH.TabIndex = 5; + this.cbMirrorH.Text = "Mirror H"; + this.cbMirrorH.UseVisualStyleBackColor = true; + // // SpriteEntryForm // this.AcceptButton = this.btnApply; this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(524, 294); + this.ClientSize = new System.Drawing.Size(614, 347); + this.Controls.Add(this.btnPreview); + this.Controls.Add(this.pbPreview); + this.Controls.Add(this.btnNewAnimation); + this.Controls.Add(this.panel1); + this.Controls.Add(this.tpRotateMirror); this.Controls.Add(this.lblCountSprites); this.Controls.Add(this.btnFwd); this.Controls.Add(this.btnBack); @@ -230,17 +422,12 @@ this.Controls.Add(this.lblDefaultSize); this.Controls.Add(this.lblAnimationSpeed); this.Controls.Add(this.tbAmimationSpeed); - this.Controls.Add(this.btnNew); + this.Controls.Add(this.btnNewSprite); this.Controls.Add(this.btnApply); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnDone); this.Controls.Add(this.lblSpriteName); this.Controls.Add(this.tbSpriteName); - this.Controls.Add(this.lblFrames); - this.Controls.Add(this.tbNumFrames); - this.Controls.Add(this.lblChosenArea); - this.Controls.Add(this.lblStartingImage); - this.Controls.Add(this.cbStartingImage); this.Controls.Add(this.pbImageField); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.MaximizeBox = false; @@ -249,6 +436,14 @@ this.Text = "SpriteEntryForm"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SpriteEntryForm_FormClosing); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).EndInit(); + this.tpRotateMirror.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage1.PerformLayout(); + this.tabPage2.ResumeLayout(false); + this.tabPage2.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -267,7 +462,7 @@ private System.Windows.Forms.Button btnDone; private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.Button btnApply; - private System.Windows.Forms.Button btnNew; + private System.Windows.Forms.Button btnNewSprite; private System.Windows.Forms.TextBox tbAmimationSpeed; private System.Windows.Forms.Label lblAnimationSpeed; private System.Windows.Forms.Label lblDefaultSize; @@ -275,5 +470,21 @@ private System.Windows.Forms.Button btnBack; private System.Windows.Forms.Button btnFwd; private System.Windows.Forms.Label lblCountSprites; + private System.Windows.Forms.TabControl tpRotateMirror; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.RadioButton rbMirror; + private System.Windows.Forms.RadioButton rbRotation; + private System.Windows.Forms.RadioButton rbFromImage; + private System.Windows.Forms.Button btnNewAnimation; + private System.Windows.Forms.PictureBox pbPreview; + private System.Windows.Forms.Button btnPreview; + private System.Windows.Forms.CheckBox cbMirrorH; + private System.Windows.Forms.CheckBox cbMirrorV; + private System.Windows.Forms.Label lblRotationDegrees; + private System.Windows.Forms.TextBox tbRotation; + private System.Windows.Forms.Label lblWhichAnim; + private System.Windows.Forms.ComboBox cbAnimation; } } \ No newline at end of file diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 01c1c51..0900b98 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -21,6 +21,7 @@ namespace SpriteLibrary SpriteController MyController; ResourceManager myResources = null; List SpriteInformation = new List(); + SpriteInfo TempInformation = null; Size SnapGridSize = new Size(5,5); SpriteDatabase myDatabase = null; int CurrentSIIndex = -1; //The information item we are editing. -1 means it is a new one. @@ -40,6 +41,7 @@ namespace SpriteLibrary { pbImageField.BackgroundImageLayout = ImageLayout.Stretch; MyController = new SpriteController(pbImageField); + UpdateMenu(); PopulateMenu(); } @@ -72,6 +74,27 @@ namespace SpriteLibrary cbStartingImage.SelectedIndex = 0; } + private void UpdateMenu() + { + lblCountSprites.Text = SpriteInformation.Count.ToString(); + if (TempInformation == null) SetUpEmptyInfo(); + } + + private void SetUpEmptyInfo() + { + TempInformation = new SpriteInfo(); + TempInformation.SpriteName = ""; + TempInformation.ViewPercent = 100; + AnimationInfo AI = new AnimationInfo(); + AI.AnimSpeed = 200; + AI.FieldsToUse = AnimationType.SpriteDefinition; + AI.Height = 100; + AI.Width = 100; + AI.StartPoint = new Point(0, 0); + AI.ViewPercent = 100; + TempInformation.Animations.Add(AI); + } + private void cbStartingImage_SelectedIndexChanged(object sender, EventArgs e) { ResourceManager rm; From 32c3fa21a734e9314e393a5060444a7d7542343b Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 17 Sep 2017 08:13:04 -0500 Subject: [PATCH 20/77] more work on the form --- SpriteLibrary/SpriteEntryForm.Designer.cs | 290 +++++++++++----------- SpriteLibrary/SpriteEntryForm.cs | 65 ++++- SpriteLibrary/SpriteInfo.cs | 5 +- 3 files changed, 210 insertions(+), 150 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 0263fdc..d494504 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -47,27 +47,27 @@ this.btnBack = new System.Windows.Forms.Button(); this.btnFwd = new System.Windows.Forms.Button(); this.lblCountSprites = new System.Windows.Forms.Label(); - this.tpRotateMirror = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.panel1 = new System.Windows.Forms.Panel(); - this.rbFromImage = new System.Windows.Forms.RadioButton(); - this.rbRotation = new System.Windows.Forms.RadioButton(); + this.TCTabPages = new System.Windows.Forms.TabControl(); + this.tpFromImage = new System.Windows.Forms.TabPage(); + this.tpMirrorRotate = new System.Windows.Forms.TabPage(); + this.cbMirrorH = new System.Windows.Forms.CheckBox(); + this.cbMirrorV = new System.Windows.Forms.CheckBox(); + this.lblRotationDegrees = new System.Windows.Forms.Label(); + this.tbRotation = new System.Windows.Forms.TextBox(); + this.lblWhichAnim = new System.Windows.Forms.Label(); + this.cbAnimation = new System.Windows.Forms.ComboBox(); + this.panelRadioButtons = new System.Windows.Forms.Panel(); this.rbMirror = new System.Windows.Forms.RadioButton(); + this.rbRotation = new System.Windows.Forms.RadioButton(); + this.rbFromImage = new System.Windows.Forms.RadioButton(); this.btnNewAnimation = new System.Windows.Forms.Button(); this.pbPreview = new System.Windows.Forms.PictureBox(); this.btnPreview = new System.Windows.Forms.Button(); - this.cbAnimation = new System.Windows.Forms.ComboBox(); - this.lblWhichAnim = new System.Windows.Forms.Label(); - this.tbRotation = new System.Windows.Forms.TextBox(); - this.lblRotationDegrees = new System.Windows.Forms.Label(); - this.cbMirrorV = new System.Windows.Forms.CheckBox(); - this.cbMirrorH = new System.Windows.Forms.CheckBox(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); - this.tpRotateMirror.SuspendLayout(); - this.tabPage1.SuspendLayout(); - this.tabPage2.SuspendLayout(); - this.panel1.SuspendLayout(); + this.TCTabPages.SuspendLayout(); + this.tpFromImage.SuspendLayout(); + this.tpMirrorRotate.SuspendLayout(); + this.panelRadioButtons.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).BeginInit(); this.SuspendLayout(); // @@ -180,7 +180,7 @@ // // tbAmimationSpeed // - this.tbAmimationSpeed.Location = new System.Drawing.Point(356, 207); + this.tbAmimationSpeed.Location = new System.Drawing.Point(356, 217); this.tbAmimationSpeed.Name = "tbAmimationSpeed"; this.tbAmimationSpeed.Size = new System.Drawing.Size(100, 22); this.tbAmimationSpeed.TabIndex = 12; @@ -188,7 +188,7 @@ // lblAnimationSpeed // this.lblAnimationSpeed.AutoSize = true; - this.lblAnimationSpeed.Location = new System.Drawing.Point(235, 210); + this.lblAnimationSpeed.Location = new System.Drawing.Point(235, 220); this.lblAnimationSpeed.Name = "lblAnimationSpeed"; this.lblAnimationSpeed.Size = new System.Drawing.Size(115, 17); this.lblAnimationSpeed.TabIndex = 13; @@ -240,67 +240,120 @@ this.lblCountSprites.TabIndex = 18; this.lblCountSprites.Text = "0"; // - // tpRotateMirror + // TCTabPages // - this.tpRotateMirror.Controls.Add(this.tabPage1); - this.tpRotateMirror.Controls.Add(this.tabPage2); - this.tpRotateMirror.Location = new System.Drawing.Point(224, 58); - this.tpRotateMirror.Name = "tpRotateMirror"; - this.tpRotateMirror.SelectedIndex = 0; - this.tpRotateMirror.Size = new System.Drawing.Size(282, 143); - this.tpRotateMirror.TabIndex = 19; + this.TCTabPages.Controls.Add(this.tpFromImage); + this.TCTabPages.Controls.Add(this.tpMirrorRotate); + this.TCTabPages.Location = new System.Drawing.Point(224, 68); + this.TCTabPages.Name = "TCTabPages"; + this.TCTabPages.SelectedIndex = 0; + this.TCTabPages.Size = new System.Drawing.Size(282, 143); + this.TCTabPages.TabIndex = 19; // - // tabPage1 + // tpFromImage // - this.tabPage1.Controls.Add(this.cbStartingImage); - this.tabPage1.Controls.Add(this.lblStartingImage); - this.tabPage1.Controls.Add(this.lblChosenArea); - this.tabPage1.Controls.Add(this.tbNumFrames); - this.tabPage1.Controls.Add(this.lblFrames); - this.tabPage1.Location = new System.Drawing.Point(4, 25); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(274, 114); - this.tabPage1.TabIndex = 0; - this.tabPage1.Text = "tpFromImage"; - this.tabPage1.UseVisualStyleBackColor = true; + this.tpFromImage.Controls.Add(this.cbStartingImage); + this.tpFromImage.Controls.Add(this.lblStartingImage); + this.tpFromImage.Controls.Add(this.lblChosenArea); + this.tpFromImage.Controls.Add(this.tbNumFrames); + this.tpFromImage.Controls.Add(this.lblFrames); + this.tpFromImage.Location = new System.Drawing.Point(4, 25); + this.tpFromImage.Name = "tpFromImage"; + this.tpFromImage.Padding = new System.Windows.Forms.Padding(3); + this.tpFromImage.Size = new System.Drawing.Size(274, 114); + this.tpFromImage.TabIndex = 0; + this.tpFromImage.Text = "From Image"; + this.tpFromImage.UseVisualStyleBackColor = true; // - // tabPage2 + // tpMirrorRotate // - this.tabPage2.Controls.Add(this.cbMirrorH); - this.tabPage2.Controls.Add(this.cbMirrorV); - this.tabPage2.Controls.Add(this.lblRotationDegrees); - this.tabPage2.Controls.Add(this.tbRotation); - this.tabPage2.Controls.Add(this.lblWhichAnim); - this.tabPage2.Controls.Add(this.cbAnimation); - this.tabPage2.Location = new System.Drawing.Point(4, 25); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(274, 114); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "tabPage2"; - this.tabPage2.UseVisualStyleBackColor = true; + this.tpMirrorRotate.Controls.Add(this.cbMirrorH); + this.tpMirrorRotate.Controls.Add(this.cbMirrorV); + this.tpMirrorRotate.Controls.Add(this.lblRotationDegrees); + this.tpMirrorRotate.Controls.Add(this.tbRotation); + this.tpMirrorRotate.Controls.Add(this.lblWhichAnim); + this.tpMirrorRotate.Controls.Add(this.cbAnimation); + this.tpMirrorRotate.Location = new System.Drawing.Point(4, 25); + this.tpMirrorRotate.Name = "tpMirrorRotate"; + this.tpMirrorRotate.Padding = new System.Windows.Forms.Padding(3); + this.tpMirrorRotate.Size = new System.Drawing.Size(274, 114); + this.tpMirrorRotate.TabIndex = 1; + this.tpMirrorRotate.Text = "Mirror / Rotation"; + this.tpMirrorRotate.UseVisualStyleBackColor = true; // - // panel1 + // cbMirrorH // - this.panel1.Controls.Add(this.rbMirror); - this.panel1.Controls.Add(this.rbRotation); - this.panel1.Controls.Add(this.rbFromImage); - this.panel1.Location = new System.Drawing.Point(224, 31); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(277, 27); - this.panel1.TabIndex = 20; + this.cbMirrorH.AutoSize = true; + this.cbMirrorH.Location = new System.Drawing.Point(35, 87); + this.cbMirrorH.Name = "cbMirrorH"; + this.cbMirrorH.Size = new System.Drawing.Size(81, 21); + this.cbMirrorH.TabIndex = 5; + this.cbMirrorH.Text = "Mirror H"; + this.cbMirrorH.UseVisualStyleBackColor = true; // - // rbFromImage + // cbMirrorV // - this.rbFromImage.AutoSize = true; - this.rbFromImage.Location = new System.Drawing.Point(14, 3); - this.rbFromImage.Name = "rbFromImage"; - this.rbFromImage.Size = new System.Drawing.Size(103, 21); - this.rbFromImage.TabIndex = 0; - this.rbFromImage.TabStop = true; - this.rbFromImage.Text = "From Image"; - this.rbFromImage.UseVisualStyleBackColor = true; + this.cbMirrorV.AutoSize = true; + this.cbMirrorV.Location = new System.Drawing.Point(148, 87); + this.cbMirrorV.Name = "cbMirrorV"; + this.cbMirrorV.Size = new System.Drawing.Size(80, 21); + this.cbMirrorV.TabIndex = 4; + this.cbMirrorV.Text = "Mirror V"; + this.cbMirrorV.UseVisualStyleBackColor = true; + // + // lblRotationDegrees + // + this.lblRotationDegrees.AutoSize = true; + this.lblRotationDegrees.Location = new System.Drawing.Point(54, 61); + this.lblRotationDegrees.Name = "lblRotationDegrees"; + this.lblRotationDegrees.Size = new System.Drawing.Size(62, 17); + this.lblRotationDegrees.TabIndex = 3; + this.lblRotationDegrees.Text = "Degrees"; + // + // tbRotation + // + this.tbRotation.Location = new System.Drawing.Point(128, 58); + this.tbRotation.Name = "tbRotation"; + this.tbRotation.Size = new System.Drawing.Size(100, 22); + this.tbRotation.TabIndex = 2; + // + // lblWhichAnim + // + this.lblWhichAnim.AutoSize = true; + this.lblWhichAnim.Location = new System.Drawing.Point(38, 8); + this.lblWhichAnim.Name = "lblWhichAnim"; + this.lblWhichAnim.Size = new System.Drawing.Size(78, 34); + this.lblWhichAnim.TabIndex = 1; + this.lblWhichAnim.Text = "Based Off\r\nAnimation#"; + // + // cbAnimation + // + this.cbAnimation.FormattingEnabled = true; + this.cbAnimation.Location = new System.Drawing.Point(128, 18); + this.cbAnimation.Name = "cbAnimation"; + this.cbAnimation.Size = new System.Drawing.Size(100, 24); + this.cbAnimation.TabIndex = 0; + // + // panelRadioButtons + // + this.panelRadioButtons.Controls.Add(this.rbMirror); + this.panelRadioButtons.Controls.Add(this.rbRotation); + this.panelRadioButtons.Controls.Add(this.rbFromImage); + this.panelRadioButtons.Location = new System.Drawing.Point(224, 35); + this.panelRadioButtons.Name = "panelRadioButtons"; + this.panelRadioButtons.Size = new System.Drawing.Size(277, 27); + this.panelRadioButtons.TabIndex = 20; + // + // rbMirror + // + this.rbMirror.AutoSize = true; + this.rbMirror.Location = new System.Drawing.Point(197, 3); + this.rbMirror.Name = "rbMirror"; + this.rbMirror.Size = new System.Drawing.Size(66, 21); + this.rbMirror.TabIndex = 2; + this.rbMirror.TabStop = true; + this.rbMirror.Text = "Mirror"; + this.rbMirror.UseVisualStyleBackColor = true; // // rbRotation // @@ -313,16 +366,16 @@ this.rbRotation.Text = "Rotate"; this.rbRotation.UseVisualStyleBackColor = true; // - // rbMirror + // rbFromImage // - this.rbMirror.AutoSize = true; - this.rbMirror.Location = new System.Drawing.Point(197, 3); - this.rbMirror.Name = "rbMirror"; - this.rbMirror.Size = new System.Drawing.Size(66, 21); - this.rbMirror.TabIndex = 2; - this.rbMirror.TabStop = true; - this.rbMirror.Text = "Mirror"; - this.rbMirror.UseVisualStyleBackColor = true; + this.rbFromImage.AutoSize = true; + this.rbFromImage.Location = new System.Drawing.Point(14, 3); + this.rbFromImage.Name = "rbFromImage"; + this.rbFromImage.Size = new System.Drawing.Size(103, 21); + this.rbFromImage.TabIndex = 0; + this.rbFromImage.TabStop = true; + this.rbFromImage.Text = "From Image"; + this.rbFromImage.UseVisualStyleBackColor = true; // // btnNewAnimation // @@ -350,59 +403,6 @@ this.btnPreview.Text = "Preview"; this.btnPreview.UseVisualStyleBackColor = true; // - // cbAnimation - // - this.cbAnimation.FormattingEnabled = true; - this.cbAnimation.Location = new System.Drawing.Point(128, 18); - this.cbAnimation.Name = "cbAnimation"; - this.cbAnimation.Size = new System.Drawing.Size(100, 24); - this.cbAnimation.TabIndex = 0; - // - // lblWhichAnim - // - this.lblWhichAnim.AutoSize = true; - this.lblWhichAnim.Location = new System.Drawing.Point(38, 8); - this.lblWhichAnim.Name = "lblWhichAnim"; - this.lblWhichAnim.Size = new System.Drawing.Size(78, 34); - this.lblWhichAnim.TabIndex = 1; - this.lblWhichAnim.Text = "Based Off\r\nAnimation#"; - // - // tbRotation - // - this.tbRotation.Location = new System.Drawing.Point(128, 58); - this.tbRotation.Name = "tbRotation"; - this.tbRotation.Size = new System.Drawing.Size(100, 22); - this.tbRotation.TabIndex = 2; - // - // lblRotationDegrees - // - this.lblRotationDegrees.AutoSize = true; - this.lblRotationDegrees.Location = new System.Drawing.Point(54, 61); - this.lblRotationDegrees.Name = "lblRotationDegrees"; - this.lblRotationDegrees.Size = new System.Drawing.Size(62, 17); - this.lblRotationDegrees.TabIndex = 3; - this.lblRotationDegrees.Text = "Degrees"; - // - // cbMirrorV - // - this.cbMirrorV.AutoSize = true; - this.cbMirrorV.Location = new System.Drawing.Point(148, 87); - this.cbMirrorV.Name = "cbMirrorV"; - this.cbMirrorV.Size = new System.Drawing.Size(80, 21); - this.cbMirrorV.TabIndex = 4; - this.cbMirrorV.Text = "Mirror V"; - this.cbMirrorV.UseVisualStyleBackColor = true; - // - // cbMirrorH - // - this.cbMirrorH.AutoSize = true; - this.cbMirrorH.Location = new System.Drawing.Point(35, 87); - this.cbMirrorH.Name = "cbMirrorH"; - this.cbMirrorH.Size = new System.Drawing.Size(81, 21); - this.cbMirrorH.TabIndex = 5; - this.cbMirrorH.Text = "Mirror H"; - this.cbMirrorH.UseVisualStyleBackColor = true; - // // SpriteEntryForm // this.AcceptButton = this.btnApply; @@ -413,8 +413,8 @@ this.Controls.Add(this.btnPreview); this.Controls.Add(this.pbPreview); this.Controls.Add(this.btnNewAnimation); - this.Controls.Add(this.panel1); - this.Controls.Add(this.tpRotateMirror); + this.Controls.Add(this.panelRadioButtons); + this.Controls.Add(this.TCTabPages); this.Controls.Add(this.lblCountSprites); this.Controls.Add(this.btnFwd); this.Controls.Add(this.btnBack); @@ -436,13 +436,13 @@ this.Text = "SpriteEntryForm"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SpriteEntryForm_FormClosing); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).EndInit(); - this.tpRotateMirror.ResumeLayout(false); - this.tabPage1.ResumeLayout(false); - this.tabPage1.PerformLayout(); - this.tabPage2.ResumeLayout(false); - this.tabPage2.PerformLayout(); - this.panel1.ResumeLayout(false); - this.panel1.PerformLayout(); + this.TCTabPages.ResumeLayout(false); + this.tpFromImage.ResumeLayout(false); + this.tpFromImage.PerformLayout(); + this.tpMirrorRotate.ResumeLayout(false); + this.tpMirrorRotate.PerformLayout(); + this.panelRadioButtons.ResumeLayout(false); + this.panelRadioButtons.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -470,10 +470,10 @@ private System.Windows.Forms.Button btnBack; private System.Windows.Forms.Button btnFwd; private System.Windows.Forms.Label lblCountSprites; - private System.Windows.Forms.TabControl tpRotateMirror; - private System.Windows.Forms.TabPage tabPage1; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.TabControl TCTabPages; + private System.Windows.Forms.TabPage tpFromImage; + private System.Windows.Forms.TabPage tpMirrorRotate; + private System.Windows.Forms.Panel panelRadioButtons; private System.Windows.Forms.RadioButton rbMirror; private System.Windows.Forms.RadioButton rbRotation; private System.Windows.Forms.RadioButton rbFromImage; diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 0900b98..f2c449b 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -41,8 +41,10 @@ namespace SpriteLibrary { pbImageField.BackgroundImageLayout = ImageLayout.Stretch; MyController = new SpriteController(pbImageField); - UpdateMenu(); PopulateMenu(); + UpdateMenu(); + SpriteInformationToForm(); + UpdateMenu(); } internal List GetUpdatedList() @@ -76,8 +78,38 @@ namespace SpriteLibrary private void UpdateMenu() { + SuspendLayout(); lblCountSprites.Text = SpriteInformation.Count.ToString(); if (TempInformation == null) SetUpEmptyInfo(); + + //Put in numbers into the combo-box of which frame to base ourselves off of + cbAnimation.Items.Clear(); + for(int i =0; i < TempInformation.Animations.Count; i++) + { + cbAnimation.Items.Add(i.ToString()); + } + if (CurrentSIAnimation == 0) + { + rbFromImage.Checked = true; + panelRadioButtons.Visible = false; + } + else + panelRadioButtons.Visible = true; + if(rbFromImage.Checked) + { + if(!TCTabPages.TabPages.Contains(tpFromImage)) + TCTabPages.TabPages.Add(tpFromImage); + if (TCTabPages.TabPages.Contains(tpMirrorRotate)) + TCTabPages.TabPages.Remove(tpMirrorRotate); + } + else + { + if (TCTabPages.TabPages.Contains(tpFromImage)) + TCTabPages.TabPages.Remove(tpFromImage); + if (!TCTabPages.TabPages.Contains(tpMirrorRotate)) + TCTabPages.TabPages.Add(tpMirrorRotate); + } + ResumeLayout(); } private void SetUpEmptyInfo() @@ -91,7 +123,6 @@ namespace SpriteLibrary AI.Height = 100; AI.Width = 100; AI.StartPoint = new Point(0, 0); - AI.ViewPercent = 100; TempInformation.Animations.Add(AI); } @@ -114,6 +145,36 @@ namespace SpriteLibrary } } + /// + /// Take the values stored in TempInformation and push it out to our form + /// + private void SpriteInformationToForm() + { + if (TempInformation == null) return; + //For the main sprite information + tbSpriteName.Text = TempInformation.SpriteName; + tbDefaultSize.Text = TempInformation.ViewPercent.ToString(); + + //From the current animation + AnimationInfo AI = null; + if (CurrentSIAnimation < 0) CurrentSIAnimation = 0; + if (CurrentSIAnimation >= TempInformation.Animations.Count) CurrentSIAnimation = TempInformation.Animations.Count -1; + if (CurrentSIAnimation < TempInformation.Animations.Count) + { + AI = TempInformation.Animations[CurrentSIAnimation]; + tbAmimationSpeed.Text = AI.AnimSpeed.ToString(); + cbStartingImage.Text = AI.ImageName; + cbMirrorH.Checked = AI.MirrorHorizontally; + cbMirrorV.Checked = AI.MirrorVertically; + cbAnimation.Text = AI.AnimationToUse.ToString(); + tbNumFrames.Text = AI.NumFrames.ToString(); + //Radio buttons + if (AI.FieldsToUse == AnimationType.SpriteDefinition) rbFromImage.Checked = true; + if (AI.FieldsToUse == AnimationType.Mirror) rbMirror.Checked = true; + if (AI.FieldsToUse == AnimationType.Rotation) rbRotation.Checked = true; + } + } + private void SpriteEntryForm_FormClosing(object sender, FormClosingEventArgs e) { myDatabase.Save(); //try saving the file diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index 6e313c1..1e3754a 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -21,9 +21,8 @@ namespace SpriteLibrary public string ImageName = ""; public int Width = -1; public int Height = -1; - public int AnimSpeed = 200; public int NumFrames = 1; - public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + public int AnimSpeed = 200; /// /// A generic cloning method that works when everything is public @@ -40,7 +39,7 @@ namespace SpriteLibrary internal string SpriteName = ""; internal int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size internal List Animations = new List(); - + /// /// A generic cloning method that works when everything is public /// From a415e89cd08e790ece57e0a6f36eba8143c9ed00 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 17 Sep 2017 15:34:51 -0500 Subject: [PATCH 21/77] SpriteInfotoForm --- SpriteLibrary/SpriteEntryForm.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index f2c449b..ea8c881 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -168,6 +168,7 @@ namespace SpriteLibrary cbMirrorV.Checked = AI.MirrorVertically; cbAnimation.Text = AI.AnimationToUse.ToString(); tbNumFrames.Text = AI.NumFrames.ToString(); + lblChosenArea.Text = AI.Width + "x" + AI.Height; //Radio buttons if (AI.FieldsToUse == AnimationType.SpriteDefinition) rbFromImage.Checked = true; if (AI.FieldsToUse == AnimationType.Mirror) rbMirror.Checked = true; From 7dea96b2663ff985a171e10ef41b21f4a94d2fb1 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 17 Sep 2017 17:07:39 -0500 Subject: [PATCH 22/77] Update drag info --- SpriteLibrary/SpriteEntryForm.Designer.cs | 7 ++- SpriteLibrary/SpriteEntryForm.cs | 64 +++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index d494504..b800d54 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -81,6 +81,9 @@ this.pbImageField.Size = new System.Drawing.Size(213, 306); this.pbImageField.TabIndex = 0; this.pbImageField.TabStop = false; + this.pbImageField.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pbImageField_MouseDown); + this.pbImageField.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbImageField_MouseMove); + this.pbImageField.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pbImageField_MouseUp); // // cbStartingImage // @@ -105,9 +108,9 @@ this.lblChosenArea.AutoSize = true; this.lblChosenArea.Location = new System.Drawing.Point(129, 44); this.lblChosenArea.Name = "lblChosenArea"; - this.lblChosenArea.Size = new System.Drawing.Size(46, 17); + this.lblChosenArea.Size = new System.Drawing.Size(86, 17); this.lblChosenArea.TabIndex = 3; - this.lblChosenArea.Text = "label2"; + this.lblChosenArea.Text = "ChosenArea"; // // tbNumFrames // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index ea8c881..1c0e422 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -27,6 +27,10 @@ namespace SpriteLibrary int CurrentSIIndex = -1; //The information item we are editing. -1 means it is a new one. int CurrentSIAnimation = -1; + bool WeAreDragging = false; + Point DragStart = new Point(-1, -1); + Rectangle ChosenArea = new Rectangle(1,1,100,100); + internal SpriteEntryForm(SpriteDatabase theDatabase, List ListToWorkOn, Size GridSize) { InitializeComponent(); @@ -109,9 +113,15 @@ namespace SpriteLibrary if (!TCTabPages.TabPages.Contains(tpMirrorRotate)) TCTabPages.TabPages.Add(tpMirrorRotate); } + UpdateChosenAreaLabel(); ResumeLayout(); } + private void UpdateChosenAreaLabel() + { + lblChosenArea.Text = ChosenArea.X + "," + ChosenArea.Y + "," + ChosenArea.Width + "," + ChosenArea.Height; + } + private void SetUpEmptyInfo() { TempInformation = new SpriteInfo(); @@ -176,9 +186,63 @@ namespace SpriteLibrary } } + /// + /// Given two locations that we have clicked on, find the area we have selected + /// + /// + /// + /// + private Rectangle AreaFromGridPoints(Point Start, Point End) + { + //Get the points translated from locations on the picturebox + Point OneImagePoint = MyController.ReturnPointAdjustedForImage(Start); + Point TwoImagePoint = MyController.ReturnPointAdjustedForImage(End); + //Now, shrink them to figure out which grid points we have chosen + Point OneGridPoint = new Point(OneImagePoint.X / SnapGridSize.Width, OneImagePoint.Y / SnapGridSize.Height); + Point TwoGridPoint = new Point(TwoImagePoint.X / SnapGridSize.Width, TwoImagePoint.Y / SnapGridSize.Height); + //Find the top-left point and the bottom-right point + Point StartGridPoint = new Point(Math.Min(OneGridPoint.X, TwoGridPoint.X), Math.Min(OneGridPoint.Y, TwoGridPoint.Y)); + Point EndGridPoint = new Point(Math.Max(OneGridPoint.X, TwoGridPoint.X), Math.Max(OneGridPoint.Y, TwoGridPoint.Y)); + //Translate them back into points on the image + Point ReturnSPoint = new Point(StartGridPoint.X * SnapGridSize.Width, StartGridPoint.Y * SnapGridSize.Height); + Point ReturnEPoint = new Point((EndGridPoint.X +1) * SnapGridSize.Width, (EndGridPoint.Y +1) * SnapGridSize.Height); + //Change it into a rectangle and return it + Rectangle ReturnRec = new Rectangle(ReturnSPoint.X, ReturnSPoint.Y, ReturnEPoint.X - ReturnSPoint.X, ReturnEPoint.Y - ReturnSPoint.Y); + return ReturnRec; + } + private void SpriteEntryForm_FormClosing(object sender, FormClosingEventArgs e) { myDatabase.Save(); //try saving the file } + + private void pbImageField_MouseMove(object sender, MouseEventArgs e) + { + //If we are dragging, process the dragging + if (WeAreDragging) + { + ChosenArea = AreaFromGridPoints(DragStart, e.Location); + UpdateChosenAreaLabel(); + } + } + + private void pbImageField_MouseDown(object sender, MouseEventArgs e) + { + //When the mouse goes down, we note that we are trying to drag + WeAreDragging = true; + DragStart = e.Location; + } + + private void pbImageField_MouseUp(object sender, MouseEventArgs e) + { + //When the mouse goes up, stop dragging and update + if(WeAreDragging) + { + ChosenArea = AreaFromGridPoints(DragStart, e.Location); + UpdateChosenAreaLabel(); + } + WeAreDragging = false; + + } } } From 30a3d1e4b3ea239e18b3eb27a4b5a253dfb591f3 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 17 Sep 2017 17:10:03 -0500 Subject: [PATCH 23/77] update the selected box from the SpriteInfo --- SpriteLibrary/SpriteEntryForm.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 1c0e422..6c49cfc 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -178,7 +178,9 @@ namespace SpriteLibrary cbMirrorV.Checked = AI.MirrorVertically; cbAnimation.Text = AI.AnimationToUse.ToString(); tbNumFrames.Text = AI.NumFrames.ToString(); - lblChosenArea.Text = AI.Width + "x" + AI.Height; + //lblChosenArea.Text = AI.Width + "x" + AI.Height; + ChosenArea = new Rectangle(AI.StartPoint.X, AI.StartPoint.Y, AI.Width, AI.Height); + UpdateChosenAreaLabel(); //Radio buttons if (AI.FieldsToUse == AnimationType.SpriteDefinition) rbFromImage.Checked = true; if (AI.FieldsToUse == AnimationType.Mirror) rbMirror.Checked = true; From 1361a46b7c90b73955cf4c20c9c75ab01342c3e6 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 17 Sep 2017 17:36:57 -0500 Subject: [PATCH 24/77] initial drag and drop visual (shows there is a bug to figure out) --- SpriteLibrary/SpriteEntryForm.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 6c49cfc..353e7ec 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -12,6 +12,7 @@ using System.IO; using System.Resources; using System.Windows.Forms; using System.Collections; +using System.Drawing.Drawing2D; namespace SpriteLibrary @@ -120,6 +121,30 @@ namespace SpriteLibrary private void UpdateChosenAreaLabel() { lblChosenArea.Text = ChosenArea.X + "," + ChosenArea.Y + "," + ChosenArea.Width + "," + ChosenArea.Height; + UpdateHighlightBox(); + } + + private void UpdateHighlightBox() + { + int transparency = 200; + Image NewFrontImage = new Bitmap(pbImageField.BackgroundImage.Width, pbImageField.BackgroundImage.Height); + Color FillColor = Color.Green; + Brush brush = new SolidBrush(Color.FromArgb(transparency, FillColor.R, FillColor.G, FillColor.B)); + Brush nobrush = new SolidBrush(Color.FromArgb(0,0,0,0)); + using (Graphics G = Graphics.FromImage(NewFrontImage)) + { + G.FillRectangle(brush, 0,0,NewFrontImage.Width,NewFrontImage.Height); + GraphicsPath path = new GraphicsPath(); + path.AddRectangle(ChosenArea); + G.SetClip(path); + G.Clear(Color.Transparent); + G.ResetClip(); + // G.FillRectangle(nobrush, ChosenArea); + + } + pbImageField.Image = NewFrontImage; + pbImageField.SizeMode = PictureBoxSizeMode.StretchImage; + pbImageField.Invalidate(); } private void SetUpEmptyInfo() From 71cf7c19c1e3f7f756b467c8456a59a6e2130dde Mon Sep 17 00:00:00 2001 From: Tim Young Date: Sun, 17 Sep 2017 18:18:22 -0500 Subject: [PATCH 25/77] Dragging works better now --- SpriteLibrary/SpriteEntryForm.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 353e7ec..53106ce 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -45,6 +45,7 @@ namespace SpriteLibrary private void LocalSetup() { pbImageField.BackgroundImageLayout = ImageLayout.Stretch; + pbImageField.BackgroundImage = new Bitmap(600, 800); MyController = new SpriteController(pbImageField); PopulateMenu(); UpdateMenu(); @@ -126,7 +127,7 @@ namespace SpriteLibrary private void UpdateHighlightBox() { - int transparency = 200; + int transparency = 50; Image NewFrontImage = new Bitmap(pbImageField.BackgroundImage.Width, pbImageField.BackgroundImage.Height); Color FillColor = Color.Green; Brush brush = new SolidBrush(Color.FromArgb(transparency, FillColor.R, FillColor.G, FillColor.B)); From caf7f8cbd21871e33a8102f8309098e46299d038 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 07:32:17 -0500 Subject: [PATCH 26/77] Add a tooltip --- SpriteLibrary/SpriteEntryForm.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 53106ce..dbf14e3 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -32,6 +32,8 @@ namespace SpriteLibrary Point DragStart = new Point(-1, -1); Rectangle ChosenArea = new Rectangle(1,1,100,100); + ToolTip myToolTip = new ToolTip(); + internal SpriteEntryForm(SpriteDatabase theDatabase, List ListToWorkOn, Size GridSize) { InitializeComponent(); @@ -47,10 +49,16 @@ namespace SpriteLibrary pbImageField.BackgroundImageLayout = ImageLayout.Stretch; pbImageField.BackgroundImage = new Bitmap(600, 800); MyController = new SpriteController(pbImageField); + + myToolTip.AutoPopDelay = 5000; + myToolTip.AutomaticDelay = 500; + PopulateMenu(); UpdateMenu(); SpriteInformationToForm(); UpdateMenu(); + + myToolTip.SetToolTip(btnNewAnimation, "Create another animation for the current sprite."); } internal List GetUpdatedList() From ee9f0465622ead63d5208f8e14777fa58bfc9bcf Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 07:41:02 -0500 Subject: [PATCH 27/77] Update a sprite-info from another sprite-info --- SpriteLibrary/SpriteInfo.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index 1e3754a..75fe6bd 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -49,6 +49,22 @@ namespace SpriteLibrary return SpriteDatabase.CloneByXMLSerializing(this); } + /// + /// Update the current SpriteInfo class such that it is identical to the class you are copying from. + /// + /// A spriteInfo class + public void CopyFrom(SpriteInfo toCopyFrom) + { + if (toCopyFrom == null) return; + SpriteName = toCopyFrom.SpriteName; + ViewPercent = toCopyFrom.ViewPercent; + Animations.Clear(); + foreach(AnimationInfo AI in toCopyFrom.Animations) + { + Animations.Add(AI.Clone()); + } + } + public Sprite CreateSprite(SpriteController ControllerToUse, SpriteDatabase TheDatabaseToUse) { Sprite DestSprite = null; From 795a4c6ce7e907e6a463961f001d103aefd711d7 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 07:47:58 -0500 Subject: [PATCH 28/77] forward/back buttons working & initial "save" --- SpriteLibrary/SpriteEntryForm.Designer.cs | 3 +++ SpriteLibrary/SpriteEntryForm.cs | 32 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index b800d54..80d9a88 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -171,6 +171,7 @@ this.btnApply.TabIndex = 10; this.btnApply.Text = "Apply"; this.btnApply.UseVisualStyleBackColor = true; + this.btnApply.Click += new System.EventHandler(this.btnApply_Click); // // btnNewSprite // @@ -222,6 +223,7 @@ this.btnBack.TabIndex = 16; this.btnBack.Text = "<"; this.btnBack.UseVisualStyleBackColor = true; + this.btnBack.Click += new System.EventHandler(this.btnBack_Click); // // btnFwd // @@ -232,6 +234,7 @@ this.btnFwd.TabIndex = 17; this.btnFwd.Text = ">"; this.btnFwd.UseVisualStyleBackColor = true; + this.btnFwd.Click += new System.EventHandler(this.btnFwd_Click); // // lblCountSprites // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index dbf14e3..8810bc7 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -280,5 +280,37 @@ namespace SpriteLibrary WeAreDragging = false; } + + private void btnApply_Click(object sender, EventArgs e) + { + if(CurrentSIIndex >0 && CurrentSIIndex < SpriteInformation.Count) + { + SpriteInformation[CurrentSIIndex].CopyFrom(TempInformation); + } + else + { + SpriteInformation.Add(TempInformation); + CurrentSIIndex = SpriteInformation.IndexOf(TempInformation); + } + UpdateMenu(); + } + + private void btnFwd_Click(object sender, EventArgs e) + { + if (SpriteInformation.Count == 0) return; //nothing to do + CurrentSIIndex++; + if (CurrentSIIndex >= SpriteInformation.Count) CurrentSIIndex = 0; + SpriteInformationToForm(); + UpdateMenu(); + } + + private void btnBack_Click(object sender, EventArgs e) + { + if (SpriteInformation.Count == 0) return; //nothing to do + CurrentSIIndex--; + if (CurrentSIIndex < 0) CurrentSIIndex = SpriteInformation.Count - 1; + SpriteInformationToForm(); + UpdateMenu(); + } } } From 8e502e3b1ee0bb4a1825d66de8d9a9ee5c4d5e9c Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 07:55:52 -0500 Subject: [PATCH 29/77] finish save by pulling info from form to the sprite information record --- SpriteLibrary/SpriteEntryForm.cs | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 8810bc7..f2e6cde 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -222,6 +222,44 @@ namespace SpriteLibrary } } + /// + /// Take the values stored in TempInformation and push it out to our form + /// + private void FormToSpriteInformation() + { + if (TempInformation == null) return; + //For the main sprite information + + TempInformation.SpriteName = tbSpriteName.Text; + int.TryParse(tbDefaultSize.Text, out TempInformation.ViewPercent); + + //From the current animation + AnimationInfo AI = null; + if (CurrentSIAnimation < 0) CurrentSIAnimation = 0; + if (CurrentSIAnimation >= TempInformation.Animations.Count) CurrentSIAnimation = TempInformation.Animations.Count - 1; + if (CurrentSIAnimation < TempInformation.Animations.Count) + { + AI = TempInformation.Animations[CurrentSIAnimation]; + + int.TryParse(tbAmimationSpeed.Text, out AI.AnimSpeed); + AI.ImageName = cbStartingImage.Text; + + AI.MirrorHorizontally = cbMirrorH.Checked; + AI.MirrorVertically = cbMirrorV.Checked; + + int.TryParse(cbAnimation.Text, out AI.AnimationToUse); + int.TryParse(tbNumFrames.Text, out AI.NumFrames); + + AI.StartPoint = ChosenArea.Location; + AI.Width = ChosenArea.Width; + AI.Height = ChosenArea.Height; + + if (rbFromImage.Checked) AI.FieldsToUse = AnimationType.SpriteDefinition; + if (rbMirror.Checked) AI.FieldsToUse = AnimationType.Mirror; + if (rbRotation.Checked) AI.FieldsToUse = AnimationType.Rotation; + } + } + /// /// Given two locations that we have clicked on, find the area we have selected /// @@ -283,6 +321,7 @@ namespace SpriteLibrary private void btnApply_Click(object sender, EventArgs e) { + FormToSpriteInformation(); if(CurrentSIIndex >0 && CurrentSIIndex < SpriteInformation.Count) { SpriteInformation[CurrentSIIndex].CopyFrom(TempInformation); From 273c381389771ca9442fee7e5bd766e9567c37e2 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 08:40:18 -0500 Subject: [PATCH 30/77] Debug Item entry and forward / back buttons --- SpriteLibrary/SpriteEntryForm.cs | 5 +++++ SpriteLibrary/SpriteInfo.cs | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index f2e6cde..52948a9 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -328,6 +328,7 @@ namespace SpriteLibrary } else { + string Try = SpriteDatabase.WriteToXMLString(TempInformation); SpriteInformation.Add(TempInformation); CurrentSIIndex = SpriteInformation.IndexOf(TempInformation); } @@ -339,6 +340,8 @@ namespace SpriteLibrary if (SpriteInformation.Count == 0) return; //nothing to do CurrentSIIndex++; if (CurrentSIIndex >= SpriteInformation.Count) CurrentSIIndex = 0; + if (TempInformation == null) TempInformation = new SpriteInfo(); + TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); SpriteInformationToForm(); UpdateMenu(); } @@ -348,6 +351,8 @@ namespace SpriteLibrary if (SpriteInformation.Count == 0) return; //nothing to do CurrentSIIndex--; if (CurrentSIIndex < 0) CurrentSIIndex = SpriteInformation.Count - 1; + if (TempInformation == null) TempInformation = new SpriteInfo(); + TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); SpriteInformationToForm(); UpdateMenu(); } diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index 75fe6bd..feceb6d 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -9,8 +9,8 @@ using System.Resources; namespace SpriteLibrary { - internal enum AnimationType { SpriteDefinition=0, Rotation=1, Mirror=2 } - internal class AnimationInfo + public enum AnimationType { SpriteDefinition=0, Rotation=1, Mirror=2 } + public class AnimationInfo { public AnimationType FieldsToUse = AnimationType.SpriteDefinition; public int AnimationToUse = 0; @@ -36,9 +36,9 @@ namespace SpriteLibrary public class SpriteInfo { - internal string SpriteName = ""; - internal int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size - internal List Animations = new List(); + public string SpriteName = ""; + public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + public List Animations = new List(); /// /// A generic cloning method that works when everything is public From fac246187526b4c0359ad7612df96d3af8e9a67f Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 10:31:47 -0500 Subject: [PATCH 31/77] Fixed some bugs with forward/back and applying new sprites. --- SpriteLibrary/SpriteEntryForm.Designer.cs | 7 ++-- SpriteLibrary/SpriteEntryForm.cs | 41 ++++++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 80d9a88..1d094af 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -181,6 +181,7 @@ this.btnNewSprite.TabIndex = 11; this.btnNewSprite.Text = "New Sprite"; this.btnNewSprite.UseVisualStyleBackColor = true; + this.btnNewSprite.Click += new System.EventHandler(this.btnNewSprite_Click); // // tbAmimationSpeed // @@ -217,7 +218,7 @@ // btnBack // this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnBack.Location = new System.Drawing.Point(49, 322); + this.btnBack.Location = new System.Drawing.Point(25, 322); this.btnBack.Name = "btnBack"; this.btnBack.Size = new System.Drawing.Size(29, 23); this.btnBack.TabIndex = 16; @@ -228,7 +229,7 @@ // btnFwd // this.btnFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnFwd.Location = new System.Drawing.Point(131, 322); + this.btnFwd.Location = new System.Drawing.Point(177, 322); this.btnFwd.Name = "btnFwd"; this.btnFwd.Size = new System.Drawing.Size(29, 23); this.btnFwd.TabIndex = 17; @@ -240,7 +241,7 @@ // this.lblCountSprites.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.lblCountSprites.AutoSize = true; - this.lblCountSprites.Location = new System.Drawing.Point(95, 325); + this.lblCountSprites.Location = new System.Drawing.Point(75, 325); this.lblCountSprites.Name = "lblCountSprites"; this.lblCountSprites.Size = new System.Drawing.Size(16, 17); this.lblCountSprites.TabIndex = 18; diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 52948a9..26452a3 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -42,6 +42,10 @@ namespace SpriteLibrary SnapGridSize = GridSize; LocalSetup(); SpriteInformation.AddRange(ListToWorkOn); + if (SpriteInformation.Count > 0) + { + SelectNewIndex(0); + } } private void LocalSetup() @@ -93,7 +97,7 @@ namespace SpriteLibrary private void UpdateMenu() { SuspendLayout(); - lblCountSprites.Text = SpriteInformation.Count.ToString(); + lblCountSprites.Text = CurrentSIIndex+":"+CurrentSIAnimation+" of " + SpriteInformation.Count.ToString(); if (TempInformation == null) SetUpEmptyInfo(); //Put in numbers into the combo-box of which frame to base ourselves off of @@ -186,7 +190,7 @@ namespace SpriteLibrary pbImageField.BackgroundImage = new Bitmap(NewImage); pbImageField.Invalidate(); } - } + } } /// @@ -328,22 +332,35 @@ namespace SpriteLibrary } else { - string Try = SpriteDatabase.WriteToXMLString(TempInformation); - SpriteInformation.Add(TempInformation); + SpriteInformation.Add(TempInformation.Clone()); CurrentSIIndex = SpriteInformation.IndexOf(TempInformation); } UpdateMenu(); } + private void WeHaveNewItem() + { + TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); + SpriteInformationToForm(); + UpdateMenu(); + } + private void SelectNewIndex(int nindex) + { + if (nindex < 0) return; + if (nindex >= SpriteInformation.Count) return; + CurrentSIIndex = nindex; + TempInformation = SpriteInformation[nindex].Clone(); + WeHaveNewItem(); + UpdateMenu(); + } + private void btnFwd_Click(object sender, EventArgs e) { if (SpriteInformation.Count == 0) return; //nothing to do CurrentSIIndex++; if (CurrentSIIndex >= SpriteInformation.Count) CurrentSIIndex = 0; if (TempInformation == null) TempInformation = new SpriteInfo(); - TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); - SpriteInformationToForm(); - UpdateMenu(); + WeHaveNewItem(); } private void btnBack_Click(object sender, EventArgs e) @@ -352,7 +369,15 @@ namespace SpriteLibrary CurrentSIIndex--; if (CurrentSIIndex < 0) CurrentSIIndex = SpriteInformation.Count - 1; if (TempInformation == null) TempInformation = new SpriteInfo(); - TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); + WeHaveNewItem(); + } + + private void btnNewSprite_Click(object sender, EventArgs e) + { + TempInformation = null; + CurrentSIIndex = -1; + + SetUpEmptyInfo(); SpriteInformationToForm(); UpdateMenu(); } From 2e5bf62fb13bd219b925dae02168cb96246dd797 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 10:33:34 -0500 Subject: [PATCH 32/77] Able to add a new animation. --- SpriteLibrary/SpriteEntryForm.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 26452a3..65b1721 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -209,6 +209,8 @@ namespace SpriteLibrary if (CurrentSIAnimation >= TempInformation.Animations.Count) CurrentSIAnimation = TempInformation.Animations.Count -1; if (CurrentSIAnimation < TempInformation.Animations.Count) { + if (CurrentSIAnimation >= TempInformation.Animations.Count) + TempInformation.Animations.Add(new AnimationInfo()); AI = TempInformation.Animations[CurrentSIAnimation]; tbAmimationSpeed.Text = AI.AnimSpeed.ToString(); cbStartingImage.Text = AI.ImageName; From 4ce60ad42231dbfc7bd65a290aa3d3ea081e558f Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 11:18:26 -0500 Subject: [PATCH 33/77] Get new animation working --- SpriteLibrary/SpriteEntryForm.Designer.cs | 1 + SpriteLibrary/SpriteEntryForm.cs | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 1d094af..b8cb5dc 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -392,6 +392,7 @@ this.btnNewAnimation.TabIndex = 21; this.btnNewAnimation.Text = "New Anim"; this.btnNewAnimation.UseVisualStyleBackColor = true; + this.btnNewAnimation.Click += new System.EventHandler(this.btnNewAnimation_Click); // // pbPreview // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 65b1721..21df9cc 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -325,10 +325,10 @@ namespace SpriteLibrary } - private void btnApply_Click(object sender, EventArgs e) + void ApplyChanges() { FormToSpriteInformation(); - if(CurrentSIIndex >0 && CurrentSIIndex < SpriteInformation.Count) + if (CurrentSIIndex > 0 && CurrentSIIndex < SpriteInformation.Count) { SpriteInformation[CurrentSIIndex].CopyFrom(TempInformation); } @@ -340,6 +340,11 @@ namespace SpriteLibrary UpdateMenu(); } + private void btnApply_Click(object sender, EventArgs e) + { + ApplyChanges(); + } + private void WeHaveNewItem() { TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); @@ -383,5 +388,15 @@ namespace SpriteLibrary SpriteInformationToForm(); UpdateMenu(); } + + private void btnNewAnimation_Click(object sender, EventArgs e) + { + ApplyChanges(); + AnimationInfo AI = TempInformation.Animations[CurrentSIAnimation].Clone(); + TempInformation.Animations.Add(AI); + CurrentSIAnimation++; + SpriteInformationToForm(); + UpdateMenu(); + } } } From 86d956365e1068ee1520cf94caa236a6400a019c Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 14:08:06 -0500 Subject: [PATCH 34/77] some documentation --- SpriteLibrary/SpriteDatabase.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 361d22e..2b31726 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -18,16 +18,33 @@ namespace SpriteLibrary } /// - /// Store of all the types of things in the ADVDemo + /// Store Sprite information in a database. You can preload your database with sprite definitions, and then + /// create the sprites as needed. This can drastically reduce the initial load time of a game or something. + /// Though, what it really does is spread out the load time. It still takes the same amount of time to + /// load all the sprites, it just loads them on-demand. Using a dictionary often hides any load time issues. /// public class SpriteDatabase { + /// + /// This is the list of SpriteInfo records that the database knows about. You can create your own list, + /// modify this list, or whatever. The database has some reasonable functions for loading and saving a + /// sprite database. + /// public List SpriteInfoList = new List(); List TheImages = new List(); ResourceManager myResourceManager = null; string Filename = ""; Size SnapGridSize = new Size(5, 5); + /// + /// The sprite database instantiation function. The filename can either be a file on the computer or it + /// can be the string name of a resource (the filename without the extension. If your file is accessed + /// by Properties.Resources.MySprites, the "filename" would be "MySprites") + /// + /// The ResourceManager for your project. Usually + /// Properties.Resources.ResourceManager + /// Either a path and file (like: @"c:\users\me\Desktop\myfile.xml") or + /// the name of a resource (like: "myfile") public SpriteDatabase(ResourceManager theResourceManager, string filename) { myResourceManager = theResourceManager; From e74de637eb150e8deb46b456d5e0aa6b9c75b0ef Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 15:29:00 -0500 Subject: [PATCH 35/77] Add animation fwd/back buttons --- SpriteLibrary/SpriteEntryForm.Designer.cs | 62 ++++++++++++++++++++--- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index b8cb5dc..f4ad359 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -63,6 +63,10 @@ this.btnNewAnimation = new System.Windows.Forms.Button(); this.pbPreview = new System.Windows.Forms.PictureBox(); this.btnPreview = new System.Windows.Forms.Button(); + this.btnReset = new System.Windows.Forms.Button(); + this.btnAnimFwd = new System.Windows.Forms.Button(); + this.btnAnimBack = new System.Windows.Forms.Button(); + this.lblAnimationFwdBack = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); this.TCTabPages.SuspendLayout(); this.tpFromImage.SuspendLayout(); @@ -106,7 +110,7 @@ // lblChosenArea // this.lblChosenArea.AutoSize = true; - this.lblChosenArea.Location = new System.Drawing.Point(129, 44); + this.lblChosenArea.Location = new System.Drawing.Point(125, 33); this.lblChosenArea.Name = "lblChosenArea"; this.lblChosenArea.Size = new System.Drawing.Size(86, 17); this.lblChosenArea.TabIndex = 3; @@ -114,7 +118,7 @@ // // tbNumFrames // - this.tbNumFrames.Location = new System.Drawing.Point(128, 75); + this.tbNumFrames.Location = new System.Drawing.Point(128, 53); this.tbNumFrames.Name = "tbNumFrames"; this.tbNumFrames.Size = new System.Drawing.Size(47, 22); this.tbNumFrames.TabIndex = 4; @@ -122,7 +126,7 @@ // lblFrames // this.lblFrames.AutoSize = true; - this.lblFrames.Location = new System.Drawing.Point(67, 75); + this.lblFrames.Location = new System.Drawing.Point(69, 53); this.lblFrames.Name = "lblFrames"; this.lblFrames.Size = new System.Drawing.Size(55, 17); this.lblFrames.TabIndex = 5; @@ -218,9 +222,9 @@ // btnBack // this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnBack.Location = new System.Drawing.Point(25, 322); + this.btnBack.Location = new System.Drawing.Point(12, 322); this.btnBack.Name = "btnBack"; - this.btnBack.Size = new System.Drawing.Size(29, 23); + this.btnBack.Size = new System.Drawing.Size(32, 23); this.btnBack.TabIndex = 16; this.btnBack.Text = "<"; this.btnBack.UseVisualStyleBackColor = true; @@ -231,7 +235,7 @@ this.btnFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnFwd.Location = new System.Drawing.Point(177, 322); this.btnFwd.Name = "btnFwd"; - this.btnFwd.Size = new System.Drawing.Size(29, 23); + this.btnFwd.Size = new System.Drawing.Size(32, 23); this.btnFwd.TabIndex = 17; this.btnFwd.Text = ">"; this.btnFwd.UseVisualStyleBackColor = true; @@ -259,6 +263,9 @@ // // tpFromImage // + this.tpFromImage.Controls.Add(this.lblAnimationFwdBack); + this.tpFromImage.Controls.Add(this.btnAnimBack); + this.tpFromImage.Controls.Add(this.btnAnimFwd); this.tpFromImage.Controls.Add(this.cbStartingImage); this.tpFromImage.Controls.Add(this.lblStartingImage); this.tpFromImage.Controls.Add(this.lblChosenArea); @@ -411,6 +418,44 @@ this.btnPreview.Text = "Preview"; this.btnPreview.UseVisualStyleBackColor = true; // + // btnReset + // + this.btnReset.Location = new System.Drawing.Point(426, 280); + this.btnReset.Name = "btnReset"; + this.btnReset.Size = new System.Drawing.Size(75, 23); + this.btnReset.TabIndex = 24; + this.btnReset.Text = "Reset"; + this.btnReset.UseVisualStyleBackColor = true; + // + // btnAnimFwd + // + this.btnAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAnimFwd.Location = new System.Drawing.Point(227, 85); + this.btnAnimFwd.Name = "btnAnimFwd"; + this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); + this.btnAnimFwd.TabIndex = 18; + this.btnAnimFwd.Text = ">"; + this.btnAnimFwd.UseVisualStyleBackColor = true; + // + // btnAnimBack + // + this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAnimBack.Location = new System.Drawing.Point(189, 85); + this.btnAnimBack.Name = "btnAnimBack"; + this.btnAnimBack.Size = new System.Drawing.Size(32, 23); + this.btnAnimBack.TabIndex = 19; + this.btnAnimBack.Text = "<"; + this.btnAnimBack.UseVisualStyleBackColor = true; + // + // lblAnimationFwdBack + // + this.lblAnimationFwdBack.AutoSize = true; + this.lblAnimationFwdBack.Location = new System.Drawing.Point(109, 88); + this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; + this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); + this.lblAnimationFwdBack.TabIndex = 20; + this.lblAnimationFwdBack.Text = "Animation:"; + // // SpriteEntryForm // this.AcceptButton = this.btnApply; @@ -418,6 +463,7 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; this.ClientSize = new System.Drawing.Size(614, 347); + this.Controls.Add(this.btnReset); this.Controls.Add(this.btnPreview); this.Controls.Add(this.pbPreview); this.Controls.Add(this.btnNewAnimation); @@ -494,5 +540,9 @@ private System.Windows.Forms.TextBox tbRotation; private System.Windows.Forms.Label lblWhichAnim; private System.Windows.Forms.ComboBox cbAnimation; + private System.Windows.Forms.Label lblAnimationFwdBack; + private System.Windows.Forms.Button btnAnimBack; + private System.Windows.Forms.Button btnAnimFwd; + private System.Windows.Forms.Button btnReset; } } \ No newline at end of file From c0d1d1599df07aa51bf4e751e84373888c9baed0 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 18 Sep 2017 15:34:30 -0500 Subject: [PATCH 36/77] Get anim fwd/backw working --- SpriteLibrary/SpriteEntryForm.Designer.cs | 2 ++ SpriteLibrary/SpriteEntryForm.cs | 35 ++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index f4ad359..3bbc4a1 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -436,6 +436,7 @@ this.btnAnimFwd.TabIndex = 18; this.btnAnimFwd.Text = ">"; this.btnAnimFwd.UseVisualStyleBackColor = true; + this.btnAnimFwd.Click += new System.EventHandler(this.btnAnimFwd_Click); // // btnAnimBack // @@ -446,6 +447,7 @@ this.btnAnimBack.TabIndex = 19; this.btnAnimBack.Text = "<"; this.btnAnimBack.UseVisualStyleBackColor = true; + this.btnAnimBack.Click += new System.EventHandler(this.btnAnimBack_Click); // // lblAnimationFwdBack // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 21df9cc..dd18a0e 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -113,7 +113,17 @@ namespace SpriteLibrary } else panelRadioButtons.Visible = true; - if(rbFromImage.Checked) + if(TempInformation.Animations.Count >1) + { + btnAnimBack.Enabled = true; + btnAnimFwd.Enabled = true; + } + else + { + btnAnimBack.Enabled = false; + btnAnimFwd.Enabled = false; + } + if (rbFromImage.Checked) { if(!TCTabPages.TabPages.Contains(tpFromImage)) TCTabPages.TabPages.Add(tpFromImage); @@ -398,5 +408,28 @@ namespace SpriteLibrary SpriteInformationToForm(); UpdateMenu(); } + + private void btnAnimBack_Click(object sender, EventArgs e) + { + ApplyChanges(); + CurrentSIAnimation--; + if (CurrentSIAnimation < 0) + CurrentSIAnimation = TempInformation.Animations.Count - 1; + + SpriteInformationToForm(); + UpdateMenu(); + } + + private void btnAnimFwd_Click(object sender, EventArgs e) + { + ApplyChanges(); + CurrentSIAnimation++; + if (CurrentSIAnimation >=TempInformation.Animations.Count) + CurrentSIAnimation = 0; + + SpriteInformationToForm(); + UpdateMenu(); + + } } } From 8067b91759644aa9f3c4ecf4ddd2c3c6d9bc6be3 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 08:35:00 -0500 Subject: [PATCH 37/77] Add preview animation fwd/back buttons --- SpriteLibrary/SpriteEntryForm.Designer.cs | 92 +++++++++++++++-------- SpriteLibrary/SpriteEntryForm.cs | 21 ++++++ 2 files changed, 81 insertions(+), 32 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 3bbc4a1..526e9d6 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -49,6 +49,9 @@ this.lblCountSprites = new System.Windows.Forms.Label(); this.TCTabPages = new System.Windows.Forms.TabControl(); this.tpFromImage = new System.Windows.Forms.TabPage(); + this.lblAnimationFwdBack = new System.Windows.Forms.Label(); + this.btnAnimBack = new System.Windows.Forms.Button(); + this.btnAnimFwd = new System.Windows.Forms.Button(); this.tpMirrorRotate = new System.Windows.Forms.TabPage(); this.cbMirrorH = new System.Windows.Forms.CheckBox(); this.cbMirrorV = new System.Windows.Forms.CheckBox(); @@ -64,9 +67,8 @@ this.pbPreview = new System.Windows.Forms.PictureBox(); this.btnPreview = new System.Windows.Forms.Button(); this.btnReset = new System.Windows.Forms.Button(); - this.btnAnimFwd = new System.Windows.Forms.Button(); - this.btnAnimBack = new System.Windows.Forms.Button(); - this.lblAnimationFwdBack = new System.Windows.Forms.Label(); + this.btnPreviewAnimFwd = new System.Windows.Forms.Button(); + this.btnPreviewAnimBack = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); this.TCTabPages.SuspendLayout(); this.tpFromImage.SuspendLayout(); @@ -279,6 +281,37 @@ this.tpFromImage.Text = "From Image"; this.tpFromImage.UseVisualStyleBackColor = true; // + // lblAnimationFwdBack + // + this.lblAnimationFwdBack.AutoSize = true; + this.lblAnimationFwdBack.Location = new System.Drawing.Point(109, 88); + this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; + this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); + this.lblAnimationFwdBack.TabIndex = 20; + this.lblAnimationFwdBack.Text = "Animation:"; + // + // btnAnimBack + // + this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAnimBack.Location = new System.Drawing.Point(189, 85); + this.btnAnimBack.Name = "btnAnimBack"; + this.btnAnimBack.Size = new System.Drawing.Size(32, 23); + this.btnAnimBack.TabIndex = 19; + this.btnAnimBack.Text = "<"; + this.btnAnimBack.UseVisualStyleBackColor = true; + this.btnAnimBack.Click += new System.EventHandler(this.btnAnimBack_Click); + // + // btnAnimFwd + // + this.btnAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAnimFwd.Location = new System.Drawing.Point(227, 85); + this.btnAnimFwd.Name = "btnAnimFwd"; + this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); + this.btnAnimFwd.TabIndex = 18; + this.btnAnimFwd.Text = ">"; + this.btnAnimFwd.UseVisualStyleBackColor = true; + this.btnAnimFwd.Click += new System.EventHandler(this.btnAnimFwd_Click); + // // tpMirrorRotate // this.tpMirrorRotate.Controls.Add(this.cbMirrorH); @@ -403,20 +436,22 @@ // // pbPreview // + this.pbPreview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbPreview.Location = new System.Drawing.Point(512, 31); this.pbPreview.Name = "pbPreview"; - this.pbPreview.Size = new System.Drawing.Size(91, 77); + this.pbPreview.Size = new System.Drawing.Size(91, 89); this.pbPreview.TabIndex = 22; this.pbPreview.TabStop = false; // // btnPreview // - this.btnPreview.Location = new System.Drawing.Point(527, 114); + this.btnPreview.Location = new System.Drawing.Point(518, 126); this.btnPreview.Name = "btnPreview"; this.btnPreview.Size = new System.Drawing.Size(75, 23); this.btnPreview.TabIndex = 23; this.btnPreview.Text = "Preview"; this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); // // btnReset // @@ -427,36 +462,25 @@ this.btnReset.Text = "Reset"; this.btnReset.UseVisualStyleBackColor = true; // - // btnAnimFwd + // btnPreviewAnimFwd // - this.btnAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimFwd.Location = new System.Drawing.Point(227, 85); - this.btnAnimFwd.Name = "btnAnimFwd"; - this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); - this.btnAnimFwd.TabIndex = 18; - this.btnAnimFwd.Text = ">"; - this.btnAnimFwd.UseVisualStyleBackColor = true; - this.btnAnimFwd.Click += new System.EventHandler(this.btnAnimFwd_Click); + this.btnPreviewAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnPreviewAnimFwd.Location = new System.Drawing.Point(561, 155); + this.btnPreviewAnimFwd.Name = "btnPreviewAnimFwd"; + this.btnPreviewAnimFwd.Size = new System.Drawing.Size(32, 23); + this.btnPreviewAnimFwd.TabIndex = 25; + this.btnPreviewAnimFwd.Text = ">"; + this.btnPreviewAnimFwd.UseVisualStyleBackColor = true; // - // btnAnimBack + // btnPreviewAnimBack // - this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimBack.Location = new System.Drawing.Point(189, 85); - this.btnAnimBack.Name = "btnAnimBack"; - this.btnAnimBack.Size = new System.Drawing.Size(32, 23); - this.btnAnimBack.TabIndex = 19; - this.btnAnimBack.Text = "<"; - this.btnAnimBack.UseVisualStyleBackColor = true; - this.btnAnimBack.Click += new System.EventHandler(this.btnAnimBack_Click); - // - // lblAnimationFwdBack - // - this.lblAnimationFwdBack.AutoSize = true; - this.lblAnimationFwdBack.Location = new System.Drawing.Point(109, 88); - this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; - this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); - this.lblAnimationFwdBack.TabIndex = 20; - this.lblAnimationFwdBack.Text = "Animation:"; + this.btnPreviewAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnPreviewAnimBack.Location = new System.Drawing.Point(518, 155); + this.btnPreviewAnimBack.Name = "btnPreviewAnimBack"; + this.btnPreviewAnimBack.Size = new System.Drawing.Size(32, 23); + this.btnPreviewAnimBack.TabIndex = 26; + this.btnPreviewAnimBack.Text = "<"; + this.btnPreviewAnimBack.UseVisualStyleBackColor = true; // // SpriteEntryForm // @@ -465,6 +489,8 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; this.ClientSize = new System.Drawing.Size(614, 347); + this.Controls.Add(this.btnPreviewAnimBack); + this.Controls.Add(this.btnPreviewAnimFwd); this.Controls.Add(this.btnReset); this.Controls.Add(this.btnPreview); this.Controls.Add(this.pbPreview); @@ -546,5 +572,7 @@ private System.Windows.Forms.Button btnAnimBack; private System.Windows.Forms.Button btnAnimFwd; private System.Windows.Forms.Button btnReset; + private System.Windows.Forms.Button btnPreviewAnimFwd; + private System.Windows.Forms.Button btnPreviewAnimBack; } } \ No newline at end of file diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index dd18a0e..9e21c1c 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -20,6 +20,8 @@ namespace SpriteLibrary internal partial class SpriteEntryForm : Form { SpriteController MyController; + SpriteController PreviewController; + ResourceManager myResources = null; List SpriteInformation = new List(); SpriteInfo TempInformation = null; @@ -34,6 +36,8 @@ namespace SpriteLibrary ToolTip myToolTip = new ToolTip(); + Sprite PreviewSprite = null; + internal SpriteEntryForm(SpriteDatabase theDatabase, List ListToWorkOn, Size GridSize) { InitializeComponent(); @@ -50,10 +54,17 @@ namespace SpriteLibrary private void LocalSetup() { + //set up the controller for the image-choice window pbImageField.BackgroundImageLayout = ImageLayout.Stretch; pbImageField.BackgroundImage = new Bitmap(600, 800); MyController = new SpriteController(pbImageField); + //set up the sprite controller for the preview window + pbPreview.BackgroundImage = new Bitmap(400, 400); + Graphics.FromImage(pbPreview.BackgroundImage).Clear(Color.Gray); + pbPreview.BackgroundImageLayout = ImageLayout.Stretch; + PreviewController = new SpriteController(pbPreview); + myToolTip.AutoPopDelay = 5000; myToolTip.AutomaticDelay = 500; @@ -431,5 +442,15 @@ namespace SpriteLibrary UpdateMenu(); } + + private void btnPreview_Click(object sender, EventArgs e) + { + //remove the old one + if (PreviewSprite != null) PreviewSprite.Destroy(); + //Create a new one + PreviewSprite = TempInformation.CreateSprite(PreviewController, myDatabase); + PreviewSprite.PutBaseImageLocation(new Point(1, 1)); + //PreviewSprite.SetSize(new Size(50, 50)); + } } } From fb0771a474b47957a470c68b6e9536296365ed14 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 08:42:04 -0500 Subject: [PATCH 38/77] Preview animations fwd/back buttons working --- SpriteLibrary/SpriteEntryForm.Designer.cs | 2 ++ SpriteLibrary/SpriteEntryForm.cs | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 526e9d6..40cd52a 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -471,6 +471,7 @@ this.btnPreviewAnimFwd.TabIndex = 25; this.btnPreviewAnimFwd.Text = ">"; this.btnPreviewAnimFwd.UseVisualStyleBackColor = true; + this.btnPreviewAnimFwd.Click += new System.EventHandler(this.btnPreviewAnimFwd_Click); // // btnPreviewAnimBack // @@ -481,6 +482,7 @@ this.btnPreviewAnimBack.TabIndex = 26; this.btnPreviewAnimBack.Text = "<"; this.btnPreviewAnimBack.UseVisualStyleBackColor = true; + this.btnPreviewAnimBack.Click += new System.EventHandler(this.btnPreviewAnimBack_Click); // // SpriteEntryForm // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 9e21c1c..c958818 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -452,5 +452,27 @@ namespace SpriteLibrary PreviewSprite.PutBaseImageLocation(new Point(1, 1)); //PreviewSprite.SetSize(new Size(50, 50)); } + + private void btnPreviewAnimBack_Click(object sender, EventArgs e) + { + if(PreviewSprite != null) + { + int Animations = PreviewSprite.AnimationCount; + int NextAnim = PreviewSprite.AnimationIndex - 1; + if (NextAnim < 0) NextAnim = Animations - 1; + PreviewSprite.ChangeAnimation(NextAnim); + } + } + + private void btnPreviewAnimFwd_Click(object sender, EventArgs e) + { + if (PreviewSprite != null) + { + int Animations = PreviewSprite.AnimationCount; + int NextAnim = PreviewSprite.AnimationIndex + 1; + if (NextAnim >= Animations) NextAnim = 0; + PreviewSprite.ChangeAnimation(NextAnim); + } + } } } From 9f6412e916d4070275c2f13acfd12fb7c920025e Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 08:44:04 -0500 Subject: [PATCH 39/77] preview fw/back buttons not enabled if only one animation --- SpriteLibrary/SpriteEntryForm.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index c958818..3b14c2d 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -128,11 +128,15 @@ namespace SpriteLibrary { btnAnimBack.Enabled = true; btnAnimFwd.Enabled = true; + btnPreviewAnimBack.Enabled = true; + btnPreviewAnimFwd.Enabled = true; } else { btnAnimBack.Enabled = false; btnAnimFwd.Enabled = false; + btnPreviewAnimBack.Enabled = false; + btnPreviewAnimFwd.Enabled = false; } if (rbFromImage.Checked) { From 005c35761c4ac5a27c5569a0df16683a44366091 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 13:10:36 -0500 Subject: [PATCH 40/77] make a ValuesDifferFromData function --- SpriteLibrary/SpriteEntryForm.cs | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 3b14c2d..8f306fe 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -291,6 +291,51 @@ namespace SpriteLibrary } } + /// + /// Take the values stored in TempInformation and push it out to our form + /// + private bool ValuesDifferFromData() + { + if (TempInformation == null) return true; + //For the main sprite information + int tValue; + + if(TempInformation.SpriteName != tbSpriteName.Text) return true; + int.TryParse(tbDefaultSize.Text, out tValue); + if(tValue != TempInformation.ViewPercent)return true; + + //From the current animation + AnimationInfo AI = null; + if (CurrentSIAnimation < 0) CurrentSIAnimation = 0; + if (CurrentSIAnimation >= TempInformation.Animations.Count) CurrentSIAnimation = TempInformation.Animations.Count - 1; + if (CurrentSIAnimation < TempInformation.Animations.Count) + { + AI = TempInformation.Animations[CurrentSIAnimation]; + + int.TryParse(tbAmimationSpeed.Text, out tValue); + if (tValue != AI.AnimSpeed) return true; + if(AI.ImageName != cbStartingImage.Text) return true; + + if(AI.MirrorHorizontally != cbMirrorH.Checked) return true; + if(AI.MirrorVertically != cbMirrorV.Checked) return true; + + int.TryParse(cbAnimation.Text, out tValue); + if (tValue != AI.AnimationToUse) return true; + + int.TryParse(tbNumFrames.Text, out tValue); + if(tValue != AI.NumFrames) return true; + + if(AI.StartPoint != ChosenArea.Location) return true; + if(AI.Width != ChosenArea.Width) return true; + if(AI.Height != ChosenArea.Height) return true; + + if (rbFromImage.Checked && AI.FieldsToUse != AnimationType.SpriteDefinition) return true; + if (rbMirror.Checked && AI.FieldsToUse != AnimationType.Mirror) return true; + if (rbRotation.Checked && AI.FieldsToUse != AnimationType.Rotation) return true; + } + return false; + } + /// /// Given two locations that we have clicked on, find the area we have selected /// From 6e2661a6488967601c603b7950000da01da489b0 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 13:19:46 -0500 Subject: [PATCH 41/77] use prompt for saving when moving around --- SpriteLibrary/SpriteEntryForm.cs | 97 +++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 8f306fe..41a2827 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -410,6 +410,21 @@ namespace SpriteLibrary UpdateMenu(); } + /// + /// Prompt to apply changes. We return true if we continue, or false if we canceled out. + /// + /// + bool PromptToApplyChangesAndContinue() + { + if(ValuesDifferFromData()) + { + DialogResult Answer = MessageBox.Show("You have unsaved Changes. Would you like to save them before proceeding?","Save?",MessageBoxButtons.YesNoCancel); + if (Answer == DialogResult.Yes) ApplyChanges(); + if (Answer == DialogResult.Cancel) return false; + } + return true; + } + private void btnApply_Click(object sender, EventArgs e) { ApplyChanges(); @@ -433,63 +448,77 @@ namespace SpriteLibrary private void btnFwd_Click(object sender, EventArgs e) { - if (SpriteInformation.Count == 0) return; //nothing to do - CurrentSIIndex++; - if (CurrentSIIndex >= SpriteInformation.Count) CurrentSIIndex = 0; - if (TempInformation == null) TempInformation = new SpriteInfo(); - WeHaveNewItem(); + if (PromptToApplyChangesAndContinue()) + { + if (SpriteInformation.Count == 0) return; //nothing to do + CurrentSIIndex++; + if (CurrentSIIndex >= SpriteInformation.Count) CurrentSIIndex = 0; + if (TempInformation == null) TempInformation = new SpriteInfo(); + WeHaveNewItem(); + } } private void btnBack_Click(object sender, EventArgs e) { - if (SpriteInformation.Count == 0) return; //nothing to do - CurrentSIIndex--; - if (CurrentSIIndex < 0) CurrentSIIndex = SpriteInformation.Count - 1; - if (TempInformation == null) TempInformation = new SpriteInfo(); - WeHaveNewItem(); + if (PromptToApplyChangesAndContinue()) + { + if (SpriteInformation.Count == 0) return; //nothing to do + CurrentSIIndex--; + if (CurrentSIIndex < 0) CurrentSIIndex = SpriteInformation.Count - 1; + if (TempInformation == null) TempInformation = new SpriteInfo(); + WeHaveNewItem(); + } } private void btnNewSprite_Click(object sender, EventArgs e) { - TempInformation = null; - CurrentSIIndex = -1; + if (PromptToApplyChangesAndContinue()) + { + TempInformation = null; + CurrentSIIndex = -1; - SetUpEmptyInfo(); - SpriteInformationToForm(); - UpdateMenu(); + SetUpEmptyInfo(); + SpriteInformationToForm(); + UpdateMenu(); + } } private void btnNewAnimation_Click(object sender, EventArgs e) { - ApplyChanges(); - AnimationInfo AI = TempInformation.Animations[CurrentSIAnimation].Clone(); - TempInformation.Animations.Add(AI); - CurrentSIAnimation++; - SpriteInformationToForm(); - UpdateMenu(); + if (PromptToApplyChangesAndContinue()) + { + AnimationInfo AI = TempInformation.Animations[CurrentSIAnimation].Clone(); + TempInformation.Animations.Add(AI); + CurrentSIAnimation++; + SpriteInformationToForm(); + UpdateMenu(); + } } private void btnAnimBack_Click(object sender, EventArgs e) { - ApplyChanges(); - CurrentSIAnimation--; - if (CurrentSIAnimation < 0) - CurrentSIAnimation = TempInformation.Animations.Count - 1; + if (PromptToApplyChangesAndContinue()) + { + CurrentSIAnimation--; + if (CurrentSIAnimation < 0) + CurrentSIAnimation = TempInformation.Animations.Count - 1; - SpriteInformationToForm(); - UpdateMenu(); + SpriteInformationToForm(); + UpdateMenu(); + } } private void btnAnimFwd_Click(object sender, EventArgs e) { - ApplyChanges(); - CurrentSIAnimation++; - if (CurrentSIAnimation >=TempInformation.Animations.Count) - CurrentSIAnimation = 0; - - SpriteInformationToForm(); - UpdateMenu(); + if (PromptToApplyChangesAndContinue()) + { + CurrentSIAnimation++; + if (CurrentSIAnimation >= TempInformation.Animations.Count) + CurrentSIAnimation = 0; + SpriteInformationToForm(); + UpdateMenu(); + } } private void btnPreview_Click(object sender, EventArgs e) From 0389b3a75996c65dad27d441e598fd530444a9eb Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 13:22:25 -0500 Subject: [PATCH 42/77] destroy the sprite if we were doing a preview --- SpriteLibrary/SpriteEntryForm.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 41a2827..6f2b924 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -432,6 +432,7 @@ namespace SpriteLibrary private void WeHaveNewItem() { + if (PreviewSprite != null) PreviewSprite.Destroy(); TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); SpriteInformationToForm(); UpdateMenu(); @@ -441,7 +442,9 @@ namespace SpriteLibrary if (nindex < 0) return; if (nindex >= SpriteInformation.Count) return; CurrentSIIndex = nindex; + if (PreviewSprite != null) PreviewSprite.Destroy(); TempInformation = SpriteInformation[nindex].Clone(); + CurrentSIAnimation = 0; //always start at animation 0 WeHaveNewItem(); UpdateMenu(); } From 5fd16be79286aa130ef0c864789ce0e7e582ca38 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 14:55:58 -0500 Subject: [PATCH 43/77] Show the current animation number --- SpriteLibrary/SpriteEntryForm.Designer.cs | 16 ++++++++++++++-- SpriteLibrary/SpriteEntryForm.cs | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 40cd52a..4d2e0ec 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -69,6 +69,7 @@ this.btnReset = new System.Windows.Forms.Button(); this.btnPreviewAnimFwd = new System.Windows.Forms.Button(); this.btnPreviewAnimBack = new System.Windows.Forms.Button(); + this.lblAnimationNumber = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); this.TCTabPages.SuspendLayout(); this.tpFromImage.SuspendLayout(); @@ -265,6 +266,7 @@ // // tpFromImage // + this.tpFromImage.Controls.Add(this.lblAnimationNumber); this.tpFromImage.Controls.Add(this.lblAnimationFwdBack); this.tpFromImage.Controls.Add(this.btnAnimBack); this.tpFromImage.Controls.Add(this.btnAnimFwd); @@ -284,7 +286,7 @@ // lblAnimationFwdBack // this.lblAnimationFwdBack.AutoSize = true; - this.lblAnimationFwdBack.Location = new System.Drawing.Point(109, 88); + this.lblAnimationFwdBack.Location = new System.Drawing.Point(69, 88); this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); this.lblAnimationFwdBack.TabIndex = 20; @@ -293,7 +295,7 @@ // btnAnimBack // this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimBack.Location = new System.Drawing.Point(189, 85); + this.btnAnimBack.Location = new System.Drawing.Point(149, 85); this.btnAnimBack.Name = "btnAnimBack"; this.btnAnimBack.Size = new System.Drawing.Size(32, 23); this.btnAnimBack.TabIndex = 19; @@ -484,6 +486,15 @@ this.btnPreviewAnimBack.UseVisualStyleBackColor = true; this.btnPreviewAnimBack.Click += new System.EventHandler(this.btnPreviewAnimBack_Click); // + // lblAnimationNumber + // + this.lblAnimationNumber.AutoSize = true; + this.lblAnimationNumber.Location = new System.Drawing.Point(190, 91); + this.lblAnimationNumber.Name = "lblAnimationNumber"; + this.lblAnimationNumber.Size = new System.Drawing.Size(16, 17); + this.lblAnimationNumber.TabIndex = 21; + this.lblAnimationNumber.Text = "0"; + // // SpriteEntryForm // this.AcceptButton = this.btnApply; @@ -576,5 +587,6 @@ private System.Windows.Forms.Button btnReset; private System.Windows.Forms.Button btnPreviewAnimFwd; private System.Windows.Forms.Button btnPreviewAnimBack; + private System.Windows.Forms.Label lblAnimationNumber; } } \ No newline at end of file diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 6f2b924..21cf804 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -117,6 +117,7 @@ namespace SpriteLibrary { cbAnimation.Items.Add(i.ToString()); } + lblAnimationNumber.Text = CurrentSIAnimation.ToString(); if (CurrentSIAnimation == 0) { rbFromImage.Checked = true; From a5c9449ddafdf8841c1f9e926e40b2a412562c07 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 14:59:52 -0500 Subject: [PATCH 44/77] fix Apply. It had not been tracking the correct item number. --- SpriteLibrary/SpriteEntryForm.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 21cf804..87579d6 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -405,8 +405,9 @@ namespace SpriteLibrary } else { - SpriteInformation.Add(TempInformation.Clone()); - CurrentSIIndex = SpriteInformation.IndexOf(TempInformation); + SpriteInfo tSI = TempInformation.Clone(); + SpriteInformation.Add(tSI); + CurrentSIIndex = SpriteInformation.IndexOf(tSI); } UpdateMenu(); } From 764d969c50f251953218a34a60778f67e782cb94 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Tue, 19 Sep 2017 15:03:24 -0500 Subject: [PATCH 45/77] Add some tooltips --- SpriteLibrary/SpriteEntryForm.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 87579d6..d7ee745 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -74,6 +74,13 @@ namespace SpriteLibrary UpdateMenu(); myToolTip.SetToolTip(btnNewAnimation, "Create another animation for the current sprite."); + myToolTip.SetToolTip(btnAnimBack, "Move to previous animation within this sprite."); + myToolTip.SetToolTip(btnAnimFwd, "Move to next animation within this sprite."); + myToolTip.SetToolTip(btnBack, "Move to previous sprite."); + myToolTip.SetToolTip(btnFwd, "Move to next sprite."); + myToolTip.SetToolTip(btnPreviewAnimBack, "Change preview to previous animation."); + myToolTip.SetToolTip(btnPreviewAnimFwd, "Change preview to next animation."); + } internal List GetUpdatedList() From 03e5724a25906a93989c605a20866d7ec0c7d28c Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 08:02:47 -0500 Subject: [PATCH 46/77] documentation of public functions --- SpriteLibrary/SpriteDatabase.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index 2b31726..f0d7357 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -85,6 +85,12 @@ namespace SpriteLibrary } } + /// + /// The SnapGrid is the block-size that your sprite will be. For example, I will often have sprites with + /// a snapgrid of 50,50. This means that the sprite can be 50x50, 100x50, or anything with a step-size + /// specified in the snap-grid. It takes a "Size" specified by System.Drawing.Size. + /// + /// The size of the grid space to snap to when dragging public void SetSnapGridSize(Size GridSize) { if (GridSize.Width <= 0) return; From 03ab2781adec3a15042d5f4cac8c30bbfa4485bf Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 08:03:07 -0500 Subject: [PATCH 47/77] prompt to save if closing form and changes have been made --- SpriteLibrary/SpriteEntryForm.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index d7ee745..e6ce6fd 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -371,7 +371,14 @@ namespace SpriteLibrary private void SpriteEntryForm_FormClosing(object sender, FormClosingEventArgs e) { - myDatabase.Save(); //try saving the file + if (PromptToApplyChangesAndContinue()) + { + myDatabase.Save(); //try saving the file + } + else + { + e.Cancel = true; + } } private void pbImageField_MouseMove(object sender, MouseEventArgs e) From 42b98b65dbcda908a77b9475ddc565df5300c6ff Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 09:59:18 -0500 Subject: [PATCH 48/77] Update change log --- SpriteLibrary/Resources/ChangeLog.rtf | 382 +++++++++++++++++++++----- 1 file changed, 312 insertions(+), 70 deletions(-) diff --git a/SpriteLibrary/Resources/ChangeLog.rtf b/SpriteLibrary/Resources/ChangeLog.rtf index 62304d7..5409f32 100644 --- a/SpriteLibrary/Resources/ChangeLog.rtf +++ b/SpriteLibrary/Resources/ChangeLog.rtf @@ -1,70 +1,312 @@ -{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\fmodern\fprq1\fcharset0 Consolas;}} -{\colortbl ;\red0\green0\blue255;\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;} -{\*\generator Riched20 10.0.14393}{\*\mmathPr\mdispDef1\mwrapIndent1440 }\viewkind4\uc1 -\pard\nowidctlpar\sa200\sl276\slmult1\f0\fs22\lang9 1.0.6\par -* Fized MouseEnterTransparent, MouseLeaveTransparent\par -* Added a number more Sprite creation functions\par -* Added a number more Sprite.AddAnimation functions\par -* Allow us to set the ending frame after we animate (which frame do we display when we are done) in AnimateOnce and AnimateJustAFewTimes\par -* After a ReplaceImage, it immediately invalidates the sprite and re-draws it.\par -* Add a series of Events, Sprite.MouseOverTransparent, Sprite.MouseEnterTransparent, and Sprite.MouseLeaveTransparent. These check the transparent areas of a sprite to see if you are moving over a solid or transparent area of a sprite. For use if there is a lot of empty area inside a sprite, and you do not want to trigger a MouseEnter function over the empty region.\par -1.0.5\par -* upgraded a lot of documentation. Started the big documentation push\par - - inline documentation updated\par - - Online documentation file: {{\field{\*\fldinst{HYPERLINK http://tyounglightsys.ddns.info/SpriteLibrary/doc }}{\fldrslt{http://tyounglightsys.ddns.info/SpriteLibrary/doc\ul0\cf0}}}}\f0\fs22\par - - Start of a large documentation PDF - Will not see the light of day until 1.0.6\par -* added a SpriteIsBeingDestroyed event. That way you can have code fired off as a particular sprite is being destroyed.\par -* added three events; MouseHover, MouseEnter, and MouseLeave. When the mouse moves over a sprite for the first time, it does the MouseEnter. When we move off the sprite, it does the MouseLeave, and when we pause over the sprite, it does a MouseHover.\par -* Added sprite opacity. Sprite.opacity = .5; \par -* fixed some issues with transparency and sprites\par -* Fixed my new way to add animations. The rotation they use is opposite of what I use. So everything rotated opposite from what was expected.\par -* Added Sprite.MoveTo(Sprite) so a Sprite can target another sprite. The moving sprite will probably need to be moving a bit faster than the destination sprite if the moving sprite hopes to catch up with it.\par -* Added GetSpriteBaseImageCenter and GetSpritePictureboxCenter to find the center-point of the sprite.\par -* Added SpriteComparisonDelegate, the ability to override the sort order (display order) of sprites. The sort order affects which sprite is printed on top of the other sprites. Whichever one has the highest priority is the one that appears on top of the other ones. The default sort order is created by: \cf2\highlight3\f1\fs19\lang1033 SpriteComparisonDelegate\highlight0 = \cf1\highlight3 delegate\cf2 (\cf4 Sprite\cf2 first, \cf4 Sprite\cf2 second) \{ \cf1 return\cf2 first.Zvalue.CompareTo(second.Zvalue); \}; \highlight0\par -\f0\fs22 The sort function simply compares the Zvalue. A more complex version might be:\cf0\lang9\par - -\pard\widctlpar\cf1\highlight3\f1\fs19\lang1033 delegate\cf2 (\cf4 Sprite\cf2 first, \cf4 Sprite\cf2 second) \{\par - \cf1 if\cf2 (first.Zvalue != second.Zvalue) \cf1 return\cf2 first.Zvalue.CompareTo(second.Zvalue);\par - \cf1 if\cf2 (first.BaseImageLocation.Y != second.BaseImageLocation.Y) \cf1 return\cf2 first.BaseImageLocation.Y.CompareTo(second.BaseImageLocation.Y);\par - \cf1 return\cf2 first.BaseImageLocation.X.CompareTo(second.BaseImageLocation.X);\par - -\pard\nowidctlpar\sa200\sl276\slmult1 \};\highlight0\par -\cf0\f0\fs22\lang9 * Added another way to Add Animations. We can create an animation that is a rotation of a different animation. For example, you can have something rotated by 45 or 90 degrees.\par -* Fixed a bug with large sprites that make other things blink\par -* SpriteController.ResetKeypressState() clears any residual keypress. Sometimes the program misses keys being pressed and released. This clears any memory, and starts it from scratch.\par -1.0.4\par -* fix timing issue with start-animation. It had not been setting the animation start time.\par -* Added ability to change the animation speed of one frame. Works across all sprites. \cf2\highlight3\f1\fs19 ChangeFrameAnimationSpeed\lang1033 / GetFrameAnimationSpeed\cf0\highlight0\f0\fs22\lang9\par -* Added the ability to return the count of animations this sprite has (Sprite.AnimationCount)\par -* Added a Sprite.GetImage(animation, frame) so we can retrieve any specific image\par -* added a sprite.unhidesprite function that does the opposite of the hidesprite function.\par -* Fix the getanimationspeed func to return the real amount\par -* Add a random number generator to the sprite controller\par -*Allow a change to the tick-speed. Default is 10ms.\par -*Add a spriteController.DestroyAllSprites function\par -* Added the ability to replace a sprite frame. (Sprite.ReplaceImage)\par -* Added a \cf2\highlight3\f1\fs19 RegisterKeyDownFunction\lang1033 and RegisterKeyUpFunction, as well as the corresponding events on the keyfilter. This allows you to trigger things when a key is pressed and released.\cf0\highlight0\f0\fs22\lang9\par -* Added a function to return all the sprites that intersect with a given rectangle\par -* Added a KeysPressed function that returns a list of all the keys which are currently pressed.\par -* Repaired a glitch in playing sounds. Set the stream position back to 0 (the beginning so you can play it a second time)\par -*Repaired a small bug with the animate-once function that kept rotating the animation once it had finished.\line * Support for large sprites. SpriteController.\cf2\highlight3 OptimizeForLargeSpriteImages\lang1033 = true/false will resize the sprite and store it in its resized state. It should print the sprite faster this way than if it needs to squish or expand the sprite every time it goes to print it.\par -*Add the ability to specify the starting frame when we tell the sprite to do an animation. \cf1\f1\fs19 public\cf2 \cf1 void\cf2 ChangeAnimation(\cf1 int\cf2 WhichAnimation, \cf1\b int\cf2 StartFrame = 0\b0 )\cf0\highlight0\f0\fs22\lang9\par -1.0.3\par -* Fixed a problem in the "animate a few times" function. It basically would only animate once, regardless of how many times you told it to animate.\par -* Fixed a problem in the sound. I was itterating through a list of sounds, and the list changed. My foreach loop would break. Changed that. Thanks, Warren for pointing that out.\par -* Fixed MoveTo - Occasionally the MoveTo will break terribly. If you move the sprite to the position where it is, it will make a vector with NaN (Not a Number) and it throws the sprite off to a place waaaay long away.\par -* Fixed MoveTo - Would occasionally send the sprite off in the wrong direction for a bit. The "last movement" time was not set, so, when a direction was set, it would think it had been kept from moving for some time, and leap forward that amount of time. This resulted in the sprite suddenly being half-way across the screen in a strange location. All fixed.\par -* Fixed MoveTo(List). It works much better now. It used to get a slightly off direction (probably a rounding issue) and would not recorrect. It always missed the destination. Changed it to be self correcting.\par -* FIxed faster movement to the left than right (due to dropping of decimals instead of rounding)\par -* Added this release notes file so people can figure out what has changed since the last update.\par -1.0.2\par -* Able to change animation speed\par -* Added MoveTo\par -* Added Mirroring\par -1.0.1\par -* Minor changes (DateTime.Now -> DateTime.UtcNow)\par -* Change to Payload structure. Was "Object" now it is a class of its own: SpritePayload\par -* return sprites at point broken terribly. Would return all the named sprites which had never been displayed. Finding all the sprites in the top-left corner returned a ton of sprites that should not have been there. Now it only returns sprites that have been printed.\par -1.0.0 Initial Version\par -} - \ No newline at end of file +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;} +{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f40\fbidi \fmodern\fcharset0\fprq1{\*\panose 020b0609020204030204}Consolas;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f42\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f44\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f45\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f46\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f47\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f48\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f431\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f432\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\f434\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f435\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f436\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f437\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);} +{\f438\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f439\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\f441\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f442\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;} +{\f444\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;}{\f445\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f448\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f449\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);} +{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;} +{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);} +{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);} +{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} +{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; +\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red43\green145\blue175;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 +\ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused +Normal Table;}}{\*\rsidtbl \rsid70908\rsid3222827}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator tim.young@lightsys.org}{\creatim\yr2017\mo9\dy20\hr8\min3} +{\revtim\yr2017\mo9\dy20\hr8\min8}{\version2}{\edmins5}{\nofpages4}{\nofwords1130}{\nofchars6445}{\nofcharsws7560}{\vern91}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} +\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701 +\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale90\rsidroot3222827 \nouicompat \fet0{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 1.0.6 +\par }{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid3222827 \hich\af39\dbch\af31505\loch\f39 * \hich\af39\dbch\af31505\loch\f39 Ad\hich\af39\dbch\af31505\loch\f39 +ded linked sprite-controllers so we can share sprite definitions between controllers (decreases load time considerably) +\par \hich\af39\dbch\af31505\loch\f39 * Added a \hich\af39\dbch\af31505\loch\f39 S\hich\af39\dbch\af31505\loch\f39 prite\hich\af39\dbch\af31505\loch\f39 Database s\hich\af39\dbch\af31505\loch\f39 +ystem that can help you define, load, and save sprites. It also decreases load time. +\par \hich\af39\dbch\af31505\loch\f39 * Adde\hich\af39\dbch\af31505\loch\f39 d the SpriteDatabase \hich\af39\dbch\af31505\loch\f39 Open\hich\af39\dbch\af31505\loch\f39 EditWindow\hich\af39\dbch\af31505\loch\f39 +, which allows you to graphically define sprites. Add your sprite images to your \hich\af39\dbch\af31505\loch\f39 resources\hich\af39\dbch\af31505\loch\f39 +, and then make a function to call the OpenEditWindow function (passing it a filename). It will save the sprite definitions to the \hich\af39\dbch\af31505\loch\f39 filename. Then you can add that file to your \hich\af39\dbch\af31505\loch\f39 +resources and load that\hich\af39\dbch\af31505\loch\f39 new resource. +\par }{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 * F}{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid3222827 \hich\af39\dbch\af31505\loch\f39 ix}{\rtlch\fcs1 \af39 \ltrch\fcs0 +\f39\lang9\langfe1033\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 ed MouseEnterTransparent, MouseLeaveTransparent +\par \hich\af39\dbch\af31505\loch\f39 * Added a number more Sprite creation functions +\par \hich\af39\dbch\af31505\loch\f39 * Added a number more Sprite.AddAnimation functions +\par \hich\af39\dbch\af31505\loch\f39 * Allow us to set the ending frame after we animate (which frame do we display when we are done) in AnimateOnce and AnimateJustAFewTimes +\par \hich\af39\dbch\af31505\loch\f39 * After a ReplaceImage, it immediately invalidates the sprite and re-draws it. +\par \hich\af39\dbch\af31505\loch\f39 * Add a series of Events, Sprite.MouseOv\hich\af39\dbch\af31505\loch\f39 +erTransparent, Sprite.MouseEnterTransparent, and Sprite.MouseLeaveTransparent. These check the transparent areas of a sprite to see if you are moving over a solid or transparent area of a sprite. For use if there is a lot of empty area inside a sprite, +\hich\af39\dbch\af31505\loch\f39 a\hich\af39\dbch\af31505\loch\f39 nd you do not want to trigger a MouseEnter function over the empty region. +\par \hich\af39\dbch\af31505\loch\f39 1.0.5 +\par \hich\af39\dbch\af31505\loch\f39 * upgraded a lot of documentation. Started the big documentation push +\par \hich\af39\dbch\af31505\loch\f39 - inline documentation updated +\par \hich\af39\dbch\af31505\loch\f39 - Online documentation file: }{\field{\*\fldinst {\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 HYPERLINK http://tyounglightsys.ddns.info +\hich\af39\dbch\af31505\loch\f39 /SpriteLibrary/doc }{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid3222827 {\*\datafield +00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b7c00000068007400740070003a002f002f00740079006f0075006e0067006c0069006700680074007300790073002e00640064006e0073002e0069006e0066006f002f005300700072006900740065004c0069006200 +72006100720079002f0064006f0063000000795881f43b1d7f48af2c825dc485276300000000a5ab0003}}}{\fldrslt {\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 http://tyounglightsys.ddns.info/SpriteLibrary/doc} +}}\sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 +\par \hich\af39\dbch\af31505\loch\f39 - Start of a large documentation PDF - Will not see the light of day until 1.0.6 +\par \hich\af39\dbch\af31505\loch\f39 * added a SpriteIsBeingDestroyed event. That way you can have code fired off as a particular sprite is being destroyed. +\par \hich\af39\dbch\af31505\loch\f39 * added three events; MouseHover, MouseEnter, and MouseLeave. When the mouse moves over a sprite for the first time, it does the Mouse\hich\af39\dbch\af31505\loch\f39 +Enter. When we move off the sprite, it does the MouseLeave, and when we pause over the sprite, it does a MouseHover. +\par \hich\af39\dbch\af31505\loch\f39 * Added sprite opacity. Sprite.opacity = .5; +\par \hich\af39\dbch\af31505\loch\f39 * fixed some issues with transparency and sprites +\par \hich\af39\dbch\af31505\loch\f39 * Fixed my new way to add animations. Th\hich\af39\dbch\af31505\loch\f39 e rotation they use is opposite of what I use. So everything rotated opposite from what was expected. +\par \hich\af39\dbch\af31505\loch\f39 * Added Sprite.MoveTo(Sprite) so a Sprite can target another sprite. The moving sprite will probably need to be moving a bit faster than the destination\hich\af39\dbch\af31505\loch\f39 + sprite if the moving sprite hopes to catch up with it. +\par \hich\af39\dbch\af31505\loch\f39 * Added GetSpriteBaseImageCenter and GetSpritePictureboxCenter to find the center-point of the sprite. +\par \hich\af39\dbch\af31505\loch\f39 * Added SpriteComparisonDelegate, the ability to override the sort order (display order) of sprit\hich\af39\dbch\af31505\loch\f39 +es. The sort order affects which sprite is printed on top of the other sprites. Whichever one has the highest priority is the one that appears on top of the other ones. The default sort order is created by: }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 SpriteComparisonDelegate}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\insrsid70908 \hich\af40\dbch\af31505\loch\f40 = }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 delegate}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 (}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf17\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 Sprite}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 fi\hich\af40\dbch\af31505\loch\f40 rst, }{\rtlch\fcs1 \af40\afs19 +\ltrch\fcs0 \f40\fs19\cf17\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 Sprite}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 second) \{ }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 return}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 first.Zvalue.CompareTo(second.Zvalue); \}; }{\rtlch\fcs1 +\af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\insrsid70908 +\par }{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\cf1\insrsid70908 \hich\af39\dbch\af31505\loch\f39 The sort function simply compares the Zvalue. A more complex version might be:}{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 delegate}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 (}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf17\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 Sprite}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 first, }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf17\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 Sprite}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 second) \{ +\par \hich\af40\dbch\af31505\loch\f40 }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 if}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 +\hich\af40\dbch\af31505\loch\f40 (first.Zvalue != second.Zvalue) }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 return}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 first\hich\af40\dbch\af31505\loch\f40 .Zvalue.CompareTo(second.Zvalue); +\par \hich\af40\dbch\af31505\loch\f40 }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 if}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 +\hich\af40\dbch\af31505\loch\f40 (first.BaseImageLocation.Y != second.BaseImageLocation.Y) }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 return}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 first.BaseImageLocation.Y.CompareTo(second.BaseImageLocation.Y); +\par \hich\af40\dbch\af31505\loch\f40 }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 return}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 +\hich\af40\dbch\af31505\loch\f40 first.BaseImageLocation.X.CompareTo(second.BaseIma\hich\af40\dbch\af31505\loch\f40 geLocation.X); +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 \};}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\insrsid70908 +\par }{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 +* Added another way to Add Animations. We can create an animation that is a rotation of a different animation. For example, you can have something rotated by 45 or 90 degrees. +\par \hich\af39\dbch\af31505\loch\f39 * Fixed a bug with large sprites that make other things blink +\par \hich\af39\dbch\af31505\loch\f39 * SpriteController.ResetKeypressState() clears any residual keypress. Sometimes the program misses keys being pressed and released. This clears any memory, and starts it from scratch. +\par \hich\af39\dbch\af31505\loch\f39 1.0.4 +\par \hich\af39\dbch\af31505\loch\f39 * \hich\af39\dbch\af31505\loch\f39 fix timing issue with start-animation. It had not been setting the animation start time. +\par \hich\af39\dbch\af31505\loch\f39 * Added ability to change the animation speed of one frame. Works across all sprites. }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\lang9\langfe1033\highlight8\langnp9\insrsid70908 \hich\af40\dbch\af31505\loch\f40 +ChangeFrameAnimationSpeed}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 / GetFrameAnimationSpeed}{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 +\par \hich\af39\dbch\af31505\loch\f39 * Added the ability to retur\hich\af39\dbch\af31505\loch\f39 n the count of animations this sprite has (Sprite.AnimationCount) +\par \hich\af39\dbch\af31505\loch\f39 * Added a Sprite.GetImage(animation, frame) so we can retrieve any specific image +\par \hich\af39\dbch\af31505\loch\f39 * added a sprite.unhidesprite function that does the opposite of the hidesprite function. +\par \hich\af39\dbch\af31505\loch\f39 * Fix the getanima\hich\af39\dbch\af31505\loch\f39 tionspeed func to return the real amount +\par \hich\af39\dbch\af31505\loch\f39 * Add a random number generator to the sprite controller +\par \hich\af39\dbch\af31505\loch\f39 *Allow a change to the tick-speed. Default is 10ms. +\par \hich\af39\dbch\af31505\loch\f39 *Add a spriteController.DestroyAllSprites function +\par \hich\af39\dbch\af31505\loch\f39 * Added the ability to replace a sprite frame. (Sprit\hich\af39\dbch\af31505\loch\f39 e.ReplaceImage) +\par \hich\af39\dbch\af31505\loch\f39 * Added a }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\lang9\langfe1033\highlight8\langnp9\insrsid70908 \hich\af40\dbch\af31505\loch\f40 RegisterKeyDownFunction}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 and RegisterKeyUpFunction, as well as the corresponding events on the keyfilter. This allows you to trigger things when a key is pressed and released.}{\rtlch\fcs1 \af39 \ltrch\fcs0 +\f39\lang9\langfe1033\langnp9\insrsid70908 +\par \hich\af39\dbch\af31505\loch\f39 * Added a function to return all the sprites that inte\hich\af39\dbch\af31505\loch\f39 rsect with a given rectangle +\par \hich\af39\dbch\af31505\loch\f39 * Added a KeysPressed function that returns a list of all the keys which are currently pressed. +\par \hich\af39\dbch\af31505\loch\f39 * Repaired a glitch in playing sounds. Set the stream position back to 0 (the beginning so you can play it a second time) +\par \hich\af39\dbch\af31505\loch\f39 *Repaire\hich\af39\dbch\af31505\loch\f39 d a small bug with the animate-once function that kept rotating the animation once it had finished.\line * Support for large sprites. SpriteController.}{\rtlch\fcs1 \af39 +\ltrch\fcs0 \f39\cf1\lang9\langfe1033\highlight8\langnp9\insrsid70908 \hich\af39\dbch\af31505\loch\f39 OptimizeForLargeSpriteImages}{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\cf1\highlight8\insrsid70908 \hich\af39\dbch\af31505\loch\f39 + = true/false will resize the sprite and store it in its resized state. It shoul\hich\af39\dbch\af31505\loch\f39 d print the sprite faster this way than if it needs to squish or expand the sprite every time it goes to print it. +\par \hich\af39\dbch\af31505\loch\f39 *Add the ability to specify the starting frame when we tell the sprite to do an animation. }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 public}{\rtlch\fcs1 +\af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 }{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 void}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 ChangeAnimation(}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 int}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 +\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 WhichAnimation, }{\rtlch\fcs1 \ab\af40\afs19 \ltrch\fcs0 \b\f40\fs19\cf2\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 int}{\rtlch\fcs1 \ab\af40\afs19 \ltrch\fcs0 +\b\f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 StartFrame = 0}{\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf1\highlight8\insrsid70908 \hich\af40\dbch\af31505\loch\f40 )}{\rtlch\fcs1 \af39 \ltrch\fcs0 +\f39\lang9\langfe1033\langnp9\insrsid70908 +\par \hich\af39\dbch\af31505\loch\f39 1.0.3 +\par \hich\af39\dbch\af31505\loch\f39 * Fixed a problem in the "animate a few times" function. It basically would only animate once, regardless of how many times you told it to animate. +\par \hich\af39\dbch\af31505\loch\f39 * Fixed a problem in the sound. I was itterating through a list of sounds, and t\hich\af39\dbch\af31505\loch\f39 he list changed. My foreach loop would break. Changed that. Thanks, Warren for pointing that out. +\par \hich\af39\dbch\af31505\loch\f39 * Fixed MoveTo - Occasionally the MoveTo will break terribly. If you move the sprite to the position where it is, it will make a vector with NaN (Not a Nu\hich\af39\dbch\af31505\loch\f39 +mber) and it throws the sprite off to a place waaaay long away. +\par \hich\af39\dbch\af31505\loch\f39 * Fixed MoveTo - Would occasionally send the sprite off in the wrong direction for a bit. The "last movement" time was not set, so, when a direction was set, it would think it had been kept f +\hich\af39\dbch\af31505\loch\f39 rom moving for some time, and leap forward that amount of time. This resulted in the sprite suddenly being half-way across the screen in a strange location. All fixed. +\par \hich\af39\dbch\af31505\loch\f39 * Fixed MoveTo(List). It works much better now. It used to get a slightly off\hich\af39\dbch\af31505\loch\f39 + direction (probably a rounding issue) and would not recorrect. It always missed the destination. Changed it to be self correcting. +\par \hich\af39\dbch\af31505\loch\f39 * FIxed faster movement to the left than right (due to dropping of decimals instead of rounding) +\par \hich\af39\dbch\af31505\loch\f39 * Added this release note\hich\af39\dbch\af31505\loch\f39 s file so people can figure out what has changed since the last update. +\par \hich\af39\dbch\af31505\loch\f39 1.0.2 +\par \hich\af39\dbch\af31505\loch\f39 * Able to change animation speed +\par \hich\af39\dbch\af31505\loch\f39 * Added MoveTo +\par \hich\af39\dbch\af31505\loch\f39 * Added Mirroring +\par \hich\af39\dbch\af31505\loch\f39 1.0.1 +\par \hich\af39\dbch\af31505\loch\f39 * Minor changes (DateTime.Now -> DateTime.UtcNow) +\par \hich\af39\dbch\af31505\loch\f39 * Change to Payload structure. Was "Object" now it is a class of its own: SpritePayload +\par \hich\af39\dbch\af31505\loch\f39 * return sprites at point broken terribly. Would return all the named sprites which had never been displayed. Finding all the sprites in the top-left corner returned\hich\af39\dbch\af31505\loch\f39 + a ton of sprites that should not have been there. Now it only returns sprites that have been printed. +\par \hich\af39\dbch\af31505\loch\f39 1.0.0 Initial Version}{\rtlch\fcs1 \af39 \ltrch\fcs0 \f39\lang9\langfe1033\langnp9\insrsid70908 +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210007b740aaca0600008f1a0000160000007468656d652f7468656d652f +7468656d65312e786d6cec595b8bdb46147e2ff43f08bd3bbe49be2cf1065bb69336bb49889d943cceda636bb2238dd18c776342a0244f7d2914d2d28706fad6 +87521a68a0a12ffd310b1bdaf447f4cc489667ec71f6420aa1640d8b34face996fce39face48ba7aed51449d239c70c2e2965bbe52721d1c8fd898c4d3967b6f +d82f345c870b148f1165316eb90bccdd6bbb9f7e7215ed881047d801fb98efa0961b0a31db2916f9088611bfc26638866b13964448c069322d8e13740c7e235a +ac944ab5628448ec3a318ac0ededc9848cb033942edddda5f31e85d358703930a2c940bac68685c28e0fcb12c1173ca089738468cb8579c6ec78881f09d7a188 +0bb8d0724beacf2dee5e2da29dcc888a2db69a5d5ffd657699c1f8b0a2e64ca607f9a49ee77bb576ee5f01a8d8c4f5eabd5aaf96fb5300341ac14a532eba4fbf +d3ec74fd0cab81d2438bef6ebd5b2d1b78cd7f758373db973f03af40a97f6f03dfef07104503af4029dedfc07b5ebd1278065e81527c6d035f2fb5bb5eddc02b +5048497cb8812ef9b56ab05c6d0e99307ac30a6ffa5ebf5ec99caf50500d7975c929262c16db6a2d420f59d2078004522448ec88c50c4fd008aa3840941c24c4 +d923d3100a6f8662c661b85429f54b55f82f7f9e3a5211413b1869d6921730e11b43928fc34709998996fb39787535c8e9ebd7274f5f9d3cfdfde4d9b393a7bf +66732b5786dd0d144f75bbb73f7df3cf8b2f9dbf7ffbf1edf36fd3a9d7f15cc7bff9e5ab377ffcf92ef7b0e255284ebf7bf9e6d5cbd3efbffeebe7e716efed04 +1de8f0218930776ee163e72e8b608116fef820b998c5304444b768c7538e622467b1f8ef89d040df5a208a2cb80e36e3783f01a9b101afcf1f1a8407613217c4 +e2f1661819c07dc6688725d628dc947369611ecee3a97df264aee3ee2274649b3b40b191e5de7c061a4b6c2e83101b34ef50140b34c531168ebcc60e31b6acee +0121465cf7c928619c4d84f380381d44ac21199203a39a56463748047959d80842be8dd8ecdf773a8cda56ddc5472612ee0d442de487981a61bc8ee602453697 +4314513de07b48843692834532d2713d2e20d3534c99d31b63ce6d36b71358af96f49b2033f6b4efd345642213410e6d3ef710633ab2cb0e831045331b7640e2 +50c77ec60fa144917387091b7c9f9977883c873ca0786bbaef136ca4fb6c35b8070aab535a1588bc324f2cb9bc8e9951bf83059d20aca4061a80a1eb1189cf14 +f93579f7ff3b7907113dfde1856545ef47d2ed8e8d7c5c50ccdb09b1de4d37d6247c1b6e5db803968cc987afdb5d348fef60b855369bd747d9fe28dbeeff5eb6 +b7ddcfef5fac57fa0cd22db7ade9765d6ddea3ad7bf709a174201614ef71b57de7d095c67d189476eab915e7cf72b3100ee59d0c1318b86982948d9330f10511 +e1204433d8e3975de964ca33d753eecc1887adbf1ab6fa96783a8ff6d9387d642d97e5e3692a1e1c89d578c9cfc7e17143a4e85a7df51896bb576ca7ea717949 +40da5e8484369949a26a21515f0eca20a98773089a85845ad97b61d1b4b06848f7cb546db0006a795660dbe4c066abe5fa1e9880113c55218ac7324f69aa97d9 +55c97c9f99de164ca302600fb1ac8055a69b92ebd6e5c9d5a5a5768e4c1b24b4723349a8c8a81ec64334c65975cad1f3d0b868ae9bab941af46428d47c505a2b +1af5c6bb585c36d760b7ae0d34d69582c6ce71cbad557d2899119ab5dc093cfac3613483dae172bb8be814de9f8d4492def097519659c24517f1300db8129d54 +0d222270e25012b55cb9fc3c0d34561aa2b8952b20081f2cb926c8ca87460e926e26194f267824f4b46b2332d2e929287caa15d6abcafcf26069c9e690ee4138 +3e760ee83cb98ba0c4fc7a5906704c38bc012aa7d11c1378a5990bd9aafed61a5326bbfa3b455543e938a2b310651d4517f314aea43ca7a3cef2186867d99a21 +a05a48b2467830950d560faad14df3ae9172d8da75cf369291d34473d5330d55915dd3ae62c60ccb36b016cbcb35798dd532c4a0697a874fa57b5d729b4bad5b +db27e45d02029ec7cfd275cfd110346aabc90c6a92f1a60c4bcdce46cddeb15ce019d4ced32434d5af2dddaec52def11d6e960f0529d1fecd6ab168626cb7da5 +8ab4faf6a17f9e60070f413cbaf022784e0557a9848f0f09820dd140ed4952d9805be491c86e0d3872e60969b98f4b7edb0b2a7e502835fc5ec1ab7aa542c36f +570b6ddfaf967b7eb9d4ed549e4063116154f6d3ef2e7d780d4517d9d71735bef105265abe69bb32625191a92f2c45455c7d812957b67f81710888cee35aa5df +ac363bb542b3daee17bc6ea7516806b54ea15b0beadd7e37f01bcdfe13d7395260af5d0dbc5aaf51a89583a0e0d54a927ea359a87b954adbabb71b3daffd24db +c6c0ca53f9c86201e155bc76ff050000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72 +656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c08 +2e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd0 +8a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa +4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f +6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72 +656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000190200007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210007b740aaca0600008f1a00001600000000000000000000000000d60200 +007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000000000000000000000 +00d40900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000cf0a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax371\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong; +\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text; +\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2; +\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List; +\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1; +\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision; +\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1; +\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1; +\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2; +\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; +\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3; +\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4; +\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4; +\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5; +\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; +\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; +\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; +\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; +\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; +\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; +\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; +\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; +\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; +\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; +\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e500000000000000000000000050f4 +a0841132d301feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file From 7ed9e548a88a263951765251274fcbdf990fe219 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 09:59:48 -0500 Subject: [PATCH 49/77] more changes. Better viewing of preview --- SpriteLibrary/SpriteEntryForm.Designer.cs | 21 ++++---- SpriteLibrary/SpriteEntryForm.cs | 59 ++++++++++++++++++++--- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 4d2e0ec..c236679 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -49,6 +49,7 @@ this.lblCountSprites = new System.Windows.Forms.Label(); this.TCTabPages = new System.Windows.Forms.TabControl(); this.tpFromImage = new System.Windows.Forms.TabPage(); + this.lblAnimationNumber = new System.Windows.Forms.Label(); this.lblAnimationFwdBack = new System.Windows.Forms.Label(); this.btnAnimBack = new System.Windows.Forms.Button(); this.btnAnimFwd = new System.Windows.Forms.Button(); @@ -69,7 +70,6 @@ this.btnReset = new System.Windows.Forms.Button(); this.btnPreviewAnimFwd = new System.Windows.Forms.Button(); this.btnPreviewAnimBack = new System.Windows.Forms.Button(); - this.lblAnimationNumber = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); this.TCTabPages.SuspendLayout(); this.tpFromImage.SuspendLayout(); @@ -283,6 +283,15 @@ this.tpFromImage.Text = "From Image"; this.tpFromImage.UseVisualStyleBackColor = true; // + // lblAnimationNumber + // + this.lblAnimationNumber.AutoSize = true; + this.lblAnimationNumber.Location = new System.Drawing.Point(190, 91); + this.lblAnimationNumber.Name = "lblAnimationNumber"; + this.lblAnimationNumber.Size = new System.Drawing.Size(16, 17); + this.lblAnimationNumber.TabIndex = 21; + this.lblAnimationNumber.Text = "0"; + // // lblAnimationFwdBack // this.lblAnimationFwdBack.AutoSize = true; @@ -463,6 +472,7 @@ this.btnReset.TabIndex = 24; this.btnReset.Text = "Reset"; this.btnReset.UseVisualStyleBackColor = true; + this.btnReset.Click += new System.EventHandler(this.btnReset_Click); // // btnPreviewAnimFwd // @@ -486,15 +496,6 @@ this.btnPreviewAnimBack.UseVisualStyleBackColor = true; this.btnPreviewAnimBack.Click += new System.EventHandler(this.btnPreviewAnimBack_Click); // - // lblAnimationNumber - // - this.lblAnimationNumber.AutoSize = true; - this.lblAnimationNumber.Location = new System.Drawing.Point(190, 91); - this.lblAnimationNumber.Name = "lblAnimationNumber"; - this.lblAnimationNumber.Size = new System.Drawing.Size(16, 17); - this.lblAnimationNumber.TabIndex = 21; - this.lblAnimationNumber.Text = "0"; - // // SpriteEntryForm // this.AcceptButton = this.btnApply; diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index e6ce6fd..94b42ad 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -170,23 +170,64 @@ namespace SpriteLibrary UpdateHighlightBox(); } + /// + /// If multiple frames are selected, retrieve all of their rectangles + /// + /// + private List AnimationFrameAreas() + { + List Frames = new List(); + Point start = ChosenArea.Location; + int animations; + int.TryParse(tbNumFrames.Text, out animations); + Frames.Add(ChosenArea); + Image tImage = myDatabase.GetImageFromName(cbStartingImage.SelectedItem.ToString(), true); + + for (int i=1; i< animations; i++) + { + start = new Point(start.X + ChosenArea.Width, start.Y); + if(start.X >= tImage.Width) + { + start.X = 0; + start.Y += ChosenArea.Height; + } + Rectangle tRec = new Rectangle(start.X, start.Y, ChosenArea.Width, ChosenArea.Height); + Frames.Add(tRec); + } + return Frames; + } + private void UpdateHighlightBox() { int transparency = 50; Image NewFrontImage = new Bitmap(pbImageField.BackgroundImage.Width, pbImageField.BackgroundImage.Height); - Color FillColor = Color.Green; + Color FillColor = Color.Gray; Brush brush = new SolidBrush(Color.FromArgb(transparency, FillColor.R, FillColor.G, FillColor.B)); Brush nobrush = new SolidBrush(Color.FromArgb(0,0,0,0)); + List areas = AnimationFrameAreas(); using (Graphics G = Graphics.FromImage(NewFrontImage)) { G.FillRectangle(brush, 0,0,NewFrontImage.Width,NewFrontImage.Height); GraphicsPath path = new GraphicsPath(); - path.AddRectangle(ChosenArea); + foreach (Rectangle one in areas) + { + path.AddRectangle(one); + } G.SetClip(path); G.Clear(Color.Transparent); G.ResetClip(); - // G.FillRectangle(nobrush, ChosenArea); - + transparency = 50; + FillColor = Color.Green; + int increment = 10; + if (areas.Count > 7) increment = 5; + foreach (Rectangle one in areas) + { + transparency += increment; + if (transparency > 150) transparency = 160; + brush = new SolidBrush(Color.FromArgb(transparency, FillColor.R, FillColor.G, FillColor.B)); + G.FillRectangle(brush, one); + } + } pbImageField.Image = NewFrontImage; pbImageField.SizeMode = PictureBoxSizeMode.StretchImage; @@ -209,14 +250,11 @@ namespace SpriteLibrary private void cbStartingImage_SelectedIndexChanged(object sender, EventArgs e) { - ResourceManager rm; - if (myResources != null) rm = myResources; - else rm = Properties.Resources.ResourceManager; //We have a selected item if (cbStartingImage.SelectedIndex >= 0) { //Load in a new image into our background - Image NewImage = (Bitmap)rm.GetObject(cbStartingImage.SelectedItem.ToString()); + Image NewImage = myDatabase.GetImageFromName(cbStartingImage.SelectedItem.ToString(),true); if (NewImage != null) { MyController.ReplaceOriginalImage(new Bitmap(NewImage)); @@ -571,5 +609,10 @@ namespace SpriteLibrary PreviewSprite.ChangeAnimation(NextAnim); } } + + private void btnReset_Click(object sender, EventArgs e) + { + SpriteInformationToForm(); + } } } From 08641c71746b66a07e3689a04f7619301ee9ad91 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:30:08 -0500 Subject: [PATCH 50/77] Destroy the preview sprite if we are moving on --- SpriteLibrary/SpriteEntryForm.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 94b42ad..45afdfd 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -475,6 +475,7 @@ namespace SpriteLibrary DialogResult Answer = MessageBox.Show("You have unsaved Changes. Would you like to save them before proceeding?","Save?",MessageBoxButtons.YesNoCancel); if (Answer == DialogResult.Yes) ApplyChanges(); if (Answer == DialogResult.Cancel) return false; + if (PreviewSprite != null) PreviewSprite.Destroy(); } return true; } From 8ee0e435287fb1b744bdae2952388dd2d0c8636d Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:46:26 -0500 Subject: [PATCH 51/77] pogress on rotation / mirror --- SpriteLibrary/SpriteEntryForm.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 45afdfd..48aa1b6 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -68,6 +68,10 @@ namespace SpriteLibrary myToolTip.AutoPopDelay = 5000; myToolTip.AutomaticDelay = 500; + rbFromImage.Click += UpdateMenuClick; + rbMirror.Click += UpdateMenuClick; + rbRotation.Click += UpdateMenuClick; + PopulateMenu(); UpdateMenu(); SpriteInformationToForm(); @@ -164,6 +168,11 @@ namespace SpriteLibrary ResumeLayout(); } + private void UpdateMenuClick(object sender, EventArgs e) + { + UpdateMenu(); + } + private void UpdateChosenAreaLabel() { lblChosenArea.Text = ChosenArea.X + "," + ChosenArea.Y + "," + ChosenArea.Width + "," + ChosenArea.Height; @@ -284,6 +293,7 @@ namespace SpriteLibrary TempInformation.Animations.Add(new AnimationInfo()); AI = TempInformation.Animations[CurrentSIAnimation]; tbAmimationSpeed.Text = AI.AnimSpeed.ToString(); + tbRotation.Text = AI.RotationDegrees.ToString(); cbStartingImage.Text = AI.ImageName; cbMirrorH.Checked = AI.MirrorHorizontally; cbMirrorV.Checked = AI.MirrorVertically; @@ -324,6 +334,8 @@ namespace SpriteLibrary AI.MirrorHorizontally = cbMirrorH.Checked; AI.MirrorVertically = cbMirrorV.Checked; + int.TryParse(tbRotation.Text, out AI.RotationDegrees); + int.TryParse(cbAnimation.Text, out AI.AnimationToUse); int.TryParse(tbNumFrames.Text, out AI.NumFrames); From 5420c2131b383a3cefd582a477b23be6136bf76d Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:49:04 -0500 Subject: [PATCH 52/77] Move animation fwd bck out of tab-page --- SpriteLibrary/SpriteEntryForm.Designer.cs | 31 +++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index c236679..9eabd9c 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -70,12 +70,14 @@ this.btnReset = new System.Windows.Forms.Button(); this.btnPreviewAnimFwd = new System.Windows.Forms.Button(); this.btnPreviewAnimBack = new System.Windows.Forms.Button(); + this.pnlAnimationFWBK = new System.Windows.Forms.Panel(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); this.TCTabPages.SuspendLayout(); this.tpFromImage.SuspendLayout(); this.tpMirrorRotate.SuspendLayout(); this.panelRadioButtons.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).BeginInit(); + this.pnlAnimationFWBK.SuspendLayout(); this.SuspendLayout(); // // pbImageField @@ -266,10 +268,6 @@ // // tpFromImage // - this.tpFromImage.Controls.Add(this.lblAnimationNumber); - this.tpFromImage.Controls.Add(this.lblAnimationFwdBack); - this.tpFromImage.Controls.Add(this.btnAnimBack); - this.tpFromImage.Controls.Add(this.btnAnimFwd); this.tpFromImage.Controls.Add(this.cbStartingImage); this.tpFromImage.Controls.Add(this.lblStartingImage); this.tpFromImage.Controls.Add(this.lblChosenArea); @@ -286,7 +284,7 @@ // lblAnimationNumber // this.lblAnimationNumber.AutoSize = true; - this.lblAnimationNumber.Location = new System.Drawing.Point(190, 91); + this.lblAnimationNumber.Location = new System.Drawing.Point(42, 24); this.lblAnimationNumber.Name = "lblAnimationNumber"; this.lblAnimationNumber.Size = new System.Drawing.Size(16, 17); this.lblAnimationNumber.TabIndex = 21; @@ -295,7 +293,7 @@ // lblAnimationFwdBack // this.lblAnimationFwdBack.AutoSize = true; - this.lblAnimationFwdBack.Location = new System.Drawing.Point(69, 88); + this.lblAnimationFwdBack.Location = new System.Drawing.Point(6, -4); this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); this.lblAnimationFwdBack.TabIndex = 20; @@ -304,7 +302,7 @@ // btnAnimBack // this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimBack.Location = new System.Drawing.Point(149, 85); + this.btnAnimBack.Location = new System.Drawing.Point(4, 18); this.btnAnimBack.Name = "btnAnimBack"; this.btnAnimBack.Size = new System.Drawing.Size(32, 23); this.btnAnimBack.TabIndex = 19; @@ -315,7 +313,7 @@ // btnAnimFwd // this.btnAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimFwd.Location = new System.Drawing.Point(227, 85); + this.btnAnimFwd.Location = new System.Drawing.Point(96, 18); this.btnAnimFwd.Name = "btnAnimFwd"; this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); this.btnAnimFwd.TabIndex = 18; @@ -496,6 +494,19 @@ this.btnPreviewAnimBack.UseVisualStyleBackColor = true; this.btnPreviewAnimBack.Click += new System.EventHandler(this.btnPreviewAnimBack_Click); // + // pnlAnimationFWBK + // + this.pnlAnimationFWBK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.pnlAnimationFWBK.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pnlAnimationFWBK.Controls.Add(this.lblAnimationNumber); + this.pnlAnimationFWBK.Controls.Add(this.lblAnimationFwdBack); + this.pnlAnimationFWBK.Controls.Add(this.btnAnimFwd); + this.pnlAnimationFWBK.Controls.Add(this.btnAnimBack); + this.pnlAnimationFWBK.Location = new System.Drawing.Point(469, 223); + this.pnlAnimationFWBK.Name = "pnlAnimationFWBK"; + this.pnlAnimationFWBK.Size = new System.Drawing.Size(133, 44); + this.pnlAnimationFWBK.TabIndex = 27; + // // SpriteEntryForm // this.AcceptButton = this.btnApply; @@ -525,6 +536,7 @@ this.Controls.Add(this.lblSpriteName); this.Controls.Add(this.tbSpriteName); this.Controls.Add(this.pbImageField); + this.Controls.Add(this.pnlAnimationFWBK); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.MaximizeBox = false; this.MinimizeBox = false; @@ -540,6 +552,8 @@ this.panelRadioButtons.ResumeLayout(false); this.panelRadioButtons.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).EndInit(); + this.pnlAnimationFWBK.ResumeLayout(false); + this.pnlAnimationFWBK.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -589,5 +603,6 @@ private System.Windows.Forms.Button btnPreviewAnimFwd; private System.Windows.Forms.Button btnPreviewAnimBack; private System.Windows.Forms.Label lblAnimationNumber; + private System.Windows.Forms.Panel pnlAnimationFWBK; } } \ No newline at end of file From 087b4283fcdb7302cdf9ea01a217ca3536575ae9 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:51:49 -0500 Subject: [PATCH 53/77] show total number of animations --- SpriteLibrary/SpriteEntryForm.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 48aa1b6..1b62100 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -128,7 +128,8 @@ namespace SpriteLibrary { cbAnimation.Items.Add(i.ToString()); } - lblAnimationNumber.Text = CurrentSIAnimation.ToString(); + //Update the animation number text + lblAnimationNumber.Text = CurrentSIAnimation.ToString() + " of " + (TempInformation.Animations.Count() -1); if (CurrentSIAnimation == 0) { rbFromImage.Checked = true; From c15bba62fb9983d59e9c51c6c84e6b769f54e76e Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:53:10 -0500 Subject: [PATCH 54/77] Cannot base a rotated or mirrored animation off something that is not created yet. --- SpriteLibrary/SpriteEntryForm.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 1b62100..c4f78f6 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -124,7 +124,8 @@ namespace SpriteLibrary //Put in numbers into the combo-box of which frame to base ourselves off of cbAnimation.Items.Clear(); - for(int i =0; i < TempInformation.Animations.Count; i++) + //We cannot base ourselves off an animation we have not created yet + for(int i =0; i < CurrentSIAnimation; i++) { cbAnimation.Items.Add(i.ToString()); } From 6e08d0d6f504f82ddc4c0ab69155933aea2a7750 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:55:00 -0500 Subject: [PATCH 55/77] hide the mirror or rotation fields we are not using --- SpriteLibrary/SpriteEntryForm.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index c4f78f6..ae78e3a 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -166,6 +166,18 @@ namespace SpriteLibrary if (!TCTabPages.TabPages.Contains(tpMirrorRotate)) TCTabPages.TabPages.Add(tpMirrorRotate); } + if(rbMirror.Checked) + { + cbMirrorH.Visible = true; + cbMirrorV.Visible = true; + tbRotation.Visible = false; + } + if (rbRotation.Checked) + { + cbMirrorH.Visible = false; + cbMirrorV.Visible = false; + tbRotation.Visible = true; + } UpdateChosenAreaLabel(); ResumeLayout(); } From 3f4e6c5e719a42b3a7bc4fd0612ba961c188eaff Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 10:57:24 -0500 Subject: [PATCH 56/77] do preview if preview fwd / back pressed but preview not pressed yet. --- SpriteLibrary/SpriteEntryForm.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index ae78e3a..f0690b2 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -605,25 +605,30 @@ namespace SpriteLibrary } } - private void btnPreview_Click(object sender, EventArgs e) + private void DoPreview() { //remove the old one if (PreviewSprite != null) PreviewSprite.Destroy(); //Create a new one PreviewSprite = TempInformation.CreateSprite(PreviewController, myDatabase); PreviewSprite.PutBaseImageLocation(new Point(1, 1)); - //PreviewSprite.SetSize(new Size(50, 50)); + } + + private void btnPreview_Click(object sender, EventArgs e) + { + DoPreview(); } private void btnPreviewAnimBack_Click(object sender, EventArgs e) { - if(PreviewSprite != null) + if (PreviewSprite != null) { int Animations = PreviewSprite.AnimationCount; int NextAnim = PreviewSprite.AnimationIndex - 1; if (NextAnim < 0) NextAnim = Animations - 1; PreviewSprite.ChangeAnimation(NextAnim); } + else DoPreview(); } private void btnPreviewAnimFwd_Click(object sender, EventArgs e) @@ -635,6 +640,7 @@ namespace SpriteLibrary if (NextAnim >= Animations) NextAnim = 0; PreviewSprite.ChangeAnimation(NextAnim); } + else DoPreview(); } private void btnReset_Click(object sender, EventArgs e) From f363a9ba7663038692357ec680f071a3f64a80f5 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 11:03:53 -0500 Subject: [PATCH 57/77] Add del sprite, del anim buttons --- SpriteLibrary/SpriteEntryForm.Designer.cs | 132 +++++++++++++--------- 1 file changed, 78 insertions(+), 54 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 9eabd9c..49a8b95 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -49,10 +49,6 @@ this.lblCountSprites = new System.Windows.Forms.Label(); this.TCTabPages = new System.Windows.Forms.TabControl(); this.tpFromImage = new System.Windows.Forms.TabPage(); - this.lblAnimationNumber = new System.Windows.Forms.Label(); - this.lblAnimationFwdBack = new System.Windows.Forms.Label(); - this.btnAnimBack = new System.Windows.Forms.Button(); - this.btnAnimFwd = new System.Windows.Forms.Button(); this.tpMirrorRotate = new System.Windows.Forms.TabPage(); this.cbMirrorH = new System.Windows.Forms.CheckBox(); this.cbMirrorV = new System.Windows.Forms.CheckBox(); @@ -60,6 +56,10 @@ this.tbRotation = new System.Windows.Forms.TextBox(); this.lblWhichAnim = new System.Windows.Forms.Label(); this.cbAnimation = new System.Windows.Forms.ComboBox(); + this.lblAnimationNumber = new System.Windows.Forms.Label(); + this.lblAnimationFwdBack = new System.Windows.Forms.Label(); + this.btnAnimBack = new System.Windows.Forms.Button(); + this.btnAnimFwd = new System.Windows.Forms.Button(); this.panelRadioButtons = new System.Windows.Forms.Panel(); this.rbMirror = new System.Windows.Forms.RadioButton(); this.rbRotation = new System.Windows.Forms.RadioButton(); @@ -71,6 +71,8 @@ this.btnPreviewAnimFwd = new System.Windows.Forms.Button(); this.btnPreviewAnimBack = new System.Windows.Forms.Button(); this.pnlAnimationFWBK = new System.Windows.Forms.Panel(); + this.btnDeleteAnim = new System.Windows.Forms.Button(); + this.btnDelSprite = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.pbImageField)).BeginInit(); this.TCTabPages.SuspendLayout(); this.tpFromImage.SuspendLayout(); @@ -155,7 +157,7 @@ // // btnDone // - this.btnDone.Location = new System.Drawing.Point(421, 309); + this.btnDone.Location = new System.Drawing.Point(528, 312); this.btnDone.Name = "btnDone"; this.btnDone.Size = new System.Drawing.Size(75, 23); this.btnDone.TabIndex = 8; @@ -165,7 +167,7 @@ // btnCancel // this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(340, 309); + this.btnCancel.Location = new System.Drawing.Point(447, 312); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 9; @@ -174,7 +176,7 @@ // // btnApply // - this.btnApply.Location = new System.Drawing.Point(340, 280); + this.btnApply.Location = new System.Drawing.Point(252, 312); this.btnApply.Name = "btnApply"; this.btnApply.Size = new System.Drawing.Size(75, 23); this.btnApply.TabIndex = 10; @@ -184,7 +186,7 @@ // // btnNewSprite // - this.btnNewSprite.Location = new System.Drawing.Point(238, 280); + this.btnNewSprite.Location = new System.Drawing.Point(252, 280); this.btnNewSprite.Name = "btnNewSprite"; this.btnNewSprite.Size = new System.Drawing.Size(92, 23); this.btnNewSprite.TabIndex = 11; @@ -281,46 +283,6 @@ this.tpFromImage.Text = "From Image"; this.tpFromImage.UseVisualStyleBackColor = true; // - // lblAnimationNumber - // - this.lblAnimationNumber.AutoSize = true; - this.lblAnimationNumber.Location = new System.Drawing.Point(42, 24); - this.lblAnimationNumber.Name = "lblAnimationNumber"; - this.lblAnimationNumber.Size = new System.Drawing.Size(16, 17); - this.lblAnimationNumber.TabIndex = 21; - this.lblAnimationNumber.Text = "0"; - // - // lblAnimationFwdBack - // - this.lblAnimationFwdBack.AutoSize = true; - this.lblAnimationFwdBack.Location = new System.Drawing.Point(6, -4); - this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; - this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); - this.lblAnimationFwdBack.TabIndex = 20; - this.lblAnimationFwdBack.Text = "Animation:"; - // - // btnAnimBack - // - this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimBack.Location = new System.Drawing.Point(4, 18); - this.btnAnimBack.Name = "btnAnimBack"; - this.btnAnimBack.Size = new System.Drawing.Size(32, 23); - this.btnAnimBack.TabIndex = 19; - this.btnAnimBack.Text = "<"; - this.btnAnimBack.UseVisualStyleBackColor = true; - this.btnAnimBack.Click += new System.EventHandler(this.btnAnimBack_Click); - // - // btnAnimFwd - // - this.btnAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnAnimFwd.Location = new System.Drawing.Point(96, 18); - this.btnAnimFwd.Name = "btnAnimFwd"; - this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); - this.btnAnimFwd.TabIndex = 18; - this.btnAnimFwd.Text = ">"; - this.btnAnimFwd.UseVisualStyleBackColor = true; - this.btnAnimFwd.Click += new System.EventHandler(this.btnAnimFwd_Click); - // // tpMirrorRotate // this.tpMirrorRotate.Controls.Add(this.cbMirrorH); @@ -390,6 +352,46 @@ this.cbAnimation.Size = new System.Drawing.Size(100, 24); this.cbAnimation.TabIndex = 0; // + // lblAnimationNumber + // + this.lblAnimationNumber.AutoSize = true; + this.lblAnimationNumber.Location = new System.Drawing.Point(42, 24); + this.lblAnimationNumber.Name = "lblAnimationNumber"; + this.lblAnimationNumber.Size = new System.Drawing.Size(16, 17); + this.lblAnimationNumber.TabIndex = 21; + this.lblAnimationNumber.Text = "0"; + // + // lblAnimationFwdBack + // + this.lblAnimationFwdBack.AutoSize = true; + this.lblAnimationFwdBack.Location = new System.Drawing.Point(6, -4); + this.lblAnimationFwdBack.Name = "lblAnimationFwdBack"; + this.lblAnimationFwdBack.Size = new System.Drawing.Size(74, 17); + this.lblAnimationFwdBack.TabIndex = 20; + this.lblAnimationFwdBack.Text = "Animation:"; + // + // btnAnimBack + // + this.btnAnimBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAnimBack.Location = new System.Drawing.Point(5, 18); + this.btnAnimBack.Name = "btnAnimBack"; + this.btnAnimBack.Size = new System.Drawing.Size(32, 23); + this.btnAnimBack.TabIndex = 19; + this.btnAnimBack.Text = "<"; + this.btnAnimBack.UseVisualStyleBackColor = true; + this.btnAnimBack.Click += new System.EventHandler(this.btnAnimBack_Click); + // + // btnAnimFwd + // + this.btnAnimFwd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAnimFwd.Location = new System.Drawing.Point(96, 18); + this.btnAnimFwd.Name = "btnAnimFwd"; + this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); + this.btnAnimFwd.TabIndex = 18; + this.btnAnimFwd.Text = ">"; + this.btnAnimFwd.UseVisualStyleBackColor = true; + this.btnAnimFwd.Click += new System.EventHandler(this.btnAnimFwd_Click); + // // panelRadioButtons // this.panelRadioButtons.Controls.Add(this.rbMirror); @@ -435,11 +437,11 @@ // // btnNewAnimation // - this.btnNewAnimation.Location = new System.Drawing.Point(238, 309); + this.btnNewAnimation.Location = new System.Drawing.Point(4, 47); this.btnNewAnimation.Name = "btnNewAnimation"; - this.btnNewAnimation.Size = new System.Drawing.Size(92, 23); + this.btnNewAnimation.Size = new System.Drawing.Size(33, 23); this.btnNewAnimation.TabIndex = 21; - this.btnNewAnimation.Text = "New Anim"; + this.btnNewAnimation.Text = "+"; this.btnNewAnimation.UseVisualStyleBackColor = true; this.btnNewAnimation.Click += new System.EventHandler(this.btnNewAnimation_Click); // @@ -464,7 +466,7 @@ // // btnReset // - this.btnReset.Location = new System.Drawing.Point(426, 280); + this.btnReset.Location = new System.Drawing.Point(366, 312); this.btnReset.Name = "btnReset"; this.btnReset.Size = new System.Drawing.Size(75, 23); this.btnReset.TabIndex = 24; @@ -498,15 +500,35 @@ // this.pnlAnimationFWBK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.pnlAnimationFWBK.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pnlAnimationFWBK.Controls.Add(this.btnDeleteAnim); this.pnlAnimationFWBK.Controls.Add(this.lblAnimationNumber); this.pnlAnimationFWBK.Controls.Add(this.lblAnimationFwdBack); this.pnlAnimationFWBK.Controls.Add(this.btnAnimFwd); this.pnlAnimationFWBK.Controls.Add(this.btnAnimBack); + this.pnlAnimationFWBK.Controls.Add(this.btnNewAnimation); this.pnlAnimationFWBK.Location = new System.Drawing.Point(469, 223); this.pnlAnimationFWBK.Name = "pnlAnimationFWBK"; - this.pnlAnimationFWBK.Size = new System.Drawing.Size(133, 44); + this.pnlAnimationFWBK.Size = new System.Drawing.Size(133, 80); this.pnlAnimationFWBK.TabIndex = 27; // + // btnDeleteAnim + // + this.btnDeleteAnim.Location = new System.Drawing.Point(95, 47); + this.btnDeleteAnim.Name = "btnDeleteAnim"; + this.btnDeleteAnim.Size = new System.Drawing.Size(33, 23); + this.btnDeleteAnim.TabIndex = 22; + this.btnDeleteAnim.Text = "-"; + this.btnDeleteAnim.UseVisualStyleBackColor = true; + // + // btnDelSprite + // + this.btnDelSprite.Location = new System.Drawing.Point(356, 280); + this.btnDelSprite.Name = "btnDelSprite"; + this.btnDelSprite.Size = new System.Drawing.Size(92, 23); + this.btnDelSprite.TabIndex = 28; + this.btnDelSprite.Text = "Del Sprite"; + this.btnDelSprite.UseVisualStyleBackColor = true; + // // SpriteEntryForm // this.AcceptButton = this.btnApply; @@ -514,12 +536,12 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; this.ClientSize = new System.Drawing.Size(614, 347); + this.Controls.Add(this.btnDelSprite); this.Controls.Add(this.btnPreviewAnimBack); this.Controls.Add(this.btnPreviewAnimFwd); this.Controls.Add(this.btnReset); this.Controls.Add(this.btnPreview); this.Controls.Add(this.pbPreview); - this.Controls.Add(this.btnNewAnimation); this.Controls.Add(this.panelRadioButtons); this.Controls.Add(this.TCTabPages); this.Controls.Add(this.lblCountSprites); @@ -604,5 +626,7 @@ private System.Windows.Forms.Button btnPreviewAnimBack; private System.Windows.Forms.Label lblAnimationNumber; private System.Windows.Forms.Panel pnlAnimationFWBK; + private System.Windows.Forms.Button btnDeleteAnim; + private System.Windows.Forms.Button btnDelSprite; } } \ No newline at end of file From 35133e64b77a0df45d82410b87094c1523c3d18d Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 11:18:31 -0500 Subject: [PATCH 58/77] delete working + tooltips --- SpriteLibrary/SpriteEntryForm.Designer.cs | 2 ++ SpriteLibrary/SpriteEntryForm.cs | 41 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 49a8b95..f7c7096 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -519,6 +519,7 @@ this.btnDeleteAnim.TabIndex = 22; this.btnDeleteAnim.Text = "-"; this.btnDeleteAnim.UseVisualStyleBackColor = true; + this.btnDeleteAnim.Click += new System.EventHandler(this.btnDeleteAnim_Click); // // btnDelSprite // @@ -528,6 +529,7 @@ this.btnDelSprite.TabIndex = 28; this.btnDelSprite.Text = "Del Sprite"; this.btnDelSprite.UseVisualStyleBackColor = true; + this.btnDelSprite.Click += new System.EventHandler(this.btnDelSprite_Click); // // SpriteEntryForm // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index f0690b2..f0b1037 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -84,7 +84,9 @@ namespace SpriteLibrary myToolTip.SetToolTip(btnFwd, "Move to next sprite."); myToolTip.SetToolTip(btnPreviewAnimBack, "Change preview to previous animation."); myToolTip.SetToolTip(btnPreviewAnimFwd, "Change preview to next animation."); - + myToolTip.SetToolTip(btnNewSprite, "Create a new sprite."); + myToolTip.SetToolTip(btnDeleteAnim, "Delete the current animation you are looking at."); + myToolTip.SetToolTip(btnDelSprite, "Delete the current sprite you are looking at."); } internal List GetUpdatedList() @@ -514,7 +516,10 @@ namespace SpriteLibrary private void WeHaveNewItem() { if (PreviewSprite != null) PreviewSprite.Destroy(); - TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); + if (CurrentSIIndex >= 0 && CurrentSIIndex < SpriteInformation.Count) + TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); + else + SetUpEmptyInfo(); SpriteInformationToForm(); UpdateMenu(); } @@ -647,5 +652,37 @@ namespace SpriteLibrary { SpriteInformationToForm(); } + + private void btnDelSprite_Click(object sender, EventArgs e) + { + if (CurrentSIIndex == -1) + { + //we are making a new sprite, but it has not been saved yet. + if (SpriteInformation.Count > 0) + { + CurrentSIIndex = 0; + WeHaveNewItem(); + return; + } + //If we are here, then we have no sprites and we are deleting our temp one. Clear it out + SetUpEmptyInfo(); + WeHaveNewItem(); + return; + } + //delete the current entry. Deal with zero entries. + DialogResult Answer = MessageBox.Show("Delete The current Sprite?", "Delete", MessageBoxButtons.YesNo); + if(Answer == DialogResult.Yes) + { + SpriteInformation.RemoveAt(CurrentSIIndex); + CurrentSIIndex--; + if (CurrentSIIndex < 0 && SpriteInformation.Count > 0) CurrentSIIndex = 0; + WeHaveNewItem(); + } + } + + private void btnDeleteAnim_Click(object sender, EventArgs e) + { + + } } } From 8bf63782468b7e35e8005ec2224a37746f71cf55 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 11:25:58 -0500 Subject: [PATCH 59/77] Make sure the preview sprite updates properly. --- SpriteLibrary/SpriteEntryForm.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index f0b1037..ce8c60d 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -515,7 +515,11 @@ namespace SpriteLibrary private void WeHaveNewItem() { - if (PreviewSprite != null) PreviewSprite.Destroy(); + if (PreviewSprite != null) + { + PreviewSprite.Destroy(); + PreviewSprite = null; + } if (CurrentSIIndex >= 0 && CurrentSIIndex < SpriteInformation.Count) TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]); else @@ -626,7 +630,7 @@ namespace SpriteLibrary private void btnPreviewAnimBack_Click(object sender, EventArgs e) { - if (PreviewSprite != null) + if (PreviewSprite != null && !PreviewSprite.Destroying) { int Animations = PreviewSprite.AnimationCount; int NextAnim = PreviewSprite.AnimationIndex - 1; From dddab20eefb66bc977821042388fdcad0d27ba47 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 11:39:09 -0500 Subject: [PATCH 60/77] Delete animations --- SpriteLibrary/SpriteEntryForm.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index ce8c60d..8b8fb40 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -686,7 +686,21 @@ namespace SpriteLibrary private void btnDeleteAnim_Click(object sender, EventArgs e) { - + //delete the current entry. Deal with zero entries. + DialogResult Answer = MessageBox.Show("Delete The current Animation?", "Delete", MessageBoxButtons.YesNo); + if (Answer == DialogResult.Yes) + { + TempInformation.Animations.RemoveAt(CurrentSIAnimation); + CurrentSIAnimation--; + if (CurrentSIAnimation < 0 && TempInformation.Animations.Count > 0) CurrentSIAnimation = 0; + if(TempInformation.Animations.Count == 0) + { + AnimationInfo AI = new AnimationInfo(); + TempInformation.Animations.Add(AI); + CurrentSIAnimation = 0; + } + WeHaveNewItem(); + } } } } From 201e42b37045b13c290017b68a4b892168bfe59d Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 11:40:56 -0500 Subject: [PATCH 61/77] Cannot save an unnamed sprite --- SpriteLibrary/SpriteEntryForm.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 8b8fb40..b287a60 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -478,6 +478,11 @@ namespace SpriteLibrary void ApplyChanges() { + if (tbSpriteName.Text == "") + { + MessageBox.Show("You cannot save a sprite that has no name."); + return; + } FormToSpriteInformation(); if (CurrentSIIndex > 0 && CurrentSIIndex < SpriteInformation.Count) { @@ -498,7 +503,12 @@ namespace SpriteLibrary /// bool PromptToApplyChangesAndContinue() { - if(ValuesDifferFromData()) + if (tbSpriteName.Text == "") + { + MessageBox.Show("You cannot save a sprite that has no name."); + return true; + } + if (ValuesDifferFromData()) { DialogResult Answer = MessageBox.Show("You have unsaved Changes. Would you like to save them before proceeding?","Save?",MessageBoxButtons.YesNoCancel); if (Answer == DialogResult.Yes) ApplyChanges(); From 08b7dbd9a1a24b978afadd266da695503b832c8e Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 12:39:34 -0500 Subject: [PATCH 62/77] done button working --- SpriteLibrary/SpriteEntryForm.Designer.cs | 1 + SpriteLibrary/SpriteEntryForm.cs | 39 ++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index f7c7096..ba2819f 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -163,6 +163,7 @@ this.btnDone.TabIndex = 8; this.btnDone.Text = "Done"; this.btnDone.UseVisualStyleBackColor = true; + this.btnDone.Click += new System.EventHandler(this.btnDone_Click); // // btnCancel // diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index b287a60..ade5e40 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -476,13 +476,35 @@ namespace SpriteLibrary } - void ApplyChanges() + int IndexOfName(string spritname) + { + for(int i=0; i< SpriteInformation.Count; i++) + { + if (SpriteInformation[i].SpriteName == spritname) + return i; + } + return -1; + } + + bool VerifySpriteBeforeSaving() { if (tbSpriteName.Text == "") { MessageBox.Show("You cannot save a sprite that has no name."); - return; + return false; } + int index = IndexOfName(tbSpriteName.Text); + if(index != CurrentSIIndex && index != -1) + { + MessageBox.Show("You cannot have two sprites with the same name."); + return false; + } + return true; + } + + void ApplyChanges() + { + if (!VerifySpriteBeforeSaving()) return; FormToSpriteInformation(); if (CurrentSIIndex > 0 && CurrentSIIndex < SpriteInformation.Count) { @@ -503,10 +525,9 @@ namespace SpriteLibrary /// bool PromptToApplyChangesAndContinue() { - if (tbSpriteName.Text == "") + if (!VerifySpriteBeforeSaving()) { - MessageBox.Show("You cannot save a sprite that has no name."); - return true; + return true; //We could not verify, say we canceled out. } if (ValuesDifferFromData()) { @@ -712,5 +733,13 @@ namespace SpriteLibrary WeHaveNewItem(); } } + + private void btnDone_Click(object sender, EventArgs e) + { + if (PromptToApplyChangesAndContinue()) + { + Close(); + } + } } } From 9754afd4cd830cc92189437accab6abc2f5d2e84 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 12:42:58 -0500 Subject: [PATCH 63/77] stave off an error --- SpriteLibrary/SpriteEntryForm.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index ade5e40..7f90650 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -741,5 +741,13 @@ namespace SpriteLibrary Close(); } } + + private void btnCancel_Click(object sender, EventArgs e) + { + if (PromptToApplyChangesAndContinue()) + { + Close(); + } + } } } From ed09c5602c7d328b3ddad87572cc3aa5be9cf6e1 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 12:43:05 -0500 Subject: [PATCH 64/77] get cancel button working --- SpriteLibrary/SpriteEntryForm.Designer.cs | 1 + SpriteLibrary/SpriteInfo.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index ba2819f..86975ac 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -174,6 +174,7 @@ this.btnCancel.TabIndex = 9; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); // // btnApply // diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index feceb6d..3407aac 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -68,6 +68,7 @@ namespace SpriteLibrary public Sprite CreateSprite(SpriteController ControllerToUse, SpriteDatabase TheDatabaseToUse) { Sprite DestSprite = null; + if (ControllerToUse == null) return null; for (int index = 0; index < Animations.Count; index++) { AnimationInfo CurrentAnimation = Animations[index]; From b25907c143455fd8e1c109293a1d66fdfc0c639d Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 13:07:14 -0500 Subject: [PATCH 65/77] Documentation for the SpriteInfo class --- SpriteLibrary/SpriteInfo.cs | 106 +++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/SpriteLibrary/SpriteInfo.cs b/SpriteLibrary/SpriteInfo.cs index 3407aac..7a312b5 100644 --- a/SpriteLibrary/SpriteInfo.cs +++ b/SpriteLibrary/SpriteInfo.cs @@ -9,19 +9,89 @@ using System.Resources; namespace SpriteLibrary { - public enum AnimationType { SpriteDefinition=0, Rotation=1, Mirror=2 } + /// + /// The SpriteInfo only recognizes a few ways to create a sprite. Here are the different ways. + /// + public enum AnimationType { + /// + /// A Sprite definition knows an image, an X and Y, a size, and a few other items. + /// + SpriteDefinition =0, + /// + /// A rotated sprite is based off a pre-existing animation, but it is rotated by some degrees. + /// + Rotation =1, + /// + /// A mirrored sprite is based off a pre-existing animation, but is mirrored vertically or horizontally. + /// + Mirror =2 } + + /// + /// An AnimationInfo class is used by the SpriteInfo class to + /// contain the instructions for creating a sprite through the dictionary. Most people will not want + /// to manually use these. It is simplest to use the + /// SpriteDatabase.OpenEditWindow function and use the built-in sprite editor. That editor will create a file + /// that can be used in the database without your needing to know about the AnimationInfo. + /// Again, you do not want to use these within + /// your program. Let the SpriteDatabase use this. The reason these are visible to the program is because + /// This code uses "XML Serialization" to load and save. XML Serialization requires the items you are + /// serializing to be "public", which makes them visible. + /// public class AnimationInfo { + /// + /// The FieldsToUse tracks which of the values in AnimationInfo are important + /// public AnimationType FieldsToUse = AnimationType.SpriteDefinition; + /// + /// If the sprite is either a mirror sprite, or a rotated sprite, it must be based off of + /// a pre-existing animation. This value states which animation we copy. + /// public int AnimationToUse = 0; + /// + /// If the sprite is a rotated copy of a pre-existing sprite, this value tells how many degrees to + /// rotate the sprite. + /// public int RotationDegrees=0; + /// + /// If the sprite is a mirrored copy of a pre-existing sprite, this value states whether or not + /// the sprite is mirrored Horizontally. + /// public bool MirrorHorizontally = false; + /// + /// If the sprite is a mirrored copy of a pre-existing sprite, this value states whether or not + /// the sprite is mirrored Vertically. + /// public bool MirrorVertically = false; + /// + /// If the sprite is based off of an image, this value is the starting point of the top-left corner + /// of the sprite on the image. You will also want to include a Width and Height. + /// public Point StartPoint = new Point(-1, -1); + /// + /// This is the image name which contains the sprite. This image should be in the Properties.Resources + /// of your project. The name you want to give is case-sensitive, and should be the exact name as + /// listed in Properties.Resources. For example, if your image name were Properties.Resources.Runner + /// you would want to use the string "Runner" Note the caps are identical, and we have removed the + /// "Properties.Resources. from the front. + /// public string ImageName = ""; + /// + /// The width of the sprite to pull from the specified image. + /// public int Width = -1; + /// + /// The height of the sprite to pull from the specified image. + /// public int Height = -1; + /// + /// The number of frames to pull, one following the other, from the specified image. + /// public int NumFrames = 1; + /// + /// The delay in milliseconds in-between frames of the sprite. This number is not exact, but is pretty + /// close to what happens. Never use a number less than 20. + /// public int AnimSpeed = 200; /// @@ -34,10 +104,33 @@ namespace SpriteLibrary } } + /// + /// A class which is used by the SpriteDatabase to build + /// Sprites. You should not need to use this in your programming. It is simplest to use the Load/Save features + /// of the SpriteDatabase, which will load and save the SpriteInfo. + /// Again, you do not want to use these within + /// your program. Let the SpriteDatabase use this. The reason these are visible to the program is because + /// This code uses "XML Serialization" to load and save. XML Serialization requires the items you are + /// serializing to be "public", which makes them visible. + /// public class SpriteInfo { + /// + /// The name of the sprite. It should be unique within your application + /// public string SpriteName = ""; + /// + /// The percentage size when the sprite is normally displayed. For example: If the image you drew your + /// sprite on has your sprite drawn on a 200x200 grid, but you want your sprite to normally be 100x100, + /// you would tell it to be 50 (50 percent of the original size). + /// public int ViewPercent = 100; //The percent size of the sprite. 100 is full. 50 is half-size + /// + /// This is the list of animations that make up the sprite. Again, you do not want to use these within + /// your program. Let the SpriteDatabase use this. The reason these are visible to the program is because + /// This code uses "XML Serialization" to load and save. XML Serialization requires the items you are + /// serializing to be "public", which makes them visible. + /// public List Animations = new List(); /// @@ -65,7 +158,16 @@ namespace SpriteLibrary } } - public Sprite CreateSprite(SpriteController ControllerToUse, SpriteDatabase TheDatabaseToUse) + /// + /// Create a sprite using the database sprite information. This does not do any checking to make sure + /// the named sprite already exists. Usually, what you want to do is to create your SpriteController and + /// register your SpriteDatabase with the controller. Then, when you ask the SpriteController for a sprite, + /// if that sprite does not exist yet, it will create it from the database. + /// + /// The sprite controller that will end up controlling the sprite + /// The database + /// + internal Sprite CreateSprite(SpriteController ControllerToUse, SpriteDatabase TheDatabaseToUse) { Sprite DestSprite = null; if (ControllerToUse == null) return null; From 4911a787d47f940be18d700273fa4f08ee8c375a Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 13:31:35 -0500 Subject: [PATCH 66/77] Documentation for the SpriteDatabase --- SpriteLibrary/SpriteDatabase.cs | 60 ++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index f0d7357..f253b48 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -123,6 +123,10 @@ namespace SpriteLibrary SpriteInfoList = new List(); //make an empty one so things do not explode. } + /// + /// Return a list of the SpriteNames that this Database knows how to create. + /// + /// A list of strings, each one is the name of a sprite public List SpriteNames() { List theNames = new List(); @@ -141,6 +145,11 @@ namespace SpriteLibrary return false; } + /// + /// Open a Sprite Edit Window. This window does not let you draw a sprite. What it does is to help + /// you define your sprites and makes the process of using Sprites in your program a lot easier. + /// + /// public void OpenEditWindow(int FirstItemIndex=-1) { SpriteEntryForm SEF = new SpriteEntryForm(this, SpriteInfoList, SnapGridSize); @@ -152,6 +161,19 @@ namespace SpriteLibrary #endregion #region General Functions + /// + /// This function returns an image from the Properties.Resources. If we tell it to UseSmartImages, then + /// it caches the image in memory. This makes it a little faster to return. If you have a lot of sprites + /// to load, using this system can speed up things a fair bit. But, try to remember not to change the + /// image that this returns unless you duplicate it first. Otherwise you will end up changing the image + /// for all the other times you reference it. This is usualy a bad thing. + /// + /// The string name of the image. If your image is usually named + /// Properties.Resources.mySpriteImage, you will want to have "mySpriteImage" as the Name passed + /// to GetImageFromName + /// A parameter stating whether we should cache the image in memory + /// or simply retrieve it from the resource manager. + /// public Image GetImageFromName(string Name, bool UseSmartImages) { Image MyImage = null; @@ -181,7 +203,16 @@ namespace SpriteLibrary return MyImage; } - public Sprite SmartDuplicateSprite(SpriteController theController, string SpriteName, bool UseSmartImages = true) + /// + /// This code is mostly handled by the sprite controller. If the SpriteController has a SpriteDatabase + /// registered, then it will automatically ask the SpriteDatabase to create any sprite it does not already + /// have. + /// + /// The controller that will manage the newly created Sprite + /// The name of the sprite to look up and then create + /// Whether or not we should cache images to give a very small increase in speed + /// + internal Sprite SmartDuplicateSprite(SpriteController theController, string SpriteName, bool UseSmartImages = true) { Sprite DestSprite = theController.DuplicateSprite(SpriteName); if (DestSprite != null) return DestSprite; @@ -279,6 +310,15 @@ namespace SpriteLibrary } } + /// + /// This is a generic function which the SpriteDatabase uses. It does XML Serialization of most anything, + /// and generates an XML String. XML Serialization will take any public value of a public class and + /// make an XML entry for it. It is a very convienent way to save data. You can "Deserialize" the value + /// with the ReadFromXMLString function. + /// + /// The type of the item that you are trying to serialize + /// the variable you are trying to turn into XML + /// An XML string public static string WriteToXMLString(T toSerialize) { XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType()); @@ -289,6 +329,16 @@ namespace SpriteLibrary return textWriter.ToString(); } } + + /// + /// This is a generic function which the SpriteDatabase uses. It does XML Deserialization of most anything, + /// and generates an XML String. XML Serialization will take any public value of a public class and + /// make an XML entry for it. It is a very convienent way to save and retrieve data. You can "Serialize" the value + /// with the WriteToXMLString function. + /// + /// The type of the item that you are trying to deserialize + /// an XML string, of something you serialized previously + /// An object of type T public static T ReadFromXmlString(string toDeserialize) where T : new() { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); @@ -296,6 +346,14 @@ namespace SpriteLibrary return (T)xmlSerializer.Deserialize(textReader); } + /// + /// This is an inefficient, but simple function to clone a class. It works by serializing an item + /// to a string, and then deserializing it into a class. The end result is that any value which is + /// publically visible is duplicated, but it is a completely separate class from the original. + /// + /// The type of the item to clone + /// The actual object to clone + /// A duplicate of the original public static T CloneByXMLSerializing(T ObjectToClone) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); From 59bea020b685bfabad0a7b466bf5f246251dd481 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 14:18:00 -0500 Subject: [PATCH 67/77] Choose a good image at the start of the window being opened. --- SpriteLibrary/SpriteDatabase.cs | 20 ++++++++++++++++++++ SpriteLibrary/SpriteEntryForm.cs | 12 ++++++++++++ 2 files changed, 32 insertions(+) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index f253b48..c1339c5 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -8,6 +8,7 @@ using System.Xml; using System.Xml.Serialization; using System.Resources; using System.IO; +using System.Collections; namespace SpriteLibrary { @@ -203,6 +204,25 @@ namespace SpriteLibrary return MyImage; } + + /// + /// Return a list of the image names in the Properties.Resources + /// + /// + public List GetImageNames() + { + List Names = new List(); + if (myResourceManager == null) return Names; + ResourceSet Rs = myResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true); + foreach (DictionaryEntry entry in Rs) + { + string resourceKey = entry.Key.ToString(); //The name + object resource = entry.Value; //The object itself + if (resource is Image) Names.Add(resourceKey); + } + return Names; + } + /// /// This code is mostly handled by the sprite controller. If the SpriteController has a SpriteDatabase /// registered, then it will automatically ask the SpriteDatabase to create any sprite it does not already diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index 7f90650..b51ebd5 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -261,11 +261,23 @@ namespace SpriteLibrary private void SetUpEmptyInfo() { + string startingimage = cbStartingImage.Text; //grab whatever we were using last + Console.WriteLine("Setting up an empty info rec."); + if(startingimage == null || startingimage == "")//If we are not looking at anything yet + { + List ImageNames = myDatabase.GetImageNames(); + if (ImageNames.Count > 0) + startingimage = ImageNames[0]; + foreach(string name in ImageNames) + Console.WriteLine(" Name: " + name); + } + Console.WriteLine("NewName=" + startingimage); TempInformation = new SpriteInfo(); TempInformation.SpriteName = ""; TempInformation.ViewPercent = 100; AnimationInfo AI = new AnimationInfo(); AI.AnimSpeed = 200; + AI.ImageName = startingimage; AI.FieldsToUse = AnimationType.SpriteDefinition; AI.Height = 100; AI.Width = 100; From dcc9d92ca9ab24d2b1a812c6750bcd5273618a81 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 14:38:30 -0500 Subject: [PATCH 68/77] Update tab indexes for things --- SpriteLibrary/SpriteDatabase.cs | 1 + SpriteLibrary/SpriteEntryForm.Designer.cs | 52 +++++++++++------------ SpriteLibrary/SpriteEntryForm.cs | 9 ++++ 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index c1339c5..c9475c4 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -154,6 +154,7 @@ namespace SpriteLibrary public void OpenEditWindow(int FirstItemIndex=-1) { SpriteEntryForm SEF = new SpriteEntryForm(this, SpriteInfoList, SnapGridSize); + SEF.SetInitialSprite(FirstItemIndex); SEF.ShowDialog(); //Use the updated list returned from the form. SpriteInfoList.Clear(); diff --git a/SpriteLibrary/SpriteEntryForm.Designer.cs b/SpriteLibrary/SpriteEntryForm.Designer.cs index 86975ac..a2a92e0 100644 --- a/SpriteLibrary/SpriteEntryForm.Designer.cs +++ b/SpriteLibrary/SpriteEntryForm.Designer.cs @@ -102,7 +102,7 @@ this.cbStartingImage.Location = new System.Drawing.Point(128, 6); this.cbStartingImage.Name = "cbStartingImage"; this.cbStartingImage.Size = new System.Drawing.Size(131, 24); - this.cbStartingImage.TabIndex = 1; + this.cbStartingImage.TabIndex = 5; this.cbStartingImage.SelectedIndexChanged += new System.EventHandler(this.cbStartingImage_SelectedIndexChanged); // // lblStartingImage @@ -128,7 +128,7 @@ this.tbNumFrames.Location = new System.Drawing.Point(128, 53); this.tbNumFrames.Name = "tbNumFrames"; this.tbNumFrames.Size = new System.Drawing.Size(47, 22); - this.tbNumFrames.TabIndex = 4; + this.tbNumFrames.TabIndex = 6; // // lblFrames // @@ -144,7 +144,7 @@ this.tbSpriteName.Location = new System.Drawing.Point(356, 10); this.tbSpriteName.Name = "tbSpriteName"; this.tbSpriteName.Size = new System.Drawing.Size(100, 22); - this.tbSpriteName.TabIndex = 6; + this.tbSpriteName.TabIndex = 1; // // lblSpriteName // @@ -160,7 +160,7 @@ this.btnDone.Location = new System.Drawing.Point(528, 312); this.btnDone.Name = "btnDone"; this.btnDone.Size = new System.Drawing.Size(75, 23); - this.btnDone.TabIndex = 8; + this.btnDone.TabIndex = 23; this.btnDone.Text = "Done"; this.btnDone.UseVisualStyleBackColor = true; this.btnDone.Click += new System.EventHandler(this.btnDone_Click); @@ -171,7 +171,7 @@ this.btnCancel.Location = new System.Drawing.Point(447, 312); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); - this.btnCancel.TabIndex = 9; + this.btnCancel.TabIndex = 22; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); @@ -181,7 +181,7 @@ this.btnApply.Location = new System.Drawing.Point(252, 312); this.btnApply.Name = "btnApply"; this.btnApply.Size = new System.Drawing.Size(75, 23); - this.btnApply.TabIndex = 10; + this.btnApply.TabIndex = 20; this.btnApply.Text = "Apply"; this.btnApply.UseVisualStyleBackColor = true; this.btnApply.Click += new System.EventHandler(this.btnApply_Click); @@ -191,7 +191,7 @@ this.btnNewSprite.Location = new System.Drawing.Point(252, 280); this.btnNewSprite.Name = "btnNewSprite"; this.btnNewSprite.Size = new System.Drawing.Size(92, 23); - this.btnNewSprite.TabIndex = 11; + this.btnNewSprite.TabIndex = 18; this.btnNewSprite.Text = "New Sprite"; this.btnNewSprite.UseVisualStyleBackColor = true; this.btnNewSprite.Click += new System.EventHandler(this.btnNewSprite_Click); @@ -201,7 +201,7 @@ this.tbAmimationSpeed.Location = new System.Drawing.Point(356, 217); this.tbAmimationSpeed.Name = "tbAmimationSpeed"; this.tbAmimationSpeed.Size = new System.Drawing.Size(100, 22); - this.tbAmimationSpeed.TabIndex = 12; + this.tbAmimationSpeed.TabIndex = 11; // // lblAnimationSpeed // @@ -226,7 +226,7 @@ this.tbDefaultSize.Location = new System.Drawing.Point(356, 246); this.tbDefaultSize.Name = "tbDefaultSize"; this.tbDefaultSize.Size = new System.Drawing.Size(100, 22); - this.tbDefaultSize.TabIndex = 15; + this.tbDefaultSize.TabIndex = 12; // // btnBack // @@ -234,7 +234,7 @@ this.btnBack.Location = new System.Drawing.Point(12, 322); this.btnBack.Name = "btnBack"; this.btnBack.Size = new System.Drawing.Size(32, 23); - this.btnBack.TabIndex = 16; + this.btnBack.TabIndex = 24; this.btnBack.Text = "<"; this.btnBack.UseVisualStyleBackColor = true; this.btnBack.Click += new System.EventHandler(this.btnBack_Click); @@ -245,7 +245,7 @@ this.btnFwd.Location = new System.Drawing.Point(177, 322); this.btnFwd.Name = "btnFwd"; this.btnFwd.Size = new System.Drawing.Size(32, 23); - this.btnFwd.TabIndex = 17; + this.btnFwd.TabIndex = 25; this.btnFwd.Text = ">"; this.btnFwd.UseVisualStyleBackColor = true; this.btnFwd.Click += new System.EventHandler(this.btnFwd_Click); @@ -268,7 +268,7 @@ this.TCTabPages.Name = "TCTabPages"; this.TCTabPages.SelectedIndex = 0; this.TCTabPages.Size = new System.Drawing.Size(282, 143); - this.TCTabPages.TabIndex = 19; + this.TCTabPages.TabIndex = 5; // // tpFromImage // @@ -307,7 +307,7 @@ this.cbMirrorH.Location = new System.Drawing.Point(35, 87); this.cbMirrorH.Name = "cbMirrorH"; this.cbMirrorH.Size = new System.Drawing.Size(81, 21); - this.cbMirrorH.TabIndex = 5; + this.cbMirrorH.TabIndex = 9; this.cbMirrorH.Text = "Mirror H"; this.cbMirrorH.UseVisualStyleBackColor = true; // @@ -317,7 +317,7 @@ this.cbMirrorV.Location = new System.Drawing.Point(148, 87); this.cbMirrorV.Name = "cbMirrorV"; this.cbMirrorV.Size = new System.Drawing.Size(80, 21); - this.cbMirrorV.TabIndex = 4; + this.cbMirrorV.TabIndex = 10; this.cbMirrorV.Text = "Mirror V"; this.cbMirrorV.UseVisualStyleBackColor = true; // @@ -335,7 +335,7 @@ this.tbRotation.Location = new System.Drawing.Point(128, 58); this.tbRotation.Name = "tbRotation"; this.tbRotation.Size = new System.Drawing.Size(100, 22); - this.tbRotation.TabIndex = 2; + this.tbRotation.TabIndex = 8; // // lblWhichAnim // @@ -352,7 +352,7 @@ this.cbAnimation.Location = new System.Drawing.Point(128, 18); this.cbAnimation.Name = "cbAnimation"; this.cbAnimation.Size = new System.Drawing.Size(100, 24); - this.cbAnimation.TabIndex = 0; + this.cbAnimation.TabIndex = 7; // // lblAnimationNumber // @@ -378,7 +378,7 @@ this.btnAnimBack.Location = new System.Drawing.Point(5, 18); this.btnAnimBack.Name = "btnAnimBack"; this.btnAnimBack.Size = new System.Drawing.Size(32, 23); - this.btnAnimBack.TabIndex = 19; + this.btnAnimBack.TabIndex = 16; this.btnAnimBack.Text = "<"; this.btnAnimBack.UseVisualStyleBackColor = true; this.btnAnimBack.Click += new System.EventHandler(this.btnAnimBack_Click); @@ -389,7 +389,7 @@ this.btnAnimFwd.Location = new System.Drawing.Point(96, 18); this.btnAnimFwd.Name = "btnAnimFwd"; this.btnAnimFwd.Size = new System.Drawing.Size(32, 23); - this.btnAnimFwd.TabIndex = 18; + this.btnAnimFwd.TabIndex = 17; this.btnAnimFwd.Text = ">"; this.btnAnimFwd.UseVisualStyleBackColor = true; this.btnAnimFwd.Click += new System.EventHandler(this.btnAnimFwd_Click); @@ -410,7 +410,7 @@ this.rbMirror.Location = new System.Drawing.Point(197, 3); this.rbMirror.Name = "rbMirror"; this.rbMirror.Size = new System.Drawing.Size(66, 21); - this.rbMirror.TabIndex = 2; + this.rbMirror.TabIndex = 4; this.rbMirror.TabStop = true; this.rbMirror.Text = "Mirror"; this.rbMirror.UseVisualStyleBackColor = true; @@ -421,7 +421,7 @@ this.rbRotation.Location = new System.Drawing.Point(120, 3); this.rbRotation.Name = "rbRotation"; this.rbRotation.Size = new System.Drawing.Size(71, 21); - this.rbRotation.TabIndex = 1; + this.rbRotation.TabIndex = 3; this.rbRotation.TabStop = true; this.rbRotation.Text = "Rotate"; this.rbRotation.UseVisualStyleBackColor = true; @@ -432,7 +432,7 @@ this.rbFromImage.Location = new System.Drawing.Point(14, 3); this.rbFromImage.Name = "rbFromImage"; this.rbFromImage.Size = new System.Drawing.Size(103, 21); - this.rbFromImage.TabIndex = 0; + this.rbFromImage.TabIndex = 2; this.rbFromImage.TabStop = true; this.rbFromImage.Text = "From Image"; this.rbFromImage.UseVisualStyleBackColor = true; @@ -461,7 +461,7 @@ this.btnPreview.Location = new System.Drawing.Point(518, 126); this.btnPreview.Name = "btnPreview"; this.btnPreview.Size = new System.Drawing.Size(75, 23); - this.btnPreview.TabIndex = 23; + this.btnPreview.TabIndex = 13; this.btnPreview.Text = "Preview"; this.btnPreview.UseVisualStyleBackColor = true; this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); @@ -471,7 +471,7 @@ this.btnReset.Location = new System.Drawing.Point(366, 312); this.btnReset.Name = "btnReset"; this.btnReset.Size = new System.Drawing.Size(75, 23); - this.btnReset.TabIndex = 24; + this.btnReset.TabIndex = 21; this.btnReset.Text = "Reset"; this.btnReset.UseVisualStyleBackColor = true; this.btnReset.Click += new System.EventHandler(this.btnReset_Click); @@ -482,7 +482,7 @@ this.btnPreviewAnimFwd.Location = new System.Drawing.Point(561, 155); this.btnPreviewAnimFwd.Name = "btnPreviewAnimFwd"; this.btnPreviewAnimFwd.Size = new System.Drawing.Size(32, 23); - this.btnPreviewAnimFwd.TabIndex = 25; + this.btnPreviewAnimFwd.TabIndex = 15; this.btnPreviewAnimFwd.Text = ">"; this.btnPreviewAnimFwd.UseVisualStyleBackColor = true; this.btnPreviewAnimFwd.Click += new System.EventHandler(this.btnPreviewAnimFwd_Click); @@ -493,7 +493,7 @@ this.btnPreviewAnimBack.Location = new System.Drawing.Point(518, 155); this.btnPreviewAnimBack.Name = "btnPreviewAnimBack"; this.btnPreviewAnimBack.Size = new System.Drawing.Size(32, 23); - this.btnPreviewAnimBack.TabIndex = 26; + this.btnPreviewAnimBack.TabIndex = 14; this.btnPreviewAnimBack.Text = "<"; this.btnPreviewAnimBack.UseVisualStyleBackColor = true; this.btnPreviewAnimBack.Click += new System.EventHandler(this.btnPreviewAnimBack_Click); @@ -528,7 +528,7 @@ this.btnDelSprite.Location = new System.Drawing.Point(356, 280); this.btnDelSprite.Name = "btnDelSprite"; this.btnDelSprite.Size = new System.Drawing.Size(92, 23); - this.btnDelSprite.TabIndex = 28; + this.btnDelSprite.TabIndex = 19; this.btnDelSprite.Text = "Del Sprite"; this.btnDelSprite.UseVisualStyleBackColor = true; this.btnDelSprite.Click += new System.EventHandler(this.btnDelSprite_Click); diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index b51ebd5..a30b2d7 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -259,6 +259,15 @@ namespace SpriteLibrary pbImageField.Invalidate(); } + internal void SetInitialSprite(int StartingSprite) + { + CurrentSIIndex = StartingSprite; + if (CurrentSIIndex >= SpriteInformation.Count) + CurrentSIIndex = SpriteInformation.Count - 1; + if (CurrentSIIndex < -1) CurrentSIIndex = -1; + WeHaveNewItem(); + } + private void SetUpEmptyInfo() { string startingimage = cbStartingImage.Text; //grab whatever we were using last From b01341439bd4b4516cf387f8c685bf3cc697bf39 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Wed, 20 Sep 2017 16:27:35 -0500 Subject: [PATCH 69/77] Have the grahical selection box represent the sprite we are based off of. It seems more realistic that way. --- SpriteLibrary/SpriteEntryForm.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index a30b2d7..d17e286 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -527,6 +527,22 @@ namespace SpriteLibrary { if (!VerifySpriteBeforeSaving()) return; FormToSpriteInformation(); + //Copy information from the frame we are based off of. This makes the visible selection + //equal to the one it is a copy of. + if(CurrentSIAnimation >=0 && TempInformation.Animations[CurrentSIAnimation].FieldsToUse != AnimationType.SpriteDefinition) + { + int which = TempInformation.Animations[CurrentSIAnimation].AnimationToUse; + if (which >= 0 && which < TempInformation.Animations.Count) + { + AnimationInfo oAI = TempInformation.Animations[TempInformation.Animations[CurrentSIAnimation].AnimationToUse]; + AnimationInfo nAI = TempInformation.Animations[CurrentSIAnimation]; + nAI.ImageName = oAI.ImageName; + nAI.StartPoint = oAI.StartPoint; + nAI.Width = oAI.Width; + nAI.Height = oAI.Height; + nAI.NumFrames = oAI.NumFrames; + } + } if (CurrentSIIndex > 0 && CurrentSIIndex < SpriteInformation.Count) { SpriteInformation[CurrentSIIndex].CopyFrom(TempInformation); From 743ab78c285e5c90d803473c5e8eb89ab08d9120 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Thu, 21 Sep 2017 06:46:31 -0500 Subject: [PATCH 70/77] Add the SpriteDatabase to a spritecontroller --- .../Properties/Resources.Designer.cs | 16 +++++-- SpriteLibrary/Properties/Resources.resx | 3 ++ SpriteLibrary/Resources/SLIcon.ico | Bin 0 -> 27062 bytes SpriteLibrary/SpriteController.cs | 44 ++++++++++++++++++ SpriteLibrary/SpriteDatabase.cs | 24 ++++++++++ SpriteLibrary/SpriteEntryForm.cs | 7 +++ SpriteLibrary/SpriteLibrary.csproj | 3 ++ 7 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 SpriteLibrary/Resources/SLIcon.ico diff --git a/SpriteLibrary/Properties/Resources.Designer.cs b/SpriteLibrary/Properties/Resources.Designer.cs index 527b3a7..076841d 100644 --- a/SpriteLibrary/Properties/Resources.Designer.cs +++ b/SpriteLibrary/Properties/Resources.Designer.cs @@ -61,15 +61,23 @@ namespace SpriteLibrary.Properties { } /// - /// Looks up a localized string similar to {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} - ///{\colortbl ;\red0\green0\blue255;} - ///{\*\generator Riched20 10.0.10586}\viewkind4\uc1 - ///\pard\sa200\sl276\slmult1\f0\fs22\lang9 This is the Running Demo, which was created to test out the SpriteController: {{\field{\*\fldinst{HYPERLINK http://www.codeproject.com/Articles/1085446/Using-Sprites-Inside-Windows-Forms }}{\fldrslt{http://www.codeproject.com/Articles/1085446/Using-Sprites-Inside-Windows-Forms\ul0\cf0}}}}\f0 [rest of string was truncated]";. + /// Looks up a localized string similar to {\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;} + ///{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f40\fbidi \fmodern\fcharset0\fprq1{\*\panose 020b0609020204030204}Consolas;}{\ [rest of string was truncated]";. /// internal static string ChangeLog { get { return ResourceManager.GetString("ChangeLog", resourceCulture); } } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon SLIcon { + get { + object obj = ResourceManager.GetObject("SLIcon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } } } diff --git a/SpriteLibrary/Properties/Resources.resx b/SpriteLibrary/Properties/Resources.resx index eb0b268..e81f0a2 100644 --- a/SpriteLibrary/Properties/Resources.resx +++ b/SpriteLibrary/Properties/Resources.resx @@ -121,4 +121,7 @@ ..\Resources\ChangeLog.rtf;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\SLIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/SpriteLibrary/Resources/SLIcon.ico b/SpriteLibrary/Resources/SLIcon.ico new file mode 100644 index 0000000000000000000000000000000000000000..89c1b63afca141f2c61c801c50deb13c3eea7989 GIT binary patch literal 27062 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 M5cm%Q|E~!AUo^#g?*IS* literal 0 HcmV?d00001 diff --git a/SpriteLibrary/SpriteController.cs b/SpriteLibrary/SpriteController.cs index de1d7c1..7a7d28b 100644 --- a/SpriteLibrary/SpriteController.cs +++ b/SpriteLibrary/SpriteController.cs @@ -146,6 +146,12 @@ namespace SpriteLibrary private SpriteAdjustmentRatio _AdjustmentRatio; + /// + /// The Sprite Database has tools to load and save sprite definitions, as well as a tool to help + /// developers create sprite definitions. + /// + private SpriteDatabase myDatabase = null; + /// /// If your sprite images need substantial growing or shrinking when displayed, you can try setting this to "true" /// to see if it makes it run any faster. What it does is to resize the image once, and keep a cached copy of that @@ -183,6 +189,39 @@ namespace SpriteLibrary Local_Setup(); } + /// + /// Create a sprite controller, specifying the picturebox on which the sprites + /// will be displayed. You want to have the PictureBox already defined, and a background image + /// already set for the PictureBox. This constructor also uses a , which + /// loads sprite definitions at construction time, and has tools for making and storing sprites. + /// + /// + /// This is an example of a Form class that defines a SpriteController. The MainDrawingArea is a + /// PictureBox. + /// + /// public partial class ShootingFieldForm : Form + /// { + /// public ShootingFieldForm() + /// { + /// InitializeComponent(); + /// MainDrawingArea.BackgroundImage = Properties.Resources.Background; + /// MainDrawingArea.BackgroundImageLayout = ImageLayout.Stretch; + /// MySpriteDatabase = new SpriteDatabase(Properties.Resources.ResourceManager, "MySpriteDefinitions"); + /// MySpriteController = new SpriteController(MainDrawingArea, MySpriteDatabase); + /// } + /// } + /// + /// + /// The PictureBox. + /// that the sprites will be drawn in + /// A SpriteDatabase to use + public SpriteController(PictureBox Area, SpriteDatabase DatabaseToUse) + { + myDatabase = DatabaseToUse; + DrawingArea = Area; + Local_Setup(); + } + /// /// Create a sprite controller, specifying the picturebox on which the sprites /// will be displayed. @@ -980,6 +1019,11 @@ namespace SpriteLibrary return Found; } } + //If we are here, we have not yet found a sprite. Now we can check our database and see if we have one defined + if(myDatabase != null) + { + return myDatabase.SmartDuplicateSprite(this, Name, true); + } return null; } diff --git a/SpriteLibrary/SpriteDatabase.cs b/SpriteLibrary/SpriteDatabase.cs index c9475c4..29c0da4 100644 --- a/SpriteLibrary/SpriteDatabase.cs +++ b/SpriteLibrary/SpriteDatabase.cs @@ -36,6 +36,7 @@ namespace SpriteLibrary ResourceManager myResourceManager = null; string Filename = ""; Size SnapGridSize = new Size(5, 5); + System.Drawing.Icon LibIcon = null; /// /// The sprite database instantiation function. The filename can either be a file on the computer or it @@ -86,6 +87,15 @@ namespace SpriteLibrary } } + /// + /// Change the Icon for the SpriteEntryForm + /// + /// An icon image + public void SetIcon(System.Drawing.Icon toSet) + { + LibIcon = toSet; + } + /// /// The SnapGrid is the block-size that your sprite will be. For example, I will often have sprites with /// a snapgrid of 50,50. This means that the sprite can be 50x50, 100x50, or anything with a step-size @@ -155,11 +165,25 @@ namespace SpriteLibrary { SpriteEntryForm SEF = new SpriteEntryForm(this, SpriteInfoList, SnapGridSize); SEF.SetInitialSprite(FirstItemIndex); + if (LibIcon != null) SEF.SetIcon(LibIcon); SEF.ShowDialog(); //Use the updated list returned from the form. SpriteInfoList.Clear(); SpriteInfoList.AddRange(SEF.GetUpdatedList()); } + + /// + /// Generate a new, named sprite from a sprite template stored in the database. Most of the time you do + /// not want to use this yourself. SpriteControllers that are defined with a database will automatically + /// look up sprite templates that they do not have sprites for. This function is just a wrapper for SmartDuplicateSprite. + /// + /// The name of the sprite to load. Names are case-sensitive. + /// The sprite controller that will store the sprite in its cache + /// A new, named sprite, or null if no such template is found. + public Sprite SpriteFromName(string Name, SpriteController ControllerToUse) + { + return SmartDuplicateSprite(ControllerToUse, Name, true); + } #endregion #region General Functions diff --git a/SpriteLibrary/SpriteEntryForm.cs b/SpriteLibrary/SpriteEntryForm.cs index d17e286..c245eb5 100644 --- a/SpriteLibrary/SpriteEntryForm.cs +++ b/SpriteLibrary/SpriteEntryForm.cs @@ -87,6 +87,8 @@ namespace SpriteLibrary myToolTip.SetToolTip(btnNewSprite, "Create a new sprite."); myToolTip.SetToolTip(btnDeleteAnim, "Delete the current animation you are looking at."); myToolTip.SetToolTip(btnDelSprite, "Delete the current sprite you are looking at."); + + Icon = Properties.Resources.SLIcon; } internal List GetUpdatedList() @@ -94,6 +96,11 @@ namespace SpriteLibrary return SpriteInformation; } + internal void SetIcon(Icon IconImage) + { + Icon = IconImage; + } + private void PopulateMenu() { ResourceManager rm = myResources; diff --git a/SpriteLibrary/SpriteLibrary.csproj b/SpriteLibrary/SpriteLibrary.csproj index eda7b56..3371803 100644 --- a/SpriteLibrary/SpriteLibrary.csproj +++ b/SpriteLibrary/SpriteLibrary.csproj @@ -85,6 +85,9 @@ + + +