From cfcd591628602184aede8518fad43ff316a3ecdc Mon Sep 17 00:00:00 2001 From: trunksbomb Date: Mon, 23 Mar 2026 16:33:48 -0400 Subject: [PATCH] still struggling to get the placement right, just need to commit for right now --- art/mockups/rename_docked_compact.png | Bin 0 -> 2549 bytes art/mockups/rename_docked_normal.png | Bin 0 -> 2632 bytes .../rename_floating_horizontal_compact.png | Bin 0 -> 2348 bytes .../rename_floating_horizontal_normal.png | Bin 0 -> 2466 bytes scripts/generate_tab_mockups.ps1 | 327 ++++++++++++++++++ .../bagtabs/client/BagTabOverlay.java | 179 +++++++++- .../assets/bagtabs/textures/gui/bookmark.png | Bin 0 -> 399 bytes .../textures/gui/normal_active_tab.png | Bin 0 -> 399 bytes .../textures/gui/normal_fill_gauge.png | Bin 0 -> 362 bytes 9 files changed, 498 insertions(+), 8 deletions(-) create mode 100644 art/mockups/rename_docked_compact.png create mode 100644 art/mockups/rename_docked_normal.png create mode 100644 art/mockups/rename_floating_horizontal_compact.png create mode 100644 art/mockups/rename_floating_horizontal_normal.png create mode 100644 scripts/generate_tab_mockups.ps1 create mode 100644 src/main/resources/assets/bagtabs/textures/gui/bookmark.png create mode 100644 src/main/resources/assets/bagtabs/textures/gui/normal_active_tab.png create mode 100644 src/main/resources/assets/bagtabs/textures/gui/normal_fill_gauge.png diff --git a/art/mockups/rename_docked_compact.png b/art/mockups/rename_docked_compact.png new file mode 100644 index 0000000000000000000000000000000000000000..62fdf3f37d20427dbb1f6c5d1c8e992fc4c54d08 GIT binary patch literal 2549 zcmds(c~BE~6vr0~aRD&_K|GLzA_IsN3seY4aHDdJPs2o)eOEi+mWjHj1QLqpd zM?hm3#tK#uu$&o=C|H9u978KdxJIssAqfFO5)wi;{B37C?M&Z1o;^m>@WZTz$n1~&`|);LBP)=AQB$$nvARAn-1lu9|5TBwwQ${h*&5P0)XcX zLv@rMJlDVIe~JPCo7=UQ4wv-!ENsgSI0PL}2^Wn#&$r+jUwKD0dA-S^qZ%mt!PMj7 z25voYFozJ0U~cE>qjS}pGmyT0)^?#!HeO8e#dv2WO6!xV8g8_Tl}N>b@9%~osPP%Q z^l8Zv=`xx30g5>Z;M#yMg3wnUU;$4ENTLCA2%SNF-RdofNZY@;FnS4UY--A~e>M8x z<#8zP+8nuy+_f$H91V-C9I9kse1gog&t>&)-pQ(QBaL|#*&7@~T3LE|`O!lB(M5S! zQximtHJFXKIs_7|pve9IJ9Ataw)wK`LyTmsMMV_vnW(DcZW6$XV+;vlgJHaR;auXK zMPoXFR-ONl$$)v#6D_9G5T!S<6_a*aM?};vKO6?K+YJicJC#~WC%K{BerN;zHjjKV zUJI;0;U9*8H%T<43e5zS6YJlMG0=7W_cHM_wl=eN@q}nxc|(4=s30sgXygcFcgY@< zMogzaNh+qWaO|XCT1;U`yQT-E}vZ&U=%`+#){;Qz2j|WNX2z zPr^MK8pPiWbD}K#%2el4?ZIqVYTNh|$HUD7?aYx*%0##Uq4Wq8hv{(SM|Y>rO!3V= zISqdS=pDT%)qx8wyf?5?2k|4UX(z4MAoFRxsWco#Av^TsXr+IySDKD(h%3YiiVNbu z(PsFQP1~PH4%tcy`U&KhxAqxX+I{63c4`8Ua`H8 zu(hbEts-ZE7lkZZF9$>^1INC#UItds`!hiorkL8e{^*sWf}J>9ElLwQerC$IdmZ6_ z?%qkOhI1G`GgXLFu2*U_bVc9~|8%-F+7|YLsO?+(3LKHNkjJ}-Uc?kJqO|u}gnjMP zuIm_ns5{3gzHFQ8HKVp$IF6I8SVC#|3f-!lVW7q}ib)^LtHb$*qcN+?izP`?!Kt_G z#issQ<#Uz|t@pe6c2s622&tBTXJ>1aZzYI#w>D}_pp(NUP+a{sVuV$#gcR{5Gb|2L zsIQKvsYK;IFY*vk=Z_%Xxgv*KL=JS0W?EHa=m@TlvnN)Rl=#i(#YA&>++BYPM#oPkEZGHISjk-C^&|ox?ynTaEs4+0E=e zH$$uq{Vkd=Y(QFhq^~Y{2kR4-Y+~^?pj@7rq8QGV*5zR<0?`@=YNI8!<6b$wSs?zp zr+Gg(fTq_4Zl|CBDcD@bA9p5781l)3iQThQ*2+9<@lh;3DPw>?hJoqqJB_|aLCI`} zRjieDkU~b<41kigSE;;dZ#N sUtZ!e$z!pls}->yu)vv*9D&w!p54B-ps{W!g^y}Lz~P`nm4ryzANko=H~;_u literal 0 HcmV?d00001 diff --git a/art/mockups/rename_docked_normal.png b/art/mockups/rename_docked_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..7b4ff2d7bda82a91b57445f0d36e137afc777d19 GIT binary patch literal 2632 zcmd^>eKb^Q9LKLr(?v4rMeAiuB+;flr%*8%FJYCDRS7Yo>{)7Liq;sDAu2_u-D+zR zqm{fw4jRHtUP_HH2;+5DC4-q!84WXLX7Axc7IT=lMOq^Zk9k&w0+h z;N$JCt*NgG0D!iqhpR6Ds3D;5K@bVOuj}&Xp`b?cb$13z+6>2`0U`po7Y6`knOgIq zOQEqww8tS50IX<)AGK!U{cvb*$kP?)cP3agSXLO+`$g&qX}yJSA=u=({ObbF&oTKs z5XrZADBlfvo~F@yue4H%ehGZO29e8QA#5!=XP5Y*%byiLZOg~1Ud}~OICH&;w)VW2 zx2Kb&#R{1RI7E40pC$#kgX3C2Mmh#q2QE3A^ceyp2qhMa&+1Bq2Yf6+(MHnA{neJc z8GBIY)ecrpiUydYxjr_a=$LwD-}G2J-qMW`j*>i6&s>T7$^^WhidnZ3;pc+71THCD z5AH^&b)yibw6ouVw3Rp~YefBdOpZQ{;EM9m{%@xju1?9vXAcXziw;f+OPp1K+bjo- zX#~G5pya&U5X>Ka z%(&x4Bb>4TWz3Hbel@(EnOXidk|14(!<9zwsCNs?uBaH^h1S6ik|#vNd4*lsO}lt2 z4G75dP;(oSd%GD7cBioEm{?G~0b;v8EsOWk2zvu=?Crx<^y<4~S7E}2u}8MWeV*cO zIDzr=2YPlNo_Z&Y!y@*f0!E14E6%a5*Lz2eE{GBMqWYJ`q{o(#&~|093t9h!)IZMw zGSBf!;MUmJ=~=U#uo=0SiUxk6ktStJau$!XU`j_Grb6fKTG5d)``9C*g{*(6Wq-h7 z^-=~E!weQSL1yN`=f({OpiO`8j)J=9o3ZxGFPr@j`|k{MLS5>=TxY#pG+`hMKJc_v zc!JMEpJ@VV9mVQd3MF=pZFvpFMF;z7|3zH+9+ZPj@TSX=Et{A!kH0eG#GI59sdj>1 zY*Xwv{FWHvu{b%hmD0`ecWz5s zy>$A*`fDr5-h6KR(nx<3aBn6~rNK~;RRy6_PRw*nt-Nw*ESq099nfVfA=T?&2ODgV zic00Gh6w6xi#X}T4dh5^_Iv_&*>QO=zn{#NsKpo4$u-2`!6E8&>yRRjukhd#WvPi) z{*Aggp7JV#-4mAMXclFBu?{moJ?WS&NbU*YJA6x>Z=S+GqRRm6Dbm!)=_s*CIXi4X zizav>7#)1ODhU}>$gM&4+$i4pCPt9@Sn__CjWm|o-#Z?;cTv72s4zdL>`GF`gpzY+ zanVt_h@f;#lpy(@1lM9;J3)abB41!CN;`TbPE!;rm21+M zX8U@016b8_6?bOtbqH(^$7y3*lEf*w5{`uhVs-Mn2(oC&mF0i_;r!2kdN literal 0 HcmV?d00001 diff --git a/art/mockups/rename_floating_horizontal_compact.png b/art/mockups/rename_floating_horizontal_compact.png new file mode 100644 index 0000000000000000000000000000000000000000..401c250a52776afe7d10e78993c271a02a9d96ed GIT binary patch literal 2348 zcmeAS@N?(olHy`uVBq!ia0y~yU}OQZ?{KgI$!S9O{{Sh*;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWCM0j)R^qjv*CsZ|@lP$y^sa{?L{)nT=0G zBH@(BLSw6f9PWZ=0g{Z%Z5S7xDE}ZS;pu*XvxY+||76~pZfn!i=IbA!M&G9`AG zIaX9uG>AQVTXsQ<hoq*O&Xxzva3xSK!#;w(4*1?(TMxCwA^GTr5HQgmD(?Wm!`QKHPz%F>v}vT%aJgCYfP z7RaPm+JVBP@3GE#cVMs_DxCB5Cn#hr`Zj~Ks&E`Hoc0_PJ`XLcQLtIBL|7!~75b3^$MSDguKxJ@&(ZH`H%`h{s^43xAhJuW<;U(%b?ZNF zDxNv_PQ}sPBEZlwIPRDC)NhYBC>V<0JPCVuWY7vvVNLwqcIVfo$@||tSzj@|DL{k! zkj9_2#{!R_dh#Rh&Z8AKcb@Uf+w&-v3mDHclGV2tfrCJ(#j>nOyL|8ppK97r>zr46 z^JIM4r*KfL06i`8FYK|#qiW+fPx|%gI7D^;m%^_RPk~ z(L2GioQGtrcTTk)yuzuDH})xR-}mN;zV%OSP{KUb#PHn%OL?_Pq36F>&FYWx(?*={ zHyw2l;Ob?UmN&a&?WkcQmsj(kV7=ARgbeYPM4OZs3isaa&6Z?Y&_=l0@e^35N+3zG_f3NOp z!OI1#4{!7TdA5B1zCUH<6BX{5J8~G_xOcm*^~3i4{~kYb z|Npo9$JZZ!cGx!w{G0kPQ^1Yq(Rv}4hqs?^|M_Waf768-3O1Yvir2|*QLxGXQ~Gi5 z^Lg^$T?OW`B>tXy=-cY%AM3gKetr5}y>het{%UoOgG&W0Ug)p0-JgB#-=BAL6>65h zSrEUsYHN4=?2nW7X2zrN|i+-=Q$@AKuCEVu7_biPvSc8~POz23L= z@1EKA_s6)cp}S${+VffUo}l_jtKp`SjV>zs-Ml zj6Z*yWclOy`H!A$eLh_f6ujpp>d)TZp1;5H|4YZ?-_v8boz&_!n14Jhz28nbFRrRi g|L1ScL$$y4o4V|i>rx9;fGr#bPgg&ebxsLQ0P?c&2><{9 literal 0 HcmV?d00001 diff --git a/art/mockups/rename_floating_horizontal_normal.png b/art/mockups/rename_floating_horizontal_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..4f3994d515b9aeed76e25855378b3a1dbe3e1fd2 GIT binary patch literal 2466 zcmeAS@N?(olHy`uVBq!ia0y~yU}OQZ?{KgI$!S9O{{Sh*;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWH!jxu=U`NJZS+JBEERk)p>R#&Iw%WL9zG zIN8$Y=90qJ!jY(=#NnD{$E;IdO!cov=_Ve_x*Uu-tbUwAA`(v1qN$JhO#DxH!O@dIGHvGvm~f<9Pkrp zm`kq2+opo@a(3M#n{PX=R_K}irl@qMmD@sJfg=a5zODNIuXeY_7T!ZUZWf%4+h13^ zK3F7*P4QmE4!5QN4}lkM0$iL-cR8FC9T!MDYN&9OD08&3H0H4^oS<-_S3yLGWtU)! zQS}eW3z)uUB&%;PQlIAy3e(~@ zPr}|EDb@t0wZy);cTUZvjp3UVa^z1eoj&)^rpfUjM*uy#_``ImcBOr0hyC77gSg$F zHL*rvy2SLk$8VnO)uyZasN#8`r*5+sy-Zc#|K>?JCN+WGyX=> zhQFMNf8M|K=Y7uiWe3Z{%j@sfe7$-+zFa(4`eX4!D-NfQgWqm_Q*XKd|DAt2|Cb#} z0{{N3mVf`Kx$M`yZKdxVyZJ9{&6{_-_WQechqvFqSNr4N@BT->4?`_z*>9AyKG(3L z-pis^;~eWl`TF0F_x@OryMDf1M*WZ9`S0fD9bzsBk;)W%ay~?8!Pj^U-_}?$E^*yN6xptR^Z^@HeYhizfi@0 zr4PS29DgsrjXn4G`WzAYEzemL^K7?OzI(X#hRychmfL!N>@1LFQLNBm`RFkJ_rD(t z{=S~SfA9Aj&1S+a%gxT)?h&2+yv+VMEMP9bbQZi{{jNDou%*k_(Si>eIpXqLH0&~r z`SZW*zai4{SfIuD*!3gVA2r&2|9iW6+RWMtq# ZA$-;8zcttOJb~>h22WQ%mvv4FO#s(2G=KmA literal 0 HcmV?d00001 diff --git a/scripts/generate_tab_mockups.ps1 b/scripts/generate_tab_mockups.ps1 new file mode 100644 index 0000000..aa2c4d1 --- /dev/null +++ b/scripts/generate_tab_mockups.ps1 @@ -0,0 +1,327 @@ +$ErrorActionPreference = 'Stop' + +Add-Type -AssemblyName System.Drawing + +$root = Split-Path -Parent $PSScriptRoot +$guiDir = Join-Path $root 'src\main\resources\assets\bagtabs\textures\gui' +$itemDir = Join-Path $root 'src\main\resources\assets\bagtabs\textures\item' +$outDir = Join-Path $root 'art\mockups' +New-Item -ItemType Directory -Force -Path $outDir | Out-Null + +function New-Bitmap { + param([int]$Width, [int]$Height) + return [System.Drawing.Bitmap]::new($Width, $Height, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb) +} + +function Load-Bitmap { + param([string]$Path) + return [System.Drawing.Bitmap]::new($Path) +} + +function Get-Half { + param( + [System.Drawing.Bitmap]$Image, + [bool]$RightHalf = $false + ) + + $halfWidth = [int]($Image.Width / 2) + $sourceX = if ($RightHalf) { $halfWidth } else { 0 } + $bmp = New-Bitmap $halfWidth $Image.Height + $graphics = [System.Drawing.Graphics]::FromImage($bmp) + try { + $graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor + $graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half + $graphics.DrawImage( + $Image, + [System.Drawing.Rectangle]::new(0, 0, $halfWidth, $Image.Height), + [System.Drawing.Rectangle]::new($sourceX, 0, $halfWidth, $Image.Height), + [System.Drawing.GraphicsUnit]::Pixel + ) + } finally { + $graphics.Dispose() + } + return $bmp +} + +function Tint-Bitmap { + param( + [System.Drawing.Bitmap]$Image, + [Nullable[int]]$Rgb + ) + + $bmp = New-Bitmap $Image.Width $Image.Height + $tr = if ($Rgb.HasValue) { (($Rgb.Value -shr 16) -band 0xFF) / 255.0 } else { 1.0 } + $tg = if ($Rgb.HasValue) { (($Rgb.Value -shr 8) -band 0xFF) / 255.0 } else { 1.0 } + $tb = if ($Rgb.HasValue) { ($Rgb.Value -band 0xFF) / 255.0 } else { 1.0 } + + for ($x = 0; $x -lt $Image.Width; $x++) { + for ($y = 0; $y -lt $Image.Height; $y++) { + $src = $Image.GetPixel($x, $y) + if ($src.A -eq 0) { + $bmp.SetPixel($x, $y, $src) + continue + } + $r = [Math]::Min(255, [int]($src.R * $tr)) + $g = [Math]::Min(255, [int]($src.G * $tg)) + $b = [Math]::Min(255, [int]($src.B * $tb)) + $bmp.SetPixel($x, $y, [System.Drawing.Color]::FromArgb($src.A, $r, $g, $b)) + } + } + + return $bmp +} + +function Compose-Layered { + param( + [System.Drawing.Bitmap]$Base, + [System.Drawing.Bitmap]$Overlay + ) + + $bmp = New-Bitmap $Base.Width $Base.Height + $graphics = [System.Drawing.Graphics]::FromImage($bmp) + try { + $graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor + $graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half + $graphics.DrawImage($Base, 0, 0, $Base.Width, $Base.Height) + $graphics.DrawImage($Overlay, 0, 0, $Overlay.Width, $Overlay.Height) + } finally { + $graphics.Dispose() + } + return $bmp +} + +function Draw-ScaledBitmap { + param( + [System.Drawing.Graphics]$Graphics, + [System.Drawing.Bitmap]$Bitmap, + [int]$X, + [int]$Y, + [int]$Width, + [int]$Height + ) + + $Graphics.DrawImage( + $Bitmap, + [System.Drawing.Rectangle]::new($X, $Y, $Width, $Height), + [System.Drawing.Rectangle]::new(0, 0, $Bitmap.Width, $Bitmap.Height), + [System.Drawing.GraphicsUnit]::Pixel + ) +} + +function Draw-Pin { + param([System.Drawing.Graphics]$Graphics, [int]$X, [int]$Y) + $yellow = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 235, 205, 86)) + $red = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 205, 55, 44)) + try { + $Graphics.FillRectangle($yellow, $X + 1, $Y + 1, 3, 5) + $Graphics.FillRectangle($yellow, $X + 2, $Y + 6, 2, 1) + $Graphics.FillRectangle($red, $X, $Y + 2, 1, 1) + } finally { + $yellow.Dispose() + $red.Dispose() + } +} + +function Draw-Fullness { + param( + [System.Drawing.Graphics]$Graphics, + [int]$X, + [int]$Y, + [int]$Width, + [int]$Height, + [double]$Percent + ) + + $back = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 40, 40, 40)) + $fill = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 105, 180, 90)) + try { + $Graphics.FillRectangle($back, $X, $Y, $Width, $Height) + $fillHeight = [Math]::Max(1, [int]([Math]::Round($Height * $Percent))) + $Graphics.FillRectangle($fill, $X, $Y + ($Height - $fillHeight), $Width, $fillHeight) + } finally { + $back.Dispose() + $fill.Dispose() + } +} + +function Draw-BagItem { + param( + [System.Drawing.Graphics]$Graphics, + [System.Drawing.Bitmap]$BagBase, + [System.Drawing.Bitmap]$BagOverlay, + [Nullable[int]]$Color, + [int]$X, + [int]$Y, + [int]$Size + ) + + $tinted = Tint-Bitmap $BagBase $Color + $bag = Compose-Layered $tinted $BagOverlay + try { + Draw-ScaledBitmap $Graphics $bag $X $Y $Size $Size + } finally { + $tinted.Dispose() + $bag.Dispose() + } +} + +function Draw-CompactText { + param( + [System.Drawing.Graphics]$Graphics, + [string]$Line1, + [string]$Line2, + [int]$X, + [int]$Y, + [int]$Width, + [int]$Height, + [System.Drawing.Color]$Color + ) + + $font = [System.Drawing.Font]::new('Microsoft Sans Serif', 5.5, [System.Drawing.FontStyle]::Bold, [System.Drawing.GraphicsUnit]::Pixel) + $brush = [System.Drawing.SolidBrush]::new($Color) + $format = [System.Drawing.StringFormat]::new() + $format.Alignment = [System.Drawing.StringAlignment]::Center + $format.LineAlignment = [System.Drawing.StringAlignment]::Center + try { + $Graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::SingleBitPerPixelGridFit + $Graphics.DrawString($Line1, $font, $brush, [System.Drawing.RectangleF]::new($X, $Y - 1, $Width, [int]($Height / 2)), $format) + $Graphics.DrawString($Line2, $font, $brush, [System.Drawing.RectangleF]::new($X, $Y + [int]($Height / 2) - 2, $Width, [int]($Height / 2) + 2), $format) + } finally { + $font.Dispose() + $brush.Dispose() + $format.Dispose() + } +} + +function New-Canvas { + param([int]$Width, [int]$Height) + $bmp = New-Bitmap $Width $Height + $graphics = [System.Drawing.Graphics]::FromImage($bmp) + $graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor + $graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half + $graphics.Clear([System.Drawing.Color]::FromArgb(255, 48, 48, 52)) + return @{ Bitmap = $bmp; Graphics = $graphics } +} + +$bagNamer = Load-Bitmap (Join-Path $guiDir 'bag_namer.png') +$tabBase = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_base.png')) +$tabOverlay = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_overlay.png')) +$compactBase = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_compact_base.png')) +$compactOverlay = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_compact_overlay.png')) +$dockTab = Load-Bitmap (Join-Path $guiDir 'bag_tabs_dock.png') +$gear = Load-Bitmap (Join-Path $guiDir 'dock_gear.png') +$lock = Load-Bitmap (Join-Path $guiDir 'dock_lock.png') +$prev = Load-Bitmap (Join-Path $guiDir 'dock_prev.png') +$next = Load-Bitmap (Join-Path $guiDir 'dock_next.png') +$bagBase = Load-Bitmap (Join-Path $itemDir 'bag.png') +$bagOverlay = Load-Bitmap (Join-Path $itemDir 'bag_overlay.png') + +$bagColors = @($null, 0x8032A8, 0xE4E5DE) +$bagFullness = @(0.82, 0.56, 0.31) +$compactNames = @( + @{ Line1 = 'Canvas'; Line2 = 'Bag' }, + @{ Line1 = 'Purple'; Line2 = 'Bag' }, + @{ Line1 = 'Pale'; Line2 = 'Bag' } +) + +function Draw-StandardStrip { + param( + [System.Drawing.Graphics]$Graphics, + [int]$X, + [int]$Y, + [bool]$Compact + ) + + Draw-ScaledBitmap $Graphics $dockTab $X $Y 18 22 + Draw-ScaledBitmap $Graphics $gear ($X + 5) ($Y + 2) 8 8 + Draw-ScaledBitmap $Graphics $lock ($X + 5) ($Y + 12) 8 8 + + $tabStep = 21 + $tabX = $X + 17 + for ($i = 0; $i -lt 3; $i++) { + if ($Compact) { + $tintedBase = Tint-Bitmap $compactBase $bagColors[$i] + $tab = Compose-Layered $tintedBase $compactOverlay + try { + Draw-ScaledBitmap $Graphics $tab ($tabX + ($i * $tabStep)) ($Y + 11) 22 11 + } finally { + $tintedBase.Dispose() + $tab.Dispose() + } + $textColor = if ($bagColors[$i] -eq $null -or $bagColors[$i] -gt 0x7F7F7F) { + [System.Drawing.Color]::FromArgb(255, 30, 30, 30) + } else { + [System.Drawing.Color]::White + } + Draw-CompactText $Graphics $compactNames[$i].Line1 $compactNames[$i].Line2 ($tabX + ($i * $tabStep) + 2) ($Y + 11) 18 10 $textColor + Draw-Fullness $Graphics ($tabX + ($i * $tabStep) + 18) ($Y + 12) 2 8 $bagFullness[$i] + } else { + $tintedBase = Tint-Bitmap $tabBase $bagColors[$i] + $tab = Compose-Layered $tintedBase $tabOverlay + try { + Draw-ScaledBitmap $Graphics $tab ($tabX + ($i * $tabStep)) $Y 22 22 + } finally { + $tintedBase.Dispose() + $tab.Dispose() + } + Draw-BagItem $Graphics $bagBase $bagOverlay $bagColors[$i] ($tabX + ($i * $tabStep) + 3) ($Y + 2) 16 + Draw-Fullness $Graphics ($tabX + ($i * $tabStep) + 18) ($Y + 3) 2 15 $bagFullness[$i] + } + } + + Draw-Pin $Graphics ($tabX + 1) ($Y + 1) + + $scrollX = $tabX + (3 * $tabStep) + Draw-ScaledBitmap $Graphics $dockTab $scrollX $Y 18 22 + Draw-ScaledBitmap $Graphics $prev ($scrollX + 5) ($Y + 2) 8 8 + Draw-ScaledBitmap $Graphics $next ($scrollX + 5) ($Y + 12) 8 8 +} + +function Save-Mockup { + param( + [string]$Name, + [bool]$Compact, + [bool]$Floating + ) + + $canvas = New-Canvas 260 220 + $bmp = $canvas.Bitmap + $graphics = $canvas.Graphics + try { + $guiX = 42 + $guiY = 28 + Draw-ScaledBitmap $graphics $bagNamer $guiX $guiY $bagNamer.Width $bagNamer.Height + + if ($Floating) { + $stripX = $guiX + 18 + $stripY = $guiY + $bagNamer.Height + 12 + } else { + $stripX = $guiX + 2 + $stripY = if ($Compact) { $guiY + $bagNamer.Height - 2 } else { $guiY + $bagNamer.Height - 3 } + } + + Draw-StandardStrip $graphics $stripX $stripY $Compact + $bmp.Save((Join-Path $outDir $Name), [System.Drawing.Imaging.ImageFormat]::Png) + } finally { + $graphics.Dispose() + $bmp.Dispose() + } +} + +Save-Mockup 'rename_docked_normal.png' $false $false +Save-Mockup 'rename_docked_compact.png' $true $false +Save-Mockup 'rename_floating_horizontal_normal.png' $false $true +Save-Mockup 'rename_floating_horizontal_compact.png' $true $true + +$bagNamer.Dispose() +$tabBase.Dispose() +$tabOverlay.Dispose() +$compactBase.Dispose() +$compactOverlay.Dispose() +$dockTab.Dispose() +$gear.Dispose() +$lock.Dispose() +$prev.Dispose() +$next.Dispose() +$bagBase.Dispose() +$bagOverlay.Dispose() diff --git a/src/main/java/com/trunksbomb/bagtabs/client/BagTabOverlay.java b/src/main/java/com/trunksbomb/bagtabs/client/BagTabOverlay.java index 0c43a2b..60ff329 100644 --- a/src/main/java/com/trunksbomb/bagtabs/client/BagTabOverlay.java +++ b/src/main/java/com/trunksbomb/bagtabs/client/BagTabOverlay.java @@ -49,6 +49,9 @@ public final class BagTabOverlay { private static final ResourceLocation PREV_ICON_TEXTURE = BagTabs.id("textures/gui/dock_prev.png"); private static final ResourceLocation NEXT_ICON_TEXTURE = BagTabs.id("textures/gui/dock_next.png"); private static final ResourceLocation POPUP_TEXTURE = BagTabs.id("textures/gui/dock_config_popup.png"); + private static final ResourceLocation BOOKMARK_TEXTURE = BagTabs.id("textures/gui/bookmark.png"); + private static final ResourceLocation NORMAL_FILL_GAUGE_TEXTURE = BagTabs.id("textures/gui/normal_fill_gauge.png"); + private static final ResourceLocation NORMAL_ACTIVE_TAB_TEXTURE = BagTabs.id("textures/gui/normal_active_tab.png"); private static final int BASE_TAB_WIDTH = 22; private static final int BASE_TAB_HEIGHT = 22; private static final int BASE_COMPACT_TAB_WIDTH = 22; @@ -59,6 +62,12 @@ public final class BagTabOverlay { private static final int POPUP_WIDTH = 140; private static final int POPUP_HEIGHT = 160; private static final int POPUP_TITLE_HEIGHT = 16; + private static final int BOOKMARK_WIDTH = 3; + private static final int BOOKMARK_HEIGHT = 7; + private static final int NORMAL_FILL_GAUGE_WIDTH = 2; + private static final int NORMAL_FILL_GAUGE_HEIGHT = 18; + private static final int NORMAL_ACTIVE_TAB_WIDTH = 20; + private static final int NORMAL_ACTIVE_TAB_HEIGHT = 4; private static final int TAB_GAP = 0; private static final int TAB_Y_OFFSET = -3; private static final int TAB_X_OFFSET = -6; @@ -629,6 +638,11 @@ public final class BagTabOverlay { } private static void renderFullnessIndicator(GuiGraphics g, RenderedTab tab, float fullness) { + if (!tab.compact()) { + renderNormalFullnessIndicator(g, tab, fullness); + return; + } + int color = interpolateColor(0xFF65D96D, 0xFFD94A4A, fullness); if (tab.isVertical()) { int trackHeight = tab.height() <= 11 ? 1 : 2; @@ -659,6 +673,88 @@ public final class BagTabOverlay { g.fill(trackX + trackWidth, trackY, trackX + trackWidth + 1, trackY + trackHeight, 0xFF000000); } + private static void renderNormalFullnessIndicator(GuiGraphics g, RenderedTab tab, float fullness) { + int color = interpolateColor(0xFF6CCBFF, 0xFF2E86FF, fullness); + g.pose().pushPose(); + g.pose().translate(0.0F, 0.0F, 10_000.0F); + if (tab.isVertical()) { + int gaugeX = tab.x() + Math.max(0, (tab.width() - NORMAL_FILL_GAUGE_HEIGHT) / 2); + int gaugeY = tab.y() + tab.height() - NORMAL_FILL_GAUGE_WIDTH - 1; + g.pose().pushPose(); + g.pose().translate(gaugeX + (NORMAL_FILL_GAUGE_HEIGHT / 2.0F), gaugeY + (NORMAL_FILL_GAUGE_WIDTH / 2.0F), 0.0F); + g.pose().mulPose(Axis.ZP.rotationDegrees(-90.0F)); + g.blit( + NORMAL_FILL_GAUGE_TEXTURE, + -(NORMAL_FILL_GAUGE_WIDTH / 2), + -(NORMAL_FILL_GAUGE_HEIGHT / 2), + 0, + 0, + NORMAL_FILL_GAUGE_WIDTH, + NORMAL_FILL_GAUGE_HEIGHT, + NORMAL_FILL_GAUGE_WIDTH, + NORMAL_FILL_GAUGE_HEIGHT + ); + + int usableHeight = NORMAL_FILL_GAUGE_HEIGHT - 2; + int fillHeight = Math.max(0, Math.min(usableHeight, Math.round(usableHeight * fullness))); + if (fillHeight > 0) { + int localLeft = -(NORMAL_FILL_GAUGE_WIDTH / 2) + 1; + int localTop = -(NORMAL_FILL_GAUGE_HEIGHT / 2) + 1 + (usableHeight - fillHeight); + int localBottom = -(NORMAL_FILL_GAUGE_HEIGHT / 2) + 1 + usableHeight; + g.fill(localLeft, localTop, localLeft + 1, localBottom, color); + } + g.pose().popPose(); + g.pose().popPose(); + return; + } + + int gaugeX = tab.x() + tab.width() - NORMAL_FILL_GAUGE_WIDTH - 1; + int gaugeY = isFlippedHorizontalShell(tab) ? tab.y() + tab.height() - NORMAL_FILL_GAUGE_HEIGHT : tab.y(); + boolean flippedVertical = isFlippedHorizontalShell(tab); + if (flippedVertical) { + g.pose().pushPose(); + g.pose().translate(gaugeX + (NORMAL_FILL_GAUGE_WIDTH / 2.0F), gaugeY + (NORMAL_FILL_GAUGE_HEIGHT / 2.0F), 0.0F); + g.pose().scale(1.0F, -1.0F, 1.0F); + g.blit( + NORMAL_FILL_GAUGE_TEXTURE, + -(NORMAL_FILL_GAUGE_WIDTH / 2), + -(NORMAL_FILL_GAUGE_HEIGHT / 2), + 0, + 0, + NORMAL_FILL_GAUGE_WIDTH, + NORMAL_FILL_GAUGE_HEIGHT, + NORMAL_FILL_GAUGE_WIDTH, + NORMAL_FILL_GAUGE_HEIGHT + ); + g.pose().popPose(); + } else { + g.blit( + NORMAL_FILL_GAUGE_TEXTURE, + gaugeX, + gaugeY, + 0, + 0, + NORMAL_FILL_GAUGE_WIDTH, + NORMAL_FILL_GAUGE_HEIGHT, + NORMAL_FILL_GAUGE_WIDTH, + NORMAL_FILL_GAUGE_HEIGHT + ); + } + + int usableHeight = NORMAL_FILL_GAUGE_HEIGHT - 2; + int fillHeight = Math.max(0, Math.min(usableHeight, Math.round(usableHeight * fullness))); + if (fillHeight > 0) { + if (flippedVertical) { + int fillTop = gaugeY + 1 + (usableHeight - fillHeight); + g.fill(gaugeX + 1, fillTop, gaugeX + 2, gaugeY + 1 + usableHeight, color); + } else { + int fillTop = gaugeY + 1 + (usableHeight - fillHeight); + g.fill(gaugeX + 1, fillTop, gaugeX + 2, gaugeY + 1 + usableHeight, color); + } + } + g.pose().popPose(); + } + private static int interpolateColor(int start, int end, float t) { float clamped = Math.max(0.0F, Math.min(1.0F, t)); int sr = (start >> 16) & 0xFF; @@ -982,18 +1078,81 @@ public final class BagTabOverlay { if (!tab.pinned()) { return; } - int x = tab.x() + 2; - int y = tab.y() + 2; - g.fill(x, y, x + 4, y + 1, 0xFFFFDA6B); - g.fill(x + 1, y + 1, x + 3, y + 4, 0xFFFFDA6B); - g.fill(x + 2, y + 4, x + 3, y + 5, 0xFFD94A4A); + + g.pose().pushPose(); + g.pose().translate(0.0F, 0.0F, 10_000.0F); + if (!tab.compact()) { + if (!tab.isVertical()) { + int bookmarkX = tab.x() + 1; + int bookmarkY = isFlippedHorizontalShell(tab) ? tab.y() + tab.height() - BOOKMARK_HEIGHT : tab.y(); + if (isFlippedHorizontalShell(tab)) { + g.blit( + BOOKMARK_TEXTURE, + bookmarkX, + bookmarkY, + 0, + BOOKMARK_HEIGHT, + BOOKMARK_WIDTH, + -BOOKMARK_HEIGHT, + BOOKMARK_WIDTH, + BOOKMARK_HEIGHT + ); + } else { + g.blit( + BOOKMARK_TEXTURE, + bookmarkX, + bookmarkY, + 0, + 0, + BOOKMARK_WIDTH, + BOOKMARK_HEIGHT, + BOOKMARK_WIDTH, + BOOKMARK_HEIGHT + ); + } + g.pose().popPose(); + return; + } + g.pose().pushPose(); + pushTabTransform(g, tab); + g.blit( + BOOKMARK_TEXTURE, + 1, + 0, + 0, + 0, + BOOKMARK_WIDTH, + BOOKMARK_HEIGHT, + BOOKMARK_WIDTH, + BOOKMARK_HEIGHT + ); + g.pose().popPose(); + g.pose().popPose(); + return; + } + + g.pose().pushPose(); + pushTabTransform(g, tab); + blitScaled(g, BOOKMARK_TEXTURE, 1, 0, 2, 5, 0, 0, BOOKMARK_WIDTH, BOOKMARK_HEIGHT, BOOKMARK_WIDTH, BOOKMARK_HEIGHT); + g.pose().popPose(); + g.pose().popPose(); } private static void renderSelectedIndicator(GuiGraphics g, RenderedTab tab, int baseWidth, int baseHeight) { if (!tab.compact()) { - int highlightTop = Math.max(baseHeight - 3, 1); - int highlightBottom = Math.max(baseHeight - 1, highlightTop + 1); - g.fill(3, highlightTop, baseWidth - 3, highlightBottom, 0xFFD94A4A); + int activeX = Math.max(0, (baseWidth - NORMAL_ACTIVE_TAB_WIDTH) / 2); + int activeY = baseHeight - NORMAL_ACTIVE_TAB_HEIGHT + 3; + g.blit( + NORMAL_ACTIVE_TAB_TEXTURE, + activeX, + activeY, + 0, + 0, + NORMAL_ACTIVE_TAB_WIDTH, + NORMAL_ACTIVE_TAB_HEIGHT, + NORMAL_ACTIVE_TAB_WIDTH, + NORMAL_ACTIVE_TAB_HEIGHT + ); return; } @@ -1006,6 +1165,10 @@ public final class BagTabOverlay { } } + private static boolean isFlippedHorizontalShell(RenderedTab tab) { + return !tab.isVertical() && Math.round(tab.rotationDegrees()) % 360 != 0; + } + private static void renderCompactLabel(GuiGraphics g, RenderedTab tab) { Minecraft minecraft = Minecraft.getInstance(); int maxTextWidth = Math.max(8, tab.width() - 4); diff --git a/src/main/resources/assets/bagtabs/textures/gui/bookmark.png b/src/main/resources/assets/bagtabs/textures/gui/bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..919db5b4a182987880457ba96845525aeb34d8bd GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^%s|Y}!3HGH?)<(INHG=%xjQkeJ16rJ$YDu$^mSxl z*x1kgCy^D%=PdAuEM{QfI}E~%$MaXD00kvWTq8{DUlXgu{EoYWf4@z!aD-xlNr1xjZ%l`G^Yn9VJMJkvZqwHP>n999M?Mpgz!Aj=DgrJ-z)b2J#4!QxCnwjm=EgCLNO z0^-be7O;2@kPQL}Kn&6kqtR_;U|?oon841!0#svQWNg5=0Aemk59qn029z8 zCa}sNOA8{&803^$1dZl<%e~~qiY3=Fa7@`rpw&x%xg8|2pq~k@B>BW-QH_ey( z61k!B>4Of&*w8-*?nX}1%(`)tS3vOl^O2Bil*^U4L1=#@$Vg9DKbLh* G2~7Y|Yf%{h literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/bagtabs/textures/gui/normal_fill_gauge.png b/src/main/resources/assets/bagtabs/textures/gui/normal_fill_gauge.png new file mode 100644 index 0000000000000000000000000000000000000000..494a365fcfc97a65edf88ae1289ad27fd92e3f45 GIT binary patch literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ee!3HD?6ZrQ7DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXKw@TIiJqTph=Qq} zp`M{(7l+t6prReA5uRzDo>~kXKn^Q|6eBAGBar0<#L`eU$T=E}%wTblvkV!T7zBZI z6cA^&vw+2OfNT&*0Ai4S7>#Z#0|PSy!vuB)7N8mfBVz-`1rT#VdRP}g%$f#dg8&oI zBqp%RAWI7%3#!Y|zyKu6W_qP~Q-6^)kSXTr;us