-
Notifications
You must be signed in to change notification settings - Fork 45
High level drawing api
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, however cumulative plotting (e.g. PLplot's strip charts) now works correctly.
- hl_gtk_drawing_area_new; Create the drawing area.
- hl_gtk_drawing_area_get_surface; Get the backing cairo surface
- 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 size-allocate 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, event_mask, &
& event_exclude, auto_add_mask, &
& tooltip, has_alpha, size_allocate, data_size_allocate) result(plota)
type(c_ptr) :: plota
type(c_ptr), intent(out), optional :: scroll
integer(kind=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
integer(kind=c_int), intent(in), optional :: event_mask, event_exclude
integer(kind=c_int), intent(in), optional :: auto_add_mask
character(kind=c_char), dimension(*), optional, intent(in) :: tooltip
integer(kind=c_int), intent(in), optional :: has_alpha
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 GTK3 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. |
| EVENT_MASK | c_int | optional | Mask for which events to pass. |
| EVENT_EXCLUDE | c_int | optional | Mask for events not to pass (this might used to prevent auto-enabling an event that should only be enabled by user actions) |
| AUTO_ADD_MASK | boolean | optional | Set to FALSE to disable automatically adding events to the event mask if a handler is provided. |
| 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 'size-allocate' signal |
| DATA_SIZE_ALLOCATE | c_ptr | optional | Data for size_allocate. |
Odd notes on mask interactions and other things.
- Scroll (wheel) events, are enabled by GDK_SCROLL_MASK or GDK_BUTTON_PRESS_MASK, thus (as far as I can see) there is no way to mask wheel events while allowing button presses to be processed.
- It does not appear to be possible to remove events by unsetting bits in the event mask.
- Adding a tooltip looks to implicitly enable some events.
- An example where an explict EVENT_MASK and EVENT_EXCLUDE might be useful would be to enable motion events only if a button is down.
- 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_expose_cb(area, event, data) bind(c) &
& result(rv)
integer(kind=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 | GTK2 = event structure, GTK3 = a cairo context Since this differs between versions, we won't use it. |
| 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 |
subroutine hl_gtk_drawing_area_cairo_destroy(cr, destroy_surface)
type(c_ptr), intent(inout) :: cr
integer(kind=c_int), intent(in), optional :: destroy_surface
| Argument | Type | Required? | Description |
|---|---|---|---|
|
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(kind=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). |
let older codes work
- 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