/* Class : scrollable_statictext SuperClass : statictext Author : Cathy Waite Turing Institute Date : Mon Jan 28 12:23:11 GMT 1991 Funtionality : Can display and format several lines of text. The text is scrollable. */ #include #include "statictext.h" #define SCROLLGAP 4 int scroll_width = OLScrollW + SCROLLGAP; /* Compute area available for actual text, treaking into account the scroll bar */ int textarea_width() { return w - margin2 - scroll_width; } int boxarea_width() { return w - scroll_width; } /*********************************************************************** Scrolling Procedures ***********************************************************************/ /* Set the given line to be the first line displayed (i.e. */ /* display_to_line) and repaint the appropropriate lined */ /* Sets top line, without notify scrollbar, thus avoiding cyclic */ /* update messages. This is the version the scrollbar should use all */ /* other methods should use "set_top_line" */ void set_top_line(int new_top) { if (new_top == display_top_line) return; gexeca(/do_set_top_line,[new_top]); if (promoted(/@scroll)) Send changevalue(display_top_line) to /@scroll; } void do_set_top_line(int new_top) { int new_bottom, old_top, old_bottom; int line_height; if ((new_top >= 0) && (new_top <= total_display_lines)) { new_bottom = min(total_display_lines,max(0,new_top+max_display_lines-1)); if ((new_bottom < display_top_line) || (new_top > display_bottom_line)) { display_top_line = new_top; display_bottom_line = new_bottom; /*need to redisplay all lines */ gexeca(/paint_text_from_line,[display_top_line]); } else /* scrolling to a line already visible, use copyarea */ { line_height = fontheight(textfont)+line_gap; if (new_top < display_top_line) { rectpath(margin,ypos_from_line(new_bottom),textarea_width,(new_bottom-display_top_line+1)*line_height); copyarea(0,(new_top-display_top_line)*line_height); old_top = display_top_line; display_top_line = new_top; display_bottom_line = new_bottom; paint_text_from_line_to(display_top_line,old_top-1); } else { rectpath(margin,ypos_from_line(display_bottom_line),textarea_width,(display_bottom_line-max(0,new_top-1))*line_height); copyarea(0,(new_top-display_top_line)*line_height); display_top_line = new_top; old_bottom = display_bottom_line; display_bottom_line = new_bottom; paint_text_from_line(old_bottom+1); } } } } void scroll_up_line() { if (display_top_line > 0) set_top_line(display_top_line-1); } void scroll_down_line() { /* Don't allow to scroll past total_display_line - 1, so last line is visible */ if (display_top_line < total_display_lines) set_top_line(display_top_line+1); } void scroll_up_page() { set_top_line(max(display_top_line-max_display_lines+1,0)); } void scroll_down_page() { set_top_line(min(display_top_line+max_display_lines-1,total_display_lines)); } void scroll_to_top() { set_top_line(0); } void scroll_to_bottom() { set_top_line(max(0,total_display_lines)); } void create_scrollbar() { olscrollbar s; s = (olscrollbar)newmember(/olscrollbar); s.rename(/@scroll); s.setscript("","/Preview { [exch] /set_top_line @parent Send } def /Action /pop load def "); s.setposition(null,0,0,0); s.map(); } void OnInit() { super.OnInit(); if (!promoted(/@scroll)) create_scrollbar(); } /* When the display map changes, the number of display lines may ahve */ /* changed, so the scrollbar sohuld be told */ void compute_display_map_from(int line_no, int char_count, char *rest_of_text) { super.compute_display_map_from(line_no,char_count,rest_of_text); Send setparameters(display_top_line,max_display_lines,total_display_lines) to /@scroll; } void compute_display_map() { if (length(value) == 0) { display_top_line = 0; display_bottom_line = 0; total_display_lines = 0; display_map = [0,0]; Send setparameters(display_top_line,max_display_lines,total_display_lines) to /@scroll; return; } compute_display_map_from(0,0,value); } /* void set_scrollbar(boolean flag) { DEBUG(flag); if ( flag && (!promoted(/@scroll))) { create_scrollbar(); scroll_width = OLScrollW + SCROLLGAP; compute_display_map(); paint(); } else if (promoted(/@scroll)) { ((olscrollbar)find_object(/@scroll)).unmap(); unpromote(/@scroll); scroll_width = 0; compute_display_map(); paint(); } } */ float minwidth() { return(super.minwidth()+ scroll_width); }