📄 iconviewc.c
字号:
IconDataC *data = (IconDataC *)item.ViewData(); if ( DataValid(data) ) DrawItem(item, *data, mode);}/*----------------------------------------------------------------------- * Find the item that contains the given coordinate */VItemC*IconViewC::PickItem(int x, int y){//// Set up a rectangle around the point in case we are in the space between// two items.// RectC rect(x-xSpacing, y-ySpacing, xSpacing*2, ySpacing*2); VItemListC list; PickItems(rect, list); VItemC *item = NULL;//// If there is more than 1 item, pick the closest// if ( list.size() == 1 ) item = list[0]; else if ( list.size() > 1 ) { int minDist = MAXINT; unsigned count = list.size(); for (int i=0; i<count; i++) { VItemC *li = list[i]; IconDataC *data = (IconDataC *)li->ViewData(); if ( data->bounds.Inside(x, y) ) { item = li; i = count; } else { int midX = data->bounds.xmin + (data->bounds.wd/2); int midY = data->bounds.ymin + (data->bounds.ht/2); int dx = x - midX; int dy = y - midY; dx *= dx; dy *= dy; int dist = (int)sqrt((double)(dx + dy)); if ( dist <= minDist ) { minDist = dist; item = li; } } } // End for each picked item } // End if more than one item picked return item;} // End PickItem/*----------------------------------------------------------------------- * Return the items in the pick rect */voidIconViewC::PickItems(RectC &pickRect, VItemListC& list){ VItemListC& visItems = viewBox->VisItems(); unsigned count = visItems.size(); for (int i=0; i<count; i++) { VItemC *item = visItems[i]; IconDataC *data = (IconDataC *)item->ViewData(); if ( !DataValid(data) ) continue;//// See if the item area overlaps the pick rectangle// if ( data->bounds.Overlaps(pickRect) ) list.append(item); } // End for each visible item} // End PickItems/*----------------------------------------------------------------------- * Change the visibility of an item */voidIconViewC::ChangeItemVis(const VItemC&){ needPlaces = True; viewBox->Changed(True);} // End ChangeItemVis/*----------------------------------------------------------------------- * Change the visibility of unknown items */voidIconViewC::ChangeItemVis(){ needPlaces = True; viewBox->Changed(True);} // End ChangeItemVis/*----------------------------------------------------------------------- * Flash an item */voidIconViewC::FlashItem(const VItemC *item){//// If an item is already flashing, stop it// if ( flashTimer ) { XtRemoveTimeOut(flashTimer); RedrawItem(*flashItem); }//// Make sure the item is visible// ScrollToItem(*item);//// Start a time out proc to flash the item a few times// flashItem = (VItemC *)item; flashCount = viewBox->FindBlinkCount(); flashOn = viewBox->SelItems().includes(item); flashTimer = XtAppAddTimeOut(halApp->context, viewBox->FindBlinkInterval(), (XtTimerCallbackProc)FlashProc, (XtPointer)this);} // End FlashItem/*----------------------------------------------------------------------- * Scroll the view window so the specified item is visible */voidIconViewC::ScrollToItem(const VItemC& item){ IconDataC *data = (IconDataC *)item.ViewData(); if ( DataValid(data) ) ScrollToItem(data);}voidIconViewC::ScrollToItem(const IconDataC *data){ if ( !data ) return; int ymax = viewBox->VisRect().ymax + viewBox->VScrollValue(); int ymin = viewBox->VisRect().ymin + viewBox->VScrollValue(); if ( data->bounds.ymax > ymax || viewBox->VisRect().ht < maxItemHt ) {//// It is off the bottom, so position the bottom of the scroll bar.// int val, size, inc, pinc, max; XmScrollBarGetValues(viewBox->VScrollBar(), &val, &size, &inc, &pinc); XtVaGetValues(viewBox->VScrollBar(), XmNmaximum, &max, NULL); val = data->bounds.ymax + ySpacing; if ( val > max ) val = max; val -= size; XmScrollBarSetValues(viewBox->VScrollBar(), val, size, inc, pinc, /*notify*/True); } else if ( data->bounds.ymin < ymin ) {//// It is off the top, so position the top of the scroll bar.// int val, size, inc, pinc, min; XmScrollBarGetValues(viewBox->VScrollBar(), &val, &size, &inc, &pinc); XtVaGetValues(viewBox->VScrollBar(), XmNminimum, &min, NULL); val = data->bounds.ymin - ySpacing; if ( val < min ) val = min; XmScrollBarSetValues(viewBox->VScrollBar(), val, size, inc, pinc, /*notify*/True); }} // End ScrollToItem/*----------------------------------------------------------------------- * Timer proc used to flash an item */voidIconViewC::FlashProc(IconViewC *This, XtIntervalId*){ if ( This->flashCount == 0 ) { This->RedrawItem(*This->flashItem); This->flashItem = NULL; This->flashTimer = (XtIntervalId)NULL; return; }//// Flip the state of the blinking item// if ( This->flashOn ) This->DrawItem(*This->flashItem, NORMAL); else This->DrawItem(*This->flashItem, INVERT); This->flashOn = !This->flashOn; This->flashCount--;//// Add this timeout again// This->flashTimer = XtAppAddTimeOut(halApp->context, This->viewBox->FindBlinkInterval(), (XtTimerCallbackProc)FlashProc, (XtPointer)This);} // End FlashProc/*----------------------------------------------------------------------- * Draw a highlight border around an item using the given color */voidIconViewC::DrawHighlight(const VItemC *item, Pixel color){ if ( !item ) return; IconDataC *data = (IconDataC *)item->ViewData(); if ( DataValid(data) ) DrawHighlight(data, color);}voidIconViewC::DrawHighlight(const IconDataC *data, Pixel color, Drawable drawto){ if ( !data ) return; XRectangle rects[4]; XRectangle *rect = rects; int xoff = viewBox->HScrollValue(); int yoff = viewBox->VScrollValue(); rect->x = data->bounds.xmin - xoff; rect->y = data->bounds.ymin - yoff; rect->width = data->bounds.wd; rect->height = hlThick; rect++; rect->x = data->bounds.xmin - xoff; rect->y = data->bounds.ymin - yoff; rect->width = hlThick; rect->height = data->bounds.ht; rect++; rect->x = data->bounds.xmax - hlThick + 1 - xoff; rect->y = data->bounds.ymin - yoff; rect->width = hlThick; rect->height = data->bounds.ht; rect++; rect->x = data->bounds.xmin - xoff; rect->y = data->bounds.ymax - hlThick + 1 - yoff; rect->width = data->bounds.wd; rect->height = hlThick; GC gc = viewBox->ViewGC(); XSetForeground(halApp->display, gc, color);//// If drawto is NULL, draw to both the offscreen pixmap and the visible window// Drawable dst1 = drawto; Drawable dst2 = (Drawable)NULL; if ( !dst1 ) { dst1 = viewBox->ViewWin(); dst2 = viewBox->ViewPm(); } XFillRectangles(halApp->display, dst1, gc, rects, 4); if ( dst2 ) XFillRectangles(halApp->display, dst2, gc, rects, 4);} // End DrawHighlight/*----------------------------------------------------------------------- * Handle a keyboard focus change event in the area */voidIconViewC::HandleFocusChange(Widget, IconViewC *This, XEvent *ev, Boolean *){ if ( !This->shown ) return; switch (ev->type) { case (FocusIn): case (EnterNotify): This->focusHere = True; This->DrawHighlight(This->hlItem, This->hlColor); break; case (FocusOut): case (LeaveNotify): This->focusHere = False; This->DrawHighlight(This->hlItem, This->regBgColor); break; default: break; }} // End HandleFocusChange/*----------------------------------------------------------------------- * Handle an input event */voidIconViewC::HandleKeyPress(XKeyEvent *ev){ if ( !focusHere || !hlItem ) return; IconDataC *data = (IconDataC *)hlItem->ViewData(); if ( !DataValid(data) ) return; KeySym keysym; Modifiers state; XtTranslateKey(halApp->display, ev->keycode, ev->state, &state, &keysym); VItemListC& visItems = viewBox->VisItems(); unsigned size = visItems.size(); VItemC *item; switch (keysym) { case (XK_Home): HighlightItem(visItems[0]); break; case (XK_End): HighlightItem(visItems[size-1]); break; case (XK_Left): if ( ev->state & ControlMask ) { item = visItems[data->row * daCols]; HighlightItem(item); } else if ( data->col > 0 ) { item = visItems[data->row * daCols + data->col - 1]; HighlightItem(item); } break; case (XK_Right): if ( ev->state & ControlMask ) { int index = (data->row+1) * daCols - 1; if ( index >= size ) index = size-1; HighlightItem(visItems[index]); } else if ( data->col < (daCols-1) ) { int index = data->row * daCols + data->col + 1; if ( index < size ) { HighlightItem(visItems[index]); } } break; case (XK_Up): if ( ev->state & ControlMask ) { item = visItems[data->col]; HighlightItem(item); } else if ( data->row > 0 ) { item = visItems[(data->row-1) * daCols + data->col]; HighlightItem(item); } break; case (XK_Down): if ( ev->state & ControlMask ) { int index = (daRows-1) * daCols + data->col; if ( index >= size ) index -= daCols; HighlightItem(visItems[index]); } else if ( data->row < (daRows-1) ) { int index = (data->row+1) * daCols + data->col; if ( index < size ) { HighlightItem(visItems[index]); } } break;#if 0 case (XK_Page_Up): { char *parms = "0"; XtCallActionProc(viewBox->VScrollBar(), "PageUpOrLeft", (XEvent*)ev, &parms, 1); } break; case (XK_Page_Down): { char *parms = "0"; XtCallActionProc(viewBox->VScrollBar(), "PageDownOrRight", (XEvent*)ev, &parms, 1); } break;#endif case (XK_space): if ( ev->state & (ShiftMask|ControlMask) ) viewBox->ToggleItem(*hlItem); else viewBox->SelectItemOnly(*hlItem); break; } // End switch keysym} // End HandleKeyPress/*----------------------------------------------------------------------- * Handle press of mouse button 1 */voidIconViewC::HandleButton1Press(XButtonEvent *be){//// There is a chance that several different selections/deselections will take// place. Wait for the button release to really do them.// viewBox->PartialSelect(True);//// See if this is part of a multiple click// unsigned long elapsed = be->time - lastClickTime; if ( elapsed <= XtGetMultiClickTime(halApp->display) ) clickCount++; else clickCount = 1; lastClickTime = be->time;//// Translate the position by the scroll factors// pickX = be->x + viewBox->HScrollValue(); pickY = be->y + viewBox->VScrollValue();//// Initialize the rubberband rectangle// pickRect.Set(pickX, pickY, 1, 1);//// Pick and highlight press item// pickList.removeAll(); pressItem = PickItem(pickX, pickY); pickDrawMode = INVERT; pickState = be->state; if ( (pickState & ControlMask) == ControlMask ) { if ( pressItem && viewBox->SelItems().includes(pressItem) ) pickDrawMode = NORMAL; } else if ( (pickState & ShiftMask) == ShiftMask ) { ; } else if ( clickCount == 1 ) { viewBox->DeselectAllItems(); if ( pressItem ) DrawItem(*pressItem, pickDrawMode); } if ( pressItem ) {// DrawItem(*pressItem, pickDrawMode); pickList.add(pressItem); HighlightItem(pressItem); } XDrawRectangle(halApp->display, viewBox->ViewWin(), pickGC, pickRect.xmin - viewBox->HScrollValue(), pickRect.ymin - viewBox->VScrollValue(), pickRect.wd, pickRect.ht);} // End HandleButton1Press/*----------------------------------------------------------------------- * Handle release of mouse button 1 */voidIconViewC::HandleButton1Release(XButtonEvent *be){ if ( scrollTimer ) XtRemoveTimeOut(scrollTimer);//// Clear the current rectangle// XDrawRectangle(halApp->display, viewBox->ViewWin(), pickGC, pickRect.xmin - viewBox->HScrollValue(), pickRect.ymin - viewBox->VScrollValue(), pickRect.wd, pickRect.ht);//// Get the list of items in the rectangle// PickItems(pickRect, pickList);//// Perform single or double click actions. If the single click fails,// reset the lastClickTime so we don't get a double click// if ( clickCount == 1 ) HandleSingleClick(); else if ( clickCount == 2 ) HandleDoubleClick(be);//// Now finish processing any selections that were queued up.// viewBox->PartialSelect(False);} // End HandleButton1Release/*----------------------------------------------------------------------- * Handle a single click event in the area. */voidIconViewC::HandleSingleClick(){//// If there isn't exactly one item selected, the the lastClickTime to 0 so// we don't get a double click// if ( pickList.size() != 1 ) lastClickTime = 0;//// If no items are selected, return// if ( pickList.size() < 1 ) return;//// Update the selection// if ( (pickState & ShiftMask) == ShiftMask ) viewBox->SelectItems(pickList); else if ( (pickState & ControlMask) == ControlMask ) { if ( pickDrawMode == INVERT ) // Selecting viewBox->SelectItems(pickList); else viewBox->DeselectItems(pickList); } else viewBox->SelectItemsOnly(pickList);} // End HandleSingleClick/*----------------------------------------------------------------------- * Handle a double click event in the area */voidIconViewC::HandleDoubleClick(XButtonEvent *be){ if ( !pressItem ) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -