Section 6 Home page Section 8

7. Changing the Window Size: Full and Resize

The next two window controls we will look at are used to alter the size of the window. The first, the FULLER, allows us to make the window its maximum size. Clicking the FULLER a second time will restore the window to its previous size. The second is the SIZER, which enables us to dynamically alter the window size to whichever dimensions we wish.

Both these controls rely on the wind_set command to set the current x, y, w, h, dimensions of the window.

7.1. FULLER

The FULL widget is used to expand our window to its maximum size. This maximum size was set when you created the window, but is usually the extent of the desktop: using WF_FULLXYWH in a call to wind_set will retrieve this maximum size. Once fulled, a window can be restored by again clicking the FULL widget. The AES enables us to retrieve the previous dimensions of a window using WF_PREVXYWH in a call to wind_get.

Fortunately, the AES will ensure the display is kept updated, in two ways. First, if the window is just made smaller, then nothing needs updating in your program, as the display has simply been truncated. Second, if the window is made full, it becomes larger, so a REDRAW event is sent to your application, to redraw the new rectangle(s). As we already handle these events, nothing extra is needed.

The function to handle the fulled event is as follows. It is divided into two parts: if the window is already full, then we need to retrieve its previous size and set the current window size to those older values. If the window is not already full, then we need to retrieve the maximum size, and set the current window size to the maximum (full) values. In addition, it is traditional to display a little animation of the window growing or shrinking to its new size, hence the calls to graf_shrinkbox. (This may not be visible on a fast computer: I can’t detect them on the Firebee!)

void do_fulled (struct win_data * wd) {
        if (is_full_window (wd)) { /* it's full, so shrink to previous size */
                int oldx, oldy, oldw, oldh;
                int fullx, fully, fullw, fullh;

                wind_get (wd->handle, WF_PREVXYWH, &oldx, &oldy, &oldw, &oldh);      // <1>
                wind_get (wd->handle, WF_FULLXYWH, &fullx, &fully, &fullw, &fullh);  // <2>
                graf_shrinkbox (oldx, oldy, oldw, oldh, fullx, fully, fullw, fullh); // <3>
                wind_set (wd->handle, WF_CURRXYWH, oldx, oldy, oldw, oldh);          // <4>

        } else { /* make full size */
                int curx, cury, curw, curh;
                int fullx, fully, fullw, fullh;

                wind_get (wd->handle, WF_CURRXYWH, &curx, &cury, &curw, &curh);
                wind_get (wd->handle, WF_FULLXYWH, &fullx, &fully, &fullw, &fullh); // <2>
                graf_growbox (curx, cury, curw, curh, fullx, fully, fullw, fullh);
                wind_set (wd->handle, WF_CURRXYWH, fullx, fully, fullw, fullh);
        }
}
  1. Find the previous dimensions of the window.

  2. Find the maximum dimensions of the window.

  3. Draw a little animation of the shrinking window.

  4. Set the window size to the previous dimensions.

Notice the function is_full_window, which returns true if the window is currently at its maximum size. This function merely checks the current and full dimensions of the window, to see if they are the same. The function is:

bool is_full_window (struct win_data * wd) {
        int curx, cury, curw, curh;
        int fullx, fully, fullw, fullh;

        wind_get (wd->handle, WF_CURRXYWH, &curx, &cury, &curw, &curh);
        wind_get (wd->handle, WF_FULLXYWH, &fullx, &fully, &fullw, &fullh);
        if (curx != fullx || cury != fully || curw != fullw || curh != fullh) {
                return false;
        } else {
                return true;
        }
}

Finally, to respond to size events, include WM_FULLED in the event loop, as follows:

case WM_FULLED:
        do_fulled (wd);
        break;

7.2. SIZER

The sizer allows the user to adjust the window dimensions to any size she chooses. The AES will tell your application when the sizer has been adjusted, and also tell you the new size of the window (in msg_buf). Your program must alter the size of the window, and make any other adjustments required to make the window contents suit its new size (this is particularly important when you have sliders as well, for which see the next section).

Fortunately, the AES will ensure the display is kept updated, just as with the fulled event, above.

The code to actually resize our window is, at this stage, simple. All we need to do is set the current dimensions of the window to the new size. We add a simple check that the new dimensions are not too small, so the user cannot reduce the window beyond a given minimum.

void do_sized (struct win_data * wd, int * msg_buf) {
        if (msg_buf[6] < MIN_WIDTH) msg_buf[6] = MIN_WIDTH;     // <1>
        if (msg_buf[7] < MIN_HEIGHT) msg_buf[7] = MIN_HEIGHT;

        wind_set (wd->handle, WF_CURRXYWH,
                  msg_buf[4], msg_buf[5], msg_buf[6], msg_buf[7]); // <2>
}
  1. To prevent the user sizing our window out of existence, we check that the new width and height won’t be too small. The minimum dimensions are defined in "windows.h".

  2. All we need to do is set our window’s current x, y, w, h to the new size.

To respond to size events, include WM_SIZED in the event loop, as follows:

case WM_SIZED:
        do_sized (wd, msg_buf); // <1>
        break;
  1. Pass the window and the message buffer to do_sized.

7.3. Sample Program: Version 4

Version 4 now supports more of the window’s widgets: you can resize the window using the button at the bottom-right, and also make the window switch between full screen and its original size.

To make the display more interesting, the window contains several lines of a poem. You need to resize the window to see more of the poem. How much you can see will depend on the size of your screen. To see the rest of the poem, we somehow need to move the window "over" the poem being displayed - this introduces our next topic, sliders.