Warning: session_start(): open(/var/lib/php/sessions/sess_okj3r1uveqssefnlkl650t5osa, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
sclass JPaintTool > MetaWithChangeListeners is Swingable, AutoCloseable {
settableWithVar File autoPersistFile;
settableWithVar double autoPersistInterval = 10.0;
settableWithVar Color brushColor = Color.black;
settableWithVar bool drawingAllowed = true;
event imageChanged(BufferedImage image);
transient settableWithChange volatile bool dirty;
transient gettable BufferedImage image;
transient ImageSurface imageSurface;
transient bool autoPersistInstalled;
transient ReliableSingleThread rstPersist = new(r _persist);
transient JPanel buttons;
transient ImageSurfaceScribbleTool scribbler;
transient JComboBox cbImageSize;
//transient settableWithVar S status;
transient new ButtonGroup colorButtonGroup;
transient simplyCached void init() {
imageSurface = makeImageSurface();
cbImageSize = jTypedComboBox(imageSizes());
main onChange(cbImageSize, l1 setImageSize);
printVars("JPaintTool.init", +image, +autoPersistFile);
if (image == null) {
setImage(makeNewImage());
if (autoPersistFile != null) {
pcall {
var img = loadImage2(autoPersistFile);
if (img != null) {
setImage(img);
print("Image loaded");
}
}
if (!autoPersistInstalled) {
set autoPersistInstalled;
awtEvery(imageSurface, autoPersistInterval, rstPersist);
bindToComponent(imageSurface, null, rstPersist);
}
}
}
varDrawingAllowed().onChangeAndNow(b -> scribbler.enabled(b));
}
BufferedImage makeNewImage() {
ret main newImage(defaultImageSize());
}
WidthAndHeight defaultImageSize() { ret getSelected(cbImageSize); }
public transient simplyCached JComponent visualize() {
init();
var filePathLabel = new JFilePathLabel(autoPersistFile).nameOnly();
varAutoPersistFile().onChange(file -> filePathLabel.setFile(file));
var filePathLabelVis = filePathLabel.visualize();
componentPopupMenuItem(filePathLabel.button.visualize(),
"Save image now", r { set dirty; rstPersist!; });
ret withTopMargin(northCenterAndSouthWithMargin(
buttons = jcenteredline(flattenToList(
jbutton("New image", rThread newImage),
withLabel("Size:", cbImageSize),
map colorSelectButton(colors()),
swing(-> new JImageSwitch(#1103078, #1103077, varDrawingAllowed())
.setToolTips(
"Drawing not allowed (click to change)",
"Drawing allowed (click to change)")),
)),
jscroll_center_borderless(imageSurface),
centerAndEast(
//jVarLabel(varStatus()),
withLeftMargin(bottomLeftControls()),
autoPersistFile == null ? jpanel()
: withSideMargin(withLabel("Image:", filePathLabelVis))
)
));
}
void setImage(BufferedImage image) {
this.image = image;
imageSurface.setImage(image);
imageChanged(image);
}
transient swappable ImageSurface makeImageSurface() {
var is = pixelatedImageSurface();
//is.setAutoZoomToDisplay(true);
//is.specialPurposed = true;
is.zoomable(false);
is.removeAllTools();
scribbler = new ImageSurfaceScribbleTool(is);
scribbler.onScribbleDone(scribble -> printStruct(scribble));
scribbler.onPainted(-> { set dirty; imageChanged(getImage()); });
varBrushColor().onChangeAndNow(color -> scribbler.setColor(color));
ret is;
}
void _persist {
if (autoPersistFile != null && dirty) {
dirty = false;
savePNGVerbose(autoPersistFile, image);
}
}
// doesn't allow drawing immediately
void loadImageProtected(File file) {
loadImage(file);
drawingAllowed(false);
}
// Note: also auto-persists to that file
void loadImage(File file) {
close(); // persist
var img = loadImage2(file);
autoPersistFile(file);
setImage(img);
}
void newImage() ctex {
close(); // persist
//if (dirty && !swingConfirm(imageSurface, "Discard image")) ret;
var file = createAutoPersistFile();
print("Created auto persist file: " + f2s(file));
autoPersistFile(file);
setImage(makeNewImage());
dirty = false;
}
// swap to make a new file every time user clicks "New image"
swappable File createAutoPersistFile() { ret autoPersistFile(); }
JToggleButton colorSelectButton(Color color) {
var btn = jImageToggleButton(main newImage(16, color),
"Select color to draw with", -> setBrushColor(color),
eq(brushColor(), color));
ret addToButtonGroup(colorButtonGroup, btn);
}
L colors() {
ret colorPaletteByBits(1); // 8 primary colors
}
L imageSizes() {
ret mapLL sixteenToNine_p(
240, 360, 480, 720
);
}
void setImageSize(WidthAndHeight size) {
if (!sameSize(getImage(), size))
newImage();
}
close {
rstPersist.triggerAndWait();
}
transient swappable JComponent bottomLeftControls() { ret jpanel(); }
}