Просмотр исходного кода

code improvements - previews 1/2

Milan Jurkulak 2 лет назад
Родитель
Сommit
d82f9d8e2a
59 измененных файлов с 806 добавлено и 644 удалено
  1. 6 2
      build.gradle.kts
  2. 10 10
      buildSrc/build.gradle.kts
  3. 6 2
      src/main/java/eu/mjdev/desktop/helpers/gif/AnimatedGifEncoder.java
  4. 8 4
      src/main/java/eu/mjdev/desktop/helpers/gif/GifDecoder.java
  5. 1 1
      src/main/java/eu/mjdev/desktop/helpers/gif/LZWEncoder.java
  6. 335 335
      src/main/java/eu/mjdev/desktop/helpers/gif/NeuQuant.java
  7. 25 5
      src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsList.kt
  8. 1 3
      src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenu.kt
  9. 10 1
      src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenuApp.kt
  10. 10 1
      src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenuCategory.kt
  11. 8 4
      src/main/kotlin/eu/mjdev/desktop/components/blur/BlurPanel.kt
  12. 15 0
      src/main/kotlin/eu/mjdev/desktop/components/button/ButtonPrimary.kt
  13. 16 0
      src/main/kotlin/eu/mjdev/desktop/components/button/ButtonSecondary.kt
  14. 23 1
      src/main/kotlin/eu/mjdev/desktop/components/button/TransparentButton.kt
  15. 8 3
      src/main/kotlin/eu/mjdev/desktop/components/card/Card.kt
  16. 9 4
      src/main/kotlin/eu/mjdev/desktop/components/card/ClassicCard.kt
  17. 14 5
      src/main/kotlin/eu/mjdev/desktop/components/card/CompactCard.kt
  18. 12 7
      src/main/kotlin/eu/mjdev/desktop/components/card/FocusableCard.kt
  19. 13 8
      src/main/kotlin/eu/mjdev/desktop/components/card/ItemCard.kt
  20. 8 4
      src/main/kotlin/eu/mjdev/desktop/components/card/PhotoCard.kt
  21. 9 4
      src/main/kotlin/eu/mjdev/desktop/components/card/WideClassicCard.kt
  22. 5 6
      src/main/kotlin/eu/mjdev/desktop/components/card/base/CardBorder.kt
  23. 7 8
      src/main/kotlin/eu/mjdev/desktop/components/card/base/CardColors.kt
  24. 4 5
      src/main/kotlin/eu/mjdev/desktop/components/card/base/CardGlow.kt
  25. 4 5
      src/main/kotlin/eu/mjdev/desktop/components/card/base/CardScale.kt
  26. 4 5
      src/main/kotlin/eu/mjdev/desktop/components/card/base/CardShape.kt
  27. 5 0
      src/main/kotlin/eu/mjdev/desktop/components/custom/BrushedLayout.kt
  28. 3 3
      src/main/kotlin/eu/mjdev/desktop/components/custom/DateTime.kt
  29. 13 3
      src/main/kotlin/eu/mjdev/desktop/components/custom/MeasureUnconstrainedView.kt
  30. 5 0
      src/main/kotlin/eu/mjdev/desktop/components/custom/VerticalScrollableBox.kt
  31. 1 2
      src/main/kotlin/eu/mjdev/desktop/components/desktop/Desktop.kt
  32. 0 1
      src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/DesktopPanelText.kt
  33. 6 1
      src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/DesktopPanelTray.kt
  34. 3 2
      src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/applets/DesktopMenuIcon.kt
  35. 1 1
      src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/applets/DesktopPanelDateTime.kt
  36. 1 1
      src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/applets/DesktopPanelLanguage.kt
  37. 11 8
      src/main/kotlin/eu/mjdev/desktop/components/draggable/DraggableView.kt
  38. 4 5
      src/main/kotlin/eu/mjdev/desktop/components/file/FolderView.kt
  39. 7 2
      src/main/kotlin/eu/mjdev/desktop/components/gallery/BoxWithControls.kt
  40. 8 3
      src/main/kotlin/eu/mjdev/desktop/components/gallery/Gallery.kt
  41. 7 6
      src/main/kotlin/eu/mjdev/desktop/components/gallery/ItemInfo.kt
  42. 8 5
      src/main/kotlin/eu/mjdev/desktop/components/grid/GridPlaced.kt
  43. 2 3
      src/main/kotlin/eu/mjdev/desktop/components/image/GifView.kt
  44. 7 2
      src/main/kotlin/eu/mjdev/desktop/components/image/ImageColoredBackground.kt
  45. 5 0
      src/main/kotlin/eu/mjdev/desktop/components/image/PhotoImage.kt
  46. 9 7
      src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveList.kt
  47. 0 16
      src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveListScope.kt
  48. 10 7
      src/main/kotlin/eu/mjdev/desktop/components/immersivelist/base/ImmersiveListBackgroundScope.kt
  49. 1 1
      src/main/kotlin/eu/mjdev/desktop/components/immersivelist/base/ImmersiveListDefaults.kt
  50. 16 13
      src/main/kotlin/eu/mjdev/desktop/components/immersivelist/base/ImmersiveListScope.kt
  51. 8 3
      src/main/kotlin/eu/mjdev/desktop/components/input/SearchFieldPassive.kt
  52. 5 0
      src/main/kotlin/eu/mjdev/desktop/components/input/SelectableOutlineEditText.kt
  53. 1 1
      src/main/kotlin/eu/mjdev/desktop/components/installer/Installer.kt
  54. 62 109
      src/main/kotlin/eu/mjdev/desktop/components/surface/Surface.kt
  55. 5 2
      src/main/kotlin/eu/mjdev/desktop/components/surface/base/SurfaceGlow.kt
  56. 6 1
      src/main/kotlin/eu/mjdev/desktop/components/text/AutoHideEmptyText.kt
  57. 1 0
      src/main/kotlin/eu/mjdev/desktop/data/App.kt
  58. 13 0
      src/main/kotlin/eu/mjdev/desktop/data/DesktopFile.kt
  59. 1 3
      src/main/kotlin/eu/mjdev/desktop/extensions/Custom.kt

+ 6 - 2
build.gradle.kts

