Hi,
I'm back from vacation and continuing my exploration of ltk. I'm currently trying to build a color picker and I'm modeling it after the blender color picker. To replicate how it looks I need a nice gradient. My first instinct was to just put a bunch of really small rectangles (pixels) on a canvas. This worked (see attachment), but it took about 5 minutes for all the pixels to be put on the canvas. Not ideal, especially if I have to redraw the gradient when the brightness value is changed by some slider or something. My next idea was to use a bitmap. This leads my to my first question: How do I get a bitmap on a canvas? I tried the following code.
```
(defvar image (open "lena_gray.bmp"))
(with-ltk () (let* ((canvas (make-instance 'canvas :width 400 :height 400))) (pack canvas) (let ((lena (create-bitmap canvas 20 20 :bitmap image))) (declare (ignore lena)))))
```
And I get a generic type-error:
The value NIL is not of type STREAM when binding STREAM [Condition of type TYPE-ERROR]The value NIL is not of type STREAM when binding STREAM [Condition of type TYPE-ERROR]
There is really no example given in the documentation. So I need help with this one (Using SBCL on Linux by the way).
The next question is concerning transparent colors. To darken the gradient I thought of having an oval over the bitmap, on which I can change the transparency value. I haven't found a way to do that with "itemconfigure". And I also haven't found a place where all the keyword arguments are listed for "itemconfigure". I'm almost certain that there are no transparency options for canvas items in tcl/tk. But in case I've overlooked them, I'm asking anyway.
I'd also like to say that I accept tips on my approach. Is there an obvious solution that I'm missing or are there other general tips I need to figure it out myself. Please let me know! Thanks in advance for any help.
Greetings, Tom.
Am Wed, 14 Aug 2019 20:49:30 +0200 schrieb Tom trashtalk217@gmail.com:
Answer follows after Tom's text...
Hi,
I'm back from vacation and continuing my exploration of ltk. I'm currently trying to build a color picker and I'm modeling it after the blender color picker. To replicate how it looks I need a nice gradient. My first instinct was to just put a bunch of really small rectangles (pixels) on a canvas. This worked (see attachment), but it took about 5 minutes for all the pixels to be put on the canvas. Not ideal, especially if I have to redraw the gradient when the brightness value is changed by some slider or something. My next idea was to use a bitmap. This leads my to my first question: How do I get a bitmap on a canvas? I tried the following code.
(defvar image (open "lena_gray.bmp")) (with-ltk () (let* ((canvas (make-instance 'canvas :width 400 :height 400))) (pack canvas) (let ((lena (create-bitmap canvas 20 20 :bitmap image))) (declare (ignore lena)))))
And I get a generic type-error:
The value NIL is not of type STREAM when binding STREAM [Condition of type TYPE-ERROR]The value NIL is not of type STREAM when binding STREAM [Condition of type TYPE-ERROR]
There is really no example given in the documentation. So I need help with this one (Using SBCL on Linux by the way).
The next question is concerning transparent colors. To darken the gradient I thought of having an oval over the bitmap, on which I can change the transparency value. I haven't found a way to do that with "itemconfigure". And I also haven't found a place where all the keyword arguments are listed for "itemconfigure". I'm almost certain that there are no transparency options for canvas items in tcl/tk. But in case I've overlooked them, I'm asking anyway.
I'd also like to say that I accept tips on my approach. Is there an obvious solution that I'm missing or are there other general tips I need to figure it out myself. Please let me know! Thanks in advance for any help.
Greetings, Tom.
Hi Tom,
In Tk, a BITMAP is a 2-color image, and a PHOTO is an image with more than 2 colors. Tk comes with built-in handlers for PPM/PGM, PNG and GIF image formats.
The full details about Tk images are here:
-> https://www.tcl.tk/man/tcl8.6/TkCmd/image.htm -> https://www.tcl.tk/man/tcl8.6/TkCmd/bitmap.htm -> https://www.tcl.tk/man/tcl8.6/TkCmd/photo.htm
Tk also comes with its own color picker, see:
-> https://www.tcl.tk/man/tcl8.6/TkCmd/chooseColor.htm
I haven't worked with LTK for a while now, but there is a Lisp variable that makes LTK print the Tcl/Tk code it generates. I usually had looked at the generated code and compared it with the examples on the Tcl/Tk man pages when I had no clue how to get what I wanted.
There's also a Tcl/Tk wiki with tons of code examples:
Hope this helps a bit... :-)
- edgar
On Wed, Aug 14, 2019 at 08:49:30PM +0200, Tom wrote:
Hi,
Hello!
I'm back from vacation and continuing my exploration of ltk.
Hope you had fun! :)
I'm currently trying to build a color picker
i think this is an exercise (and a good one in my opinion) otherwise please consider using:
https://www.tcl.tk/man/tcl8.6/TkCmd/chooseColor.htm
and I'm modeling it after the blender color picker. To replicate how it looks I need a nice gradient. My first instinct was to just put a bunch of really small rectangles (pixels) on a canvas. This worked (see attachment), but it took about 5 minutes for all the pixels to be put on the canvas. Not ideal,
Yes, canvas is slow for these operations.
especially if I have to redraw the gradient when the brightness value is changed by some slider or something. My next idea was to use a bitmap. This leads my to my first question: How do I get a bitmap on a canvas? I tried the following code.
Please note that 'bitmap' is for 1 bit color depth image (i e. two color) plus a transparency binary value, according to the documentation:
https://www.tcl.tk/man/tcl8.6/TkCmd/bitmap.htm
Moreover the format the library accepts is not MS bitmap but X11 bitmap format, never used but likely these are the specification (please someone correct if i am wrong):
https://en.wikipedia.org/wiki/X_BitMap
What i think you need is a photo-image:
https://www.tcl.tk/man/tcl8.6/TkCmd/photo.htm
that, instead support 24bit (plus alpha in the upcoming 8.7 release of tcl/tk) color depth image.
Tk supports only PNG and GIF format (you can write your own loader but this is a more complicate task, so i will stick to PNG here):
(with-ltk () (let ((canvas (make-canvas nil :width 64 :height 64)) (image (make-image))) (image-load image "/path/to/a/file/in/png/format.png") (create-image canvas 0 0 :image image) (pack canvas)))
There is really no example given in the documentation. So I need help with this one (Using SBCL on Linux by the way).
The next question is concerning transparent colors. To darken the gradient I thought of having an oval over the bitmap, on which I can change the transparency value. I haven't found a way to do that with "itemconfigure". And I also haven't found a place where all the keyword arguments are listed for "itemconfigure".
I suggest to look at the ltk sources and the official tk documentation.
https://www.tcl.tk/man/tcl8.6/TkCmd/canvas.htm
IIRC usually the options that 'ltk:itemconfigure' accepts are the same that 'ltk:create-*' accepts.
I'm almost certain that there are no transparency options for canvas items in tcl/tk. But in case I've overlooked them, I'm asking anyway.
As far as i know there is not an alpha channel but probably you could just do the calculation for transparency value outside and draw the oval with the results color (in this case could be useful to look at ltk:image-setpixel); this, also, could be a tedious and complex task to accomplish, though.
I'd also like to say that I accept tips on my approach. Is there an obvious solution that I'm missing or are there other general tips I need to figure it out myself. Please let me know! Thanks in advance for any help.
Well the best i can suggest is to take a look here :-)
https://github.com/VitoVan/cl-pkr
Bye, and happy hacking! :)
C.
PS: annoying legal stuff: all my code in this message is released under MIT license https://opensource.org/licenses/MIT
Hi,
I did some things, and now it's on Github. Feel free to look: https://github.com/Trashtalk217/ltk-colorpicker.
Thanks for the advice I got. I now use two images for displaying the color wheel and the white-to-black gradient. While most of the code is still yanky as heck (just look at my installation instructions -_-). I've managed to create something that works, which I'm very happy with. And although the color wheel doesn't become darker when you turn down the brightness, I don't necessarily need it. I can do fine without.
Edgar noted that there's a lisp variable which controls if the Tk code gets printed out to standard output, but they didn't know which one it was. I found it: (setf *debug-tk* t). I've barely used it because Tk hasn't particularly the nicest syntax, but I know where it is if I need it.
Otherwise, thanks again for the help, and I hope you all have a great day.
Greetings, Tom
On 8/15/19 10:41 AM, cage wrote:
On Wed, Aug 14, 2019 at 08:49:30PM +0200, Tom wrote:
Hi,
Hello!
I'm back from vacation and continuing my exploration of ltk.
Hope you had fun! :)
I'm currently trying to build a color picker
i think this is an exercise (and a good one in my opinion) otherwise please consider using:
https://www.tcl.tk/man/tcl8.6/TkCmd/chooseColor.htm
and I'm modeling it after the blender color picker. To replicate how it looks I need a nice gradient. My first instinct was to just put a bunch of really small rectangles (pixels) on a canvas. This worked (see attachment), but it took about 5 minutes for all the pixels to be put on the canvas. Not ideal,
Yes, canvas is slow for these operations.
especially if I have to redraw the gradient when the brightness value is changed by some slider or something. My next idea was to use a bitmap. This leads my to my first question: How do I get a bitmap on a canvas? I tried the following code.
Please note that 'bitmap' is for 1 bit color depth image (i e. two color) plus a transparency binary value, according to the documentation:
https://www.tcl.tk/man/tcl8.6/TkCmd/bitmap.htm
Moreover the format the library accepts is not MS bitmap but X11 bitmap format, never used but likely these are the specification (please someone correct if i am wrong):
https://en.wikipedia.org/wiki/X_BitMap
What i think you need is a photo-image:
https://www.tcl.tk/man/tcl8.6/TkCmd/photo.htm
that, instead support 24bit (plus alpha in the upcoming 8.7 release of tcl/tk) color depth image.
Tk supports only PNG and GIF format (you can write your own loader but this is a more complicate task, so i will stick to PNG here):
(with-ltk () (let ((canvas (make-canvas nil :width 64 :height 64)) (image (make-image))) (image-load image "/path/to/a/file/in/png/format.png") (create-image canvas 0 0 :image image) (pack canvas)))
There is really no example given in the documentation. So I need help with this one (Using SBCL on Linux by the way).
The next question is concerning transparent colors. To darken the gradient I thought of having an oval over the bitmap, on which I can change the transparency value. I haven't found a way to do that with "itemconfigure". And I also haven't found a place where all the keyword arguments are listed for "itemconfigure".
I suggest to look at the ltk sources and the official tk documentation.
https://www.tcl.tk/man/tcl8.6/TkCmd/canvas.htm
IIRC usually the options that 'ltk:itemconfigure' accepts are the same that 'ltk:create-*' accepts.
I'm almost certain that there are no transparency options for canvas items in tcl/tk. But in case I've overlooked them, I'm asking anyway.
As far as i know there is not an alpha channel but probably you could just do the calculation for transparency value outside and draw the oval with the results color (in this case could be useful to look at ltk:image-setpixel); this, also, could be a tedious and complex task to accomplish, though.
I'd also like to say that I accept tips on my approach. Is there an obvious solution that I'm missing or are there other general tips I need to figure it out myself. Please let me know! Thanks in advance for any help.
Well the best i can suggest is to take a look here :-)
https://github.com/VitoVan/cl-pkr
Bye, and happy hacking! :)
C.
PS: annoying legal stuff: all my code in this message is released under MIT license https://opensource.org/licenses/MIT
On Mon, Aug 19, 2019 at 12:00:26AM +0200, Tom wrote:
Hi,
Hello!
I did some things, and now it's on Github. Feel free to look: https://github.com/Trashtalk217/ltk-colorpicker.
Congratulations! I hope you had fun with CL and LTK! :)
Thanks for the advice I got. I now use two images for displaying the color wheel and the white-to-black gradient. While most of the code is still yanky as heck (just look at my installation instructions -_-).
That code looks clean and effective to me i think i can see you have a good programming background (and, for inesplicable reasons, i thought you was a lisp newbie but seems i was wrong); I have anyway a couple of humble considerations that i think are worth noting:
- FWIW the equivalent of '%' operation in C99 is 'cl:rem', not 'cl:mod' (probably you are aware of that but, if not, this can save a few bug in the future :-) )
http://clhs.lisp.se/Body/f_mod_r.htm
- likely is better to replace 'cl:merge-pathnames' with an asdf function 'asdf:system-relative-pathname'
https://common-lisp.net/project/asdf/asdf.html#Miscellaneous-Functions
Maybe (just guessing) this could solve your installation problem (sorry i did not got your code running for lack of time :( ).
- some lisper suggested (on IRC?) to not to insert empty lines in forms that are not toplevel so:
(defun foo () .... )
(defun bar () ... )
is ok but:
(defun baz () (form1) (form2)
(form3))
not, instead:
(defun baz () (form1) (form2) (form3))
and i followed this rule more or less strictly (but this is just a stylistic choice, of course)
- sometimes is better to reformat the math expressions for clarity, for example:
https://github.com/Trashtalk217/ltk-colorpicker/blob/master/ltk-colorpicker....
(+ (- (acos (/ x r))) (* 2 pi))
to:
(+ (- (acos (/ x r))) (* 2 pi))
this way i feel it is more clear the sum's operators but, again, YMMV.
I hope what i wrote do not annoyed you, all of above are just opinions not law :)
Anyway, again: congratulation!
Bye! C.