📄 panel_scroll.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)panel_scroll.c 1.1 92/07/30 Copyr 1984 Sun Micro";#endif#endif/*****************************************************************************//* panel_scroll.c *//* Copyright (c) 1985 by Sun Microsystems, Inc. *//*****************************************************************************/#include <suntool/panel_impl.h>static paint_scrolled_panel();static partial_paint();static does_intersect();static panel_adjust_scrollbar_rects();static void normalize_top(), normalize_bottom(), normalize_left(), normalize_right();static top_pair(), left_pair();/****************************************************************************//* panel_scroll *//****************************************************************************/voidpanel_scroll(panel, sb)panel_handle panel;Scrollbar sb;{ Scroll_motion motion; int caret_was_on = panel->caret_on; int offset, line_ht; int normalize, align_to_max, scrolling_up, vertical; panel_item_handle low_ip, high_ip; if (caret_was_on) { panel_caret_on(panel, FALSE); } motion = (Scroll_motion) scrollbar_get(sb, SCROLL_REQUEST_MOTION); vertical = (Scrollbar_setting) scrollbar_get(sb, SCROLL_DIRECTION) == SCROLL_VERTICAL; offset = (int) scrollbar_get(sb, SCROLL_VIEW_START); normalize = (int) scrollbar_get(sb, SCROLL_NORMALIZE); line_ht = (int) scrollbar_get(sb, SCROLL_LINE_HEIGHT); switch (motion) { case SCROLL_ABSOLUTE: case SCROLL_FORWARD: case SCROLL_PAGE_FORWARD: case SCROLL_LINE_FORWARD: align_to_max = FALSE; scrolling_up = TRUE; break; case SCROLL_BACKWARD: align_to_max = FALSE; scrolling_up = FALSE; break; case SCROLL_MAX_TO_POINT: align_to_max = TRUE; scrolling_up = TRUE; break; case SCROLL_POINT_TO_MAX: align_to_max = TRUE; scrolling_up = FALSE; break; case SCROLL_PAGE_BACKWARD: align_to_max = FALSE; scrolling_up = FALSE; break; case SCROLL_LINE_BACKWARD: align_to_max = FALSE; scrolling_up = FALSE; break; } if (!line_ht) { if (motion==SCROLL_LINE_FORWARD || motion==SCROLL_LINE_BACKWARD) { normalize = TRUE; /* object-normalize 0 line heights! */ if (vertical) { (void) top_pair(panel, &low_ip, &high_ip); if (scrolling_up && high_ip) offset = high_ip->rect.r_top + high_ip->rect.r_height + 1; else if (!scrolling_up && low_ip) offset = low_ip->rect.r_top - 1; } else { (void) left_pair(panel, &low_ip, &high_ip); if (scrolling_up && high_ip) offset = high_ip->rect.r_left + high_ip->rect.r_width + 1; else if (!scrolling_up && low_ip) offset = low_ip->rect.r_left - 1; } if (offset < 0) /*be sure we didn't go negative*/ offset = 0; } }/* if (high_ip && low_ip) if (scrolling_up) offset = high_ip->rect.r_top + high_ip->rect.r_height + 1; else offset = low_ip->rect.r_top - 1; else if (low_ip) offset = panel->v_end; else offset = 0;*//* if (high_ip && low_ip) if (scrolling_up) offset = high_ip->rect.r_left + high_ip->rect.r_width + 1; else offset = low_ip->rect.r_left - 1; else if (low_ip) offset = panel->h_end; else offset = 0;*/ if (vertical) { panel->v_offset = offset; if (normalize) { if (!line_ht) { if (align_to_max) normalize_bottom(panel, scrolling_up); else normalize_top(panel, scrolling_up); } } offset = panel->v_offset; } else { panel->h_offset = offset; if (normalize) { if (!line_ht) { if (align_to_max) normalize_right(panel, scrolling_up); else normalize_left(panel, scrolling_up); } } offset = panel->h_offset; } (void)scrollbar_set(sb, SCROLL_VIEW_START, offset, 0); paint_scrolled_panel(panel, sb); if (caret_was_on) panel_caret_on(panel, TRUE);}/* * Object normalization methodology: * A line is drawn through all the objects at the current view_offset. * The two rectangles (ip's) straddling this line, just above & below, * are obtained. The offset is then modified to be just above or below * this rectangle [by the margin length] depending on the direction * of scrolling and on whether or not the topmost ip intersects offset. * * low_ip * +-------+ * | | <----intersects=TRUE *---------------------------------------------------- offset * | | +-------+ * +-------+ | | * +-------+ * high_ip * * */statictop_pair(panel, low_ip, high_ip)panel_handle panel;panel_item_handle *low_ip, *high_ip;{ register panel_item_handle ip; register int low_top = -1; register int high_top = panel->v_end; register int top; int target = panel->v_offset; int intersects = FALSE;/*fix for sb neg truncation: pin at 0:target = -1 => low_ip = null*/ if (target == 0) target = -1; *high_ip = NULL; *low_ip = NULL; for (ip = panel->items; ip; ip = ip->next) { if (!hidden(ip)) { top = ip->rect.r_top; if (top <= target) { if (top > low_top) { low_top = top; *low_ip = ip; intersects = (top + ip->rect.r_height > target); } } else { if (top < high_top) { high_top = top; *high_ip = ip; } } } }/* if (!*high_ip) *high_ip = *low_ip; else if (!*low_ip) *low_ip = *high_ip;*/ return intersects;}static voidnormalize_top(panel, scrolling_up)panel_handle panel;int scrolling_up;{ panel_item_handle low_ip, high_ip; register int top; int intersects; intersects = top_pair(panel, &low_ip, &high_ip); if (high_ip && low_ip) { top = high_ip->rect.r_top; if (intersects) top = low_ip->rect.r_top; } else if (low_ip) top = low_ip->rect.r_top; else top = 0; top -= panel->v_margin; if (top <= panel->v_margin) top = 0; panel->v_offset = top;}/* * Bottom aligned normalization methodology: * Like the above but with the bottoms of the rectangles used in the * calculations of position and the high ip determining the intersection. * low_ip * +-------+ * | | * high_ip +-------+ * +-------+ * | | <----intersects=TRUE *---------------------------------------------------- offset * | | * +-------+ * */static voidnormalize_bottom(panel, scrolling_up)panel_handle panel;int scrolling_up;{ register panel_item_handle ip; register int low_bottom = 0; register int high_bottom = panel->v_end; register int top, bottom; int target = panel->v_offset + view_height(panel); int intersects = FALSE; for (ip = panel->items; ip; ip = ip->next) { if (!hidden(ip)) { top = ip->rect.r_top; bottom = top + ip->rect.r_height; if (bottom >= target) { if (bottom < high_bottom) { high_bottom = bottom; intersects = (top < target); } } else { if (bottom > low_bottom) low_bottom = bottom; } } } bottom = low_bottom; if (!scrolling_up && intersects) bottom = high_bottom; top = bottom + panel->v_margin - view_height(panel); if (top <= panel->v_margin) top = 0; panel->v_offset = top;}staticleft_pair(panel, low_ip, high_ip)panel_handle panel;panel_item_handle *low_ip, *high_ip;{ register panel_item_handle ip; register int low_left = -1; register int high_left = panel->h_end; register int left; int target = panel->h_offset; int intersects = FALSE;/*fix for sb neg truncation: pin at 0:target = -1 => low_ip = null*/ if (target == 0) target = -1; *high_ip = NULL; *low_ip = NULL; for (ip = panel->items; ip; ip = ip->next) { if (!hidden(ip)) { left = ip->rect.r_left; if (left <= target) { if (left > low_left) { low_left = left; *low_ip = ip; intersects = (left + ip->rect.r_width > target); } } else { if (left < high_left) { high_left = left; *high_ip = ip; } } } }/* if (!*high_ip) *high_ip = *low_ip; else if (!*low_ip) *low_ip = *high_ip;*/ return intersects;}static voidnormalize_left(panel, scrolling_up)panel_handle panel;int scrolling_up;{ panel_item_handle low_ip, high_ip; register int left; int intersects; intersects = left_pair(panel, &low_ip, &high_ip); if (high_ip && low_ip) { left = high_ip->rect.r_left; if (intersects) left = low_ip->rect.r_left; } else if (low_ip) left = low_ip->rect.r_left; else left = 0; left -= panel->h_margin; if (left <= panel->h_margin) left = 0; panel->h_offset = left;}static voidnormalize_right(panel, scrolling_up)panel_handle panel;int scrolling_up;{ register panel_item_handle ip; register int low_right = 0; register int high_right = panel->h_end; register int left, right; int target = panel->h_offset + view_width(panel); int intersects; for (ip = panel->items; ip; ip = ip->next) { if (!hidden(ip)) { left = ip->rect.r_left; right = left + ip->rect.r_width; if (right >= target) { if (right < high_right) { high_right = right; intersects = (left < target); } } else { if (right > low_right) low_right = right; } } } right = low_right; if (!scrolling_up && intersects) right = high_right; left = right + panel->h_margin - view_width(panel); if (left <= panel->h_margin) left = 0; panel->h_offset = left;}/****************************************************************************//* paint_scrolled_panel *//* Redisplays scrolled panel with minimum repaint, shifting the portion of *//* the panel which is visible in both the old and new positions. *//****************************************************************************/staticpaint_scrolled_panel(panel, sb)register panel_handle panel;Scrollbar sb;{ register unsigned new_offset, old_offset; register int visible_end, delta; register int width, height, xsrc, ysrc, xdest, ydest; Scrollbar_setting direction; Rect rect; old_offset = (unsigned) scrollbar_get(sb, SCROLL_LAST_VIEW_START); new_offset = (unsigned) scrollbar_get(sb, SCROLL_VIEW_START); direction = (Scrollbar_setting) scrollbar_get(sb, SCROLL_DIRECTION); delta = new_offset > old_offset ? new_offset - old_offset : old_offset - new_offset; if (direction == SCROLL_VERTICAL) { visible_end = view_height(panel); width = BIG; height = visible_end; xsrc = 0; ysrc = delta; xdest = 0; ydest = delta;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -