This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
neofx-zoomedit/window.c
2007-06-22 11:57:05 +00:00

143 lines
4.9 KiB
C

#include "window.h"
#include "ui.h"
#include "draw.h"
#include <gtk/gtk.h>
static GtkWidget *drawingArea = NULL;
static GtkAdjustment *hAdjustment = NULL, *vAdjustment = NULL;
static gboolean deleteEvent(GtkWidget *widget, GdkEvent *event, gpointer data) {
return FALSE;
}
static gboolean scrollEvent(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) {
const gdouble x = event->x/widget->allocation.width, y = event->y/widget->allocation.height;
switch(event->direction) {
case GDK_SCROLL_UP:
zoomIn(1.1, x, y);
break;
case GDK_SCROLL_DOWN:
zoomOut(1.1, x, y);
}
}
static void destroy(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
static void refreshScrolling() {
if(getImageWidth() < drawingArea->allocation.width)
setXTranslate((getImageWidth()-drawingArea->allocation.width)/2);
else
setXTranslate(gtk_adjustment_get_value(hAdjustment));
if(getImageHeight() < drawingArea->allocation.height)
setYTranslate((getImageHeight()-drawingArea->allocation.height)/2);
else
setYTranslate(gtk_adjustment_get_value(vAdjustment));
gtk_widget_queue_draw(drawingArea);
}
static void updateScrollbars(double x, double y) {
const gdouble imageWidth = getImageWidth(), imageHeight = getImageHeight();
const gdouble width = drawingArea->allocation.width, height = drawingArea->allocation.height;
gdouble upper, pageSize, value;
gdk_window_freeze_updates(drawingArea->window);
g_object_get(G_OBJECT(hAdjustment), "upper", &upper, "page_size", &pageSize, NULL);
g_object_set(G_OBJECT(hAdjustment), "upper", imageWidth, "page_size", width, NULL);
gtk_adjustment_changed(hAdjustment);
if((pageSize > upper && width < imageWidth) || upper == 0)
value = (imageWidth-width)/2;
else
value = (gtk_adjustment_get_value(hAdjustment)+pageSize*x)/upper*imageWidth-width*x;
gtk_adjustment_set_value(hAdjustment, MAX(MIN(value, imageWidth-width), 0));
g_object_get(G_OBJECT(vAdjustment), "upper", &upper, "page_size", &pageSize, NULL);
g_object_set(G_OBJECT(vAdjustment), "upper", imageHeight, "page_size", height, NULL);
if((pageSize > upper && height < imageHeight) || upper == 0)
value = (imageHeight-height)/2;
else
value = (gtk_adjustment_get_value(vAdjustment)+pageSize*y)/upper*imageHeight-height*y;
gtk_adjustment_set_value(vAdjustment, MAX(MIN(value, imageHeight-height), 0));
gdk_window_thaw_updates(drawingArea->window);
refreshScrolling();
}
static void updateScrollbarsCentered() {
updateScrollbars(0.5, 0.5);
}
GtkWidget* createMainWindow() {
GtkWidget *window, *vbox, *menubar, *toolbar, *table, *vScroll, *hScroll;
GdkColor color = {0, 0, 0, 0};
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(deleteEvent), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
menubar = getMenu();
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
toolbar = getToolbar();
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
gtk_window_add_accel_group(GTK_WINDOW(window), getAccels());
table = gtk_table_new(2, 2, FALSE);
gtk_box_pack_end(GTK_BOX(vbox), table, TRUE, TRUE, 0);
drawingArea = gtk_drawing_area_new();
gtk_widget_modify_bg(drawingArea, GTK_WIDGET_STATE(drawingArea), &color);
g_signal_connect(G_OBJECT(drawingArea), "configure-event", G_CALLBACK(updateScrollbarsCentered), NULL);
g_signal_connect(G_OBJECT(drawingArea), "expose-event", G_CALLBACK(drawTopView), NULL);
g_signal_connect(G_OBJECT(drawingArea), "scroll-event", G_CALLBACK(scrollEvent), NULL);
gtk_widget_add_events(drawingArea, GDK_SCROLL_MASK);
gtk_table_attach(GTK_TABLE(table), drawingArea, 0, 1, 0, 1, GTK_FILL|GTK_EXPAND|GTK_SHRINK, GTK_FILL|GTK_EXPAND|GTK_SHRINK, 0, 0);
hAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 0, 10, 100, 100));
hScroll = gtk_hscrollbar_new(hAdjustment);
g_signal_connect(G_OBJECT(hScroll), "value-changed", G_CALLBACK(refreshScrolling), NULL);
gtk_table_attach(GTK_TABLE(table), hScroll, 0, 1, 1, 2, GTK_FILL|GTK_EXPAND|GTK_SHRINK, 0, 0, 0);
vAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 0, 10, 100, 100));
vScroll = gtk_vscrollbar_new(vAdjustment);
g_signal_connect(G_OBJECT(vScroll), "value-changed", G_CALLBACK(refreshScrolling), NULL);
gtk_table_attach(GTK_TABLE(table), vScroll, 1, 2, 0, 1, 0, GTK_FILL|GTK_EXPAND|GTK_SHRINK, 0, 0);
gtk_widget_show_all(vbox);
return window;
}
void zoomIn(double factor, double x, double y) {
setScale(getScale()*factor);
updateScrollbars(x, y);
}
void zoomOut(double factor, double x, double y) {
setScale(getScale()/factor);
updateScrollbars(x, y);
}
void zoomInCentered(double factor) {
zoomIn(factor, 0.5, 0.5);
}
void zoomOutCentered(double factor) {
zoomOut(factor, 0.5, 0.5);
}