From ee2ed4c4695e3e051925d3c213732165fcbc4e05 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jul 2022 10:35:51 -0400 Subject: [PATCH] Better color picker --- core/assets-raw/sprites/ui/alpha-bg-line.png | Bin 0 -> 1331 bytes core/assets-raw/sprites/ui/slider-back.9.png | Bin 197 -> 2418 bytes .../src/mindustry/ui/dialogs/ColorPicker.java | 156 ++++++++++++++++-- gradle.properties | 2 +- 4 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 core/assets-raw/sprites/ui/alpha-bg-line.png diff --git a/core/assets-raw/sprites/ui/alpha-bg-line.png b/core/assets-raw/sprites/ui/alpha-bg-line.png new file mode 100644 index 0000000000000000000000000000000000000000..02becdcf15d341425465a6016adb307c6dd87c61 GIT binary patch literal 1331 zcmV-31 zaB^>EX>4U6ba`-PAZ2)IW&i+q+TE35lHDK($G>}u9zj3^k7G2>^aeeC{~BNRz1?ox zo$05>i5et8_@N2skMARV!$r|!NNS!-&JkBCsc^-_<8_tQQ%tL0*JBCKFY-W-1%^m4 z%Jpb<>sQG2qaiw8<-zv~`!+v6NXYq;Q`&~gc};S0dk*#3hT2wKq3k=| zVO_&~4le>jmb$``FrPvaSMOH@GH;fO(a@79^q{jO5|$`$V@Sx$=iLd6&k1@-@?#d> zXP-YwKG&@w?{b-UjxhP<0_i)s-2VC5vD^{y>%xBh^>g+;M)xt!>+5RD$Y|abwUSK_ zGf+H`a#^osG{dc!+iC^PV~q{Sdu;JQYgCAl@ewFdr%Hp)H8yGpG4aWUk-4!fnTv7Z zCX-W|jRu<(>Ea;S_zWTt^BoHuZ1^an-qbeL5A6%oXj9`wYU5VWRsN zKn>=(4~wqh=;OPaGu{ ziyf?VFe{lF@f2}P)pW`ivL36Pw>WE+8f)E?zc8HFSC+X>a~Mf1VhIvND5#-~3T(t_ z)k(3Cru~GEf5`PqYT&7<@8hQ+A~wO`%W#-p}Zpa=^eX z(7WdK*4oGE1CXJvQa8ZCAuw8`>~)`a_jLC5@0nJAKht({XIB}-X#fBK24YJ`L;xxP zBmgxV#iqpo000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2j&M44g(O{j_}j~002ix zL_t(&-tE${4FDhv1Hr&bnKnaZCK!SO3GRB!&5x>DaiF_T=8>7<|K9%$z9s+xAOHk_ p01yBIKmZ5;0U!VbfB+BxuiCiN4pGR#n@s=!002ovPDHLkV1hPNZW90i literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/ui/slider-back.9.png b/core/assets-raw/sprites/ui/slider-back.9.png index 71762a216384c9f8d41ed1f374acc675ea8138a7..013c6cc7bdc27d80826e13861cb50026f3219751 100644 GIT binary patch delta 2408 zcmY+Fc{CIX8^#Bh8QHsp42_T_4KAbZjFF6OWQ%GHGGpI&W63f#)|)KJMHu@UqYxQF zXtEAj3dOjMhA<&(A-?W+&UerK{&;`y`#k48=l$nB=b>?Ip3IOV^6cKeZX0Ut6b=at z4siGKb%TUP2D(AqBD~xIfQa`LTl>sjCH})H%)?E8Y@W29jKU1PyEdl+ z#k4%>q7ov9=eMnj@in}6z#-x99ud;Tg=P;Mhayzg-tn$T=4`By$5ogVP2o-T7poJw zQ6w3Y&dxE-gSS7-beAZJQOsbQ2OFDZ-GesN_K#c0r|rbZSLr+gl|-qLUFkBK#=cwV z3{d@aOR}Bo2cL`8wt7^1IwzEd*{EMNZ7m(B)ZcV}tlaw8JiBBNvg+3~Bluye>HP_D zWcW>;N9WsboFWH13xm84U$F5B&U8a1EcIcC(qg_^*vHBQjNdQ8P1S>^$TJGZDJcxe zQ3ov}vM6x|?M_HJKO1RuYBqO}j_|%BjL@EQ6^ZW9{!YJzr(5k*YkQ?h;I&!fh9U=I z_WsLkE6a@+hlk}#7q`20u#$(F&#G>$RgC%OeO4ds(f<Au8sR%C zr?11j$HBL@uQ?~5b}`dXv=9s_F3-@SWm%7yN$N?)xJ`~KDLXiPH8fSSb4Dv*;w^V> zcvsuGn8Pmm*E{8TmUyLHXr8@57#5uiUoP=UNABnd`}7K2c8xEQOVipkZ#I7$Fva_p zO{_evR^g89s7bW8?g(>Q3O#G1sq~tmA4EO@DUS4ZFWo7u3bxUFD1nycS9J46(Jg3@ zlJ#u2>HIL>BL0<(JVS#UqBfg*mlChbJ}Qk4yVCuTdy?+`eGeNO31ug=Y1--ZK9R!fIcj zd+*kG0H_mKF)tjAi-X>HDwub_2X7Ce9K_piFtU4^jeNC%Rk|6rB-Z=3*i>S8lsSj& zmh1Q=DtiWLk5hlba$I`yfI^1;ne348YoP{9Xq#LqHY0>d3dcQKjFMV0?u}I%CA&G6 z%@D`O?jc6?(+f{GMbkL9VnlH*RN965niEwzq(5fFd%!I3VXAX8*jB~Zs8;@Mn3kPc z&;#1_)6Mt1dwhi)#haTGXNkYDtvxMjr$;8QksjVW>mJsX6^{^0+5Aj_;fh12u>Q4m z!Vg+Zw9OwopDDc>tGZ9B;mfy6im@Kxt!#L<0xcCw1pz_17b8FaYRkmU6vf!j~1 z?z^k6GOViG-rA3Mujh7A@Hk($Mho>7Y#(;K+drM^+In1Ixwq`SsP+&JyX>3Y#oScm+I0BYGj(sp7E;SCbBa8m%M+|6 zq3p7vey*%nLUNtnz(Ri89Y@gNH-vS#ho;mg(0T$f1y%uKN? zbCU`z#rsq8?1D7esg{C@2>-40+gKtY!k9lXn0~8GP1dv)rJqX(c`0N4;k|5SOX8cr z{e1gZ!i!@n&+krHx3V=5Ubgz)Nedz#{q)6sE#k{YN%@a>o+=z+ZFykx#5UC>YMrh% zmUB@}?@0!NtD^5gtgh8<@bVH@1%^=|t<>>wdsuIoT<*bR8jfsVyLbMi4dDi=msbLd z3DN5J*~?9z*K{Xr!^xF?`312$ZC9sG@ua(=$vYIK6R5sx$hUU{$ytw5(4ksM4TLUR z;;P$GT(YFzWQ8KaPYg$F7s@5RkA+Wz%0AHVdD1;OY44XS6Pfbmi(3kD{qWKRWd z%LG8TW*oOv=a0-@4T^49W3A@GsRfXR%(Pi~c(X}YN!s~Fwfmy&!|c^GLVZF@2ex@x zXt$)DDD7l&VeI%N*~X-2$ypiz;E4A^p{&p-)c^AEX9^a?JV2WC>VauEo943@q}dQ= zMhP4%Di$=UB3hzfEoMhhr*8A*X~`=?(?~wu-RZQ)aVbspg7qZGHxB0KPvxJ_DjcaP zKTF>EtM$zK8gh-nq2DpARqF$OLk#_3roePQ*RI0jD557Jd%wikJzGN&jSdCl_BOum zKwme(iw;8KCktqRA`_h<{)ux8NFn2yz{tTXk(*gJm?6w-51}T9{RG;=#S!it?m|h8 ziJC|zsKM6Lr6LtOHkn+NT=uxqrZeNKE$amhdme+`Dm+Z+F6e9=Cgh=rCU}vn84&#| zVhUMKaz?cl_Yy?E^dY_hZ*>_!6C4!OgH?+;1sYd@$8qy>cHakh)s!WGZ8-3fiv)s+w+_;K8^wOm;zlQz-vV%k_!yxl;a+BT;Et@>@tp!6YO>1RdjGpvf>j(006+_ zeAU0QDuE zE3+LFghxUzwN>-*mYM);xc7Z0GAMi$jOEZ?Ln2z=USBA9#DK@;V(7Cd;X7tQA-4od zlG7|}%1$&D^L%p@{`-;RhNIBpRlAlSwpWroTvNla;QK$}Ni(%~FZ;>xC?ZOsV1^dM zoyUG#udSOZIJ1)P^WJ2m_LVZrie{Wj)PgZqDg69Wt6X*Up8xArRl6Tv+-AOQt$t9k W!uzwk`IZCS!r cons = c -> {}; Color current = new Color(); + float h, s, v, a; + TextField hexField; + Slider hSlider, sSlider, vSlider, aSlider; public ColorPicker(){ super("@pickcolor"); @@ -23,6 +31,17 @@ public class ColorPicker extends BaseDialog{ this.cons = consumer; show(); + if(hueTex == null){ + hueTex = Pixmaps.hueTexture(128, 1); + hueTex.setFilter(TextureFilter.linear); + } + + float[] values = color.toHsv(new float[3]); + h = values[0]; + s = values[1]; + v = values[2]; + a = color.a; + cont.clear(); cont.pane(t -> { t.table(Tex.pane, i -> { @@ -32,25 +51,113 @@ public class ColorPicker extends BaseDialog{ }}).size(200f); }).colspan(2).padBottom(5); - float w = 150f; - t.row(); - t.defaults().padBottom(4); - t.add("R").color(Pal.remove); - t.slider(0f, 1f, 0.01f, current.r, current::r).width(w); - t.row(); - t.add("G").color(Color.lime); - t.slider(0f, 1f, 0.01f, current.g, current::g).width(w); - t.row(); - t.add("B").color(Color.royal); - t.slider(0f, 1f, 0.01f, current.b, current::b).width(w); - t.row(); + t.defaults().padBottom(6).width(400f).height(44f); + + t.stack(new Image(new TextureRegion(hueTex)), hSlider = new Slider(0f, 360f, 0.3f, false){{ + setValue(h); + moved(value -> { + h = value; + updateColor(); + }); + }}).row(); + + t.stack(new Element(){ + @Override + public void draw(){ + float first = Tmp.c1.set(current).saturation(0f).a(parentAlpha).toFloatBits(); + float second = Tmp.c1.set(current).saturation(1f).a(parentAlpha).toFloatBits(); + + Fill.quad( + x, y, first, + x + width, y, second, + x + width, y + height, second, + x, y + height, first + ); + } + }, sSlider = new Slider(0f, 1f, 0.001f, false){{ + setValue(s); + moved(value -> { + s = value; + updateColor(); + }); + }}).row(); + + t.stack(new Element(){ + @Override + public void draw(){ + float first = Tmp.c1.set(current).value(0f).a(parentAlpha).toFloatBits(); + float second = Tmp.c1.fromHsv(h, s, 1f).a(parentAlpha).toFloatBits(); + + Fill.quad( + x, y, first, + x + width, y, second, + x + width, y + height, second, + x, y + height, first + ); + } + }, vSlider = new Slider(0f, 1f, 0.001f, false){{ + setValue(v); + + moved(value -> { + v = value; + updateColor(); + }); + }}).row(); + if(alpha){ - t.add("A"); - t.slider(0f, 1f, 0.01f, current.a, current::a).width(w); - t.row(); + t.stack(new Image(Tex.alphaBgLine), new Element(){ + @Override + public void draw(){ + float first = Tmp.c1.set(current).a(0f).toFloatBits(); + float second = Tmp.c1.set(current).a(parentAlpha).toFloatBits(); + + Fill.quad( + x, y, first, + x + width, y, second, + x + width, y + height, second, + x, y + height, first + ); + } + }, aSlider = new Slider(0f, 1f, 0.001f, false){{ + setValue(a); + + moved(value -> { + a = value; + updateColor(); + }); + }}).row(); } + + hexField = t.field(current.toString(), value -> { + try{ + current.set(Color.valueOf(value).a(a)); + current.toHsv(values); + h = values[0]; + s = values[1]; + v = values[2]; + a = current.a; + + hSlider.setValue(h); + sSlider.setValue(s); + vSlider.setValue(v); + if(aSlider != null){ + aSlider.setValue(a); + } + + updateColor(false); + }catch(Exception ignored){ + } + }).size(130f, 40f).valid(text -> { + //garbage performance but who cares this runs only every key type anyway + try{ + Color.valueOf(text); + return true; + }catch(Exception e){ + return false; + } + }).get(); }); buttons.clear(); @@ -60,4 +167,21 @@ public class ColorPicker extends BaseDialog{ hide(); }); } + + void updateColor(){ + updateColor(true); + } + + void updateColor(boolean updateField){ + current.fromHsv(h, s, v); + current.a = a; + + if(hexField != null && updateField){ + String val = current.toString(); + if(current.a >= 0.9999f){ + val = val.substring(0, 6); + } + hexField.setText(val); + } + } } diff --git a/gradle.properties b/gradle.properties index 77ed3793fc..b3da1e740d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,4 +25,4 @@ org.gradle.caching=true #used for slow jitpack builds; TODO see if this actually works org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 -archash=b1b88883e2 +archash=47925a7b91