static bool AdjustRect( gui_window *wnd, SAREA *area ) { if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) { if( ( area->col + area->width ) < wnd->hgadget->pos ) { return( false ); } else { if( area->col < wnd->hgadget->pos ) { area->width -= ( wnd->hgadget->pos - area->col ); area->col = 0; } else { area->col -= wnd->hgadget->pos; } } } if( ( wnd->vgadget != NULL ) && !GUI_VSCROLL_EVENTS_SET( wnd ) ) { if( ( area->row + area->height ) < wnd->vgadget->pos ) { return( false ); } else { if( area->row < wnd->vgadget->pos ) { area->height -= ( wnd->vgadget->pos - area->row ); area->row = 0; } else { area->row -= wnd->vgadget->pos; } } } area->col += wnd->use.col; area->row += wnd->use.row; return( GUIIntersectRect( area, &wnd->dirty ) ); }
static void SendPointEvent( gui_window *wnd, gui_event gui_ev, gui_coord *point ) { gui_point pt; bool down_sent; down_sent = ButtonDownSent == wnd; switch( gui_ev ) { case GUI_LBUTTONDOWN : case GUI_RBUTTONDOWN : ButtonDownSent = wnd; break; case GUI_LBUTTONUP : case GUI_RBUTTONUP : ButtonDownSent = NULL; break; default : break; } /* if the mouse event is not on the border, or if it is a mouse up on * the border */ if( down_sent || ( MouseState == MOUSE_CLIENT ) ) { if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) { point->x += wnd->hgadget->pos; } if( ( wnd->vgadget != NULL ) && !GUI_VSCROLL_EVENTS_SET( wnd ) ) { point->y += wnd->vgadget->pos; } GUIMakeRelative( wnd, point, &pt ); GUIEVENTWND( wnd, gui_ev, &pt ); } }
void GUIWndDirtyRect( gui_window * wnd, gui_rect * rect ) { SAREA area; GUIScaleToScreenRectR( rect, &area ); /* adjust for scrolling */ if( ( wnd->vgadget != NULL ) && !GUI_VSCROLL_EVENTS_SET( wnd ) ) { if( area.row < wnd->vgadget->pos ) { if( ( area.row + area.height ) < wnd->vgadget->pos ) { return; // rect entirely above visible area; } else { /* only bottom portion of rect visible */ area.height -= ( wnd->vgadget->pos - area.row ); area.row = 0; } } else { area.row -= wnd->vgadget->pos; } } if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) { if( area.col < wnd->hgadget->pos ) { if( ( area.col + area.width ) < wnd->hgadget->pos ) { return; // rect entirely to left of visible area; } else { /* only right portion of rect visible */ area.width -= ( wnd->hgadget->pos - area.col ); area.col = 0; } } else { area.col -= wnd->hgadget->pos; } } /* adjust top left to inside client area */ area.row += wnd->use.row; area.col += wnd->use.col; /* ensure we're only redrawing in the client area */ if( area.row > ( wnd->use.row + wnd->use.height ) ) { /* area entirely below visible area */ return; } if( area.col > ( wnd->use.col + wnd->use.width ) ) { /* area entirely to right of visible area */ return; } if( ( area.row + area.height ) > ( wnd->use.row + wnd->use.height ) ) { /* area goes past bottom of visible area - clip */ area.height = wnd->use.row + wnd->use.height - area.row; } if( ( area.col + area.width ) > ( wnd->use.col + wnd->use.width ) ) { /* area goes past right of visible area - clip */ area.width = wnd->use.col + wnd->use.width - area.col; } GUIDirtyArea( wnd, &area ); }
static void MapLocation( gui_window *wnd, gui_point *point ) { GUIScaleToScreenRPt( point ); if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) { point->x -= wnd->hgadget->pos; } if( ( wnd->vgadget != NULL ) && !GUI_VSCROLL_EVENTS_SET( wnd ) ) { point->y -= wnd->vgadget->pos; } point->x += wnd->use.col + 1; point->y += wnd->use.row + 1; }
void GUIWndDirtyRow( gui_window * wnd, gui_ord row ) { SAREA area; area.row = row + wnd->use.row; if( ( wnd->vgadget != NULL ) && !GUI_VSCROLL_EVENTS_SET( wnd ) ) { area.row -= wnd->vgadget->pos; } area.col = wnd->use.col; area.width = wnd->use.width; area.height = 1; GUIDirtyArea( wnd, &area ); }
bool GUIProcessEvent( EVENT ev ) { gui_event gui_ev; ORD row, col; gui_window *wnd; int prev; int diff; gui_ctl_id id; gui_window *menu_window; bool new_curr_wnd; VSCREEN *screen; // this is processed before all others and signals the end for all // GUI UI windows ( unconditional ) if( ev == EV_KILL_UI ) { GUIDestroyWnd( NULL ); return( false ); } ev = MapMiddleToRight( ev ); ev = CheckPrevEvent( ev ); wnd = NULL; if( uimouseinstalled() ) { screen = uivmousepos( NULL, &row, &col ); if( screen != NULL && (screen->flags & V_GUI_WINDOW) != 0 ) { wnd = (gui_window *)((char *)screen - offsetof( gui_window, screen )); } } if( GUIDoKeyboardMoveResize( ev ) ) { return( true ); } if( MouseState == MOUSE_MOVE || MouseState == MOUSE_SIZE ) { if( GUIDoMoveResizeCheck( GUIMouseWnd, ev, row, col ) ) { MouseState = MOUSE_FREE; return( true ); } if( GUI_WND_MINIMIZED( GUIMouseWnd ) ) { switch( ev ) { case EV_MOUSE_DCLICK : case EV_MOUSE_RELEASE : case EV_MOUSE_DRAG : ProcessMinimizedMouseEvent( ev, row, col ); } } else { switch( ev ) { case EV_MOUSE_RELEASE : case EV_MOUSE_DRAG : case EV_MOUSE_DRAG_R : ProcessMouseReleaseDrag( ev, GUI_LBUTTONUP, row, col ); } } return( true ); } new_curr_wnd = SetCurrWnd( ev, wnd ); if( GUIProcessAltMenuEvent( ev ) ) { return( true ); } /* Only deal with press and dclick events for minimized windows. * All other non-menu events are ingored. */ if( !IS_CTLEVENT( ev ) && ( GUICurrWnd != NULL ) && GUI_WND_MINIMIZED( GUICurrWnd ) ) { /* ignore event if mouse not in minimized current window */ if( GUICurrWnd == wnd ) { switch( ev ) { case EV_MOUSE_PRESS : case EV_MOUSE_DCLICK : case EV_MOUSE_RELEASE : GUIMouseWnd = GUICurrWnd; ProcessMinimizedMouseEvent( ev, row, col ); break; } } return( true ); } if( !IS_CTLEVENT( ev ) && ( GUICurrWnd != NULL ) && GUIIsOpen( GUICurrWnd ) ) { /* see if any of the controls in the window consume the event */ ev = GUIProcessControlEvent( GUICurrWnd, ev, row, col ); /* See if the event is for on of the scroll bars. */ /* Diff and prev are used if the event return is */ /* EV_SCROLL_HORIZONTAL or EV_SCROLL_VERTICAL. */ if( !new_curr_wnd || ( GUIGetWindowStyles() & ( GUI_INACT_GADGETS+GUI_INACT_SAME ) ) ) { ev = GUIGadgetFilter( GUICurrWnd, ev, &prev, &diff ); } if( ev == EV_NO_EVENT ) { return( true ); } } gui_ev = GUI_NO_EVENT; ev = GUIMapKeys( ev ); switch( ev ) { case EV_MOUSE_DCLICK_R : ProcessMousePos( GUI_RBUTTONDBLCLK, row, col, wnd ); return( true ); break; case EV_MOUSE_RELEASE_R : ProcessMouseReleaseDrag( ev, GUI_RBUTTONUP, row, col ); return( true ); break; case EV_MOUSE_DRAG_R : if( GUICurrWnd != GUIMouseWnd ) { /* got drag without press first */ ProcessMousePress( EV_MOUSE_PRESS_R, GUI_LBUTTONDOWN, row, col, new_curr_wnd ); } case EV_MOUSE_MOVE : ProcessMousePos( GUI_MOUSEMOVE, row, col, wnd ); return( true ); break; case EV_MOUSE_RELEASE : ProcessMouseReleaseDrag( ev, GUI_LBUTTONUP, row, col ); return( true ); break; case EV_MOUSE_DRAG : if( GUICurrWnd != GUIMouseWnd ) { /* got drag without press first */ ProcessMousePress( EV_MOUSE_PRESS, GUI_LBUTTONDOWN, row, col, new_curr_wnd ); } ProcessMouseReleaseDrag( ev, GUI_MOUSEMOVE, row, col ); return( true ); break; case EV_MOUSE_PRESS_R : ProcessMousePress( ev, GUI_RBUTTONDOWN, row, col, new_curr_wnd ); return( true ); break; case EV_MOUSE_PRESS : ProcessMousePress( ev, GUI_LBUTTONDOWN, row, col, new_curr_wnd ); return( true ); break; case EV_MOUSE_DCLICK : ProcessMousePress( ev, GUI_LBUTTONDBLCLK, row, col, new_curr_wnd ); return( true ); break; case EV_NO_EVENT : gui_ev = GUI_NO_EVENT; break; case EV_SCROLL_UP : case EV_SCROLL_DOWN : case EV_SCROLL_PAGE_UP : case EV_SCROLL_PAGE_DOWN : case EV_SCROLL_LEFT : case EV_SCROLL_RIGHT : case EV_SCROLL_LEFT_PAGE : case EV_SCROLL_RIGHT_PAGE : if( GUICurrWnd != NULL ) { ProcessScrollEvent( ev ); return( true ); } break; case EV_SCROLL_VERTICAL : if( GUI_VSCROLL_EVENTS_SET( GUICurrWnd ) ) { DoScrollDrag( GUICurrWnd->vgadget, prev, diff ); } else { GUIWholeWndDirty( GUICurrWnd ); } return( true ); break; case EV_SCROLL_HORIZONTAL : if( GUI_HSCROLL_EVENTS_SET( GUICurrWnd ) ) { DoScrollDrag( GUICurrWnd->hgadget, prev, diff ); } else { GUIWholeWndDirty( GUICurrWnd ); } return( true ); break; case EV_MENU_INITPOPUP : ProcessInitPopupEvent(); return( true ); break; #if 0 case EV_BACKGROUND_RESIZE : { gui_window *root; root = GUIGetRootWindow(); if( root != NULL ) { GUIZoomWnd( root, GUI_NONE ); } } return( true ); break; #endif default : if( IS_CTLEVENT( ev ) ) { if( !GUIMDIProcessEvent( ev ) ) { menu_window = GUIGetMenuWindow(); if( menu_window != NULL ) { id = EV2ID( ev ); GUIEVENTWND( menu_window, GUI_CLICKED, &id ); } } return( true ); } break; } if( ( GUICurrWnd != NULL ) && (gui_ev != GUI_NO_EVENT ) ) { GUIEVENTWND( GUICurrWnd, gui_ev, NULL ); } return( true ); }
void GUIXDrawText( gui_window *wnd, const char *text, size_t length, gui_coord *in_pos, gui_attr attr, gui_ord extentx, bool draw_extent ) { int vscroll; /* vertical scroll adjust amount */ int hscroll; /* horizontal scroll adjust amount */ size_t my_length; /* actual length of text (may be > length) */ gui_coord my_pos; /* pos in screen coords */ int pos; /* position to draw on VSCREEN */ int col; /* index into string */ gui_coord extent; SAREA area; int width; int frame_adjust; if( attr >= wnd->num_attrs ) { return; } if( !( wnd->style & GUI_VISIBLE ) ) { return; } if( wnd->style & GUI_NOFRAME ) { frame_adjust = 0; } else { frame_adjust = 1; } my_pos.x = in_pos->x; my_pos.y = in_pos->y; GUIScaleToScreenR( &my_pos ); /* adjust for scrolling */ vscroll = 0; if( ( wnd->vgadget != NULL ) && ( !GUI_VSCROLL_EVENTS_SET( wnd ) ) ) { vscroll += wnd->vgadget->pos; } hscroll = 0; if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) { hscroll += wnd->hgadget->pos; } if( ( my_pos.y - vscroll + frame_adjust ) < frame_adjust ) { /* row to draw is not visible with vertical scrolling */ return; } if( text != NULL ) { my_length = strlen( text ); if( my_length < length ) { length = my_length; } } else { my_length = 0; } /* if text shows even with scrolling */ if( ( my_pos.x + length ) > hscroll ) { pos = frame_adjust; /* position on VSCREEN */ col = 0; /* index into curr string */ /* start of text in dirty region */ if( ( ( wnd->dirty.col - 1 ) <= ( my_pos.x - hscroll ) ) && ( my_pos.x >= hscroll ) ) { pos += ( my_pos.x - hscroll ); } else { /* start of text to left of dirty region */ pos += wnd->dirty.col - 1; if( my_pos.x < hscroll ) { /* start of text scrolled off screen */ col += ( hscroll - my_pos.x + wnd->dirty.col - 1 ); length -= ( hscroll - my_pos.x + wnd->dirty.col - 1 ); } else { /* start of text visible but to left of dirty region */ col += ( wnd->dirty.col - 1 + hscroll - my_pos.x ); length -= ( wnd->dirty.col - 1 + hscroll - my_pos.x ); } } /* should deal with decreasing length due to text off screen to right */ if( ( length > 0 ) && ( ( col - hscroll ) < ( wnd->dirty.col + wnd->dirty.width ) ) ) { if( ( pos + length ) > ( wnd->dirty.col + wnd->dirty.width ) ) { length = wnd->dirty.col + wnd->dirty.width - pos; } if( length > 0 ) { char *p; const char *cp; for( cp = text; cp < text+col; cp += GUICharLen( *cp ) ) ; if( cp != text + col ) { p = alloca( length ); cp = memcpy( p, text+col, length ); p[0] = ' '; } uivtextput( &wnd->screen, my_pos.y - vscroll + frame_adjust, pos, wnd->colours[attr], cp, length ); } else { length = 0; } } else { length = 0; } } else { pos = -length + 1; /* so (pos+length) will be 1 for drawing extent */ } if( draw_extent ) { if( extentx == GUI_NO_COLUMN ) { /* this is the most that will be covered. It will be adjust for starting position and dirty rect */ extentx = wnd->use.width; } else { /* record total width user wants to cover, adjusting for * portion not visible due to scrolling scrolling */ extent.x = extentx + in_pos->x; GUIScaleToScreenR( &extent ); extentx = extent.x - hscroll; } if( ( pos + length ) <= extentx ) { area.row = my_pos.y - vscroll + frame_adjust; area.height = 1; area.col = pos + length; /* adjust left border for dirty area */ if( area.col < wnd->dirty.col ) { area.col = wnd->dirty.col; } width = extentx - area.col + 1; /* adjust right border for dirty area */ if( ( area.col + width ) > ( wnd->dirty.col + wnd->dirty.width ) ) { width = wnd->dirty.width + wnd->dirty.col - area.col; } if( width > 0 ) { area.width = width; uivfill( &wnd->screen, area, wnd->colours[attr], ' ' ); } } } }