@@ -26,10 +26,14 @@ plugins {
 group = libs.versions.packageName.get()
 group = libs.versions.packageName.get()
 version = libs.versions.packageVersion.get()
 version = libs.versions.packageVersion.get()
 
 
+configurations.all {
+    resolutionStrategy.cacheChangingModulesFor(0, "seconds")
+}
+
 kotlin {
 kotlin {
 //    jvm()
 //    jvm()
 //    linuxX64() {
 //    linuxX64() {
-        /* Specify additional settings for the 'linux' target here */
+    /* Specify additional settings for the 'linux' target here */
 //    }
 //    }
     jvmToolchain {
     jvmToolchain {
         languageVersion.set(JavaLanguageVersion.of(21))
         languageVersion.set(JavaLanguageVersion.of(21))
@@ -117,7 +121,7 @@ allprojects {
         // dbus
         // dbus
         implementation(libs.dbus.java.core)
         implementation(libs.dbus.java.core)
         implementation(libs.dbus.java.transport.native.unixsocket)
         implementation(libs.dbus.java.transport.native.unixsocket)
- // testing yet :
+        // testing yet :
         // gettext
         // gettext
         implementation("org.gnu.gettext:libintl:0.18.3")
         implementation("org.gnu.gettext:libintl:0.18.3")
         // custom components
         // custom components

+ 10 - 10
buildSrc/build.gradle.kts

@@ -18,13 +18,13 @@ dependencies {
 //    implementation(libs.gradle.api)
 //    implementation(libs.gradle.api)
 }
 }
 
 
-gradlePlugin {
-    plugins {
-        register("DesktopPlugin") {
-            id = "DesktopPlugin"
-            displayName = "DesktopPlugin"
-            description = "Common application plugin to handle all stuffs needed."
-            implementationClass = "org.mjdev.gradle.plugin.DesktopPlugin"
-        }
-    }
-}
+//gradlePlugin {
+//    plugins {
+//        register("DesktopPlugin") {
+//            id = "DesktopPlugin"
+//            displayName = "DesktopPlugin"
+//            description = "Common application plugin to handle all stuffs needed."
+//            implementationClass = "org.mjdev.gradle.plugin.DesktopPlugin"
+//        }
+//    }
+//}

+ 6 - 2
src/main/java/eu/mjdev/desktop/helpers/gif/AnimatedGifEncoder.java

@@ -1,8 +1,12 @@
 package eu.mjdev.desktop.helpers.gif;
 package eu.mjdev.desktop.helpers.gif;
 
 
-import java.io.*;
 import java.awt.*;
 import java.awt.*;
-import java.awt.image.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
 
 
 @SuppressWarnings("unused")
 @SuppressWarnings("unused")
 public class AnimatedGifEncoder {
 public class AnimatedGifEncoder {

+ 8 - 4
src/main/java/eu/mjdev/desktop/helpers/gif/GifDecoder.java

@@ -1,10 +1,14 @@
 package eu.mjdev.desktop.helpers.gif;
 package eu.mjdev.desktop.helpers.gif;
 
 
-import java.net.*;
-import java.io.*;
-import java.util.*;
 import java.awt.*;
 import java.awt.*;
-import java.awt.image.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
 
 
 public class GifDecoder {
 public class GifDecoder {
     public static final int STATUS_OK = 0;
     public static final int STATUS_OK = 0;

+ 1 - 1
src/main/java/eu/mjdev/desktop/helpers/gif/LZWEncoder.java

@@ -1,7 +1,7 @@
 package eu.mjdev.desktop.helpers.gif;
 package eu.mjdev.desktop.helpers.gif;
 
 
-import java.io.OutputStream;
 import java.io.IOException;
 import java.io.IOException;
+import java.io.OutputStream;
 
 
 class LZWEncoder {
 class LZWEncoder {
     private static final int EOF = -1;
     private static final int EOF = -1;

+ 335 - 335
src/main/java/eu/mjdev/desktop/helpers/gif/NeuQuant.java

@@ -3,341 +3,341 @@ package eu.mjdev.desktop.helpers.gif;
 
 
 @SuppressWarnings("ALL")
 @SuppressWarnings("ALL")
 public class NeuQuant {
 public class NeuQuant {
-	protected static final int netsize = 256;
-	protected static final int prime1 = 499;
-	protected static final int prime2 = 491;
-	protected static final int prime3 = 487;
-	protected static final int prime4 = 503;
-	protected static final int minpicturebytes = (3 * prime4);
-	protected static final int maxnetpos = (netsize - 1);
-	protected static final int netbiasshift = 4;
-	protected static final int ncycles = 100;
-	protected static final int intbiasshift = 16;
-	protected static final int intbias = (1 << intbiasshift);
-	protected static final int gammashift = 10;
-	protected static final int gamma = (1 << gammashift);
-	protected static final int betashift = 10;
-	protected static final int beta = (intbias >> betashift);
-	protected static final int betagamma =		(intbias << (gammashift - betashift));
-	protected static final int initrad = (netsize >> 3);
-	protected static final int radiusbiasshift = 6;
-	protected static final int radiusbias = (1 << radiusbiasshift);
-	protected static final int initradius = (initrad * radiusbias);
-	protected static final int radiusdec = 30;
-	protected static final int alphabiasshift = 10;
-	protected static final int initalpha = (((int) 1) << alphabiasshift);
-	protected int alphadec;
-	protected static final int radbiasshift = 8;
-	protected static final int radbias = (1 << radbiasshift);
-	protected static final int alpharadbshift = (alphabiasshift + radbiasshift);
-	protected static final int alpharadbias = (((int) 1) << alpharadbshift);
-	protected byte[] thepicture;
-	protected int lengthcount;
-	protected int samplefac;
-	protected int[][] network;
-	protected int[] netindex = new int[256];
-	protected int[] bias = new int[netsize];
-	protected int[] freq = new int[netsize];
-	protected int[] radpower = new int[initrad];
+    protected static final int netsize = 256;
+    protected static final int prime1 = 499;
+    protected static final int prime2 = 491;
+    protected static final int prime3 = 487;
+    protected static final int prime4 = 503;
+    protected static final int minpicturebytes = (3 * prime4);
+    protected static final int maxnetpos = (netsize - 1);
+    protected static final int netbiasshift = 4;
+    protected static final int ncycles = 100;
+    protected static final int intbiasshift = 16;
+    protected static final int intbias = (1 << intbiasshift);
+    protected static final int gammashift = 10;
+    protected static final int gamma = (1 << gammashift);
+    protected static final int betashift = 10;
+    protected static final int beta = (intbias >> betashift);
+    protected static final int betagamma = (intbias << (gammashift - betashift));
+    protected static final int initrad = (netsize >> 3);
+    protected static final int radiusbiasshift = 6;
+    protected static final int radiusbias = (1 << radiusbiasshift);
+    protected static final int initradius = (initrad * radiusbias);
+    protected static final int radiusdec = 30;
+    protected static final int alphabiasshift = 10;
+    protected static final int initalpha = (((int) 1) << alphabiasshift);
+    protected int alphadec;
+    protected static final int radbiasshift = 8;
+    protected static final int radbias = (1 << radbiasshift);
+    protected static final int alpharadbshift = (alphabiasshift + radbiasshift);
+    protected static final int alpharadbias = (((int) 1) << alpharadbshift);
+    protected byte[] thepicture;
+    protected int lengthcount;
+    protected int samplefac;
+    protected int[][] network;
+    protected int[] netindex = new int[256];
+    protected int[] bias = new int[netsize];
+    protected int[] freq = new int[netsize];
+    protected int[] radpower = new int[initrad];
 
 
-	public NeuQuant(byte[] thepic, int len, int sample) {
-		int i;
-		int[] p;
-		thepicture = thepic;
-		lengthcount = len;
-		samplefac = sample;
-		network = new int[netsize][];
-		for (i = 0; i < netsize; i++) {
-			network[i] = new int[4];
-			p = network[i];
-			p[0] = p[1] = p[2] = (i << (netbiasshift + 8)) / netsize;
-			freq[i] = intbias / netsize; /* 1/netsize */
-			bias[i] = 0;
-		}
-	}
-	
-	public byte[] colorMap() {
-		byte[] map = new byte[3 * netsize];
-		int[] index = new int[netsize];
-		for (int i = 0; i < netsize; i++)
-			index[network[i][3]] = i;
-		int k = 0;
-		for (int i = 0; i < netsize; i++) {
-			int j = index[i];
-			map[k++] = (byte) (network[j][0]);
-			map[k++] = (byte) (network[j][1]);
-			map[k++] = (byte) (network[j][2]);
-		}
-		return map;
-	}
-	
-	public void inxbuild() {
-		int i, j, smallpos, smallval;
-		int[] p;
-		int[] q;
-		int previouscol, startpos;
-		previouscol = 0;
-		startpos = 0;
-		for (i = 0; i < netsize; i++) {
-			p = network[i];
-			smallpos = i;
-			smallval = p[1]; /* index on g */
-			for (j = i + 1; j < netsize; j++) {
-				q = network[j];
-				if (q[1] < smallval) { /* index on g */
-					smallpos = j;
-					smallval = q[1]; /* index on g */
-				}
-			}
-			q = network[smallpos];
-			if (i != smallpos) {
-				j = q[0];
-				q[0] = p[0];
-				p[0] = j;
-				j = q[1];
-				q[1] = p[1];
-				p[1] = j;
-				j = q[2];
-				q[2] = p[2];
-				p[2] = j;
-				j = q[3];
-				q[3] = p[3];
-				p[3] = j;
-			}
-			if (smallval != previouscol) {
-				netindex[previouscol] = (startpos + i) >> 1;
-				for (j = previouscol + 1; j < smallval; j++)
-					netindex[j] = i;
-				previouscol = smallval;
-				startpos = i;
-			}
-		}
-		netindex[previouscol] = (startpos + maxnetpos) >> 1;
-		for (j = previouscol + 1; j < 256; j++)
-			netindex[j] = maxnetpos; /* really 256 */
-	}
-	
-	public void learn() {
-		int i, j, b, g, r;
-		int radius, rad, alpha, step, delta, samplepixels;
-		byte[] p;
-		int pix, lim;
-		if (lengthcount < minpicturebytes)
-			samplefac = 1;
-		alphadec = 30 + ((samplefac - 1) / 3);
-		p = thepicture;
-		pix = 0;
-		lim = lengthcount;
-		samplepixels = lengthcount / (3 * samplefac);
-		delta = samplepixels / ncycles;
-		alpha = initalpha;
-		radius = initradius;
-		rad = radius >> radiusbiasshift;
-		if (rad <= 1)
-			rad = 0;
-		for (i = 0; i < rad; i++)
-			radpower[i] =
-				alpha * (((rad * rad - i * i) * radbias) / (rad * rad));
-		if (lengthcount < minpicturebytes)
-			step = 3;
-		else if ((lengthcount % prime1) != 0)
-			step = 3 * prime1;
-		else {
-			if ((lengthcount % prime2) != 0)
-				step = 3 * prime2;
-			else {
-				if ((lengthcount % prime3) != 0)
-					step = 3 * prime3;
-				else
-					step = 3 * prime4;
-			}
-		}
-		i = 0;
-		while (i < samplepixels) {
-			b = (p[pix + 0] & 0xff) << netbiasshift;
-			g = (p[pix + 1] & 0xff) << netbiasshift;
-			r = (p[pix + 2] & 0xff) << netbiasshift;
-			j = contest(b, g, r);
-			altersingle(alpha, j, b, g, r);
-			if (rad != 0)
-				alterneigh(rad, j, b, g, r); /* alter neighbours */
-			pix += step;
-			if (pix >= lim)
-				pix -= lengthcount;
-			i++;
-			if (delta == 0)
-				delta = 1;
-			if (i % delta == 0) {
-				alpha -= alpha / alphadec;
-				radius -= radius / radiusdec;
-				rad = radius >> radiusbiasshift;
-				if (rad <= 1)
-					rad = 0;
-				for (j = 0; j < rad; j++)
-					radpower[j] =
-						alpha * (((rad * rad - j * j) * radbias) / (rad * rad));
-			}
-		}
-	}
-	
-	public int map(int b, int g, int r) {
-		int i, j, dist, a, bestd;
-		int[] p;
-		int best;
-		bestd = 1000; /* biggest possible dist is 256*3 */
-		best = -1;
-		i = netindex[g]; /* index on g */
-		j = i - 1; /* start at netindex[g] and work outwards */
-		while ((i < netsize) || (j >= 0)) {
-			if (i < netsize) {
-				p = network[i];
-				dist = p[1] - g; /* inx key */
-				if (dist >= bestd)
-					i = netsize; /* stop iter */
-				else {
-					i++;
-					if (dist < 0)
-						dist = -dist;
-					a = p[0] - b;
-					if (a < 0)
-						a = -a;
-					dist += a;
-					if (dist < bestd) {
-						a = p[2] - r;
-						if (a < 0)
-							a = -a;
-						dist += a;
-						if (dist < bestd) {
-							bestd = dist;
-							best = p[3];
-						}
-					}
-				}
-			}
-			if (j >= 0) {
-				p = network[j];
-				dist = g - p[1]; /* inx key - reverse dif */
-				if (dist >= bestd)
-					j = -1; /* stop iter */
-				else {
-					j--;
-					if (dist < 0)
-						dist = -dist;
-					a = p[0] - b;
-					if (a < 0)
-						a = -a;
-					dist += a;
-					if (dist < bestd) {
-						a = p[2] - r;
-						if (a < 0)
-							a = -a;
-						dist += a;
-						if (dist < bestd) {
-							bestd = dist;
-							best = p[3];
-						}
-					}
-				}
-			}
-		}
-		return (best);
-	}
+    public NeuQuant(byte[] thepic, int len, int sample) {
+        int i;
+        int[] p;
+        thepicture = thepic;
+        lengthcount = len;
+        samplefac = sample;
+        network = new int[netsize][];
+        for (i = 0; i < netsize; i++) {
+            network[i] = new int[4];
+            p = network[i];
+            p[0] = p[1] = p[2] = (i << (netbiasshift + 8)) / netsize;
+            freq[i] = intbias / netsize; /* 1/netsize */
+            bias[i] = 0;
+        }
+    }
 
 
-	public byte[] process() {
-		learn();
-		unbiasnet();
-		inxbuild();
-		return colorMap();
-	}
-	
-	public void unbiasnet() {
-		int i, j;
-		for (i = 0; i < netsize; i++) {
-			network[i][0] >>= netbiasshift;
-			network[i][1] >>= netbiasshift;
-			network[i][2] >>= netbiasshift;
-			network[i][3] = i; /* record colour no */
-		}
-	}
-	
-	protected void alterneigh(int rad, int i, int b, int g, int r) {
-		int j, k, lo, hi, a, m;
-		int[] p;
-		lo = i - rad;
-		if (lo < -1)
-			lo = -1;
-		hi = i + rad;
-		if (hi > netsize)
-			hi = netsize;
-		j = i + 1;
-		k = i - 1;
-		m = 1;
-		while ((j < hi) || (k > lo)) {
-			a = radpower[m++];
-			if (j < hi) {
-				p = network[j++];
-				try {
-					p[0] -= (a * (p[0] - b)) / alpharadbias;
-					p[1] -= (a * (p[1] - g)) / alpharadbias;
-					p[2] -= (a * (p[2] - r)) / alpharadbias;
-				} catch (Exception e) {
-				} // prevents 1.3 miscompilation
-			}
-			if (k > lo) {
-				p = network[k--];
-				try {
-					p[0] -= (a * (p[0] - b)) / alpharadbias;
-					p[1] -= (a * (p[1] - g)) / alpharadbias;
-					p[2] -= (a * (p[2] - r)) / alpharadbias;
-				} catch (Exception e) {
-				}
-			}
-		}
-	}
-	
-	protected void altersingle(int alpha, int i, int b, int g, int r) {
-		int[] n = network[i];
-		n[0] -= (alpha * (n[0] - b)) / initalpha;
-		n[1] -= (alpha * (n[1] - g)) / initalpha;
-		n[2] -= (alpha * (n[2] - r)) / initalpha;
-	}
-	
-	protected int contest(int b, int g, int r) {
-		int i, dist, a, biasdist, betafreq;
-		int bestpos, bestbiaspos, bestd, bestbiasd;
-		int[] n;
-		bestd = ~(((int) 1) << 31);
-		bestbiasd = bestd;
-		bestpos = -1;
-		bestbiaspos = bestpos;
-		for (i = 0; i < netsize; i++) {
-			n = network[i];
-			dist = n[0] - b;
-			if (dist < 0)
-				dist = -dist;
-			a = n[1] - g;
-			if (a < 0)
-				a = -a;
-			dist += a;
-			a = n[2] - r;
-			if (a < 0)
-				a = -a;
-			dist += a;
-			if (dist < bestd) {
-				bestd = dist;
-				bestpos = i;
-			}
-			biasdist = dist - ((bias[i]) >> (intbiasshift - netbiasshift));
-			if (biasdist < bestbiasd) {
-				bestbiasd = biasdist;
-				bestbiaspos = i;
-			}
-			betafreq = (freq[i] >> betashift);
-			freq[i] -= betafreq;
-			bias[i] += (betafreq << gammashift);
-		}
-		freq[bestpos] += beta;
-		bias[bestpos] -= betagamma;
-		return (bestbiaspos);
-	}
+    public byte[] colorMap() {
+        byte[] map = new byte[3 * netsize];
+        int[] index = new int[netsize];
+        for (int i = 0; i < netsize; i++)
+            index[network[i][3]] = i;
+        int k = 0;
+        for (int i = 0; i < netsize; i++) {
+            int j = index[i];
+            map[k++] = (byte) (network[j][0]);
+            map[k++] = (byte) (network[j][1]);
+            map[k++] = (byte) (network[j][2]);
+        }
+        return map;
+    }
+
+    public void inxbuild() {
+        int i, j, smallpos, smallval;
+        int[] p;
+        int[] q;
+        int previouscol, startpos;
+        previouscol = 0;
+        startpos = 0;
+        for (i = 0; i < netsize; i++) {
+            p = network[i];
+            smallpos = i;
+            smallval = p[1]; /* index on g */
+            for (j = i + 1; j < netsize; j++) {
+                q = network[j];
+                if (q[1] < smallval) { /* index on g */
+                    smallpos = j;
+                    smallval = q[1]; /* index on g */
+                }
+            }
+            q = network[smallpos];
+            if (i != smallpos) {
+                j = q[0];
+                q[0] = p[0];
+                p[0] = j;
+                j = q[1];
+                q[1] = p[1];
+                p[1] = j;
+                j = q[2];
+                q[2] = p[2];
+                p[2] = j;
+                j = q[3];
+                q[3] = p[3];
+                p[3] = j;
+            }
+            if (smallval != previouscol) {
+                netindex[previouscol] = (startpos + i) >> 1;
+                for (j = previouscol + 1; j < smallval; j++)
+                    netindex[j] = i;
+                previouscol = smallval;
+                startpos = i;
+            }
+        }
+        netindex[previouscol] = (startpos + maxnetpos) >> 1;
+        for (j = previouscol + 1; j < 256; j++)
+            netindex[j] = maxnetpos; /* really 256 */
+    }
+
+    public void learn() {
+        int i, j, b, g, r;
+        int radius, rad, alpha, step, delta, samplepixels;
+        byte[] p;
+        int pix, lim;
+        if (lengthcount < minpicturebytes)
+            samplefac = 1;
+        alphadec = 30 + ((samplefac - 1) / 3);
+        p = thepicture;
+        pix = 0;
+        lim = lengthcount;
+        samplepixels = lengthcount / (3 * samplefac);
+        delta = samplepixels / ncycles;
+        alpha = initalpha;
+        radius = initradius;
+        rad = radius >> radiusbiasshift;
+        if (rad <= 1)
+            rad = 0;
+        for (i = 0; i < rad; i++)
+            radpower[i] =
+                    alpha * (((rad * rad - i * i) * radbias) / (rad * rad));
+        if (lengthcount < minpicturebytes)
+            step = 3;
+        else if ((lengthcount % prime1) != 0)
+            step = 3 * prime1;
+        else {
+            if ((lengthcount % prime2) != 0)
+                step = 3 * prime2;
+            else {
+                if ((lengthcount % prime3) != 0)
+                    step = 3 * prime3;
+                else
+                    step = 3 * prime4;
+            }
+        }
+        i = 0;
+        while (i < samplepixels) {
+            b = (p[pix + 0] & 0xff) << netbiasshift;
+            g = (p[pix + 1] & 0xff) << netbiasshift;
+            r = (p[pix + 2] & 0xff) << netbiasshift;
+            j = contest(b, g, r);
+            altersingle(alpha, j, b, g, r);
+            if (rad != 0)
+                alterneigh(rad, j, b, g, r); /* alter neighbours */
+            pix += step;
+            if (pix >= lim)
+                pix -= lengthcount;
+            i++;
+            if (delta == 0)
+                delta = 1;
+            if (i % delta == 0) {
+                alpha -= alpha / alphadec;
+                radius -= radius / radiusdec;
+                rad = radius >> radiusbiasshift;
+                if (rad <= 1)
+                    rad = 0;
+                for (j = 0; j < rad; j++)
+                    radpower[j] =
+                            alpha * (((rad * rad - j * j) * radbias) / (rad * rad));
+            }
+        }
+    }
+
+    public int map(int b, int g, int r) {
+        int i, j, dist, a, bestd;
+        int[] p;
+        int best;
+        bestd = 1000; /* biggest possible dist is 256*3 */
+        best = -1;
+        i = netindex[g]; /* index on g */
+        j = i - 1; /* start at netindex[g] and work outwards */
+        while ((i < netsize) || (j >= 0)) {
+            if (i < netsize) {
+                p = network[i];
+                dist = p[1] - g; /* inx key */
+                if (dist >= bestd)
+                    i = netsize; /* stop iter */
+                else {
+                    i++;
+                    if (dist < 0)
+                        dist = -dist;
+                    a = p[0] - b;
+                    if (a < 0)
+                        a = -a;
+                    dist += a;
+                    if (dist < bestd) {
+                        a = p[2] - r;
+                        if (a < 0)
+                            a = -a;
+                        dist += a;
+                        if (dist < bestd) {
+                            bestd = dist;
+                            best = p[3];
+                        }
+                    }
+                }
+            }
+            if (j >= 0) {
+                p = network[j];
+                dist = g - p[1]; /* inx key - reverse dif */
+                if (dist >= bestd)
+                    j = -1; /* stop iter */
+                else {
+                    j--;
+                    if (dist < 0)
+                        dist = -dist;
+                    a = p[0] - b;
+                    if (a < 0)
+                        a = -a;
+                    dist += a;
+                    if (dist < bestd) {
+                        a = p[2] - r;
+                        if (a < 0)
+                            a = -a;
+                        dist += a;
+                        if (dist < bestd) {
+                            bestd = dist;
+                            best = p[3];
+                        }
+                    }
+                }
+            }
+        }
+        return (best);
+    }
+
+    public byte[] process() {
+        learn();
+        unbiasnet();
+        inxbuild();
+        return colorMap();
+    }
+
+    public void unbiasnet() {
+        int i, j;
+        for (i = 0; i < netsize; i++) {
+            network[i][0] >>= netbiasshift;
+            network[i][1] >>= netbiasshift;
+            network[i][2] >>= netbiasshift;
+            network[i][3] = i; /* record colour no */
+        }
+    }
+
+    protected void alterneigh(int rad, int i, int b, int g, int r) {
+        int j, k, lo, hi, a, m;
+        int[] p;
+        lo = i - rad;
+        if (lo < -1)
+            lo = -1;
+        hi = i + rad;
+        if (hi > netsize)
+            hi = netsize;
+        j = i + 1;
+        k = i - 1;
+        m = 1;
+        while ((j < hi) || (k > lo)) {
+            a = radpower[m++];
+            if (j < hi) {
+                p = network[j++];
+                try {
+                    p[0] -= (a * (p[0] - b)) / alpharadbias;
+                    p[1] -= (a * (p[1] - g)) / alpharadbias;
+                    p[2] -= (a * (p[2] - r)) / alpharadbias;
+                } catch (Exception e) {
+                } // prevents 1.3 miscompilation
+            }
+            if (k > lo) {
+                p = network[k--];
+                try {
+                    p[0] -= (a * (p[0] - b)) / alpharadbias;
+                    p[1] -= (a * (p[1] - g)) / alpharadbias;
+                    p[2] -= (a * (p[2] - r)) / alpharadbias;
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+
+    protected void altersingle(int alpha, int i, int b, int g, int r) {
+        int[] n = network[i];
+        n[0] -= (alpha * (n[0] - b)) / initalpha;
+        n[1] -= (alpha * (n[1] - g)) / initalpha;
+        n[2] -= (alpha * (n[2] - r)) / initalpha;
+    }
+
+    protected int contest(int b, int g, int r) {
+        int i, dist, a, biasdist, betafreq;
+        int bestpos, bestbiaspos, bestd, bestbiasd;
+        int[] n;
+        bestd = ~(((int) 1) << 31);
+        bestbiasd = bestd;
+        bestpos = -1;
+        bestbiaspos = bestpos;
+        for (i = 0; i < netsize; i++) {
+            n = network[i];
+            dist = n[0] - b;
+            if (dist < 0)
+                dist = -dist;
+            a = n[1] - g;
+            if (a < 0)
+                a = -a;
+            dist += a;
+            a = n[2] - r;
+            if (a < 0)
+                a = -a;
+            dist += a;
+            if (dist < bestd) {
+                bestd = dist;
+                bestpos = i;
+            }
+            biasdist = dist - ((bias[i]) >> (intbiasshift - netbiasshift));
+            if (biasdist < bestbiasd) {
+                bestbiasd = biasdist;
+                bestbiaspos = i;
+            }
+            betafreq = (freq[i] >> betashift);
+            freq[i] -= betafreq;
+            bias[i] += (betafreq << gammashift);
+        }
+        freq[bestpos] += beta;
+        bias[bestpos] -= betagamma;
+        return (bestbiaspos);
+    }
 }
 }

+ 25 - 5
src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsList.kt

@@ -8,12 +8,18 @@
 
 
 package eu.mjdev.desktop.components.appsmenu
 package eu.mjdev.desktop.components.appsmenu
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.itemsIndexed
 import androidx.compose.foundation.lazy.itemsIndexed
 import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
 import eu.mjdev.desktop.data.App
 import eu.mjdev.desktop.data.App
 import eu.mjdev.desktop.data.Category
 import eu.mjdev.desktop.data.Category
 import eu.mjdev.desktop.extensions.ColorUtils.alpha
 import eu.mjdev.desktop.extensions.ColorUtils.alpha
@@ -26,11 +32,11 @@ fun AppsList(
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     category: String = "",
     category: String = "",
     listState: LazyListState = rememberForeverLazyListState("AppsMenu"),
     listState: LazyListState = rememberForeverLazyListState("AppsMenu"),
-    onCategoryClick: DesktopScope.(Category) -> Unit,
-    onCategoryContextMenuClick: DesktopScope.(Category) -> Unit,
-    onAppClick: DesktopScope.(App) -> Unit,
-    onAppContextMenuClick: DesktopScope.(App) -> Unit,
-    items: List<Any>
+    onCategoryClick: DesktopScope.(Category) -> Unit = {},
+    onCategoryContextMenuClick: DesktopScope.(Category) -> Unit = {},
+    onAppClick: DesktopScope.(App) -> Unit = {},
+    onAppContextMenuClick: DesktopScope.(App) -> Unit = {},
+    items: List<Any> = listOf()
 ) = withDesktopScope {
 ) = withDesktopScope {
     LazyColumn(
     LazyColumn(
         modifier = modifier,
         modifier = modifier,
@@ -66,4 +72,18 @@ fun AppsList(
             }
             }
         }
         }
     }
     }
+}
+
+@Preview
+@Composable
+fun AppsListPreview() {
+    AppsList(
+        modifier = Modifier.padding(8.dp)
+            .background(
+                Color.Gray,
+                RoundedCornerShape(16.dp)
+            )
+            .padding(8.dp),
+        items = listOf(App.Test, App.Test, App.Test)
+    )
 }
 }

+ 1 - 3
src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenu.kt

@@ -177,9 +177,7 @@ fun AppsMenu(
                                 backgroundColor.alpha(0.9f),
                                 backgroundColor.alpha(0.9f),
                                 backgroundColor.alpha(0.7f),
                                 backgroundColor.alpha(0.7f),
                                 backgroundColor.alpha(0.3f),
                                 backgroundColor.alpha(0.3f),
-                            ),
-//                            startX = 0f,
-//                            endX = 0f
+                            )
                         )
                         )
                         Box(
                         Box(
                             modifier = Modifier.fillMaxWidth()
                             modifier = Modifier.fillMaxWidth()

+ 10 - 1
src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenuApp.kt

@@ -3,6 +3,7 @@ package eu.mjdev.desktop.components.appsmenu
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Divider
 import androidx.compose.material.Divider
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
@@ -92,4 +93,12 @@ fun AppsMenuApp(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun AppsMenuAppPreview() = AppsMenuApp()
+fun AppsMenuAppPreview() = AppsMenuApp(
+    modifier = Modifier.padding(8.dp)
+        .background(
+            Color.Gray,
+            RoundedCornerShape(16.dp)
+        )
+        .padding(8.dp),
+    app = App.Test
+)

+ 10 - 1
src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenuCategory.kt

@@ -3,6 +3,7 @@ package eu.mjdev.desktop.components.appsmenu
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Divider
 import androidx.compose.material.Divider
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
@@ -79,4 +80,12 @@ fun AppsMenuCategory(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun AppsMenuCategoryPreview() = AppsMenuCategory()
+fun AppsMenuCategoryPreview() = AppsMenuCategory(
+    modifier = Modifier.padding(8.dp)
+        .background(
+            Color.Gray,
+            RoundedCornerShape(16.dp)
+        )
+        .padding(8.dp),
+    category = Category("Audio")
+)

+ 8 - 4
src/main/kotlin/eu/mjdev/desktop/components/blur/BlurPanel.kt

@@ -8,11 +8,9 @@
 
 
 package eu.mjdev.desktop.components.blur
 package eu.mjdev.desktop.components.blur
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.BoxWithConstraints
-import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
@@ -73,3 +71,9 @@ fun BlurPanel(
         content()
         content()
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun BlurPanelPreview() = BlurPanel(
+    modifier = Modifier.size(480.dp, 800.dp)
+)

+ 15 - 0
src/main/kotlin/eu/mjdev/desktop/components/button/ButtonPrimary.kt

@@ -1,9 +1,16 @@
 package eu.mjdev.desktop.components.button
 package eu.mjdev.desktop.components.button
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.Button
 import androidx.compose.material.Button
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import eu.mjdev.desktop.components.text.TextAny
 import eu.mjdev.desktop.components.text.TextAny
+import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
 import eu.mjdev.desktop.provider.DesktopScope.Companion.withDesktopScope
 import eu.mjdev.desktop.provider.DesktopScope.Companion.withDesktopScope
 
 
 @Composable
 @Composable
@@ -29,3 +36,11 @@ fun ButtonPrimary(
         }
         }
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun ButtonPrimaryPreview() = Box(
+    modifier = Modifier.fillMaxSize().background(Color.SuperDarkGray)
+) {
+    ButtonPrimary()
+}

+ 16 - 0
src/main/kotlin/eu/mjdev/desktop/components/button/ButtonSecondary.kt

@@ -1,11 +1,19 @@
 package eu.mjdev.desktop.components.button
 package eu.mjdev.desktop.components.button
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.Button
 import androidx.compose.material.Button
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import eu.mjdev.desktop.components.text.TextAny
 import eu.mjdev.desktop.components.text.TextAny
+import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
 import eu.mjdev.desktop.provider.DesktopScope.Companion.withDesktopScope
 import eu.mjdev.desktop.provider.DesktopScope.Companion.withDesktopScope
 
 
+// todo
 @Composable
 @Composable
 fun ButtonSecondary(
 fun ButtonSecondary(
     text: String = "Button",
     text: String = "Button",
@@ -29,3 +37,11 @@ fun ButtonSecondary(
         }
         }
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun ButtonSecondaryPreview() = Box(
+    modifier = Modifier.fillMaxSize().background(Color.SuperDarkGray)
+) {
+    ButtonSecondary()
+}

+ 23 - 1
src/main/kotlin/eu/mjdev/desktop/components/button/TransparentButton.kt

@@ -8,15 +8,23 @@
 
 
 package eu.mjdev.desktop.components.button
 package eu.mjdev.desktop.components.button
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.Button
 import androidx.compose.material.Button
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Icon
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
+import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
 import eu.mjdev.desktop.extensions.Compose.noElevation
 import eu.mjdev.desktop.extensions.Compose.noElevation
 import eu.mjdev.desktop.extensions.Compose.transparent
 import eu.mjdev.desktop.extensions.Compose.transparent
+import eu.mjdev.desktop.icons.Icons
 
 
 @Composable
 @Composable
 fun TransparentButton(
 fun TransparentButton(
@@ -30,4 +38,18 @@ fun TransparentButton(
     colors = ButtonDefaults.transparent(),
     colors = ButtonDefaults.transparent(),
     elevation = ButtonDefaults.noElevation(),
     elevation = ButtonDefaults.noElevation(),
     content = content
     content = content
-)
+)
+
+@Preview
+@Composable
+fun TransparentButtonPreview() = Box(
+    modifier = Modifier.fillMaxSize().background(Color.SuperDarkGray)
+) {
+    TransparentButton {
+        Icon(
+            imageVector = Icons.User,
+            contentDescription = "",
+            tint = Color.White
+        )
+    }
+}

+ 8 - 3
src/main/kotlin/eu/mjdev/desktop/components/card/Card.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.ColumnScope
@@ -23,7 +24,7 @@ import eu.mjdev.desktop.components.surface.Surface
 
 
 @Composable
 @Composable
 fun Card(
 fun Card(
-    onClick: () -> Unit,
+    onClick: () -> Unit = {},
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     onLongClick: (() -> Unit)? = null,
     onLongClick: (() -> Unit)? = null,
     shape: CardShape = CardDefaults.shape(),
     shape: CardShape = CardDefaults.shape(),
@@ -32,7 +33,7 @@ fun Card(
     border: CardBorder = CardDefaults.border(),
     border: CardBorder = CardDefaults.border(),
     glow: CardGlow = CardDefaults.glow(),
     glow: CardGlow = CardDefaults.glow(),
     interactionSource: MutableInteractionSource? = null,
     interactionSource: MutableInteractionSource? = null,
-    content: @Composable ColumnScope.() -> Unit
+    content: @Composable ColumnScope.() -> Unit = {}
 ) = Surface(
 ) = Surface(
     onClick = onClick,
     onClick = onClick,
     onLongClick = onLongClick,
     onLongClick = onLongClick,
@@ -45,4 +46,8 @@ fun Card(
     interactionSource = interactionSource,
     interactionSource = interactionSource,
 ) {
 ) {
     Column(content = content)
     Column(content = content)
-}
+}
+
+@Preview
+@Composable
+fun CardPreview() = Card()

+ 9 - 4
src/main/kotlin/eu/mjdev/desktop/components/card/ClassicCard.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
@@ -17,9 +18,9 @@ import eu.mjdev.desktop.components.card.base.*
 @Suppress("unused")
 @Suppress("unused")
 @Composable
 @Composable
 fun ClassicCard(
 fun ClassicCard(
-    onClick: () -> Unit,
-    image: @Composable BoxScope.() -> Unit,
-    title: @Composable () -> Unit,
+    onClick: () -> Unit = {},
+    image: @Composable BoxScope.() -> Unit = {},
+    title: @Composable () -> Unit = {},
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     onLongClick: (() -> Unit)? = null,
     onLongClick: (() -> Unit)? = null,
     subtitle: @Composable () -> Unit = {},
     subtitle: @Composable () -> Unit = {},
@@ -46,4 +47,8 @@ fun ClassicCard(
         Box(contentAlignment = CardDefaults.ContentImageAlignment, content = image)
         Box(contentAlignment = CardDefaults.ContentImageAlignment, content = image)
         Column { CardContent(title = title, subtitle = subtitle, description = description) }
         Column { CardContent(title = title, subtitle = subtitle, description = description) }
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun ClassicCardPreview() = ClassicCard()

+ 14 - 5
src/main/kotlin/eu/mjdev/desktop/components/card/CompactCard.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.BoxScope
@@ -26,9 +27,9 @@ import eu.mjdev.desktop.components.card.base.CardDefaults.SubtitleAlpha
 
 
 @Composable
 @Composable
 fun CompactCard(
 fun CompactCard(
-    onClick: () -> Unit,
-    image: @Composable BoxScope.() -> Unit,
-    title: @Composable () -> Unit,
+    onClick: () -> Unit = {},
+    image: @Composable BoxScope.() -> Unit = {},
+    title: @Composable () -> Unit = {},
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     onLongClick: (() -> Unit)? = null,
     onLongClick: (() -> Unit)? = null,
     subtitle: @Composable () -> Unit = {},
     subtitle: @Composable () -> Unit = {},
@@ -71,7 +72,7 @@ fun CompactCard(
 
 
 @Composable
 @Composable
 fun CardContent(
 fun CardContent(
-    title: @Composable () -> Unit,
+    title: @Composable () -> Unit = {},
     subtitle: @Composable () -> Unit = {},
     subtitle: @Composable () -> Unit = {},
     description: @Composable () -> Unit = {}
     description: @Composable () -> Unit = {}
 ) {
 ) {
@@ -90,10 +91,18 @@ fun CardContent(
     ProvideTextStyle(MaterialTheme.typography.body2) {
     ProvideTextStyle(MaterialTheme.typography.body2) {
         Box(
         Box(
             modifier = Modifier.graphicsLayer {
             modifier = Modifier.graphicsLayer {
-            alpha = DescriptionAlpha
+                alpha = DescriptionAlpha
             }
             }
         ) {
         ) {
             description()
             description()
         }
         }
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun CardContentPreview() = CardContent()
+
+@Preview
+@Composable
+fun CompactCardPreview() = CompactCard()

+ 12 - 7
src/main/kotlin/eu/mjdev/desktop/components/card/FocusableCard.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
@@ -17,8 +18,11 @@ import androidx.compose.material.icons.filled.BrokenImage
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.focus.FocusState
+import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
@@ -26,17 +30,14 @@ import eu.mjdev.desktop.components.card.base.*
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusBorder
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusBorder
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusGlow
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusGlow
 import eu.mjdev.desktop.components.image.ImageAny
 import eu.mjdev.desktop.components.image.ImageAny
-import eu.mjdev.desktop.extensions.Compose.rememberFocusState
-import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
-import eu.mjdev.desktop.helpers.compose.FocusHelper
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.onFocusChanged
-import androidx.compose.ui.graphics.RectangleShape
 import eu.mjdev.desktop.components.text.AutoHideEmptyText
 import eu.mjdev.desktop.components.text.AutoHideEmptyText
 import eu.mjdev.desktop.components.text.TextAny
 import eu.mjdev.desktop.components.text.TextAny
 import eu.mjdev.desktop.extensions.Compose.focusState
 import eu.mjdev.desktop.extensions.Compose.focusState
 import eu.mjdev.desktop.extensions.Compose.isFocused
 import eu.mjdev.desktop.extensions.Compose.isFocused
+import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
+import eu.mjdev.desktop.extensions.Compose.rememberFocusState
 import eu.mjdev.desktop.extensions.Compose.requestFocusOnTouch
 import eu.mjdev.desktop.extensions.Compose.requestFocusOnTouch
+import eu.mjdev.desktop.helpers.compose.FocusHelper
 
 
 @Composable
 @Composable
 fun FocusableCard(
 fun FocusableCard(
@@ -156,4 +157,8 @@ fun FocusableCard(
     onClick = {
     onClick = {
         onClick?.invoke(item)
         onClick?.invoke(item)
     },
     },
-)
+)
+
+@Preview
+@Composable
+fun FocusableCardPreview() = FocusableCard()

+ 13 - 8
src/main/kotlin/eu/mjdev/desktop/components/card/ItemCard.kt

@@ -8,27 +8,28 @@
 
 
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.BrokenImage
 import androidx.compose.material.icons.filled.BrokenImage
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
 import eu.mjdev.desktop.components.card.base.*
 import eu.mjdev.desktop.components.card.base.*
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusBorder
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusBorder
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusGlow
 import eu.mjdev.desktop.components.card.base.CardDefaults.colorFocusGlow
-import eu.mjdev.desktop.helpers.compose.FocusHelper
 import eu.mjdev.desktop.components.image.ImageAny
 import eu.mjdev.desktop.components.image.ImageAny
 import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
 import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
 import eu.mjdev.desktop.extensions.Compose.rememberFocusState
 import eu.mjdev.desktop.extensions.Compose.rememberFocusState
-import androidx.compose.runtime.MutableState
-import androidx.compose.ui.focus.FocusState
+import eu.mjdev.desktop.helpers.compose.FocusHelper
 
 
 @Composable
 @Composable
 fun ItemCard(
 fun ItemCard(
@@ -42,7 +43,7 @@ fun ItemCard(
     border: CardBorder = CardDefaults.colorFocusBorder(Color.Green),
     border: CardBorder = CardDefaults.colorFocusBorder(Color.Green),
     glow: CardGlow = CardDefaults.colorFocusGlow(Color.Green),
     glow: CardGlow = CardDefaults.colorFocusGlow(Color.Green),
     aspectRatio: Float = 16f / 9f,
     aspectRatio: Float = 16f / 9f,
-    placeholder : @Composable () -> Unit = {
+    placeholder: @Composable () -> Unit = {
         Image(
         Image(
             imageVector = Icons.Filled.BrokenImage,
             imageVector = Icons.Filled.BrokenImage,
             "",
             "",
@@ -66,8 +67,8 @@ fun ItemCard(
     ),
     ),
     focusRequester: FocusRequester = rememberFocusRequester(item),
     focusRequester: FocusRequester = rememberFocusRequester(item),
     titlePadding: PaddingValues = PaddingValues(8.dp),
     titlePadding: PaddingValues = PaddingValues(8.dp),
-    showTitle:Boolean = true,
-    onFocus: ((item: Any?, fromUser:Boolean) -> Unit)? = null,
+    showTitle: Boolean = true,
+    onFocus: ((item: Any?, fromUser: Boolean) -> Unit)? = null,
     onClick: ((item: Any?) -> Unit)? = null,
     onClick: ((item: Any?) -> Unit)? = null,
 ) = FocusableCard(
 ) = FocusableCard(
     modifier = modifier,
     modifier = modifier,
@@ -90,4 +91,8 @@ fun ItemCard(
     onClick = onClick,
     onClick = onClick,
     showTitle = showTitle,
     showTitle = showTitle,
     placeholder = placeholder
     placeholder = placeholder
-)
+)
+
+@Preview
+@Composable
+fun ItemCardPreview() = ItemCard()

+ 8 - 4
src/main/kotlin/eu/mjdev/desktop/components/card/PhotoCard.kt

@@ -1,11 +1,12 @@
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.padding
-import androidx.compose.ui.Modifier
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.MutableState
+import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
@@ -14,12 +15,12 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
 import eu.mjdev.desktop.components.card.base.CardDefaults
 import eu.mjdev.desktop.components.card.base.CardDefaults
 import eu.mjdev.desktop.components.card.base.CardScale
 import eu.mjdev.desktop.components.card.base.CardScale
-import eu.mjdev.desktop.extensions.Compose.rememberFocusState
-import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
-import eu.mjdev.desktop.helpers.compose.FocusHelper
 import eu.mjdev.desktop.components.image.ImageAny
 import eu.mjdev.desktop.components.image.ImageAny
 import eu.mjdev.desktop.components.image.PhotoImage
 import eu.mjdev.desktop.components.image.PhotoImage
 import eu.mjdev.desktop.extensions.Compose.isFocused
 import eu.mjdev.desktop.extensions.Compose.isFocused
+import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
+import eu.mjdev.desktop.extensions.Compose.rememberFocusState
+import eu.mjdev.desktop.helpers.compose.FocusHelper
 import eu.mjdev.desktop.provider.DesktopProvider
 import eu.mjdev.desktop.provider.DesktopProvider
 import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
 import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
 
 
@@ -95,3 +96,6 @@ fun computeCardWidth(
 //        config.screenHeightDp / ratio
 //        config.screenHeightDp / ratio
 //}.dp
 //}.dp
 
 
+@Preview
+@Composable
+fun PhotoCardPreview() = PhotoCard()

+ 9 - 4
src/main/kotlin/eu/mjdev/desktop/components/card/WideClassicCard.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.card
 package eu.mjdev.desktop.components.card
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
@@ -17,9 +18,9 @@ import eu.mjdev.desktop.components.card.base.*
 @Suppress("unused")
 @Suppress("unused")
 @Composable
 @Composable
 fun WideClassicCard(
 fun WideClassicCard(
-    onClick: () -> Unit,
-    image: @Composable BoxScope.() -> Unit,
-    title: @Composable () -> Unit,
+    onClick: () -> Unit = {},
+    image: @Composable BoxScope.() -> Unit = {},
+    title: @Composable () -> Unit = {},
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     onLongClick: (() -> Unit)? = null,
     onLongClick: (() -> Unit)? = null,
     subtitle: @Composable () -> Unit = {},
     subtitle: @Composable () -> Unit = {},
@@ -48,4 +49,8 @@ fun WideClassicCard(
             Column { CardContent(title = title, subtitle = subtitle, description = description) }
             Column { CardContent(title = title, subtitle = subtitle, description = description) }
         }
         }
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun WideClassicCardPreview() = WideClassicCard()

+ 5 - 6
src/main/kotlin/eu/mjdev/desktop/components/card/base/CardBorder.kt

@@ -12,11 +12,10 @@ import androidx.compose.runtime.Immutable
 import eu.mjdev.desktop.components.surface.base.Border
 import eu.mjdev.desktop.components.surface.base.Border
 
 
 @Immutable
 @Immutable
-class CardBorder
-internal constructor(
-    internal val border: Border,
-    internal val focusedBorder: Border,
-    internal val pressedBorder: Border
+class CardBorder(
+    val border: Border,
+    val focusedBorder: Border,
+    val pressedBorder: Border
 ) {
 ) {
     override fun equals(other: Any?): Boolean {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (this === other) return true
@@ -37,6 +36,6 @@ internal constructor(
 
 
     override fun toString(): String {
     override fun toString(): String {
         return "CardBorder(border=$border, focusedBorder=$focusedBorder, " +
         return "CardBorder(border=$border, focusedBorder=$focusedBorder, " +
-            "pressedBorder=$pressedBorder)"
+                "pressedBorder=$pressedBorder)"
     }
     }
 }
 }

+ 7 - 8
src/main/kotlin/eu/mjdev/desktop/components/card/base/CardColors.kt

@@ -12,14 +12,13 @@ import androidx.compose.runtime.Immutable
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
 
 
 @Immutable
 @Immutable
-class CardColors
-internal constructor(
-    internal val containerColor: Color,
-    internal val contentColor: Color,
-    internal val focusedContainerColor: Color,
-    internal val focusedContentColor: Color,
-    internal val pressedContainerColor: Color,
-    internal val pressedContentColor: Color
+class CardColors(
+    val containerColor: Color,
+    val contentColor: Color,
+    val focusedContainerColor: Color,
+    val focusedContentColor: Color,
+    val pressedContainerColor: Color,
+    val pressedContentColor: Color
 ) {
 ) {
     override fun equals(other: Any?): Boolean {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (this === other) return true

+ 4 - 5
src/main/kotlin/eu/mjdev/desktop/components/card/base/CardGlow.kt

@@ -12,11 +12,10 @@ import androidx.compose.runtime.Immutable
 import eu.mjdev.desktop.components.surface.base.Glow
 import eu.mjdev.desktop.components.surface.base.Glow
 
 
 @Immutable
 @Immutable
-class CardGlow
-internal constructor(
-    internal val glow: Glow,
-    internal val focusedGlow: Glow,
-    internal val pressedGlow: Glow
+class CardGlow(
+    val glow: Glow,
+    val focusedGlow: Glow,
+    val pressedGlow: Glow
 ) {
 ) {
     override fun equals(other: Any?): Boolean {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (this === other) return true

+ 4 - 5
src/main/kotlin/eu/mjdev/desktop/components/card/base/CardScale.kt

@@ -12,11 +12,10 @@ import androidx.compose.runtime.Immutable
 
 
 @Suppress("unused")
 @Suppress("unused")
 @Immutable
 @Immutable
-class CardScale
-internal constructor(
-    internal val scale: Float,
-    internal val focusedScale: Float,
-    internal val pressedScale: Float
+class CardScale(
+    val scale: Float,
+    val focusedScale: Float,
+    val pressedScale: Float
 ) {
 ) {
     override fun equals(other: Any?): Boolean {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (this === other) return true

+ 4 - 5
src/main/kotlin/eu/mjdev/desktop/components/card/base/CardShape.kt

@@ -12,11 +12,10 @@ import androidx.compose.runtime.Immutable
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.Shape
 
 
 @Immutable
 @Immutable
-class CardShape
-internal constructor(
-    internal val shape: Shape,
-    internal val focusedShape: Shape,
-    internal val pressedShape: Shape
+class CardShape(
+    val shape: Shape,
+    val focusedShape: Shape,
+    val pressedShape: Shape
 ) {
 ) {
     override fun equals(other: Any?): Boolean {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (this === other) return true

+ 5 - 0
src/main/kotlin/eu/mjdev/desktop/components/custom/BrushedLayout.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.custom
 package eu.mjdev.desktop.components.custom
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Canvas
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
@@ -29,3 +30,7 @@ fun BrushedLayout(
         }
         }
     )
     )
 }
 }
+
+@Preview
+@Composable
+fun BrushedLayoutPreview() = BrushedLayout()

+ 3 - 3
src/main/kotlin/eu/mjdev/desktop/components/custom/DateTime.kt

@@ -27,7 +27,7 @@ fun DateTime(
     showTime: Boolean = true,
     showTime: Boolean = true,
     showDate: Boolean = true,
     showDate: Boolean = true,
     talkEveryHour: Boolean = false,
     talkEveryHour: Boolean = false,
-    talkOnClick :Boolean = true
+    talkOnClick: Boolean = true
 ) = Box(
 ) = Box(
     modifier = modifier
     modifier = modifier
         .background(backgroundColor)
         .background(backgroundColor)
@@ -44,10 +44,10 @@ fun DateTime(
         showTime = showTime,
         showTime = showTime,
         showDate = showDate,
         showDate = showDate,
         talkEveryHour = talkEveryHour,
         talkEveryHour = talkEveryHour,
-        talkOnClick=talkOnClick
+        talkOnClick = talkOnClick
     )
     )
 }
 }
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun DateTimePreview() = DateTime()
+fun DateTimePreview() = DateTime()

+ 13 - 3
src/main/kotlin/eu/mjdev/desktop/components/custom/MeasureUnconstrainedView.kt

@@ -1,14 +1,16 @@
 package eu.mjdev.desktop.components.custom
 package eu.mjdev.desktop.components.custom
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.layout.SubcomposeLayout
 import androidx.compose.ui.layout.SubcomposeLayout
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
+import eu.mjdev.desktop.components.text.TextAny
 
 
 @Composable
 @Composable
 fun MeasureUnconstrainedView(
 fun MeasureUnconstrainedView(
     viewToMeasure: @Composable () -> Unit,
     viewToMeasure: @Composable () -> Unit,
-    content: @Composable (measuredWidth: Dp, measuredHeight: Dp) -> Unit,
+    content: @Composable (DpSize) -> Unit,
 ) {
 ) {
     SubcomposeLayout { constraints ->
     SubcomposeLayout { constraints ->
         val measured = subcompose("viewToMeasure", viewToMeasure)[0]
         val measured = subcompose("viewToMeasure", viewToMeasure)[0]
@@ -16,10 +18,18 @@ fun MeasureUnconstrainedView(
         val measuredWidth = measured.width.toDp()
         val measuredWidth = measured.width.toDp()
         val measuredHeight = measured.height.toDp()
         val measuredHeight = measured.height.toDp()
         val contentPlaceable = subcompose("content") {
         val contentPlaceable = subcompose("content") {
-            content(measuredWidth, measuredHeight)
+            content(DpSize(measuredWidth, measuredHeight))
         }[0].measure(constraints)
         }[0].measure(constraints)
         layout(contentPlaceable.width, contentPlaceable.height) {
         layout(contentPlaceable.width, contentPlaceable.height) {
             contentPlaceable.place(0, 0)
             contentPlaceable.place(0, 0)
         }
         }
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun MeasureUnconstrainedViewPreview() = MeasureUnconstrainedView({
+    TextAny("test")
+}, { size ->
+    TextAny("test size: $size")
+})

+ 5 - 0
src/main/kotlin/eu/mjdev/desktop/components/custom/VerticalScrollableBox.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.custom
 package eu.mjdev.desktop.components.custom
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.LazyListState
@@ -32,3 +33,7 @@ fun VerticalScrollableBox(
 ) {
 ) {
     content.invoke(this)
     content.invoke(this)
 }
 }
+
+@Preview
+@Composable
+fun VerticalScrollableBoxPreview() = VerticalScrollableBox()

+ 1 - 2
src/main/kotlin/eu/mjdev/desktop/components/desktop/Desktop.kt

@@ -1,7 +1,6 @@
 package eu.mjdev.desktop.components.desktop
 package eu.mjdev.desktop.components.desktop
 
 
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.desktop.ui.tooling.preview.Preview
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
@@ -41,7 +40,7 @@ fun Desktop(
                 modifier = Modifier.fillMaxSize(),
                 modifier = Modifier.fillMaxSize(),
                 path = api.currentUser.userDirs.desktopDirectory,
                 path = api.currentUser.userDirs.desktopDirectory,
                 showHomeFolder = true,
                 showHomeFolder = true,
-                orientation = Orientation.Vertical,
+//                orientation = Orientation.Vertical,
             )
             )
             MemoryChart(
             MemoryChart(
                 modifier = Modifier.size(350.dp, 300.dp)
                 modifier = Modifier.size(350.dp, 300.dp)

+ 0 - 1
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/DesktopPanelText.kt

@@ -62,4 +62,3 @@ fun DesktopPanelText(
 @Preview
 @Preview
 @Composable
 @Composable
 fun DesktopPanelTextPreview() = DesktopPanelText()
 fun DesktopPanelTextPreview() = DesktopPanelText()
-

+ 6 - 1
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/DesktopPanelTray.kt

@@ -1,5 +1,6 @@
 package eu.mjdev.desktop.components.desktoppanel
 package eu.mjdev.desktop.components.desktoppanel
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Row
@@ -26,4 +27,8 @@ fun DesktopPanelTray(
         modifier = modifier.background(backgroundColor, RoundedCornerShape(round)).padding(padding),
         modifier = modifier.background(backgroundColor, RoundedCornerShape(round)).padding(padding),
         content = content
         content = content
     )
     )
-}
+}
+
+@Preview
+@Composable
+fun DesktopPanelTrayPreview() = DesktopPanelTray()

+ 3 - 2
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/applets/DesktopMenuIcon.kt

@@ -1,7 +1,8 @@
 package eu.mjdev.desktop.components.desktoppanel.applets
 package eu.mjdev.desktop.components.desktoppanel.applets
 
 
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.desktop.ui.tooling.preview.Preview
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
@@ -41,4 +42,4 @@ fun DesktopMenuIcon(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun DesktopMenuIconPreview() = DesktopMenuIcon()
+fun DesktopMenuIconPreview() = DesktopMenuIcon()

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/applets/DesktopPanelDateTime.kt

@@ -66,4 +66,4 @@ fun DesktopPanelDateTime(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun DesktopPanelDateTimePreview() = DesktopPanelDateTime()
+fun DesktopPanelDateTimePreview() = DesktopPanelDateTime()

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/applets/DesktopPanelLanguage.kt

@@ -24,4 +24,4 @@ fun DesktopPanelLanguage(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun DesktopPanelLanguagePreview() = DesktopPanelLanguage()
+fun DesktopPanelLanguagePreview() = DesktopPanelLanguage()

+ 11 - 8
src/main/kotlin/eu/mjdev/desktop/components/draggable/DraggableView.kt

@@ -1,14 +1,13 @@
 package eu.mjdev.desktop.components.draggable
 package eu.mjdev.desktop.components.draggable
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.detectDragGestures
 import androidx.compose.foundation.gestures.detectDragGestures
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.runtime.*
+import androidx.compose.foundation.layout.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
@@ -28,8 +27,8 @@ fun DraggableView(
     dragBackgroundColor: Color = Color.White.copy(alpha = 0.3f),
     dragBackgroundColor: Color = Color.White.copy(alpha = 0.3f),
     contentPadding: PaddingValues = PaddingValues(0.dp),
     contentPadding: PaddingValues = PaddingValues(0.dp),
     zIndex: Float = Float.MIN_VALUE,
     zIndex: Float = Float.MIN_VALUE,
-    onDragStart:()->Unit={},
-    onDragEnd:()->Unit={},
+    onDragStart: () -> Unit = {},
+    onDragEnd: () -> Unit = {},
     onTap: () -> Unit = {},
     onTap: () -> Unit = {},
     onDoubleTap: () -> Unit = {},
     onDoubleTap: () -> Unit = {},
     onClick: () -> Unit = {},
     onClick: () -> Unit = {},
@@ -83,3 +82,7 @@ fun DraggableView(
         }
         }
     )
     )
 }
 }
+
+@Preview
+@Composable
+fun DraggableViewPreview() = DraggableView()

+ 4 - 5
src/main/kotlin/eu/mjdev/desktop/components/file/FolderView.kt

@@ -1,7 +1,6 @@
 package eu.mjdev.desktop.components.file
 package eu.mjdev.desktop.components.file
 
 
 import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.desktop.ui.tooling.preview.Preview
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
@@ -47,7 +46,7 @@ fun FolderView(
     iconSpacing: Dp = 2.dp,
     iconSpacing: Dp = 2.dp,
     iconSize: DpSize = DpSize(128.dp, 128.dp),
     iconSize: DpSize = DpSize(128.dp, 128.dp),
     path: File? = File("/"),
     path: File? = File("/"),
-    orientation: Orientation = Orientation.Vertical, // todo
+//    orientation: Orientation = Orientation.Vertical, // todo
     guideVisibleState: VisibilityState = rememberVisibilityState(false),
     guideVisibleState: VisibilityState = rememberVisibilityState(false),
 ) = withDesktopScope {
 ) = withDesktopScope {
     val files by rememberFiles(path, api.homeDir, showHidden, directoryFirst, showHomeFolder)
     val files by rememberFiles(path, api.homeDir, showHidden, directoryFirst, showHomeFolder)
@@ -58,8 +57,8 @@ fun FolderView(
                 iconSize = iconSize,
                 iconSize = iconSize,
             )
             )
         }
         }
-    ) { mw, mh ->
-        val rows = max(1, ((api.containerSize.height / mh).toInt()))
+    ) { size ->
+        val rows = max(1, ((api.containerSize.height / size.height).toInt()))
         val columns = max(1, (files.size.div(rows)))
         val columns = max(1, (files.size.div(rows)))
         Box(
         Box(
             modifier = modifier,
             modifier = modifier,
@@ -95,7 +94,7 @@ fun FolderView(
             }
             }
             GuideLines(
             GuideLines(
                 modifier = modifier,
                 modifier = modifier,
-                cellSize = DpSize(mw, mh),
+                cellSize = size,
                 color = iconsTintColor.alpha(0.5f),
                 color = iconsTintColor.alpha(0.5f),
                 lineSize = 1.dp,
                 lineSize = 1.dp,
                 visible = guideVisibleState.isVisible
                 visible = guideVisibleState.isVisible

+ 7 - 2
src/main/kotlin/eu/mjdev/desktop/components/gallery/BoxWithControls.kt

@@ -1,5 +1,6 @@
 package eu.mjdev.desktop.components.gallery
 package eu.mjdev.desktop.components.gallery
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.mutableStateOf
@@ -27,7 +28,7 @@ fun BoxWithControls(
         src: Any?,
         src: Any?,
         bckColor: Color,
         bckColor: Color,
         controlsState: MutableState<Boolean>
         controlsState: MutableState<Boolean>
-    ) -> Unit
+    ) -> Unit = { _, _, _ -> }
 ) = ImageColoredBackground(
 ) = ImageColoredBackground(
     modifier = modifier
     modifier = modifier
 //        .swipeGestures(
 //        .swipeGestures(
@@ -49,4 +50,8 @@ fun BoxWithControls(
     if (controlsState.value) {
     if (controlsState.value) {
         controls(src, bckColor, controlsState)
         controls(src, bckColor, controlsState)
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun BoxWithControlsPreview() = BoxWithControls()

+ 8 - 3
src/main/kotlin/eu/mjdev/desktop/components/gallery/Gallery.kt

@@ -1,5 +1,6 @@
 package eu.mjdev.desktop.components.gallery
 package eu.mjdev.desktop.components.gallery
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.LazyListState
@@ -16,14 +17,14 @@ import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
-import eu.mjdev.desktop.components.image.ImageAny
-import kotlinx.coroutines.delay
 import eu.mjdev.desktop.components.card.PhotoCard
 import eu.mjdev.desktop.components.card.PhotoCard
-import eu.mjdev.desktop.components.immersivelist.ImmersiveInnerList
+import eu.mjdev.desktop.components.image.ImageAny
 import eu.mjdev.desktop.components.immersivelist.ImmersiveList
 import eu.mjdev.desktop.components.immersivelist.ImmersiveList
+import eu.mjdev.desktop.components.immersivelist.base.ImmersiveInnerList
 import eu.mjdev.desktop.extensions.Compose.rememberDerivedState
 import eu.mjdev.desktop.extensions.Compose.rememberDerivedState
 import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
 import eu.mjdev.desktop.extensions.Compose.rememberFocusRequester
 import eu.mjdev.desktop.helpers.bitmap.Bitmap
 import eu.mjdev.desktop.helpers.bitmap.Bitmap
+import kotlinx.coroutines.delay
 import java.io.File
 import java.io.File
 
 
 @Composable
 @Composable
@@ -192,3 +193,7 @@ val contentScaleSaver = Saver<MutableState<ContentScale>, String>(
         )
         )
     }
     }
 )
 )
+
+@Preview
+@Composable
+fun GalleryPreview() = Gallery()

+ 7 - 6
src/main/kotlin/eu/mjdev/desktop/components/gallery/ItemInfo.kt

@@ -3,12 +3,9 @@ package eu.mjdev.desktop.components.gallery
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.slideInVertically
 import androidx.compose.animation.slideInVertically
 import androidx.compose.animation.slideOutVertically
 import androidx.compose.animation.slideOutVertically
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
@@ -82,4 +79,8 @@ fun ItemInfo(
             }
             }
         }
         }
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun ItemInfoPreview() = ItemInfo()

+ 8 - 5
src/main/kotlin/eu/mjdev/desktop/components/grid/GridPlaced.kt

@@ -1,5 +1,6 @@
 package eu.mjdev.desktop.components.grid
 package eu.mjdev.desktop.components.grid
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.Layout
@@ -11,19 +12,17 @@ import kotlin.math.min
 
 
 @Composable
 @Composable
 fun GridPlaced(
 fun GridPlaced(
-    cells: GridPlacedCells,
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
+    cells: GridPlacedCells = GridPlacedCells(2, 2),
     placementPolicy: GridPlacedPlacementPolicy = GridPlacedPlacementPolicy.DEFAULT,
     placementPolicy: GridPlacedPlacementPolicy = GridPlacedPlacementPolicy.DEFAULT,
-    content: GridPlacedScope.() -> Unit
+    content: GridPlacedScope.() -> Unit = {}
 ) {
 ) {
     val scopeContent: GridPlacedScopeImpl = GridPlacedScopeImpl(cells, placementPolicy).apply(content)
     val scopeContent: GridPlacedScopeImpl = GridPlacedScopeImpl(cells, placementPolicy).apply(content)
     val displayContent: List<GridPlacedContent> = scopeContent.data.toList()
     val displayContent: List<GridPlacedContent> = scopeContent.data.toList()
     Layout(
     Layout(
         modifier = modifier,
         modifier = modifier,
         content = {
         content = {
-            displayContent.forEach {
-                it.item(GridPlacedItemScopeImpl)
-            }
+            displayContent.forEach { cnt -> cnt.item(GridPlacedItemScopeImpl) }
         }
         }
     ) { measurables, constraints ->
     ) { measurables, constraints ->
         check(constraints.maxWidth != Constraints.Infinity) { "Infinity width not allowed in GridPad" }
         check(constraints.maxWidth != Constraints.Infinity) { "Infinity width not allowed in GridPad" }
@@ -49,3 +48,7 @@ fun GridPlaced(
         }
         }
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun GridPlacedPreview() = GridPlaced()

+ 2 - 3
src/main/kotlin/eu/mjdev/desktop/components/image/GifView.kt

@@ -21,8 +21,7 @@ fun GifView(
 ) = BoxWithConstraints {
 ) = BoxWithConstraints {
     val file by remember(src) { mutableStateOf(File(src)) }
     val file by remember(src) { mutableStateOf(File(src)) }
     val streamData by remember(file) { mutableStateOf(FileInputStream(file)) }
     val streamData by remember(file) { mutableStateOf(FileInputStream(file)) }
-    val gifDecoder by remember(streamData) { mutableStateOf(
-        GifDecoder().apply { read(streamData) }) }
+    val gifDecoder by remember(streamData) { mutableStateOf(GifDecoder().apply { read(streamData) }) }
     val framesCount by remember(gifDecoder) { mutableStateOf(gifDecoder.frameCount) }
     val framesCount by remember(gifDecoder) { mutableStateOf(gifDecoder.frameCount) }
     var currentFrame by remember(gifDecoder) { mutableStateOf(0) }
     var currentFrame by remember(gifDecoder) { mutableStateOf(0) }
     var decodedImage by remember { mutableStateOf<BufferedImage?>(null) }
     var decodedImage by remember { mutableStateOf<BufferedImage?>(null) }
@@ -50,4 +49,4 @@ fun GifView(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun GifViewPreview() = GifView()
+fun GifViewPreview() = GifView()

+ 7 - 2
src/main/kotlin/eu/mjdev/desktop/components/image/ImageColoredBackground.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.image
 package eu.mjdev.desktop.components.image
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.runtime.*
 import androidx.compose.runtime.*
@@ -21,8 +22,8 @@ import eu.mjdev.desktop.extensions.BitmapUtils.cut
 import eu.mjdev.desktop.extensions.BitmapUtils.topMostColor
 import eu.mjdev.desktop.extensions.BitmapUtils.topMostColor
 import eu.mjdev.desktop.extensions.ColorUtils.nonAlphaValue
 import eu.mjdev.desktop.extensions.ColorUtils.nonAlphaValue
 import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
 import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
-import eu.mjdev.desktop.extensions.Modifier.conditional
 import eu.mjdev.desktop.extensions.Image.loadPicture
 import eu.mjdev.desktop.extensions.Image.loadPicture
+import eu.mjdev.desktop.extensions.Modifier.conditional
 
 
 @Composable
 @Composable
 fun ImageColoredBackground(
 fun ImageColoredBackground(
@@ -71,4 +72,8 @@ fun ImageColoredBackground(
             bckColor = bc
             bckColor = bc
         }
         }
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun ImageColoredBackgroundPreview() = ImageColoredBackground()

+ 5 - 0
src/main/kotlin/eu/mjdev/desktop/components/image/PhotoImage.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.image
 package eu.mjdev.desktop.components.image
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.border
@@ -123,3 +124,7 @@ fun PhotoImage(
 //        )
 //        )
     }
     }
 }
 }
+
+@Preview
+@Composable
+fun PhotoImagePreview() = PhotoImage()

+ 9 - 7
src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveList.kt

@@ -1,18 +1,16 @@
 package eu.mjdev.desktop.components.immersivelist
 package eu.mjdev.desktop.components.immersivelist
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableIntState
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.*
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.platform.LocalFocusManager
 import androidx.compose.ui.platform.LocalFocusManager
+import eu.mjdev.desktop.components.immersivelist.base.ImmersiveListBackgroundScope
+import eu.mjdev.desktop.components.immersivelist.base.ImmersiveListScope
 import eu.mjdev.desktop.extensions.Compose.bringIntoViewIfChildrenAreFocused
 import eu.mjdev.desktop.extensions.Compose.bringIntoViewIfChildrenAreFocused
 
 
 @Suppress("IllegalExperimentalApiUsage")
 @Suppress("IllegalExperimentalApiUsage")
@@ -50,4 +48,8 @@ fun ImmersiveList(
             focusManager.moveFocus(FocusDirection.Enter)
             focusManager.moveFocus(FocusDirection.Enter)
         }.list()
         }.list()
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun ImmersiveListPreview() = ImmersiveList()

+ 0 - 16
src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveListScope.kt

@@ -1,16 +0,0 @@
-package eu.mjdev.desktop.components.immersivelist
-
-import androidx.compose.runtime.Immutable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.onFocusChanged
-
-@Immutable
-class ImmersiveListScope internal constructor(
-    private val onFocused: (Int) -> Unit
-) {
-    fun Modifier.immersiveListItem(index: Int): Modifier {
-        return this then onFocusChanged {
-            if (it.isFocused) onFocused(index)
-        }
-    }
-}

+ 10 - 7
src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveListBackgroundScope.kt → src/main/kotlin/eu/mjdev/desktop/components/immersivelist/base/ImmersiveListBackgroundScope.kt

@@ -1,11 +1,14 @@
-package eu.mjdev.desktop.components.immersivelist
+/*
+ * Copyright (c) Milan Jurkulák 2024.
+ *  Contact:
+ *  e: mimoccc@gmail.com
+ *  e: mj@mjdev.org
+ *  w: https://mjdev.org
+ */
 
 
-import androidx.compose.animation.AnimatedContentTransitionScope
-import androidx.compose.animation.AnimatedVisibilityScope
-import androidx.compose.animation.ContentTransform
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
-import androidx.compose.animation.togetherWith
+package eu.mjdev.desktop.components.immersivelist.base
+
+import androidx.compose.animation.*
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Immutable

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveListDefaults.kt → src/main/kotlin/eu/mjdev/desktop/components/immersivelist/base/ImmersiveListDefaults.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.immersivelist
+package eu.mjdev.desktop.components.immersivelist.base
 
 
 import androidx.compose.animation.EnterTransition
 import androidx.compose.animation.EnterTransition
 import androidx.compose.animation.ExitTransition
 import androidx.compose.animation.ExitTransition

+ 16 - 13
src/main/kotlin/eu/mjdev/desktop/components/immersivelist/ImmersiveInnerList.kt → src/main/kotlin/eu/mjdev/desktop/components/immersivelist/base/ImmersiveListScope.kt

@@ -6,28 +6,31 @@
  *  w: https://mjdev.org
  *  w: https://mjdev.org
  */
  */
 
 
-package eu.mjdev.desktop.components.immersivelist
+package eu.mjdev.desktop.components.immersivelist.base
 
 
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
-import androidx.compose.animation.slideInVertically
-import androidx.compose.animation.slideOutVertically
+import androidx.compose.animation.*
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.State
-import androidx.compose.runtime.derivedStateOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.*
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Brush.Companion.verticalGradient
 import androidx.compose.ui.graphics.Brush.Companion.verticalGradient
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
 import eu.mjdev.desktop.extensions.ColorUtils.createVerticalColorBrush
 import eu.mjdev.desktop.extensions.ColorUtils.createVerticalColorBrush
 import eu.mjdev.desktop.helpers.compose.Gravity
 import eu.mjdev.desktop.helpers.compose.Gravity
 
 
+@Immutable
+class ImmersiveListScope internal constructor(
+    private val onFocused: (Int) -> Unit
+) {
+    fun Modifier.immersiveListItem(index: Int): Modifier {
+        return this then onFocusChanged {
+            if (it.isFocused) onFocused(index)
+        }
+    }
+}
+
 @Composable
 @Composable
 fun ImmersiveListScope.ImmersiveInnerList(
 fun ImmersiveListScope.ImmersiveInnerList(
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
@@ -66,4 +69,4 @@ fun ImmersiveListScope.ImmersiveInnerList(
             content()
             content()
         }
         }
     }
     }
-}
+}

+ 8 - 3
src/main/kotlin/eu/mjdev/desktop/components/input/SearchFieldPassive.kt

@@ -8,6 +8,7 @@
 
 
 package eu.mjdev.desktop.components.input
 package eu.mjdev.desktop.components.input
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.padding
@@ -33,7 +34,7 @@ fun SearchFieldPassive(
     textState: MutableState<String> = mutableStateOf(""),
     textState: MutableState<String> = mutableStateOf(""),
     textColor: Color = Color.White,
     textColor: Color = Color.White,
     textStyle: TextStyle = TextStyle.Default,
     textStyle: TextStyle = TextStyle.Default,
-    textSize:TextUnit = 18.sp,
+    textSize: TextUnit = 18.sp,
     onClearClick: () -> Unit = {}
     onClearClick: () -> Unit = {}
 ) = SelectableOutlineEditText(
 ) = SelectableOutlineEditText(
     value = textState.value,
     value = textState.value,
@@ -41,7 +42,7 @@ fun SearchFieldPassive(
     enabled = false,
     enabled = false,
     singleLine = true,
     singleLine = true,
     textStyle = textStyle,
     textStyle = textStyle,
-    textSize=textSize,
+    textSize = textSize,
     colors = TextFieldDefaults.outlinedTextFieldColors(
     colors = TextFieldDefaults.outlinedTextFieldColors(
         backgroundColor = Color.Transparent,
         backgroundColor = Color.Transparent,
         textColor = textColor,
         textColor = textColor,
@@ -65,4 +66,8 @@ fun SearchFieldPassive(
             )
             )
         }
         }
     }
     }
-)
+)
+
+@Preview
+@Composable
+fun SearchFieldPassivePreview() = SearchFieldPassive()

+ 5 - 0
src/main/kotlin/eu/mjdev/desktop/components/input/SelectableOutlineEditText.kt

@@ -1,5 +1,6 @@
 package eu.mjdev.desktop.components.input
 package eu.mjdev.desktop.components.input
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.foundation.text.selection.SelectionContainer
 import androidx.compose.foundation.text.selection.SelectionContainer
@@ -106,3 +107,7 @@ fun SelectableOutlineEditText(
         colors = colors
         colors = colors
     )
     )
 }
 }
+
+@Preview
+@Composable
+fun SelectableOutlineEditTextPreview() = SelectableOutlineEditText()

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/installer/Installer.kt

@@ -57,4 +57,4 @@ fun Installer(
 
 
 @Preview
 @Preview
 @Composable
 @Composable
-fun InfoWindowPreview() = Installer()
+fun InfoWindowPreview() = Installer()

+ 62 - 109
src/main/kotlin/eu/mjdev/desktop/components/surface/Surface.kt

@@ -12,15 +12,12 @@ import androidx.compose.animation.core.CubicBezierEasing
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.tween
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.foundation.background
 import androidx.compose.foundation.background
 import androidx.compose.foundation.interaction.*
 import androidx.compose.foundation.interaction.*
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.material.LocalContentColor
 import androidx.compose.material.LocalContentColor
-//import androidx.compose.material3.LocalAbsoluteTonalElevation
-//import androidx.compose.material3.LocalContentColor
-//import androidx.compose.material3.MaterialTheme
-//import androidx.compose.material3.surfaceColorAtElevation
 import androidx.compose.runtime.*
 import androidx.compose.runtime.*
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
@@ -39,7 +36,7 @@ import eu.mjdev.desktop.helpers.compose.zIndex
 @Suppress("SameParameterValue")
 @Suppress("SameParameterValue")
 @Composable
 @Composable
 fun Surface(
 fun Surface(
-    onClick: () -> Unit,
+    onClick: () -> Unit = {},
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     onLongClick: (() -> Unit)? = null,
     onLongClick: (() -> Unit)? = null,
     enabled: Boolean = true,
     enabled: Boolean = true,
@@ -50,65 +47,38 @@ fun Surface(
     border: ClickableSurfaceBorder = ClickableSurfaceDefaults.border(),
     border: ClickableSurfaceBorder = ClickableSurfaceDefaults.border(),
     glow: ClickableSurfaceGlow = ClickableSurfaceDefaults.glow(),
     glow: ClickableSurfaceGlow = ClickableSurfaceDefaults.glow(),
     interactionSource: MutableInteractionSource? = null,
     interactionSource: MutableInteractionSource? = null,
-    content: @Composable (BoxScope.() -> Unit)
+    content: @Composable BoxScope.() -> Unit = {}
 ) {
 ) {
-    @Suppress("NAME_SHADOWING")
-    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
+    @Suppress("NAME_SHADOWING") val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val focused by interactionSource.collectIsFocusedAsState()
     val focused by interactionSource.collectIsFocusedAsState()
     val pressed by interactionSource.collectIsPressedAsState()
     val pressed by interactionSource.collectIsPressedAsState()
     SurfaceImpl(
     SurfaceImpl(
-        modifier = modifier
-            .onMousePress {
-                if (enabled) onClick()
-            }
-            .onMouseLongPress {
-                if (enabled) onLongClick?.invoke()
-            },
+        modifier = modifier.onMousePress {
+            if (enabled) onClick()
+        }.onMouseLongPress {
+            if (enabled) onLongClick?.invoke()
+        },
         selected = false,
         selected = false,
         enabled = enabled,
         enabled = enabled,
         tonalElevation = tonalElevation,
         tonalElevation = tonalElevation,
-        shape =
-            ClickableSurfaceDefaults.shape(
-                enabled = enabled,
-                focused = focused,
-                pressed = pressed,
-                shape = shape
-            ),
-        color =
-            ClickableSurfaceDefaults.containerColor(
-                enabled = enabled,
-                focused = focused,
-                pressed = pressed,
-                colors = colors
-            ),
-        contentColor =
-            ClickableSurfaceDefaults.contentColor(
-                enabled = enabled,
-                focused = focused,
-                pressed = pressed,
-                colors = colors
-            ),
-        scale =
-            ClickableSurfaceDefaults.scale(
-                enabled = enabled,
-                focused = focused,
-                pressed = pressed,
-                scale = scale
-            ),
-        border =
-            ClickableSurfaceDefaults.border(
-                enabled = enabled,
-                focused = focused,
-                pressed = pressed,
-                border = border
-            ),
-        glow =
-            ClickableSurfaceDefaults.glow(
-                enabled = enabled,
-                focused = focused,
-                pressed = pressed,
-                glow = glow
-            ),
+        shape = ClickableSurfaceDefaults.shape(
+            enabled = enabled, focused = focused, pressed = pressed, shape = shape
+        ),
+        color = ClickableSurfaceDefaults.containerColor(
+            enabled = enabled, focused = focused, pressed = pressed, colors = colors
+        ),
+        contentColor = ClickableSurfaceDefaults.contentColor(
+            enabled = enabled, focused = focused, pressed = pressed, colors = colors
+        ),
+        scale = ClickableSurfaceDefaults.scale(
+            enabled = enabled, focused = focused, pressed = pressed, scale = scale
+        ),
+        border = ClickableSurfaceDefaults.border(
+            enabled = enabled, focused = focused, pressed = pressed, border = border
+        ),
+        glow = ClickableSurfaceDefaults.glow(
+            enabled = enabled, focused = focused, pressed = pressed, glow = glow
+        ),
         interactionSource = interactionSource,
         interactionSource = interactionSource,
         content = content
         content = content
     )
     )
@@ -130,8 +100,7 @@ private fun SurfaceImpl(
     interactionSource: MutableInteractionSource? = null,
     interactionSource: MutableInteractionSource? = null,
     content: @Composable (BoxScope.() -> Unit)
     content: @Composable (BoxScope.() -> Unit)
 ) {
 ) {
-    @Suppress("NAME_SHADOWING")
-    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
+    @Suppress("NAME_SHADOWING") val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val focused by interactionSource.collectIsFocusedAsState()
     val focused by interactionSource.collectIsFocusedAsState()
     val pressed by interactionSource.collectIsPressedAsState()
     val pressed by interactionSource.collectIsPressedAsState()
     val surfaceAlpha = stateAlpha(enabled = enabled, focused = focused, pressed = pressed, selected = selected)
     val surfaceAlpha = stateAlpha(enabled = enabled, focused = focused, pressed = pressed, selected = selected)
@@ -141,42 +110,30 @@ private fun SurfaceImpl(
         LocalContentColor provides contentColor,
         LocalContentColor provides contentColor,
 //        LocalAbsoluteTonalElevation provides absoluteElevation
 //        LocalAbsoluteTonalElevation provides absoluteElevation
     ) {
     ) {
-        val zIndex by
-        animateFloatAsState(
-            targetValue = if (focused) FocusedZIndex else NonFocusedZIndex,
-            label = "zIndex"
+        val zIndex by animateFloatAsState(
+            targetValue = if (focused) FocusedZIndex else NonFocusedZIndex, label = "zIndex"
         )
         )
         val backgroundColorByState = surfaceColorAtElevation(
         val backgroundColorByState = surfaceColorAtElevation(
             color = color,
             color = color,
-            elevation = tonalElevation, // LocalAbsoluteTonalElevation.current
+//            elevation = tonalElevation, // LocalAbsoluteTonalElevation.current
         )
         )
         Box(
         Box(
-            modifier =
-                modifier
-                    .tvSurfaceScale(
-                        scale = scale,
-                        interactionSource = interactionSource,
-                    )
-                    .surfaceGlow(shape, glow)
-                    .zIndex(zIndex)
-                    .conditional(border != Border.None) {
-                        surfaceBorder(shape, border)
-                    }
-                    .background(backgroundColorByState, shape)
-                    .graphicsLayer {
-                        this.alpha = surfaceAlpha
-                        this.shape = shape
-                        this.clip = true
-                        this.compositingStrategy = CompositingStrategy.Offscreen
-                    },
-            propagateMinConstraints = true
+            modifier = modifier.tvSurfaceScale(
+                scale = scale,
+                interactionSource = interactionSource,
+            ).surfaceGlow(shape, glow).zIndex(zIndex).conditional(border != Border.None) {
+                surfaceBorder(shape, border)
+            }.background(backgroundColorByState, shape).graphicsLayer {
+                this.alpha = surfaceAlpha
+                this.shape = shape
+                this.clip = true
+                this.compositingStrategy = CompositingStrategy.Offscreen
+            }, propagateMinConstraints = true
         ) {
         ) {
             Box(
             Box(
-                modifier =
-                    Modifier.graphicsLayer {
-                        this.alpha = if (!enabled) DisabledContentAlpha else EnabledContentAlpha
-                    },
-                content = content
+                modifier = Modifier.graphicsLayer {
+                    this.alpha = if (!enabled) DisabledContentAlpha else EnabledContentAlpha
+                }, content = content
             )
             )
         }
         }
     }
     }
@@ -186,7 +143,7 @@ private fun SurfaceImpl(
 @Composable
 @Composable
 fun surfaceColorAtElevation(
 fun surfaceColorAtElevation(
     color: Color,
     color: Color,
-    elevation: Dp
+//    elevation: Dp
 ): Color {
 ): Color {
 //    if (color == MaterialTheme.colorScheme.surface) {
 //    if (color == MaterialTheme.colorScheme.surface) {
 //        return MaterialTheme.colorScheme.surfaceColorAtElevation(elevation)
 //        return MaterialTheme.colorScheme.surfaceColorAtElevation(elevation)
@@ -212,32 +169,24 @@ fun Modifier.tvSurfaceScale(
     val interaction by interactionSource.interactions.collectAsState(initial = FocusInteraction.Focus())
     val interaction by interactionSource.interactions.collectAsState(initial = FocusInteraction.Focus())
     val animationSpec = defaultScaleAnimationSpec(interaction)
     val animationSpec = defaultScaleAnimationSpec(interaction)
     val animatedScale by animateFloatAsState(
     val animatedScale by animateFloatAsState(
-        targetValue = scale,
-        animationSpec = animationSpec,
-        label = "tv-surface-scale"
+        targetValue = scale, animationSpec = animationSpec, label = "tv-surface-scale"
     )
     )
     return this.graphicsLayer(scaleX = animatedScale, scaleY = animatedScale)
     return this.graphicsLayer(scaleX = animatedScale, scaleY = animatedScale)
 }
 }
 
 
-fun defaultScaleAnimationSpec(interaction: Interaction): TweenSpec<Float> =
-    tween(
-        durationMillis =
-            when (interaction) {
-                is FocusInteraction.Focus -> SurfaceScaleTokens.focusDuration
-                is FocusInteraction.Unfocus -> SurfaceScaleTokens.unFocusDuration
-                is PressInteraction.Press -> SurfaceScaleTokens.pressedDuration
-                is PressInteraction.Release -> SurfaceScaleTokens.releaseDuration
-                is PressInteraction.Cancel -> SurfaceScaleTokens.releaseDuration
-                else -> SurfaceScaleTokens.releaseDuration
-            },
-        easing = SurfaceScaleTokens.enterEasing
-    )
+fun defaultScaleAnimationSpec(interaction: Interaction): TweenSpec<Float> = tween(
+    durationMillis = when (interaction) {
+        is FocusInteraction.Focus -> SurfaceScaleTokens.focusDuration
+        is FocusInteraction.Unfocus -> SurfaceScaleTokens.unFocusDuration
+        is PressInteraction.Press -> SurfaceScaleTokens.pressedDuration
+        is PressInteraction.Release -> SurfaceScaleTokens.releaseDuration
+        is PressInteraction.Cancel -> SurfaceScaleTokens.releaseDuration
+        else -> SurfaceScaleTokens.releaseDuration
+    }, easing = SurfaceScaleTokens.enterEasing
+)
 
 
 fun stateAlpha(
 fun stateAlpha(
-    enabled: Boolean,
-    focused: Boolean,
-    pressed: Boolean,
-    selected: Boolean
+    enabled: Boolean, focused: Boolean, pressed: Boolean, selected: Boolean
 ): Float {
 ): Float {
     return when {
     return when {
         !enabled && pressed -> DisabledPressedStateAlpha
         !enabled && pressed -> DisabledPressedStateAlpha
@@ -258,3 +207,7 @@ internal const val EnabledContentAlpha = 1f
 
 
 private const val FocusedZIndex = 0.5f
 private const val FocusedZIndex = 0.5f
 private const val NonFocusedZIndex = 0f
 private const val NonFocusedZIndex = 0f
+
+@Preview
+@Composable
+fun SurfacePreview() = Surface()

+ 5 - 2
src/main/kotlin/eu/mjdev/desktop/components/surface/base/SurfaceGlow.kt

@@ -10,7 +10,10 @@ package eu.mjdev.desktop.components.surface.base
 
 
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.*
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Outline
+import androidx.compose.ui.graphics.Paint
+import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
 import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
 import androidx.compose.ui.node.DrawModifierNode
 import androidx.compose.ui.node.DrawModifierNode
@@ -28,7 +31,7 @@ internal fun Modifier.surfaceGlow(
 ): Modifier {
 ): Modifier {
     val color = surfaceColorAtElevation(
     val color = surfaceColorAtElevation(
         color = glow.elevationColor,
         color = glow.elevationColor,
-        elevation = glow.elevation
+//        elevation = glow.elevation
     )
     )
     val glowBlurRadiusPx = with(LocalDensity.current) {
     val glowBlurRadiusPx = with(LocalDensity.current) {
         glow.elevation.toPx()
         glow.elevation.toPx()

+ 6 - 1
src/main/kotlin/eu/mjdev/desktop/components/text/AutoHideEmptyText.kt

@@ -1,5 +1,6 @@
 package eu.mjdev.desktop.components.text
 package eu.mjdev.desktop.components.text
 
 
+import androidx.compose.desktop.ui.tooling.preview.Preview
 import androidx.compose.material.LocalTextStyle
 import androidx.compose.material.LocalTextStyle
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
@@ -58,4 +59,8 @@ fun AutoHideEmptyText(
             style = style
             style = style
         )
         )
     }
     }
-}
+}
+
+@Preview
+@Composable
+fun AutoHideEmptyTextPreview() = AutoHideEmptyText()

+ 1 - 0
src/main/kotlin/eu/mjdev/desktop/data/App.kt

@@ -168,6 +168,7 @@ class App(
     }
     }
 
 
     companion object {
     companion object {
+        val Test = App(DesktopFile.Test)
         val Empty: App = App()
         val Empty: App = App()
 
 
         fun List<String>?.ifEmptyCategories(block: () -> List<String>) = this?.filter { s ->
         fun List<String>?.ifEmptyCategories(block: () -> List<String>) = this?.filter { s ->

+ 13 - 0
src/main/kotlin/eu/mjdev/desktop/data/DesktopFile.kt

@@ -297,6 +297,19 @@ class DesktopFile(
         const val Prop_X_Ubuntu_UseOverlayScrollbars = "X-Ubuntu-UseOverlayScrollbars"
         const val Prop_X_Ubuntu_UseOverlayScrollbars = "X-Ubuntu-UseOverlayScrollbars"
 
 
         val Empty = DesktopFile()
         val Empty = DesktopFile()
+        val Test = DesktopFile(
+            fileData = """
+                [Desktop Entry]
+                Name=mjdev-desktop
+                Comment=MJDev desktop environment
+                Exec=/opt/mjdev-desktop/bin/mjdev-desktop
+                Icon=/opt/mjdev-desktop/lib/mjdev-desktop.png
+                Terminal=false
+                Type=Application
+                Categories=Desktop
+                MimeType=
+                """.trimMargin()
+        )
 
 
         operator fun Ini.get(
         operator fun Ini.get(
             type: DesktopEntryType
             type: DesktopEntryType

+ 1 - 3
src/main/kotlin/eu/mjdev/desktop/extensions/Custom.kt

@@ -190,6 +190,7 @@ object Custom {
         defaultValue: String = ""
         defaultValue: String = ""
     ) = value?.toString() ?: defaultValue
     ) = value?.toString() ?: defaultValue
 
 
+    // todo move to uiState
     @Composable
     @Composable
     fun <T> flowBlock(
     fun <T> flowBlock(
         initial: T,
         initial: T,
@@ -225,16 +226,13 @@ object Custom {
         onError: (Throwable) -> Unit = { e -> e.printStackTrace() },
         onError: (Throwable) -> Unit = { e -> e.printStackTrace() },
         block: suspend () -> T,
         block: suspend () -> T,
     ): MutableState<T> {
     ): MutableState<T> {
-        println("flow block called")
         val result = remember { mutableStateOf(initial) }
         val result = remember { mutableStateOf(initial) }
         LaunchedEffect(key) {
         LaunchedEffect(key) {
-            println("launching for new key")
             flow {
             flow {
                 emit(block())
                 emit(block())
             }.catch { t ->
             }.catch { t ->
                 onError(t)
                 onError(t)
             }.flowOn(coroutineContext).collect { r ->
             }.flowOn(coroutineContext).collect { r ->
-                println("got new result")
                 result.value = r
                 result.value = r
             }
             }
         }
         }