Comments (14)
Okay, previously there were no bindings generated for GdkPixbuf because I thought it had fewer use cases. Now, I have added it in commit 6ab0131. Please upgrade to use it.
from cl-gtk4.
I suspect that your pathname contains a ~
that cannot be expanded by GTK. To address this, you need to use (namestring (truename (cu/display u)))
to expand it on the Lisp side.
from cl-gtk4.
That didn't help either, and when I (format t "~a" (cu/display u))
, I get the full path /Users/jonathanbennett/.roswell/lisp/quicklisp/local-projects/megastrike/data/images/units/vehicles/Pumapat.png
from cl-gtk4.
Can you load cl-gdk4
and try this in your application?
(let ((texture (gdk:make-texture :path "/path/to/your/image/file")))
(format t "WIDTH: ~A HEIGHT: ~A~%" (gdk:texture-width texture) (gdk:texture-height texture)))
The function gdk:make-texture
should signal an error when it fails to open the file. Once the texture is loaded successfully, you can create a picture with (gtk:make-picture :paintable texture)
.
from cl-gtk4.
the above snippet accurately reports the size of the image (84x72 px), but the image is still not rendering. It is a png file, is the a possible reason for the error?
EDIT: Using gtk:make-image
once more renders it (when using a texture or a file). This makes me wonder if I need to do something to set the size of the image when using a picture, but I do not see anything that I could change to set the picture size.
from cl-gtk4.
Have you tried a minimal example like this?
(define-application (:name picture-test
:id "org.bohonghuang.gtk4.issue-33")
(define-main-window (window (make-application-window :application *application*))
(setf (window-title window) "Picture Test"
(window-child window) (make-picture :filename "/path/to/your/image/file"))
(unless (widget-visible-p window)
(window-present window))))
The snippet is tested to run on both Windows and GNU/Linux, and the size of the picture defaults to the dimensions of the image file.
from cl-gtk4.
The minimum example you just posted works on MacOS as well (just tested it now). Is it possible that you can't have a picture inside a box or inside a ListBoxChild?
from cl-gtk4.
The minimum size of Picture
defaults to zeros, so you could use (setf (widget-size-request picture) '(100 100))
to set the size manually after creating a picture.
from cl-gtk4.
Ok, I've got that working. I'm struggling to figure out how I could draw the picture in a drawing area.
EDIT: Ok, here is the code that has gotten me the closest to managing to draw the images on the screen.
(let ((unit (function-that-returns-nil-or-the-occupant-of-a-hex)))
(when unit
(with-gdk-rgba (color "#000000")
(gdk:cairo-set-source-rgba cr color)
(gdk:cairo-set-source-pixbuf cr
(gdk:pixbuf-get-from-texture (cu/display unit)) ;; cu/display unit returns a GDK:Texture
(point-x (nth 5 hex-points))
(point-y (nth 5 hex-points))))
cairo:stroke)))
In the screenshot attached, there should be an image inside the top-left hex (the one that would be labeled 0101, but instead it is completely empty. It put something there, because the text telling you the hex number is gone from that hex, but whatever is there is invisible.
from cl-gtk4.
I have rewritten this down to the smallest possible code I can envision might do this:
(defun draw-test-window ()
(let ((window (gtk:make-application-window :application gtk:*application*))
(picture (gtk:make-drawing-area)))
(setf (gtk:window-child window) picture
(gtk:drawing-area-content-width picture) 500
(gtk:drawing-area-content-height picture) 500
(gtk:drawing-area-draw-func picture) (list (cffi:callback %draw-func)
(cffi:null-pointer)
(cffi:null-pointer)))
(unless (gtk:widget-visible-p window)
(gtk:window-present window))))
(defun draw-func (area cr width height)
(declare (ignore area)
(optimize (speed 3)
(debug 0)
(safety 0)))
(with-gdk-rgba (color "#000000")
(let ((texture (gdk:make-texture :path (namestring (merge-pathnames "images/units/mechs/Akuma.png" *data-folder*)))))
(gdk:cairo-set-source-pixbuf cr
(gdk:pixbuf-get-from-texture texture)
(coerce (the fixnum 100) 'double-float)
(coerce (the fixnum 100) 'double-float))
(cairo:fill-path))))
Having (cairo:stroke)
as the final line also does not draw anything on the screen. In both cases, I get a blank white screen which is 500 by 500 pixels. I expected the image to be displayed 100 pixel down from the top and over from the left.
EDIT:
Sorry, I forgot to include the callback function, but this was copy/pasted from your Cairo demo so I suspect you're familiar with it.
(cffi:defcallback %draw-func :void ((area :pointer)
(cr :pointer)
(width :int)
(height :int)
(data :pointer))
(declare (ignore data))
(let ((cairo:*context* (make-instance 'cairo:context
:pointer cr
:width width
:height height
:pixel-based-p nil)))
(draw-func (make-instance 'gir::object-instance
:class (gir:nget gtk:*ns* "DrawingArea")
:this area)
(make-instance 'gir::struct-instance
:class (gir:nget megastrike::*ns* "Context")
:this cr)
width height)))
from cl-gtk4.
Having
(cairo:stroke)
as the final line also does not draw anything on the screen. In both cases, I get a blank white screen which is 500 by 500 pixels. I expected the image to be displayed 100 pixel down from the top and over from the left.
You haven't set a path using functions like cairo:rectangle
, so there won't be anything drawn. The following code can help you draw your image in the center of the canvas.
(defun draw-func (area cr canvas-width canvas-height)
(declare (ignore area)
(optimize (speed 3)
(debug 0)
(safety 0)))
(let ((texture (gdk:make-texture :path (namestring (truename (merge-pathnames "images/units/mechs/Akuma.png" *data-folder*))))))
(let* ((canvas-width (coerce (the fixnum canvas-width) 'single-float))
(canvas-height (coerce (the fixnum canvas-height) 'single-float))
(width (coerce (the fixnum (gdk:texture-width texture)) 'single-float))
(height (coerce (the fixnum (gdk:texture-height texture)) 'single-float))
(x (/ (- canvas-width width) 2.0))
(y (/ (- canvas-height width) 2.0)))
(cairo:rectangle x y width height)
(gdk:cairo-set-source-pixbuf cr (gdk:pixbuf-get-from-texture texture) (coerce x 'double-float) (coerce y 'double-float))
(cairo:fill-path)
(with-gdk-rgba (color "#FF0000")
(cairo:rectangle x y width height)
(gdk:cairo-set-source-rgba cr color)
(cairo:set-line-width 3.0)
(cairo:stroke)))))
where x
and y
are the coordinates of the top-left corner of the image, you can change them to position the image wherever you want it to be drawn.
from cl-gtk4.
Ok, got that part working within my program. The problem now is a matter of scaling. Based on reading the GDK Documentation and a few examples in Python, it appears I need to use GdkPixbuf.Pixbuf.scale_simple, but I can't find it in GDK4. If I use (cairo:scale)
, it scales all the coordinates (obviously), meaning the x and y origin for the image shifts.
from cl-gtk4.
Next question. The images I have are all black and white. I'd like to mark which team they are on by painting the unit the team's color (which I've got in the format returned by gdk:rgba-to-string
). I looked at GdkPixbuf.Pixbuf.composite-color-simple, but it wants a GUINT32
rather than an RGBA color structure. Should I be controlling this in Cairo?
from cl-gtk4.
- You can directly provide the color value in the format
#xRRGGBBAA
. - If you are familiar with
cffi
, the conversion betweenGdkRGBA
and theRGBA8888
should not be difficult:
(cffi:defcstruct gdk-rgba
(red :float)
(green :float)
(blue :float)
(alpha :float))
(cffi:defcstruct rgba8888
(red :uint8)
(green :uint8)
(blue :uint8)
(alpha :uint8))
(defun rgba-color-value (rgba)
(cffi:with-foreign-slots (((r1 red) (g1 green) (b1 blue) (a1 alpha)) (gobj:object-pointer rgba) (:struct gdk-rgba))
(cffi:with-foreign-object (pointer '(:struct rgba8888))
(cffi:with-foreign-slots (((r2 red) (g2 green) (b2 blue) (a2 alpha)) pointer (:struct rgba8888))
(setf r2 (round (* r1 #xFF))
g2 (round (* g1 #xFF))
b2 (round (* b1 #xFF))
a2 (round (* a1 #xFF))))
(cffi:mem-ref pointer :uint32))))
(with-gdk-rgba (rgba "#FF0000FF")
(assert (= (rgba-color-value rgba) #xFF0000FF)))
from cl-gtk4.
Related Issues (20)
- Can't make a GStream binding. HOT 1
- Typelib file for namespace 'Gtk', version '4.0' not found HOT 4
- How to make a GListStore of fixnums / How to subclass GObject HOT 2
- Library needs more documentation HOT 1
- Can't create simple application. HOT 4
- FLOATING-POINT-INVALID-OPERATION HOT 5
- arithmetic error DIVISION-BY-ZERO signalled HOT 2
- Cant create wigets to store it in variable HOT 1
- When vertically scaling the window, there is an artifact with the buttons. HOT 1
- No symbol named "POINTER-OBJECT" HOT 2
- Error g_error_free on Windows 11 HOT 6
- Can't properly pass "user_data" to callback for open file dialog HOT 2
- Support for Subclassing? HOT 1
- Radio buttons HOT 1
- Connect widget to key-pressed event HOT 3
- Can I create my own widgets? HOT 2
- (ql:quickload :cl-gtk4) fails, many issues: HOT 3
- Hoping for examples or documents about dialogs HOT 2
- Making executable HOT 2
- cl-gtk4 not working under SBCL v2.4.5 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cl-gtk4.