📄 window.c
字号:
/*
window.c
window manager functions and variables
*/
#include "usrif.h"
#undef NULL
#ifdef TRUE #undef TRUE #endif
#ifdef FALSE #undef FALSE #endif
#include <stdio.h>
/* window management variables */
static window_t *front, *back;
int num_windows = 0;
/* globals */
extern seg_t *desk_seg;
extern rect_t screen;
/* minimum window size */
#define MIN_WX 100
#define MIN_WY 70
/* viewport for window manager */
vport_t *the_port = NULL;
/* base rectangle for new_rect() */
rect_t base_rect;
/* new window size */
#define HSIZE 400
#define VSIZE 300
/* offsets for new window */
#define HDEL 50
#define VDEL 50
#define VBASE (screen.top-VSIZE-VDEL)
#define HBASE HDEL
/* new window rectangle, offset variables */
int hdir = HDEL, vdir = 0-HDEL;
/*
window manager initialization function
init_window()
called to reset window list,
also creates and draws the
desktop segment
*/
init_window()
{
vport_t *new_vport();
front = back = NULL;
num_windows = 0;
/* make primary viewport */
the_port = new_vport(&screen);
/* map to entire screen */
the_port->window = &screen;
/* make desktop segment */
make_desktop();
draw_seg(desk_seg, the_port);
/* set first window place and size */
set_rect(&base_rect,
HBASE, VBASE, HBASE+HSIZE, VBASE+VSIZE);
}
/*
window creation functions
new_window( name, segment, rect )
instantiates a new window structure,
creates the window shape segment
to correspond with name and rect,
links window into window list,
draws new window,
and returns a pointer to new window
new_rect()
creates new window rectangle,
offset from last time
new_rect() was called
*/
window_t *new_window( name, segment, rect )
char *name;
seg_t *segment;
rect_t *rect;
{
window_t *new;
key_t *mykey, *inst_key();
rect_t *inst_rect(), *new_rect(), *copy_rect();
text_t *inst_text();
void view_window();
num_windows++;
if(num_windows > MAX_WINDOWS)
return(NULL);
if(new = CALLOC( 1, window_t))
{
new->name = name;
/* check for minimum window size */
if( (rect->right - rect->left) < MIN_WX)
rect->right = rect->left + MIN_WX;
if( (rect->top - rect->bottom) < MIN_WY)
rect->top = rect->bottom + MIN_WY;
/* get new window rectangle */
new->area = rect;
/* make title area rectangle */
new->title = inst_rect(
new->area->left + 2,
new->area->top - 20,
new->area->right - 2,
new->area->top - 2);
/* make data area rectangle */
new->pane = inst_rect(
new->area->left + 1,
new->area->bottom + 1,
new->area->right - 1,
new->area->top - 22);
/* make segment for window */
cr_seg( name );
add_attr(RESET);
/* fill shape background */
add_attr(FILL);
add_rect(copy_rect(new->area));
add_attr(NOFILL);
/* frame shape background */
add_attr(FRAME);
add_attr(BLACK);
add_rect(copy_rect(new->area));
/* fill window title area */
add_attr(FILL);
add_attr(BLACK);
add_rect(copy_rect(new->title));
add_attr(WHITE);
text(name,
new->title->left + 8,
new->title->bottom + 5,
LEFT , BOTTOM);
new->shape = cl_seg();
new->data = segment;
new->data_win = copy_rect(segment->bbox);
draw_win( new );
/* link to top of window list */
/* no windows exist */
if(front == NULL)
back = front = new;
/* some windows exist */
else {
/* make new window the front window */
front->prev = new;
new->next = front;
new->prev = NULL;
front = new;
}
}
else
error("can't create new window");
/* set up window customer */
new->button_fn = &view_window;
return(new);
}
rect_t *new_rect()
{
rect_t r, *n, *copy_rect();
int p;
/* copy current base window rectangle */
n = copy_rect(&base_rect);
offset_rect(&base_rect, hdir, vdir);
/* move base rectangle to new position */
if( base_rect.right > screen.right)
{
p = base_rect.bottom;
set_rect(&base_rect,HBASE,p,HBASE+HSIZE,p+VSIZE);
}
if( base_rect.bottom < screen.bottom)
{
p = base_rect.left;
set_rect(&base_rect,p,VBASE,p+HSIZE,VBASE+VSIZE);
}
return(n);
}
/*
window pop function
pop_window(window)
makes given window the
top, or active, window
*/
pop_window( window )
window_t *window;
{
/* already on top? */
if(window == front)
return;
/* relink to top */
if(window == back)
{
/* window is bottom one */
window->prev->next = NULL;
back = window->prev;
}
else /* not front or back */
{
window->prev->next = window->next;
window->next->prev = window->prev;
}
front->prev = window;
window->next = front;
window->prev = NULL;
front = window;
/* draw window */
draw_win(window);
}
/*
window detection functions
front_window()
returns window pointer to
active, or front, window
what_window( where )
returns pointer to
top window that the point
where is in, else NULL
in_window( point, window)
in_title( point, window)
in_pane( point, window)
these return TRUE if point
is in the region, else FALSE
*/
window_t *front_window()
{
return(front);
}
window_t *what_window( where )
point_t *where;
{
window_t *mywin, *inwin;
inwin = NULL;
mywin = back;
while(mywin != NULL)
{
if(in_window( where, mywin ))
inwin = mywin;
/* next higher window */
mywin = mywin->prev;
}
return(inwin);
}
in_window( point, window)
point_t *point;
window_t *window;
{
if(pt_in_rect( window->area, point))
return(TRUE);
return(FALSE);
}
in_title( point, window)
point_t *point;
window_t *window;
{
if(pt_in_rect( window->title, point))
return(TRUE);
return(FALSE);
}
in_pane( point, window)
point_t *point;
window_t *window;
{
if(pt_in_rect( window->pane, point))
return(TRUE);
return(FALSE);
}
/*
window menu control functions
mod_window( event, window )
queries user for window modification
for the active window, then performs
selected modification operation
view_window( event, window )
queries user for view operation
for active window, then performs
selected view operation
*/
/* operation selection menu item definitions */
#define CANCEL 0
#define MOVE 1
#define SIZE 2
#define CLOSE 3
/* window modify operation selection menu items */
char *mod_ops[4] =
{
"Cancel",
"Move",
"Size",
"Close"
};
mod_window( event, window )
event_t *event;
window_t *window;
{
int sel;
rect_t *old_rect, *copy_rect();
/* pops up menu, user selects item */
sel = pop_up_menu( 4, mod_ops );
/* which item was selected? */
switch(sel)
{
case CANCEL :
/* user decided not to modify */
return;
case MOVE :
/* animate window move */
{
point_t first, last, delta;
key_t *key;
/* copy window bounds */
old_rect = copy_rect(window->area);
get_cursor(&first);
xor_rect(window->area,FRAME);
/* animate window outline */
while(event->what != DN_BUTTON_EVENT)
{
get_cursor(&last);
event = get_next_event();
delta.x = event->where.x - last.x;
delta.y = event->where.y - last.y;
if( delta.x != 0 || delta.y != 0)
{
/* remove old outline */
xor_rect(window->area,FRAME);
/* set new outline */
offset_rect(window->area, delta.x, delta.y);
/* add new outline */
xor_rect(window->area,FRAME);
}
}
/* found new window size */
xor_rect(window->area,FRAME);
/* calculate window's change in position */
delta.x = event->where.x - first.x;
delta.y = event->where.y - first.y;
/* offset window's regions */
offset_rect(window->title, delta.x, delta.y);
offset_rect(window->pane, delta.x, delta.y);
offset_rect(window->shape->bbox, delta.x, delta.y);
/* offset window's shape segment */
key = window->shape->data;
while(key != NULL)
{
switch(key->type)
{
case RECT :
offset_rect(key->key.rect, delta.x, delta.y);
break;
case TEXT :
key->key.text->origin.x += delta.x;
key->key.text->origin.y += delta.y;
break;
}
key = key->next;
}
/* refresh bit map */
all_wins( old_rect );
free(old_rect);
draw_win( window );
}
break;
case SIZE :
/* animate window sizing */
{
point_t first, last, delta;
key_t *key;
/* copy window bounds */
old_rect = copy_rect(window->area);
first.x = window->area->right;
first.y = screen.top - window->area->bottom;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -