From c6dc6730841034d1cf7d6391e5336667792f5537 Mon Sep 17 00:00:00 2001 From: cecil Date: Sat, 4 Nov 2017 11:58:03 -0400 Subject: [PATCH] Added support for Launchpad dialog Moved tourists to end of list Added Update poller to ensure list stays sorted --- .vs/AlphabeticalKerbals/v14/.suo | Bin 54272 -> 55808 bytes AlphabeticalKerbals/KerbalSorter.cs | 102 ++++++++++++------ .../Properties/AssemblyInfo.cs | 4 +- AlphabeticalKerbals/SceneHooks.cs | 97 +++++++++++++++-- distrib/AlphabeticalKerbals.zip | Bin 3504 -> 4175 bytes .../AlphabeticalKerbals.dll | Bin 7680 -> 9216 bytes 6 files changed, 164 insertions(+), 39 deletions(-) diff --git a/.vs/AlphabeticalKerbals/v14/.suo b/.vs/AlphabeticalKerbals/v14/.suo index 6e13616ef4da306b3a45e5626dcf821bfd6e3496..5250dd45edcea805582e55f1127d3f9e8c15aae5 100644 GIT binary patch delta 1182 zcmZWoYfMx}6rQCgsfq-a?@qt|>-9+i4WZmk@YLS)-Mk+R-sF1KEMSkqH zA*QjKmi@G;(QeRUY?}IDXOkM!8mK0yhzcbB>JOv8HO9aX>w})z>?I`5&6hdnJKvp| zbIy$Uo6Stvek@z4u++$6%uc5C-%n3ZOV);7y>*~5z~f3#sf{dlpoJJ^sS6{5V zQ!Mt`m+`GQsefO*nWzBaQ^J;1I7ssWLN#H(JZ{vkYOUmK!+EVH8VqEEoKpn3MG^x$ zF7aq}m0|5i{4~b$OVbXMsyzcoj3fLIrmAc75+bZ9KZwpyM3Z}|cwN)YL+IRDgFtN^ zifa1}DJz~O$E16K$a3xDS|+hRbY+ehvb<6!huje1tVhP&56JA0ljjgykcvpDRzZ%A z*R>(s$@>^)-YwipUn9a_{Kd1jQAnn5B?zCR)YwHteTqc8W5t3Na`w+sS!y|p>tCMW zMm|O75v=1S%ScWCVJmLW?ZF+}3WVL;4cQo(lO+?A?htqK`9u}YqIm;48zO0?L=C&~ z-@Gk`?78f{^&`UbL(XLP>FUj}Y1_$psnE85;cGmhXl?e!r{!X7Z(BCL^4x~%c`J%N zDi^9}y$imJ&-p^cD!=1V#4dK_cCaS)H9JgbVQuuavJU*YaX0!l6>)~4O`iz!(n}?? ziFL5`6mCz7E6}^S9*xMu3xCuxObO=F860dBL-8|sadI8%FOT8PmCxfrz80TdO~7}< z4(G8ltW0zw^2fg-cJ&#@xcLhP<5PU*H?cgiR?CoS%O_BUqXQSP;n?FjvU=87O@_?4 z3chP+q5u7uR4pQQd^mL(? delta 986 zcmY*YZ%9*76u;-aZN9B-Zfdn0*)~m#LKKyfM5oi7W}APq1gET`!W1og2AZKClMI}P zL?|juDk3Vq5)mO5qevnD^~Jta5EK#72m2D_I(I1Aef&7*{LVS|z4N>G^-jpW_vL|% z?QCsX7~4(0L|BPLB7z1CDa~U+FN{kS8qlLt+F`Z?XY}8y7r{h%cM5h%T`+*ZC7%g^ z7%PFABRIb;MH}4)J7anZ7e#J0CDK~*|B@{uYa|#5n+SSB3_*12$SMRIAr^C$WQ|}k zxFtmD7RjxP%<)x^CApC=5eS|}Va>0eF-i*{qgFde!Q%DujPt&zf@It{Z-?UK- zvUNiaRez;X6vl2Om;HY3v1EeQOl&@OT4yjUXP_E4XA}d7da=aZsMgGyqB@G&b@s5| z1R~OGWS7mWtQdQ}ww87fkq~B$U2!CDQH|#) zes)~MvyN1pbeMIUhewA@)wtkzCe!2?DYfH6r_C-7`xNV7E%XSjidhLOVzsQ4?Z+i& zjzp?iTzPZ^;v3u8adw6UsOThl9qcq_I(P8_*OOSDzwZ@rXO0HACMVAf4Or;Ol7Xd) z_k$DDi!Z|v-t=_Zo2j>*x{uKd&(n_WOpP+>>;!(eTW4SyER*F5;LDO^?!IS~aY%K@ z*_VK~JqUpzjT8~0C=7q~&GS8vcFN-wkj<;dTER?LIeOJ8&zjt#02KbSZxXCcf{HHJ zR1ev`yx>|l@Q=@1_14_g3}XpXD)|;{41XPYEkhi_+djB}*5P{mbUguE%XEW=yy(BP zGFJ5%LO~0kn3gpB>D)A+dualD7u;C%E+4<#vSIm+?<2Etr#B4fDhTkv?a{1%4;)VI diff --git a/AlphabeticalKerbals/KerbalSorter.cs b/AlphabeticalKerbals/KerbalSorter.cs index b6fc702..03ee7b1 100644 --- a/AlphabeticalKerbals/KerbalSorter.cs +++ b/AlphabeticalKerbals/KerbalSorter.cs @@ -11,6 +11,12 @@ namespace AlphabeticalKerbals class KerbalSorter { static void print(string s) { MonoBehaviour.print("AlphabeticalKerbals: " + s); } + + /// + /// Sorts the kerbals in the CrewAssignmentDialog + /// Will not work on dialogs that do not use the CrewAssignmentDialog GUI element + /// + /// success static public bool Sort_Kerbals() { if (CrewAssignmentDialog.Instance == null) @@ -21,7 +27,7 @@ namespace AlphabeticalKerbals { UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; - UIList_QSort(avail, 0, avail.Count-1); + UIList_QSort(avail, 0, avail.Count - 1); #if DEBUG for (int i = 0; i < avail.Count; i++) @@ -33,41 +39,19 @@ namespace AlphabeticalKerbals #endif return true; - + /* - print("AlphabeticalKerbals: OnEditorCrewOpened has CrewAssignmentDialog yay!!!"); - UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; - UIListItem first = avail.GetUilistItemAt(0); - - print("AlphabeticalKerbals: Got first item in UIList"); - - if (first == null) - { - //happens on first load - print("AlphabeticalKerbals: Uhhh.... first is null?"); - } - if (first.gameObject == null) - { - print("AlphabeticalKerbals: Uhhh.... gameObject is null?"); - } - Component[] comps = first.gameObject.GetComponents(); - print("AlphabeticalKerbals: Uhhh.... got components???"); for (int i = 0; i < comps.Length; ++i) { print($"Component {i}: {comps[i].GetType()}"); } - CrewListItem firstdata = first.GetComponent(); - print("AlphabeticalKerbals: Got a component for crew list item"); - print("AlphabeticalKerbals: Got crew name: " + firstdata.GetName()); - - print("AlphabeticalKerbals: Got component list"); foreach (Component comp in firstdata) { - print("AlphabeticalKerbals: Got a component"); - print("AlphabeticalKerbals: Component name is " + comp.name); - print("AlphabeticalKerbals: Component type is " + comp.GetType().Name); - print("AlphabeticalKerbals: Component string is " + comp.ToString()); + print("Got a component"); + print("Component name is " + comp.name); + print("Component type is " + comp.GetType().Name); + print("Component string is " + comp.ToString()); } */ @@ -77,6 +61,57 @@ namespace AlphabeticalKerbals return false; } + /// + /// Sorts Kerbals, but first checks the list to make sure it's not already sorted. + /// Overall, this ends up using more resources than just blind-sorting, but in cases + /// where the list is almost always going to be correctly sorted, it may save some time. + /// + /// success + static public bool Sort_Kerbals_If_Needed() + { + if (CrewAssignmentDialog.Instance == null) + { + print("OnEditorCrewOpened has no CrewAssignmentDialog yet..."); + return false; + } + else + { + UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; + bool unsorted = false; + + int i = 0; + for (; i < (avail.Count - 1); i++) + { + UIListItem li = avail.GetUilistItemAt(i); + UIListItem li2 = avail.GetUilistItemAt(i + 1); + CrewListItem crew = li.GetComponent(); + if (UIList_Cmp(li, li2) > 0) + { + unsorted = true; + + break; + } + + } + + if (unsorted) + { + print("Change in Kerbal List detected, re-sorting"); +#if DEBUG + print("Sort_If_Needed: Sort IS needed due to i = " + i.ToString()); + for (i = 0; i < avail.Count; i++) + { + UIListItem li = avail.GetUilistItemAt(i); + CrewListItem crew = li.GetComponent(); + print("BEFORE SORT = " + crew.GetName()); + } +#endif + Sort_Kerbals(); + } + return true; + } + } + /// /// Return value positive means left > right, return value negative means left < right /// @@ -85,16 +120,21 @@ namespace AlphabeticalKerbals /// static int UIList_Cmp(UIListItem left, UIListItem right) { - if (left == null) { return 1; } // null values are considered greatest, so they are sorted at the end - if (right == null) { return -1; } // null values are considered greatest, so they are sorted at the end - CrewListItem ldata = null; CrewListItem rdata = null; try { ldata = left.GetComponent(); } catch { return 1; } try { rdata = right.GetComponent(); } catch { return -1; } +#if DEBUG if (ldata == null) { return 1; } if (rdata == null) { return -1; } +#endif + + bool ltourist = ldata.GetCrewRef().type == ProtoCrewMember.KerbalType.Tourist; + bool rtourist = rdata.GetCrewRef().type == ProtoCrewMember.KerbalType.Tourist; + + if (ltourist && !rtourist) { return 1; } // tourists are also sorted to the end + if (!ltourist && rtourist) { return -1; } // tourists are also sorted to the end return ldata.GetName().CompareTo(rdata.GetName()); } diff --git a/AlphabeticalKerbals/Properties/AssemblyInfo.cs b/AlphabeticalKerbals/Properties/AssemblyInfo.cs index 024eef3..becac0e 100644 --- a/AlphabeticalKerbals/Properties/AssemblyInfo.cs +++ b/AlphabeticalKerbals/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] +[assembly: AssemblyVersion("0.2.0.0")] +[assembly: AssemblyFileVersion("0.2.0.0")] diff --git a/AlphabeticalKerbals/SceneHooks.cs b/AlphabeticalKerbals/SceneHooks.cs index d8f74c5..7c5e612 100644 --- a/AlphabeticalKerbals/SceneHooks.cs +++ b/AlphabeticalKerbals/SceneHooks.cs @@ -10,12 +10,19 @@ using System.Text; namespace AlphabeticalKerbals { + public class AlphabetStatic + { + public static readonly TimeSpan update_interval = new TimeSpan(0, 0, 0, 0, 750); + } + [KSPAddon(KSPAddon.Startup.EditorAny, false)] public class AlphabetVAB : MonoBehaviour { public bool HasBeenSorted; public EditorScreen CurrentEditorScreen; private int sortAttempts; + private DateTime last_update; + /// /// Module initialization @@ -73,19 +80,19 @@ namespace AlphabeticalKerbals { try { - CurrentEditorScreen = screen; - HasBeenSorted = false; - sortAttempts = 0; - - if (screen == EditorScreen.Crew) + if (CurrentEditorScreen != EditorScreen.Crew && screen == EditorScreen.Crew) { + last_update = DateTime.Now; + HasBeenSorted = false; + sortAttempts = 0; OnEditorCrewOpened(); } } catch (Exception e) { print("AlphabeticalKerbals: There was an error in OnEditorScreenChange"); - } + } + CurrentEditorScreen = screen; } /// @@ -109,6 +116,26 @@ namespace AlphabeticalKerbals } } + public void Update() + { + if (CurrentEditorScreen == EditorScreen.Crew) + { + if (last_update + AlphabetStatic.update_interval < DateTime.Now) + { + // polling 3-4 times per second for crew panel updates + OnCrewPanelTick(); + last_update = DateTime.Now; + } + + } + } + + public void OnCrewPanelTick() + { + KerbalSorter.Sort_Kerbals_If_Needed(); + } + + } @@ -116,10 +143,68 @@ namespace AlphabeticalKerbals [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] public class AlphabetSC : MonoBehaviour { + public bool DialogUp = false; + + private DateTime last_update; + public void Start() { print("AlphabeticalKerbals: AlphabetSC started!"); } + public void Update() + { + if (!DialogUp) + { + if (VesselSpawnDialog.Instance != null && VesselSpawnDialog.Instance.Visible) + { + if (CrewAssignmentDialog.Instance != null && CrewAssignmentDialog.Instance.isActiveAndEnabled) + { + OnLaunchDialog(); + DialogUp = true; + last_update = DateTime.Now; + } + } + + } + else if (DialogUp) + { + if (VesselSpawnDialog.Instance == null || !VesselSpawnDialog.Instance.Visible) + { + if (CrewAssignmentDialog.Instance == null || !CrewAssignmentDialog.Instance.isActiveAndEnabled) + { + OnLaunchDialogClose(); + DialogUp = false; + } + + } + else if (last_update + AlphabetStatic.update_interval < DateTime.Now) + { + // polling 3-4 times per second for crew panel updates + OnLaunchDialogTick(); + last_update = DateTime.Now; + } + + } + } + + public void OnLaunchDialog() + { + print("Alphabetical Kerbals: Vessel Spawn Dialog detected."); + + KerbalSorter.Sort_Kerbals(); + + } + + public void OnLaunchDialogClose() + { + } + + public void OnLaunchDialogTick() + { + KerbalSorter.Sort_Kerbals_If_Needed(); + } + + } } diff --git a/distrib/AlphabeticalKerbals.zip b/distrib/AlphabeticalKerbals.zip index 9db0f6e9c4f732122dc881d3fbb19949197c7521..7c77231adbd7f9ff256916a64eddf6eee550dabd 100644 GIT binary patch delta 3905 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 QHdB))5F!S*3;+NC0Q)vn!vFvP diff --git a/distrib/AlphabeticalKerbals/AlphabeticalKerbals.dll b/distrib/AlphabeticalKerbals/AlphabeticalKerbals.dll index 94d665327934c6abe56a1d26a3172cf248708129..0cd5eabbec46d8113ef69560362f6f19d7729bfb 100644 GIT binary patch delta 3949 zcmai1du&_P8UN0?55Hn3*G}vteZ*C?P207!KuMFdgqFUNbj?PWImvBm)%8tn zrw<@;s+A6qw$a_KQU`1>U}J1ZOEYbVbsJRdpHXQ=+BDF#tU_pl4UNb6gASmXVPgYFm)uRHb3?m+W8 zqV2+P8_^}@RAZ>(%S08>-(CxEyOAgDA=c`>w;rY_J`3#!S%NLLf6iLj5__I4soMhv zaovs&CyicON)!tbF?(ltjlF|!4QE^!-0XwAz8H>A8${lF;Oq5G(5niE2e2Gd7R=9Pm8jg{n&I_(&RqhPYL=2vKj00LC zaaz#9X+J_KL`Jo@+Q%i4cOHWwb$%BqR#7nfV5os%qi#jOXVn7guCNN%b*kT;)I4oG z5_gBMFwbz3*Ti+J4z4bV7MkOY8)}@1_L52-Kk1d|08ur07CCaLL!cs*j~XfN zi7mi9FV|(MK3!cNRc#Hso+k7{7Oho?BIsu9MTNUB|8*Z zzS?c5%YEEqXeA0kP|0W_$YYDZ7(-rONmdknEb|#^WKT#nRJHTRC6hxK?(7i+%RY;M zmp%V0Quk*$y5njbm5bG1jk|^=;ngv_TdgfZ)={G#8H$Nr!gX{;N^w2Dn8y|)+4!z7 zuIN9pviSz+Gia+CZ_kY*RIExk%;$btmZzgI@GE)%WcfzO))K&UlVe5gdcIj$u}8(c zVu+VWK0UGJGbgr+iDGksL0&vOg*~R?h6Ke8J5`G!D-lWv7Y~ZmNf=r<`H?VS1t}eL$dX1YaGJgDOfcExl0YD@#`B)^4+^|wA zmq%o}MM3u4vJr`vv#hUoNajnKt!(4>h=is^^JB}9pG-1_%DhQ~$AV(i=vaHMOD!)~2$lcQ$*YLUvF>Wy=VM8@Rma+ZH=V*3D!j&}R9R(b0f8rw8YbP@Mj1Z(Oq zAbuTmde1N5AdU^@9pxUQ2#_fuTcpOIZ6`^GR)$(2B^h znm$JLJF$ueopUsqnn5p>#zc67E?zfpcB$YzN&nzt%qj3B?Y)lkR&W+?Bo!;U z11rwxejul>N%;*auT{ib!FnL0|8G%gmGqpJb8o};VDzTqp%W@YN}{`UbfTzwX&IC% zS|RZ!iCq%=B<_?rBryf7p|q3_NqihwPjAtP)=0D16|Hzv_&vBT(?{BB$cL0$(AgKX zF5oV08!={U16cV#@ickZ04rKh>e(bHR;b6Qj=f3`!nIL*h#J}Je3FhKfKF$C-=$^j zOY}n=K_}F6*t7@e0xbWc*YIj6EX}aI5Bo)a0rExuKD|h9X`cYSDrYa!ZxkP!m25lN z%M@al$)&F@(oPm&b!>>)2;PoIqW}!i6mS7O0&JqEfC>6Fa3x&=u9w&??OUYWFY${K zN9k|yIY3qXD|lmE#Ge4R@+9@rFiq2U=q#P5*Xi%1&R~O31HO8%UVgb!S5;cXHsQ5) z(RTHksVq5{e@H^J!)U^HYED3Tw!>NnHx!E^22@mhPRpK zm^nt{W??v;?;0(n51U=tvEFQIBxBe6npH7i-|E{?6vFOwK0T5#X|q|_mO5xsPpV)J zq#+Du(}iQb+3|GNq^(wJY~a|0Ntv?Xgp)SGQV@gNvs+V>+0p$y=~TuV@6K3xuuP1B zkTR)!VR+J!H&3R=x(fLAnEQ$E4z?13yL0A|UFJR-u$(WI8<=Rfna`V<{)yC)tmL*o zsaVx{eYAn}=mAU-U_;b{i!U8I>DN?r~PYO z80Z=sOWQy7$K6f^gA?{^{^q4Sa#q0-#CMtpN6Z{KrHiIRX&)_E0_S{zy(}qOvCTSy zM0(78A!i*Uu=XCBOl8nZA@^m?vSv?JKC*kT8}I)q%F;NQ6vg9~1#W?yqY>CM(6+*w zrvjug*bDfKN*tpkY&qy{7`Gr5;9cQt5*92$I@StfN^b{dJDn%{I*}_`S)uDV@OP&uOGtP~gEK!ulHC1^yYJdvx9ZXZ zif-J=b^I7G_Htc!_F|^9>FCpK6k428;o_%HP#=&%|5eW4e*r(YxvQ1bH>7V*r^WJe*n8coT>l- delta 2572 zcmZuzeQaCR760A)uAl9f#Lcr4+i|?qFG*YDgf?lD6|_NHNN6I|rjQkqQbf`&V%2C( zom5?!RwwEPl=5XBA1WUkLen%@|5~c8onTNv+CZT4(V|Z4qE4Hp!B(w&><`d1?RW39 zw~6*j?|0An-E+=8_uS+6JUcY|^@s0m?@?cjqdLx^Jy$1sfFub!Ag}4Kyl_+OLLV@q ziM7BvtKuc?`xLD>4HIvHmN&5GRE|KQE;Kn!b+RacE@vUM zG*!Q_8kSM(s5aLx}#2gE?V?#T3Otq`-YdmVj~w(GG-kO2B1^t_UpY?bM3?h+9@G>SWXnRb%J~#~C3m^Q{b-XI_qp7DIwK_U8hY-DFRDnr$c0@1;xm z4F!&Do=Z4(YDd#POPH@7GWk8p%sKH=^~7?kg@&c27XMeF46htQciW1<8q&Iixs_gJ z%X|aV(~bva^<)buK=6oqcpe&RvGM_hJU6zx-BQ%5I>?ksLI)`ZoPWFRrnMgn$BcF1 z{#LUt_^*dMubyDJJN5%_aehb3qcf!)yKbM>dpsTG&rx%mM{$0CP2Zyp}t{CDbq z75>u5(y}fEt#kt$6K$qBHk9G@8jEAr^$b*GFxxmPp0#XvQlk*NtVMW5_bVNIi6;BVz=+B86~MpaomC+KzvMH5J$ z%{MXyumd@SsX!w(SZA%Pj3!vCJkDC1sYUoSqR(iGb+a*xzYtH#54qB$&SO(fN2%bT zx29opf~Zj?scGT$~9s zv&EO!bd46XegZcWCAJ!Q-pJpTx_kB$1ukOB7f}j(jp+vC{1KBA_>+ucizS$nK5Yxp z;X8PX)rek$R~lSraM<7t2FDFf5}UEZ$h!?5CT8$E^s2Il=Xo#7*g6j~*oSyk^;4dc zSFt7!sdaq0Z&Mq1cW+~i4moQpKF1T-$yHBH6E9f%*!$PXG3;Yd8&NTWd-(0!Vm*x} zY{d~WKgV%o4bw^HJ@RYh5p)vYD|378wj6cHi{)&^UScaY5j!wW>_UmS3Xc-MX7F0W zUvK15gSQymjwfmJZM-hFV;b*@1H|8pZVd8sc>s^#IlPKDp=Mc9)-)LW%z>S&@9cl$ z54eus@WuV4zdTMGq6?$^l~fvT^gn56^RJG1{`T0K(E6#Fjg$V1F>gM-XjFv1Q8aHO z|A&oze#qVEf6M)<|AM>3KjU`9uAeGxo4jMRSeltCVflP6eyhlg>>8Mwo+%agp?K$Q zgS+=k-mzn5pWd#^f2FzLpGoYTf2!%nmj1COGjII*rITXl`_E1sC@xtf{A20GSKc5) zkg-@y@jkLDEaK}dJH9&%DdT(Mdnm87a)^Y(R(v=<90~OZv_Ux{KI~uK(pnDXM0_w3 z%_&atK`E`Uh&Xn0eD-|9|9DLr7MP)>?$TI<0|eNG6om_R~Av`0m_<6+K^RcEa` zfz@LofygiK+Imw<-?@X*=7-W9mv%(K|D+`!3p2FdjJeRo@6J3Ydi|3buez_i}qV`G>vL#CN^ba-e_SZU2X;^o0KdGT?_+