Я создаю вложенное приложение GTK: есть GtkNotebook - GtkGrid - GtkGrid - GtkFrame - GtkDrawingArea.
В GtkDrawingArea (я фиксирую размер с помощью запроса размера) я создаю чертежи и создаю возможность для увеличения с помощью колеса прокрутки.
Логически, когда я «увеличиваю», поверхность становится больше, и для просмотра всего чертежа необходимы полосы прокрутки.
Как их получить? Я пробовал GtkLayout и GtkSrolledWindow в разных комбинациях, но они не работали. На Inte rnet.
я не нашел ни одного полезного примера. Как можно получить прокручиваемую область рисования? С чего мне начать копаться? Любые советы приветствуются!
Спасибо.
Кстати: я использую Debian, GTK3, C и Cairo
MCVE: я создал этот пример. Это dr aws прямоугольник, и вы можете увеличить его с помощью колеса прокрутки. Это происходит в кадре 300x300. Я хотел бы иметь этот кадр с полосами прокрутки. Любые идеи, как это сделать?
Этот код может быть скомпилирован с помощью
gcc `pkg-config --cflags gtk+-3.0` -lm -o cf cf.c `pkg-config --libs gtk+-3.0`
ср. c:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#define ZOOMING_STEP 1.2
typedef struct m_data
{
double scaling_factor;
cairo_surface_t *circle_surface_p, *final_surface_p;
GtkWidget *window_p;
} m_data_struct;
static void activate(GtkApplication *, gpointer);
static gboolean zoom_it(GtkWidget *, GdkEvent *, gpointer);
static gboolean configure_it(GtkWidget *, GdkEventConfigure *, gpointer);
static gboolean draw_it(GtkWidget *, cairo_t *, gpointer);
int main(int argc, char **argv)
{
GtkApplication *app_p;
m_data_struct my_data;
int status;
my_data.scaling_factor = 1.0/11.0;
my_data.final_surface_p = NULL;
app_p = gtk_application_new("calc.foil", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app_p, "activate", G_CALLBACK(activate), &my_data);
status = g_application_run(G_APPLICATION(app_p), 0, NULL);
g_object_unref(app_p);
}
static void activate(GtkApplication *app_p, gpointer g_data_p)
{
GtkWidget *frame_p, *notebook_p, *grid0_p, *grid1_p, *drawing_area_p;
m_data_struct *my_data_p;
cairo_t *cr_p;
my_data_p = (m_data_struct *)g_data_p;
my_data_p->window_p = gtk_application_window_new(app_p);
gtk_window_set_title(GTK_WINDOW(my_data_p->window_p), "Fot Calculation");
gtk_container_set_border_width(GTK_CONTAINER(my_data_p->window_p), 8);
notebook_p = gtk_notebook_new();
gtk_container_add(GTK_CONTAINER(my_data_p->window_p), notebook_p);
grid0_p = gtk_grid_new();
gtk_notebook_append_page(GTK_NOTEBOOK(notebook_p), grid0_p,
gtk_label_new("First Tab"));
grid1_p = gtk_grid_new();
gtk_grid_attach(GTK_GRID(grid0_p), grid1_p, 2, 2, 2, 50);
frame_p = gtk_frame_new("Rectangle");
drawing_area_p = gtk_drawing_area_new();
gtk_widget_set_size_request(frame_p, 300, 300);
g_signal_connect(drawing_area_p, "configure-event",
G_CALLBACK(configure_it), g_data_p);
g_signal_connect(drawing_area_p, "draw", G_CALLBACK(draw_it), g_data_p);
g_signal_connect(drawing_area_p, "scroll-event", G_CALLBACK(zoom_it),
g_data_p);
gtk_widget_set_events(drawing_area_p,
gtk_widget_get_events(drawing_area_p)
| GDK_SCROLL_MASK);
gtk_container_add(GTK_CONTAINER(frame_p), drawing_area_p);
gtk_grid_attach(GTK_GRID(grid1_p), frame_p, 1, 0, 1, 2);
my_data_p->circle_surface_p
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 3000, 3000);
cr_p = cairo_create(my_data_p->circle_surface_p);
cairo_set_line_width(cr_p, 10);
cairo_rectangle(cr_p, 100, 100, 2900, 2900);
cairo_set_source_rgb(cr_p, 0, 0, 0);
cairo_stroke(cr_p);
gtk_widget_show_all(my_data_p->window_p);
}
static gboolean zoom_it(GtkWidget *widget_p,
GdkEvent *event_p,
gpointer g_data_p)
{
if (((GdkEventScroll *)event_p)->direction == GDK_SCROLL_UP)
{
((m_data_struct *)g_data_p)->scaling_factor *= ZOOMING_STEP;
configure_it(widget_p, (GdkEventConfigure *)event_p, g_data_p);
gtk_widget_queue_draw(widget_p);
}
if (((GdkEventScroll *)event_p)->direction == GDK_SCROLL_DOWN)
{
((m_data_struct *)g_data_p)->scaling_factor /= ZOOMING_STEP;
configure_it(widget_p, (GdkEventConfigure *)event_p, g_data_p);
gtk_widget_queue_draw(widget_p);
}
return TRUE;
}
static gboolean configure_it(GtkWidget *widget_p,
GdkEventConfigure *event_p,
gpointer g_data_p)
{
cairo_t *cr_p;
m_data_struct * my_data_p;
my_data_p = (m_data_struct *)g_data_p;
if (my_data_p->final_surface_p)
cairo_surface_destroy(my_data_p->final_surface_p);
my_data_p->final_surface_p
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 300, 300);
cr_p = cairo_create(my_data_p->final_surface_p);
cairo_scale(cr_p, my_data_p->scaling_factor, my_data_p->scaling_factor);
cairo_set_source_surface(cr_p, my_data_p->circle_surface_p, 0, 0);
cairo_paint(cr_p);
cairo_destroy(cr_p);
return TRUE;
}
static gboolean draw_it(GtkWidget *widget_p,
cairo_t *cr_p,
gpointer g_data_p)
{
cairo_set_source_surface(cr_p, ((m_data_struct *)g_data_p)->final_surface_p,
0, 0);
cairo_paint(cr_p);
return FALSE;
}