/***************************************************************************/ /***************************************************************************/ /* */ /* (c) 1995-1999. The Regents of the University of California. All */ /* rights reserved. */ /* */ /* This work was produced at the University of California, Lawrence */ /* Livermore National Laboratory (UC LLNL) under contract no. */ /* W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy */ /* (DOE) and The Regents of the University of California (University) */ /* for the operation of UC LLNL. Copyright is reserved to the */ /* University for purposes of controlled dissemination, */ /* commercialization through formal licensing, or other disposition */ /* under terms of Contract 48; DOE policies, regulations and orders; */ /* and U.S. statutes. The rights of the Federal Government are */ /* reserved under Contract 48 subject to the restrictions agreed upon */ /* by the DOE and University. */ /* */ /* */ /* DISCLAIMER */ /* */ /* This software was prepared as an account of work sponsored by an */ /* agency of the United States Government. Neither the United States */ /* Government nor the University of California nor any of their */ /* employees, makes any warranty, express or implied, or assumes any */ /* liability or responsibility for the accuracy, completeness, or */ /* usefulness of any information, apparatus, product, or process */ /* disclosed, or represents that its specific commercial products, */ /* process, or service by trade name, trademark, manufacturer, or */ /* otherwise, does not necessarily constitute or imply its */ /* endorsement, recommendation, or favoring by the United States */ /* Government or the University of California. The views and opinions */ /* of the authors expressed herein do not necessarily state or reflect */ /* those of the United States Government or the University of */ /* California, and shall not be used for advertising or product */ /* endorsement purposes. */ /* */ /* Permission to use, copy, modify and distribute this software and its */ /* documentation for any non-commercial purpose, without fee, is */ /* hereby granted, provided that the above copyright notice and this */ /* permission notice appear in all copies of the software and */ /* supporting documentation, and that all UC LLNL identification in */ /* the user interface remain unchanged. The title to copyright LLNL */ /* XDIR shall at all times remain with The Regents of the University */ /* of California and users agree to preserve same. Users seeking the */ /* right to make derivative works with LLNL XDIR for commercial */ /* purposes may obtain a license from the Lawrence Livermore National */ /* Laboratory's Technology Transfer Office, P.O. Box 808, L-795, */ /* Livermore, CA 94550. */ /* */ /***************************************************************************/ /***************************************************************************/ #include #include #include "xdir.h" #define INTERVAL 50L static int pivot_x; static int pivot_y; static int corner_x; static int corner_y; static int upper_left_x; static int upper_left_y; static int lower_right_x; static int lower_right_y; static struct dirwin_st *toggle_dirwin; static XtIntervalId toggle_rect_timer_id; extern Display *display; extern Window root_window; extern GC gc_rect; extern XtAppContext app; void adjust_selection_states(); void set_toggle_rect_timer(); /* * point_in_drawing_area - Returns true if virtual point (x,y) is in the * drawing area's window. */ point_in_drawing_area(dirwin, x, y, above, below, to_left, to_right) struct dirwin_st *dirwin; int x; int y; int *above; int *below; int *to_left; int *to_right; { Window child; int x_da; int y_da; int x_point; int y_point; Dimension drawing_area_width; Dimension drawing_area_height; /* Get drawing area dimensions */ XtVaGetValues(dirwin->w_drawingArea, XmNwidth, &drawing_area_width, XmNheight, &drawing_area_height, NULL ); /* Get coordinates of drawing area's origin */ XTranslateCoordinates(display, XtWindow(dirwin->w_drawingArea), root_window, 0, 0, &x_da, &y_da, &child); /* Convert point into global coordinates */ XTranslateCoordinates(display, XtWindow(dirwin->w_drawingArea), root_window, actual_x(dirwin, x), actual_y(dirwin, y), &x_point, &y_point, &child); /* Is point in drawing area window? */ *to_left = x_point < x_da; *to_right = x_point >= (int)(x_da+drawing_area_width); *above = y_point < y_da; *below = y_point >= (int)(y_da+drawing_area_height); if (*to_left || *to_right || *above || *below) return False; else return True; } void init_toggle_rect(dirwin, x, y) struct dirwin_st *dirwin; int x; int y; { int i; /* Clear error flag */ raise_okflag(); /* Remember which dirwin */ toggle_dirwin = dirwin; /* First clear other hosts' selected directory entries */ if (!toggle_dirwin->has_selection) { clear_selected_entries(); toggle_dirwin->has_selection = True; } /* Draw rectangle */ pivot_x = x; pivot_y = y; corner_x = x; corner_y = y; XDrawRectangle(display, XtWindow(toggle_dirwin->w_drawingArea), gc_rect, actual_x(toggle_dirwin, x), actual_y(toggle_dirwin, y), 0, 0); /* Remember original selection states of entries */ for (i=0; inentries; i++) toggle_dirwin->entries[i].original_state = toggle_dirwin->entries[i].state; } void draw_toggle_rect() { upper_left_x = MIN(pivot_x, corner_x); upper_left_y = MIN(pivot_y, corner_y); lower_right_x = MAX(pivot_x, corner_x); lower_right_y = MAX(pivot_y, corner_y); XDrawRectangle(display, XtWindow(toggle_dirwin->w_drawingArea), gc_rect, actual_x(toggle_dirwin, upper_left_x), actual_y(toggle_dirwin, upper_left_y), lower_right_x-upper_left_x, lower_right_y-upper_left_y); } void move_toggle_rect(x, y) int x; int y; { int above; int below; int to_left; int to_right; int in_drawing_area; /* This is slow, so don't do it between erasing and redrawing rect */ in_drawing_area = point_in_drawing_area(toggle_dirwin, x, y, &above, &below, &to_left, &to_right); /* Erase previous rectangle */ draw_toggle_rect(); corner_x = x; corner_y = y; /* Scroll if necessary */ if (!in_drawing_area) { if (above) scroll_up(toggle_dirwin); else if (below) scroll_down(toggle_dirwin); if (to_left) scroll_left(toggle_dirwin); else if (to_right) scroll_right(toggle_dirwin); } /* Only directory entries in the toggle rectangle should be toggled */ adjust_selection_states(toggle_dirwin); /* Draw new rectangle */ draw_toggle_rect(); } /* * adjust_selection_states - Sets the "state" field of each directory entry * in the toggle rectangle to the opposite of * what it is in the field "original_state". */ void adjust_selection_states(dirwin) struct dirwin_st *dirwin; { int i; int need_to_toggle; int row; for (i=0; inentries; i++) { need_to_toggle = False; if (entry_in_toggle_rect(&dirwin->entries[i])) { if (dirwin->entries[i].state == dirwin->entries[i].original_state) need_to_toggle = True; } else { if (dirwin->entries[i].state != dirwin->entries[i].original_state) need_to_toggle = True; } if (need_to_toggle) { if (dirwin->entries[i].state == UNSELECTED) dirwin->entries[i].state = SELECTED; else dirwin->entries[i].state = UNSELECTED; row = dirwin->entries[i].indx%toggle_dirwin->nrows; if (row >= toggle_dirwin->first_visible_row && row < toggle_dirwin->first_visible_row +toggle_dirwin->nrows_visible) draw_entry(&dirwin->entries[i]); } } } /* * entry_in_toggle_rect - Returns True if the directory entry specified * by "einfo" is in the toggle rectangle. * */ entry_in_toggle_rect(einfo) struct entry_info *einfo; { int col; int row; int x; int y; switch (toggle_dirwin->layout) { case TABULAR: case ICONIC: col = einfo->indx/toggle_dirwin->nrows; row = einfo->indx%toggle_dirwin->nrows; x = HMARGIN+col*(toggle_dirwin->max_entry_width+HSPACING); y = row*(toggle_dirwin->entry_height+VSPACING); break; case TREE: x = HMARGIN+einfo->level*INDENT+CWIDTH+CMARGIN; y = einfo->indx*(toggle_dirwin->entry_height+VSPACING); break; case FULL_INFO: x = HMARGIN; y = einfo->indx*(toggle_dirwin->entry_height+VSPACING); break; } if (x+einfo->width < upper_left_x || x > lower_right_x || y+einfo->dirwin->entry_height < upper_left_y || y > lower_right_y) return False; else return True; } void remove_toggle_rect() { /* Erase previous rectangle */ draw_toggle_rect(); update_dir_controls(); } void cb_toggle_rect(client_data, id) XtPointer client_data; XtIntervalId *id; { Window root; Window child; int root_x; int root_y; int win_x; int win_y; unsigned int keys_buttons; if (XQueryPointer(display, XtWindow(toggle_dirwin->w_drawingArea), &root, &child, &root_x, &root_y, &win_x, &win_y, &keys_buttons)) move_toggle_rect(virtual_x(toggle_dirwin, win_x), virtual_y(toggle_dirwin, win_y)); set_toggle_rect_timer(); } void set_toggle_rect_timer() { toggle_rect_timer_id = XtAppAddTimeOut(app, INTERVAL, (XtTimerCallbackProc)cb_toggle_rect, NULL); } void unset_toggle_rect_timer() { XtRemoveTimeOut(toggle_rect_timer_id); }