sclass G22SnPSelector > MetaWithChangeListeners is Swingable { settable new SnPSettings settings; // show powers of two in pixelRows selector or all numbers? settableWithVar bool powerOfTwoPixelRows = true; settable int maxPixelRows = 512; JLabel lblColors; SnPSettings get() { ret settings; } cachedVisualize { var colors = jspinner(settings.colors, 2, 256); main onChange(colors, -> { settings.colors = intFromSpinner(colors); change(); }); var pixelRows = jListSpinner(pixelRowsList(), settings.pixelRows); main onChange(pixelRows, -> { settings.pixelRows = intFromSpinner(pixelRows); change(); }); varPowerOfTwoPixelRows().onChange(-> spinnerSetNumberList(pixelRows, pixelRowsList()); var menuItem = jLiveValueCheckBoxMenuItem("Only show powers of two", varPowerOfTwoPixelRows()); swing { new JPopupMenu menu; menu.add(menuItem); pixelRows.setComponentPopupMenu(menu); } lblColors = jSimpleLabel(" colors @ "); bindChangeListenerToComponent(this, lblColors, -> toolTip(lblColors, makeToolTip())); ret hstack( colors, lblColors, pixelRows, jlabel(" p")); } L pixelRowsList() { ret powerOfTwoPixelRows ? powersOfTwoUpTo(maxPixelRows) : virtualCountList_incl(1, maxPixelRows); } S makeToolTip() { long pixels = area(sixteenToNine_p(settings.pixelRows)); int colorBits = numberOfBitsNeededToRepresentNOptions(settings.colors); int bytes = iceil_div(pixels*colorBits, 8); ret "Information per frame: " + nBytes(bytes) +" (assuming a 16:9 aspect ratio)"; } }