-
Notifications
You must be signed in to change notification settings - Fork 45
High level drawing api
The graphics specific modules provide a high level interface to the
GtkDrawingArea widget which is compatible with the plplot
library and
at least in simple cases relieves the user of the hassle of managing
redraws. There is also a high level interface to the gdk-pixbuf library
that allows the easy mapping of 2 and 3 dimensional Fortran arrays to
GdkPixbuf objects.
module gtk_draw_hl
This module provides a high-level drawing interface which automatically handles redrawing on exposure, and bundles the most likely events to be needed.
Note:
This module has undergone a major rewrite which has considerably streamlined the code. To the ordinary user, the most noticable difference is that the backing image is now a cairo image surface rather than a GDK pixbuf. When using PLplot, the "memcairo" device is not readily usable any more (extcairo is now the only supported driver), however cumulative plotting (e.g. PLplot's strip charts) now works correctly.
Routine list:
- hl_gtk_drawing_area_new; Create the drawing area.
- hl_gtk_drawing_area_get_surface; Get the backing cairo surface
- hl_gtk_drawing_area_get_gdk_pixbuf; Get the contents to a GdkPixbuf
- hl_gtk_drawing_area_expose_cb; Default callback for expose events.
- hl_gtk_drawing_area_destroy_cb; Default callback for destroy signal
- hl_gtk_drawing_area_resize_cb; Default callback for resize signal
- hl_gtk_drawing_area_cairo_new; Create a cairo context attached to the backing surface.
- hl_gtk_drawing_area_resize: Resize the drawing area and the backing surface
- hl_gtk_drawing_area_cairo_destroy; Destroy the context.
function hl_gtk_drawing_area_new(scroll, size, ssize, expose_event, &
& data_expose, button_press_event, data_button_press, &
& button_release_event, data_button_release, scroll_event, &
& data_scroll, motion_event, data_motion, realize, data_realize, &
& configure_event, data_configure, key_press_event, data_key_press, &
& key_release_event, data_key_release, enter_event, data_enter, &
& leave_event, data_leave, destroy, data_destroy, &
& tooltip, has_alpha, size_allocate, data_size_allocate, &
& cairo_status, hscroll_policy, vscroll_policy) result(plota)
type(c_ptr) :: plota
type(c_ptr), intent(out), optional :: scroll
integer(c_int), intent(in), optional, dimension(2) :: size, ssize
type(c_funptr), optional :: expose_event, button_press_event, &
& button_release_event, scroll_event, key_press_event, &
& key_release_event, motion_event, realize, configure_event,&
& enter_event, leave_event, destroy, size_allocate
type(c_ptr), intent(in), optional :: data_expose, data_button_press, &
& data_button_release, data_scroll, data_motion, data_realize, &
& data_configure, data_key_press, data_key_release, data_enter, &
& data_leave, data_destroy, data_size_allocate
character(kind=c_char), dimension(*), optional, intent(in) :: tooltip
integer(c_int), intent(in), optional :: has_alpha
integer(c_int), intent(out), optional :: cairo_status
integer(c_int), intent(in), optional :: hscroll_policy, vscroll_policy
A high-level drawing area
Argument | Type | Required? | Description |
---|---|---|---|
SCROLL | c_ptr | optional | If present, then the drawing area will be placed in a scrollable window, whose pointer will be returned here. If it is present, then it rather than the drawable should be used for packing. |
SIZE | c_int() | optional | The requested size for the area. If no size is given then a default size of 256x256 is used. |
SSIZE | c_int() : | optional | The requested size for a scrolling window |
EXPOSE_EVENT | c_funptr | optional | Callback for expose-event signal. N.B. In GTK 3 the signal is called "draw". If this is not given then a default handler is provided which copies the image surface to the drawing area. |
DATA_EXPOSE | c_ptr | optional | Data for expose_event callback |
BUTTON_PRESS_EVENT | c_funptr | optional | Callback for button-press-event signal |
DATA_BUTTON_PRESS | c_ptr | optional | Data for button_press_event callback |
BUTTON_RELEASE_EVENT | c_funptr | optional | Callback for button-release-event signal |
DATA_BUTTON_RELEASE | c_ptr | optional | Data for button_release_event callback |
SCROLL_EVENT | c_funptr | optional | Callback for scroll-event signal |
DATA_SCROLL | c_ptr | optional | Data for scroll_event callback |
REALIZE | c_funptr | optional | Callback for realize signal |
DATA_REALIZE | c_ptr | optional | Data for realize callback |
CONFIGURE_EVENT | c_funptr | optional | Callback for configure-event signal |
DATA_CONFIGURE | c_ptr | optional | Data for configure_event callback |
KEY_PRESS_EVENT | c_funptr | optional | Callback for key-press-event signal |
DATA_KEY_PRESS | c_ptr | optional | Data for key_press_event callback |
KEY_RELEASE_EVENT | c_funptr | optional | Callback for key-release-event signal |
DATA_KEY_RELEASE | c_ptr | optional | Data for key_release_event callback |
MOTION_EVENT | c_funptr | optional | Callback for the motion-notify-event signal |
DATA_MOTION | c_ptr | optional | Data for motion_event |
ENTER_EVENT | c_funptr | optional | Callback for the enter-notify-event signal |
DATA_ENTER | c_ptr | optional | Data for enter_event |
LEAVE_EVENT | c_funptr | optional | Callback for the leave-notify-event signal |
DATA_LEAVE | c_ptr | optional | Data for leave_event |
DESTROY | c_funptr | optional | Callback when the widget is destroyed. |
DATA_DESTROY | c_ptr | optional | Data to pass to the destroy callback. |
TOOLTIP | string | optional | Tooltip for the drawing area. |
HAS_ALPHA | boolean | optional | If a pixbuf is used, should it have an alpha (transparency) channel (default=FALSE) |
SIZE_ALLOCATE | c_funptr | optional | Callback for the 'resize' signal ('size-allocate' in GTK 3). |
DATA_SIZE_ALLOCATE | c_ptr | optional | Data for size_allocate. |
CAIRO_STATUS | c_int | optional | Status code from the cairo surface. |
HSCROLL_POLICY | int | optional | Horizontal scrolling policy for the containing scroll window (default AUTOMATIC). |
VSCROLL_POLICY | int | optional | Vertical scrolling policy for the containing scroll window (default AUTOMATIC). |
- If an explicit size is given then the drawing area cannot be made smaller than that by resizing the containing window
function hl_gtk_drawing_area_get_surface(area) result(isurface)
type(c_ptr) :: isurface
type(c_ptr), intent(in) :: area
Convenience routine to get the backing surface of a drawing area.
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area whose surface is required. |
function hl_gtk_drawing_area_get_gdk_pixbuf(area, x0, y0, xsize, ysize) &
& result(pixb)
type(c_ptr) :: pixb
type(c_ptr), intent(in) :: area
integer(c_int), intent(in), optional :: x0, y0, xsize, ysize
Read a drawing area (strictly the cairo surface backing store) to a GDK pixbuf.
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area |
X0, Y0 | c_int | optional | The origin of the area to return (defaults 0) |
XSIZE, YSIZE | c_int | optional | The size of the region to return (defaults, from the origin to the top right of the surface). |
subroutine hl_gtk_drawing_area_draw_pixbuf(area, pixbuf, x, y)
type(c_ptr), intent(in) :: area, pixbuf
integer(c_int), intent(in), optional :: x, y
Render a GdkPixbuf on a drawing area
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area. |
PIXBUF | c_ptr | required | The pixbuf to draw. |
X, Y | c_int | optional | The coordinate of the upper left corner of the pixbuf on the drawing area (defaults 0). |
If you are rendering a pixbuf among other operations then just use gdk_cairo_set_source_pixbuf directly on the context with which you are working.
function hl_gtk_drawing_area_expose_cb(area, event, data) bind(c) &
& result(rv)
integer(c_int) :: rv
type(c_ptr), value :: area, event, data
Default callback for exposing a drawing area. For this to be connected no explicit expose callback should be specified.
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area |
EVENT | c_ptr | required | event structure in GTK+2, a cairo context in GTK>=3 |
DATA | c_ptr | required | A pointer to user data (not used). |
subroutine hl_gtk_drawing_area_destroy_cb(area, data) bind(c)
type(c_ptr), value :: area, data
Default callback for the destroy signal on the drawing area. Just destroys the backing surface.
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area being destroyed. |
DATA | c_ptr | required | User data for the callback (not used) |
subroutine hl_gtk_drawing_area_resize_cb(area, data) bind(c)
type(c_ptr), value :: area, data
Default call back for resizing the drawing area, just copies the old backing store to the new one
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area being destroyed. |
DATA | c_ptr | required | User data for the callback (not used) |
function hl_gtk_drawing_area_cairo_new(area) result(cr)
type(c_ptr) :: cr
type(c_ptr), intent(in) :: area
Create a cairo context which will draw into the backing surface
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area to which we will draw. |
After the drawing operations, you should call gtk_widget_queue_draw
to update the plot on the screen and hl_gtk_pixbuf_cairo_destroy
to destroy the cairo context.
subroutine hl_gtk_drawing_area_cairo_destroy(cr, destroy_surface)
type(c_ptr), intent(inout) :: cr
integer(c_int), intent(in), optional :: destroy_surface
Update the backing surface and destroy the cairo context
Argument | Type | Required? | Description |
---|---|---|---|
CR | c_ptr | required | The cairo context to put in the pixbuf |
DESTROY_SURFACE | boolean | optional | Set to TRUE to destroy the cairo_surface as well as the context. Normally the cairo surface is destroyed by the destroy callback of the drawing area, so does not need to be explicitly destroyed. |
This is called following drawing operations to the context created by
hl_gtk_drawing_area_cairo_new
. N.B. This does not update the window,
use gtk_widget_queue_draw to do that.
subroutine hl_gtk_drawing_area_resize(area, size, copy)
type(c_ptr), intent(in) :: area
integer(c_int), intent(in), optional, dimension(2) :: size
logical, optional, intent(in) :: copy
Resize a drawing area and its backing store.
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The area to resize. |
SIZE | int(2) | optional | The new size, if omitted, then the backing store is resized to match the drawing area (e.g. after resizing the containing window). |
COPY | logical | optional | Set to .true. to copy the surface contents to the new backing store. |
subroutine hl_gtk_drawing_area_get_size(area, width, height)
type(c_ptr), intent(in) :: area
integer(c_int), intent(out), optional :: width, height
Convenience routine to get the current size of a drawing area
Argument | Type | Required? | Description |
---|---|---|---|
AREA | c_ptr | required | The drawing area whose size is needed. |
WIDTH | c_int | optional | The width of the area. |
HEIGHT | c_int | optional | The height of the area |
module gdk_pixbuf_hl
Some routines to facilitate the use of GDK pixbufs from Fortran. Allows the use of short-int images to avoid the issues that may result from Fortran's 8-bit integers being signed while GdkPixbuf pixels are unsigned.
function hl_gdk_pixbuf_new_empty(width, height, alpha, bits) &
& result(pixbuf)
type(c_ptr) :: pixbuf
integer(c_int), intent(in) :: width, height
integer(c_int), intent(in), optional :: alpha, bits
Create a new empty pixbuf of the given size
Argument | Type | Required? | Description |
---|---|---|---|
WIDTH | int | required | The width in pixels of the pixbuf |
HEIGHT | int | required | The height in pixels of the pixbuf |
ALPHA | boolean | optional | Whether to include an alpha channel (default=FALSE) |
BITS | int | optional | The nuber of bits per sample (default=8). |
This routine will usually be called via the generic interface hl_gdk_pixbuf_new.
function hl_gdk_pixbuf_new_file(file, width, height, aspect, &
& error) result(pixbuf)
type(c_ptr) :: pixbuf
character(len=*), intent(in) :: file
integer(c_int), optional, intent(in) :: width, height, aspect
character(len=*), optional, intent(out) :: error
Read an image file into a new pixbuf
Argument | Type | Required? | Description |
---|---|---|---|
FILE | string | required | The file to read |
WIDTH | int | optional | The desired width for the pixbuf |
HEIGHT | int | optional | The desired height for the pixbuf |
ASPECT | boolean | optional | If sizing is given then set to TRUE to preserve the aspect ratio, or FALSE not to. If both dimensions are given, then the default is FALSE, if one is given, the default is TRUE. |
ERROR | gerror | optional | The error code & message. |
This routine will usually be called via the generic interface hl_gdk_pixbuf_new.
function hl_gdk_pixbuf_new_data8(data) result(pixbuf)
type(c_ptr) :: pixbuf
integer(c_int8_t), dimension(:,:,:), intent(in) :: data
Create a pixbuf from an RGB(A) array of values.
Argument | Type | Required? | Description |
---|---|---|---|
DATA | int8 | required | The data values as a 1..4 x n x m array. |
This routine will usually be called via the generic interface hl_gdk_pixbuf_new.
function hl_gdk_pixbuf_new_data8g(data) result(pixbuf)
type(c_ptr) :: pixbuf
integer(c_int8_t), dimension(:,:), intent(in) :: data
Create a pixbuf from a greyscale array of values.
Argument | Type | Required? | Description |
---|---|---|---|
DATA | int8 | required | The data values as a n x m array. |
This routine will usually be called via the generic interface hl_gdk_pixbuf_new.
function hl_gdk_pixbuf_new_data16(data) result(pixbuf)
type(c_ptr) :: pixbuf
integer(c_short), dimension(:,:,:), intent(in) :: data
Create a pixbuf from an RGB(A) array of values. This version uses 2-byte integers to avoid the signing issues of the c_int8_t type.
Argument | Type | Required? | Description |
---|---|---|---|
DATA | short | required | The data values as a 1..4 x n x m array. |
This routine will usually be called via the generic interface hl_gdk_pixbuf_new.
function hl_gdk_pixbuf_new_data16g(data) result(pixbuf)
type(c_ptr) :: pixbuf
integer(c_short), dimension(:,:), intent(in) :: data
Create a pixbuf from a greyscale array of values. This version uses 2-byte integers to avoid the signing issues of the c_int8_t type.
Argument | Type | Required? | Description |
---|---|---|---|
DATA | short | required | The data values as a n x m array. |
This routine will usually be called via the generic interface hl_gdk_pixbuf_new.
subroutine hl_gdk_pixbuf_get_pixels8(pixbuf, pixels)
type(c_ptr), intent(in) :: pixbuf
integer(c_int8_t), dimension(:,:,:), allocatable, intent(out) :: pixels
Get the pixels of a pixbuf and return them as a Fortran 3xnxm or 4xnxm array
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to read |
PIXELS | int8 | required | Will contain the image. |
This is normally called via the generic hl_gdk_pixbuf_get_pixels interface. Implemented as a subroutine to allow this.
subroutine hl_gdk_pixbuf_get_pixels16(pixbuf, pixels)
type(c_ptr), intent(in) :: pixbuf
integer(c_short), dimension(:,:,:), allocatable, intent(out) :: pixels
Get the pixels of a pixbuf and return them as a Fortran 3xnxm or 4xnxm array. This version returns as a short array to evade the signing issues of 8-bit integers in Fortran
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to read |
PIXELS | short | required | Will contain the image. |
This is normally called via the generic hl_gdk_pixbuf_get_pixels interface. Implemented as a subroutine to allow this.
subroutine hl_gdk_pixbuf_set_pixels8(pixbuf, pixels, xoff, yoff)
type(c_ptr), intent(in) :: pixbuf
integer(c_int8_t), dimension(:,:,:), intent(in) :: pixels
integer, intent(in), optional :: xoff, yoff
Set the pixels of a pixbuf from a Fortran array.
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to update |
PIXELS | int8 | required | Contains the image to insert. |
XOFF | int | optional | The X-offset at which to write the image. |
YOFF | int | optional | The Y-offset at which to write the image. |
This is normally called via the generic hl_gdk_pixbuf_set_pixels interface. N.B. To leave a gap at the "high" sides of the pixbuf, just use a smaller input array or array slice than the pixbuf size.
subroutine hl_gdk_pixbuf_set_pixels8g(pixbuf, pixels, xoff, yoff)
type(c_ptr), intent(in) :: pixbuf
integer(c_int8_t), dimension(:,:), intent(in) :: pixels
integer, intent(in), optional :: xoff, yoff
Set the pixels of a pixbuf from a Fortran array (greyscale).
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to update |
PIXELS | int8 | required | Contains the image to insert. |
XOFF | int | optional | The X-offset at which to write the image. |
YOFF | int | optional | The Y-offset at which to write the image. |
This is normally called via the generic hl_gdk_pixbuf_set_pixels interface. N.B. To leave a gap at the "high" sides of the pixbuf, just use a smaller input array or array slice than the pixbuf size.
subroutine hl_gdk_pixbuf_set_pixels16(pixbuf, pixels, xoff, yoff)
type(c_ptr), intent(in) :: pixbuf
integer(c_short), dimension(:,:,:), intent(in) :: pixels
integer, intent(in), optional :: xoff, yoff
Set the pixels of a pixbuf from a Fortran array (16-bit).
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to update |
PIXELS | short | required | Contains the image to insert. |
XOFF | int | optional | The X-offset at which to write the image. |
YOFF | int | optional | The Y-offset at which to write the image. |
This is normally called via the generic hl_gdk_pixbuf_set_pixels interface. N.B. To leave a gap at the "high" sides of the pixbuf, just use a smaller input array or array slice than the pixbuf size.
subroutine hl_gdk_pixbuf_set_pixels16g(pixbuf, pixels, xoff, yoff)
type(c_ptr), intent(in) :: pixbuf
integer(c_short), dimension(:,:), intent(in) :: pixels
integer, intent(in), optional :: xoff, yoff
Set the pixels of a pixbuf from a Fortran array (16-bit, greyscale).
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to update |
PIXELS | short | required | Contains the image to insert. |
XOFF | int | optional | The X-offset at which to write the image. |
YOFF | int | optional | The Y-offset at which to write the image. |
This is normally called via the generic hl_gdk_pixbuf_set_pixels interface. N.B. To leave a gap at the "high" sides of the pixbuf, just use a smaller input array or array slice than the pixbuf size.
subroutine hl_gdk_pixbuf_info(pixbuf, nchannels, bits, alpha, &
& height, width, rowstride)
type(c_ptr), intent(in) :: pixbuf
integer(c_int), optional, intent(out) :: nchannels, bits, alpha, &
& height, width, rowstride
Return information about an existing pixbuf.
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to be queried. |
NCHANNELS | int | optional | How many channels does the pixbuf have? |
BITS | int | optional | How many bits per pixel? |
ALPHA | boolean | optional | Does the pixbuf have an alpha channel? |
HEIGHT | int | optional | How many rows in the image. |
WIDTH | int | optional | How many columns in the image. |
ROWSTRIDE | int | optional | How many bytes between the start of successive rows. |
subroutine hl_gdk_pixbuf_save(pixbuf, file, type, options, ok, error)
type(c_ptr), intent(in) :: pixbuf
character(len=*), intent(in) :: file
character(len=*), intent(in), optional :: type
character(len=*), dimension(:), intent(in), optional :: options
logical, intent(out), optional :: ok
character(len=*), intent(out), optional :: error
Save a pixbuf to a file.
Argument | Type | Required? | Description |
---|---|---|---|
PIXBUF | c_ptr | required | The pixbuf to save |
FILE | f_string | required | The filename to which to save. |
TYPE | f_string | optional | The file type to use, if not given then it is deduced from the extension. |
OPTIONS | f_string() | optional | A list of options in the form "option=value". |
OK | logical | optional | Was the write successful. |
ERROR | f_string | optional | An error message if the write failed. |
subroutine hl_gdk_pixbuf_get_formats(names, writable, description, &
& scalable, license)
character(len=*), intent(out), dimension(:), allocatable :: names
logical, intent(out), dimension(:), allocatable, optional :: writable, &
& scalable
character(len=*), intent(out), dimension(:), allocatable, &
& optional :: license
character(len=*), intent(out), dimension(:), allocatable, &
& optional :: description
Get information about the available file formats for reading/writing pixbufs.
Argument | Type | Required? | Description |
---|---|---|---|
NAMES | f_string() | required | The names found |
WRITABLE | logical() | optional | Whether the formats are writable. |
DESCRIPTION | f_string() | optional | Descriptions of the formats. |
SCALABLE | logical() | optional | Whether the formats are scalable. |
LICENSE | f_string() | optional | The licence of the format module. |
function hl_gdk_pixbuf_format_info(name, mime_types, extensions, &
& writable, scalable, description, license) result(found)
logical :: found
character(len=*), intent(in) :: name
character(len=*), intent(out), optional, allocatable, &
& dimension(:) :: mime_types, extensions
logical, intent(out), optional :: writable, scalable
character(len=*), intent(out), optional :: description, license
Get information about a specific file type.
Argument | Type | Required? | Description |
---|---|---|---|
NAME | string | required | The file type to query. |
MIME_TYPE | fstring() | optional | Will contain a list of mime-types associated with this file type. |
EXTENSIONS | fstring() | optional | Will contain a list of file extensions normally used for this type. |
WRITABLE | logical | optional | Whether the type is writable. |
SCALABLE | logical | optional | Whether the type is scalable. |
DESCRIPTION | f_string | optional | A description of the file type. |
LICENSE | f_string | optional | The license of the module for the file type. |
Returns .true. if the type is found, .false. if it is not.
function hl_gdk_pixbuf_format_find(mime_type, extension) result(name)
character(len=hl_gdk_pixbuf_type_len) :: name
character(len=*), intent(in), optional :: mime_type, extension
Find the format type appropriate to a mime_type or a filename extension.
Argument | Type | Required? | Description |
---|---|---|---|
MIME_TYPE | f_string | optional | The mime-type to match. |
EXTENSION | f_string | optional | The file extension to match. |
If no match is found then an empty string is returned. Mime_type has precedence over extension.
- Installation
- My first gtk-fortran application
- Drawing an image in a PNG file (without GUI)
- A program also usable without GUI
- Using Glade3 and gtkf-sketcher (GTK 3)
- Using gtk-fortran as a fpm dependency
- Debugging with GtkInspector
- Learning from examples
- Video tutorials
- How to start my own project from a gtk-fortran example
- git basics
- CMake basics
- Alternatives to CMake
- How to migrate to GTK 4
- How to contribute to gtk-fortran
- How to hack the cfwrapper with other C libraries