/* * Table of Contents / Page list for xdvi * * Copyright (c) 1993, 1995 * MATSUURA Syun syun@fuka.info.waseda.ac.jp * HIRAHARA Atsushi hirahara@fuka.info.waseda.ac.jp * ONO Kouichi onono@fuka.info.waseda.ac.jp * All rights reserved. */ #include #include #include #include #include #include #include #include #include /* #include "xdvi.h" */ #include "xdvi-config.h" /* added by Masahito Yamaga */ #ifdef TOC /* added by Masahito Yamaga */ #include "toc.h" #ifdef MARKPAGE #include "markpage.h" #endif /* MARKPAGE */ #ifdef PAGENUM static int view_y; #else extern int pageno_correct; #endif /* PAGENUM */ static Widget list_widget, viewport=NULL; static char *toc[MAX_PAGE]; static int press_page_2 = -1; static int press_page_3 = -1; extern void keystroke(); extern Widget panel_widget; static int Get_Item_Number(); /* added by Masahito Yamaga */ static int get_Page_size() { int offset = 0; int min_page = 0; int max_page = 0; int min_pageno_len = 0; int max_pageno_len = 0; #ifdef PAGENUM int i; for (i = 0; i < total_pages; i++) { max_page = MAX(page_index[i].number, max_page); min_page = MIN(page_index[i].number, min_page); } #else min_page = pageno_correct - 1; max_page = min_page + total_pages; #endif /* PAGENUM */ if(min_page>=0) { offset = 0; /* plus symbol is hidden */ } else { offset = 1; /* offset for minus symbol */ min_page = - min_page; } for(min_pageno_len = offset; min_page>0; min_page /= 10, min_pageno_len++); if(max_page >= 0) { offset = 0; /* plus symbol is hidden */ } else { offset = 1; /* offset for minus symbol */ max_page = - max_page; } for(max_pageno_len = offset; max_page>0; max_page /= 10, max_pageno_len++); return MAX(min_pageno_len, max_pageno_len); /* Plus 1 for minus symbol */ } static int /* get TOC's width size */ get_TOC_size() { int fontwidth = 8; #ifdef TOOLKIT Widget w; XFontStruct *font; #ifdef XtNinternational XFontSet fs; Boolean i18n; #endif /* XtNinternational */ /* tricky :-< */ w = XtVaCreateWidget("list", listWidgetClass, top_level, NULL); XtVaGetValues(w, XtNfont, &font, #ifdef XtNinternational XtNfontSet, &fs, XtNinternational, &i18n, #endif /* XtNinternational */ NULL); XtDestroyWidget(w); fontwidth = font->max_bounds.width; #ifdef XtNinternational if (i18n) { XFontSetExtents *ext = XExtentsOfFontSet(fs); fontwidth = ext->max_ink_extent.width; } #endif /* XtNinternational */ #endif /* TOOLKIT */ /* Print format is " NN<" get_Page_size() is number of N */ #ifdef SMALL_PANEL #ifdef MARKPAGE return (get_Page_size()+4)*fontwidth+15; #else return (get_Page_size()+2)*fontwidth+15; #endif /* MARKPAGE */ #else /* !SMALL_PANEL */ #ifdef MARKPAGE return (get_Page_size()+4)*fontwidth+20; #else return (get_Page_size()+2)*fontwidth+20; #endif /* MARKPAGE */ #endif /* SMALL_PANEL */ } static void /* set TOC's string */ set_TOC() { int i = 0; char s[PAGENUMLEN]; for(i = 0; ilist_index, 1, (XEvent *)NULL); #else keystroke('g', item->list_index+pageno_correct, 1, (XEvent *)NULL); Redraw_TOC(); #endif /* PAGENUM */ } #ifdef MARKPAGE static void /* Called when Button-2 | 3 pressed */ Press_Mark_Page(w, event, button) Widget w; XEvent *event; int button; { int x = 0; switch(button) { /* Get item number */ case Button2: press_page_2 = x = Get_Item_Number(w, event->xbutton.y); break; case Button3: press_page_3 = x = Get_Item_Number(w, event->xbutton.y); break; } ReverseTheMarkOfPage(x); Redraw_TOC(); } static void /* Set or Reset TOC mark */ set_Drag_TOC(button, x) int button, x; { int i = 0; i = (button==Button2) ? press_page_2: press_page_3; if(i=x; i--) { if(button==Button2) { MarkPage(i); } else { UnmarkPage(i); } } } } static void /* Called when Button-2 | 3 released */ Release_Mark_Page(w, event, button) Widget w; XEvent *event; int button; { int x = 0; x = Get_Item_Number(w, event->xbutton.y); /* Get item number */ switch(button) { case Button2: if((press_page_2!=x) && (press_page_2!=-1)) set_Drag_TOC(button, x); press_page_2 = 0; break; case Button3: if((press_page_3!=x) && (press_page_3!=-1)) set_Drag_TOC(button, x); press_page_3 = 0; break; } Redraw_TOC(); } static void /* Called when mouse leaved the LIST-widget */ Leave_Mark_Page(w, event, button) Widget w; XEvent *event; int button; { press_page_2 = press_page_3 = -1; } #endif /* MARKPAGE */ static void /* TOC's event handler */ TOCs_Event_Handler(w, n, event) Widget w; int n; XEvent *event; { int i = 0; Dimension length; Arg arglist[10]; Widget y_bar; y_bar = XtNameToWidget(viewport, "vertical"); if (y_bar) { XtSetArg(arglist[i], XtNlength, &length); i++; XtGetValues(y_bar, arglist, i); } switch(event->type) { case ButtonPress: /* when TOC pressed */ switch(event->xbutton.button) { case Button2: Press_Mark_Page(w, event, Button2); break; case Button3: Press_Mark_Page(w, event, Button3); break; case Button4: if (y_bar) XtCallCallbacks(y_bar, XtNscrollProc, (XtPointer) ((int) -length)); break; case Button5: if (y_bar) XtCallCallbacks(y_bar, XtNscrollProc, (XtPointer) ((int) +length)); break; } break; case ButtonRelease: /* when TOC released */ switch(event->xbutton.button) { case Button2: Release_Mark_Page(w, event, Button2); break; case Button3: Release_Mark_Page(w, event, Button3); break; } break; case LeaveNotify: /* when TOC leaved */ Leave_Mark_Page(w, event); break; } } void Create_TOC(h) XtArgVal h; { int i = 0; char s[PAGENUMLEN]; static int height; static int width; if (!(height) || (int)h > 0) height = (int)h - 50; width = MAX(width, get_TOC_size()); if(total_pages>MAX_PAGE) total_pages = MAX_PAGE; set_TOC(); viewport = XtVaCreateWidget("viewport", viewportWidgetClass, panel_widget, XtNallowVert, True, XtNforceBars, True, #ifdef SMALL_PANEL XtNx, 64, #else XtNx, 78, #endif /* SMALL_PANEL */ XtNy, 20, XtNheight, height, XtNwidth, width, NULL); list_widget = XtVaCreateWidget("list", listWidgetClass, viewport, XtNlist, toc, XtNdefaultColumns, 1, XtNforceColumns, True, XtNx, 100, XtNy, 20, XtNheight, height, XtNwidth, width, XtNlongest, LONGESTPAGENUM, XtNverticalList, True, NULL); XtManageChild(list_widget); XtManageChild(viewport); XtAddCallback(list_widget, XtNcallback, SelectThisPage, (XtPointer)NULL); #ifdef PAGENUM XtAddCallback(viewport, XtNreportCallback, SendReportProc, (XtPointer)NULL); #endif /* PAGENUM */ #ifdef MARKPAGE XtAddEventHandler(list_widget, ButtonPressMask | ButtonReleaseMask | LeaveWindowMask, False, TOCs_Event_Handler, NULL); #endif /* MARKPAGE */ } static int Get_Item_Number(w, mouse_y) Widget w; int mouse_y; { int i = 0; int row_height = 0; int index = 0; Dimension row_space, internal_height; XFontStruct *font; #ifdef XtNinternational XFontSet fs; Boolean i18n; #endif /* XtNinternational */ Arg arglist[10]; XtSetArg(arglist[i], XtNfont, &font); i++; #ifdef XtNinternational XtSetArg(arglist[i], XtNfontSet, &fs); i++; XtSetArg(arglist[i], XtNinternational, &i18n); i++; #endif /* XtNinternational */ XtSetArg(arglist[i], XtNinternalHeight, &internal_height); i++; XtSetArg(arglist[i], XtNrowSpacing, &row_space); i++; XtGetValues(w, arglist, i); row_height = font->max_bounds.ascent +font->max_bounds.descent +(int)row_space; #ifdef XtNinternational if (i18n) { XFontSetExtents *ext = XExtentsOfFontSet(fs); row_height = ext->max_ink_extent.height + (int)row_space; } #endif /* XtNinternational */ index = (mouse_y-internal_height)/row_height; return index; } void Center_TOC(current_page, next_page) int current_page, next_page; { int i = 0; Position x, y; Dimension row_space, view_height, font_height; XFontStruct *font; #ifdef XtNinternational XFontSet fs; Boolean i18n; #endif /* XtNinternational */ Arg arglist[10]; XtSetArg(arglist[i], XtNfont, &font); i++; #ifdef XtNinternational XtSetArg(arglist[i], XtNfontSet, &fs); i++; XtSetArg(arglist[i], XtNinternational, &i18n); i++; #endif /* XtNinternational */ XtSetArg(arglist[i], XtNrowSpacing, &row_space); i++; XtGetValues(list_widget, arglist, i); font_height = (font->max_bounds.ascent +font->max_bounds.descent +row_space); #ifdef XtNinternational if (i18n) { XFontSetExtents *ext = XExtentsOfFontSet(fs); font_height = ext->max_ink_extent.height + row_space; } #endif /* XtNinternational */ y = font_height*next_page; i = 0; XtSetArg(arglist[i], XtNheight, &view_height); i++; XtSetArg(arglist[i], XtNx, &x); i++; XtGetValues(viewport, arglist, i); if(((next_page>current_page) && (y>=view_y+view_height-font_height+1)) || ((next_pageslider_y; } #endif /* TOC added by Masahito Yamaga */