summaryrefslogtreecommitdiff
path: root/app/wlib/gtklib/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/wlib/gtklib/window.c')
-rw-r--r--app/wlib/gtklib/window.c268
1 files changed, 209 insertions, 59 deletions
diff --git a/app/wlib/gtklib/window.c b/app/wlib/gtklib/window.c
index 489f35e..65706fd 100644
--- a/app/wlib/gtklib/window.c
+++ b/app/wlib/gtklib/window.c
@@ -48,6 +48,7 @@ extern wBool_t listHelpStrings;
static wControl_p firstWin = NULL, lastWin;
static int keyState;
static wBool_t gtkBlockEnabled = TRUE;
+static wBool_t maximize_at_next_show = FALSE;
/*
*****************************************************************************
@@ -58,6 +59,44 @@ static wBool_t gtkBlockEnabled = TRUE;
*/
/**
+ * Get the "monitor" size for the window (strictly the nearest or most used monitor)
+ * Note in OSX there is one giant virtual monitor so this doesn't work to force resize down...
+ *
+ */
+
+static GdkRectangle getMonitorDimensions(GtkWidget * widget) {
+
+ GdkRectangle monitor_dimensions;
+
+ GdkScreen *screen = NULL;
+
+ int monitor;
+
+ GtkWidget * toplevel = gtk_widget_get_toplevel(widget);
+
+ if (gtk_widget_is_toplevel(GTK_WIDGET(toplevel)) &&
+ gtk_widget_get_parent_window(GTK_WIDGET(toplevel))) {
+
+ GdkWindow * window = GDK_WINDOW(gtk_widget_get_parent_window(GTK_WIDGET(toplevel)));
+
+ screen = gdk_window_get_screen(GDK_WINDOW(window));
+
+ monitor = gdk_screen_get_monitor_at_window(screen,GDK_WINDOW(window));
+
+ } else {
+
+ screen = gdk_screen_get_default();
+
+ monitor = gdk_screen_get_primary_monitor(screen);
+
+ }
+
+ gdk_screen_get_monitor_geometry(screen,monitor,&monitor_dimensions);
+
+ return monitor_dimensions;
+}
+
+/**
* Get the window size from the resource (.rc) file. The size is saved under the key
* SECTIONWINDOWSIZE.window name
*
@@ -71,6 +110,16 @@ static void getWinSize(wWin_p win, const char * nameStr)
const char *cp;
char *cp1, *cp2;
+ /*
+ * Clamp window to be no bigger than one monitor size (to start - the user can always maximize)
+ */
+
+ GdkRectangle monitor_dimensions = getMonitorDimensions(GTK_WIDGET(win->gtkwin));
+
+ wPos_t maxDisplayWidth = monitor_dimensions.width-5;
+ wPos_t maxDisplayHeight = monitor_dimensions.height-25;
+
+
if ((win->option&F_RESIZE) &&
(win->option&F_RECALLPOS) &&
(cp = wPrefGetString(SECTIONWINDOWSIZE, nameStr)) &&
@@ -84,6 +133,9 @@ static void getWinSize(wWin_p win, const char * nameStr)
h = 10;
}
+ if (w > maxDisplayWidth) w = maxDisplayWidth;
+ if (h > maxDisplayHeight) h = maxDisplayHeight;
+
win->w = win->origX = w;
win->h = win->origY = h;
win->option &= ~F_AUTOSIZE;
@@ -103,7 +155,7 @@ static void saveSize(wWin_p win)
if ((win->option&F_RESIZE) &&
(win->option&F_RECALLPOS) &&
gtk_widget_get_visible(GTK_WIDGET(win->gtkwin))) {
- char pos_s[20];
+ char pos_s[20];
sprintf(pos_s, "%d %d", win->w,
win->h-(BORDERSIZE + ((win->option&F_MENUBAR)?MENUH:0)));
@@ -121,14 +173,13 @@ static void saveSize(wWin_p win)
static void getPos(wWin_p win)
{
char *cp1, *cp2;
- wPos_t gtkDisplayWidth = gdk_screen_width();
- wPos_t gtkDisplayHeight = gdk_screen_height();
+ GdkRectangle monitor_dimensions = getMonitorDimensions(GTK_WIDGET(win->gtkwin));
if ((win->option&F_RECALLPOS) && (!win->shown)) {
- const char *cp;
+ const char *cp;
if ((cp = wPrefGetString(SECTIONWINDOWPOS, win->nameStr))) {
- int x, y;
+ int x, y;
x = strtod(cp, &cp1);
@@ -142,12 +193,12 @@ static void getPos(wWin_p win)
return;
}
- if (y > gtkDisplayHeight-win->h) {
- y = gtkDisplayHeight-win->h;
+ if (y > monitor_dimensions.height+monitor_dimensions.y-win->h) {
+ y = monitor_dimensions.height+monitor_dimensions.y-win->h;
}
- if (x > gtkDisplayWidth-win->w) {
- x = gtkDisplayWidth-win->w;
+ if (x > monitor_dimensions.width+monitor_dimensions.x-win->w) {
+ x = monitor_dimensions.width+monitor_dimensions.x-win->w;
}
if (x <= 0) {
@@ -176,7 +227,7 @@ static void savePos(wWin_p win)
int x, y;
if ((win->option&F_RECALLPOS)) {
- char pos_s[20];
+ char pos_s[20];
gdk_window_get_position(gtk_widget_get_window(GTK_WIDGET(win->gtkwin)), &x, &y);
x -= 5;
@@ -216,7 +267,7 @@ void wWinGetSize(
}
*width = w;
- *height = h - BORDERSIZE - ((win->option&F_MENUBAR)?MENUH:0);
+ *height = h - BORDERSIZE - ((win->option&F_MENUBAR)?win->menu_height:0);
}
/**
@@ -234,8 +285,8 @@ void wWinSetSize(
{
win->busy = TRUE;
win->w = width;
- win->h = height + BORDERSIZE + ((win->option&F_MENUBAR)?MENUH:0);
- gtk_widget_set_size_request(win->gtkwin, win->w, win->h);
+ win->h = height + BORDERSIZE + ((win->option&F_MENUBAR)?win->menu_height:0);
+ //gtk_widget_set_size_request(win->gtkwin, win->w, win->h);
gtk_widget_set_size_request(win->widget, win->w, win->h);
win->busy = FALSE;
}
@@ -271,11 +322,15 @@ void wWinShow(
gtk_widget_size_request(win->gtkwin, &requisition);
if (requisition.width != win->w || requisition.height != win->h) {
- gtk_widget_set_size_request(win->gtkwin, win->w, win->h);
- gtk_widget_set_size_request(win->widget, win->w, win->h);
+ //gtk_window_resize(GTK_WINDOW(win->gtkwin), win->w, win->h);
+ gtk_widget_set_size_request(win->gtkwin, win->w, win->h);
+ gtk_widget_set_size_request(win->widget, win->w-20, win->h);
if (win->option&F_MENUBAR) {
- gtk_widget_set_size_request(win->menubar, win->w, MENUH);
+ gtk_widget_set_size_request(win->menubar, win->w-20, MENUH);
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(win->menubar, &allocation);
+ win->menu_height = allocation.height;
}
}
}
@@ -299,6 +354,10 @@ void wWinShow(
} else {
wlibDoModal(win, TRUE);
}
+ if (maximize_at_next_show) {
+ gtk_window_maximize(GTK_WINDOW(win->gtkwin));
+ maximize_at_next_show = FALSE;
+ }
} else {
wFlush();
saveSize(win);
@@ -340,6 +399,18 @@ wBool_t wWinIsVisible(
}
/**
+ * Returns whether the window is maximized.
+ *
+ * \param win IN window
+ * \return TRUE if maximized, FALSE otherwise
+ */
+
+wBool_t wWinIsMaximized(wWin_p win)
+{
+ return win->maximize_initially;
+}
+
+/**
* Sets the title of <win> to <title>.
*
* \param varname1 IN window
@@ -480,6 +551,25 @@ void wWinDoCancel(
******************************************************************************
*/
+static int window_redraw(
+ wWin_p win,
+ wBool_t doWinProc)
+{
+ wControl_p b;
+
+ if (win==NULL) {
+ return FALSE;
+ }
+
+ for (b=win->first; b != NULL; b = b->next) {
+ if (b->repaintProc) {
+ b->repaintProc(b);
+ }
+ }
+
+ return FALSE;
+}
+
static gint window_delete_event(
GtkWidget *widget,
GdkEvent *event,
@@ -511,25 +601,6 @@ static gint window_delete_event(
return (TRUE);
}
-static int window_redraw(
- wWin_p win,
- wBool_t doWinProc)
-{
- wControl_p b;
-
- if (win==NULL) {
- return FALSE;
- }
-
- for (b=win->first; b != NULL; b = b->next) {
- if (b->repaintProc) {
- b->repaintProc(b);
- }
- }
-
- return FALSE;
-}
-
static int fixed_expose_event(
GtkWidget * widget,
GdkEventExpose * event,
@@ -542,27 +613,37 @@ static int fixed_expose_event(
}
}
+static int resizeTime(wWin_p win) {
+
+ if (win->resizeW == win->w && win->resizeH == win->h) { // If hasn't changed since last
+ win->resizeTimer = 0;
+ return FALSE; //Stop Timer and don't resize
+ }
+ if (win->busy==FALSE && win->winProc) { //Always drive once
+ win->winProc(win, wResize_e, win->data);
+ win->resizeW = win->w; //Remember this one
+ win->resizeH = win->h;
+ }
+ return TRUE; //Will redrive after another timer interval
+}
+
static int window_configure_event(
GtkWidget * widget,
GdkEventConfigure * event,
wWin_p win)
{
-// wPos_t h;
if (win==NULL) {
return FALSE;
}
- //h = event->height - BORDERSIZE;
-
- //if (win->option&F_MENUBAR) {
- //h -= MENUH;
- //}
-
if (win->option&F_RESIZE) {
if (event->width < 10 || event->height < 10) {
return TRUE;
}
+ int w = win->w;
+ int h = win->h;
+
if (win->w != event->width || win->h != event->height) {
win->w = event->width;
@@ -577,11 +658,18 @@ static int window_configure_event(
}
if (win->option&F_MENUBAR) {
- gtk_widget_set_size_request(win->menubar, win->w, MENUH);
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(win->menubar, &allocation);
+ win->menu_height= allocation.height;
+ gtk_widget_set_size_request(win->menubar, win->w-20, win->menu_height);
}
-
- if (win->busy==FALSE && win->winProc) {
- win->winProc(win, wResize_e, win->data);
+ if (win->resizeTimer) { // Already have a timer
+ return FALSE;
+ } else {
+ win->resizeW = w; //Remember where this started
+ win->resizeH = h;
+ win->resizeTimer = g_timeout_add(200,(GSourceFunc)resizeTime,win); // 200ms delay
+ return FALSE;
}
}
}
@@ -590,6 +678,38 @@ static int window_configure_event(
}
/**
+ * Event handler for window state changes (maximize)
+ * Handles maximize event by storing the new state in the internal structure and
+ * calling the event handler
+ *
+ * \param widget gtk widget
+ * \param event event information
+ * \param win the wlib internal window data
+ * \return TRUE if win is valid,
+ */
+
+gboolean window_state_event(
+ GtkWidget *widget,
+ GdkEventWindowState *event,
+ wWin_p win)
+{
+ if (!win) {
+ return (FALSE);
+ }
+
+ win->maximize_initially = FALSE;
+
+ if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
+ win->maximize_initially = TRUE;
+ }
+
+ if (win->busy==FALSE && win->winProc) {
+ win->winProc(win, wState_e, win->data);
+ }
+
+ return TRUE;
+}
+/**
* Get current state of shift, ctrl or alt keys.
*
* \return or'ed value of WKEY_SHIFT, WKEY_CTRL and WKEY_ALT depending on state
@@ -680,19 +800,22 @@ static gint window_char_event(
*******************************************************************************
*/
+
/**
- * Create a window
+ * Create a window.
+ * Default width and height are replaced by values stored in the configuration
+ * file (.rc)
*
* \param parent IN parent window
* \param winType IN type of window
- * \param x IN x position
- * \param y IN y position
+ * \param x IN default width
+ * \param y IN default height
* \param labelStr IN window title
- * \param nameStr IN
- * \param option IN
+ * \param nameStr IN name of window
+ * \param option IN misc options for placement and sizing of window
* \param winProc IN window procedure
* \param data IN additional data to pass to the window procedure
- * \return describe the return value
+ * \return the newly created window
*/
static wWin_p wWinCommonCreate(
@@ -711,7 +834,9 @@ static wWin_p wWinCommonCreate(
w = wlibAlloc(NULL, winType, x, y, labelStr, sizeof *w, data);
w->busy = TRUE;
w->option = option;
- getWinSize(w, nameStr);
+ w->resizeTimer = 0;
+
+
h = BORDERSIZE;
if (w->option&F_MENUBAR) {
@@ -728,6 +853,9 @@ static wWin_p wWinCommonCreate(
GTK_WINDOW(gtkMainW->gtkwin));
}
}
+ if (winType != W_MAIN) {
+ getWinSize(w, nameStr);
+ }
if (option & F_HIDE) {
gtk_widget_hide(w->gtkwin);
@@ -738,6 +866,7 @@ static wWin_p wWinCommonCreate(
gtk_window_set_position(GTK_WINDOW(w->gtkwin), GTK_WIN_POS_CENTER_ON_PARENT);
}
+
w->widget = gtk_fixed_new();
if (w->widget == 0) {
@@ -748,7 +877,10 @@ static wWin_p wWinCommonCreate(
w->menubar = gtk_menu_bar_new();
gtk_container_add(GTK_CONTAINER(w->widget), w->menubar);
gtk_widget_show(w->menubar);
- gtk_widget_set_size_request(w->menubar, -1, MENUH);
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(w->menubar, &allocation);
+ w->menu_height = allocation.height;
+ gtk_widget_set_size_request(w->menubar, -1, w->menu_height);
}
gtk_container_add(GTK_CONTAINER(w->gtkwin), w->widget);
@@ -758,14 +890,14 @@ static wWin_p wWinCommonCreate(
w->w = 0;
w->realY = h;
w->h = 0;
- } else {
+ } else if (w->origX != 0){
w->w = w->realX = w->origX;
w->h = w->realY = w->origY+h;
- gtk_widget_set_size_request(w->gtkwin, w->w, w->h);
- gtk_widget_set_size_request(w->widget, w->w, w->h);
+ gtk_window_set_default_size(GTK_WINDOW(w->gtkwin), w->w, w->h);
+ //gtk_widget_set_size_request(w->widget, w->w-20, w->h);
if (w->option&F_MENUBAR) {
- gtk_widget_set_size_request(w->menubar, w->w, MENUH);
+ gtk_widget_set_size_request(w->menubar, w->w-20, MENUH);
}
}
@@ -777,6 +909,8 @@ static wWin_p wWinCommonCreate(
G_CALLBACK(fixed_expose_event), w);
g_signal_connect(GTK_OBJECT(w->gtkwin), "configure_event",
G_CALLBACK(window_configure_event), w);
+ g_signal_connect(GTK_OBJECT(w->gtkwin), "window-state-event",
+ G_CALLBACK(window_state_event), w);
g_signal_connect(GTK_OBJECT(w->gtkwin), "key_press_event",
G_CALLBACK(window_char_event), w);
g_signal_connect(GTK_OBJECT(w->gtkwin), "key_release_event",
@@ -813,7 +947,16 @@ static wWin_p wWinCommonCreate(
lastWin = (wControl_p)w;
gtk_widget_show(w->widget);
gtk_widget_realize(w->gtkwin);
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(w->gtkwin, &allocation);
+ w->menu_height = allocation.height;
+
w->busy = FALSE;
+
+ if (option&F_MAXIMIZE) {
+ maximize_at_next_show = TRUE;
+ }
+
return w;
}
@@ -846,8 +989,11 @@ wWin_p wWinMainCreate(
void * data) /* User context */
{
char *pos;
+ long isMaximized;
- if (pos = strchr(name, ';')) {
+ pos = strchr(name, ';');
+
+ if (pos) {
/* if found, split application name and configuration name */
strcpy(wConfigName, pos + 1);
} else {
@@ -855,8 +1001,12 @@ wWin_p wWinMainCreate(
strcpy(wConfigName, name);
}
+ wPrefGetInteger("draw", "maximized", &isMaximized, 0);
+ option = option | (isMaximized?F_MAXIMIZE:0);
+
gtkMainW = wWinCommonCreate(NULL, W_MAIN, x, y, labelStr, nameStr, option,
winProc, data);
+
wDrawColorWhite = wDrawFindColor(0xFFFFFF);
wDrawColorBlack = wDrawFindColor(0x000000);
return gtkMainW;