📄 fieldviewc.c
字号:
if ( dst2 ) XFillRectangle(halApp->display, dst2, gc, x, y, sepThick+1, ht);//// Invert part of separator if item is selected// if ( invert ) { XSetForeground(halApp->display, gc, invFgColor); XDrawLine(halApp->display, dst1, gc, x, y+hlThick, x, data.bounds.ymax - viewBox->VScrollValue() - hlThick); XFillRectangle(halApp->display, dst1, gc, x, y+hlThick, sepThick+1, data.bounds.ht - hlThick*2); if ( dst2 ) { XDrawLine(halApp->display, dst2, gc, x, y+hlThick, x, data.bounds.ymax - viewBox->VScrollValue() - hlThick); XFillRectangle(halApp->display, dst2, gc, x, y+hlThick, sepThick+1, data.bounds.ht - hlThick*2); } } } // End sepThick > 1//// Move to next column// x += sepThick; } // End for each column} // End DrawItemSeparators/*----------------------------------------------------------------------- * Public method to redraw the specified item */voidFieldViewC::RedrawItem(const VItemC& item){ if ( !viewBox->Realized() ) return;//// Get icon data// ItemDataC *data = (ItemDataC *)item.ViewData(); if ( DataValid(data) ) RedrawItem(*data);}voidFieldViewC::RedrawItem(ItemDataC& data){ if ( !viewBox->Realized() ) return;//// Redraw if item not clipped out// RectC drawBounds(data.bounds.xmin, data.bounds.ymin, data.bounds.wd, data.bounds.ht+ySpacing); RectC sarea = viewBox->VisRect(); sarea.xmin += viewBox->HScrollValue(); sarea.xmax += viewBox->HScrollValue(); sarea.ymin += viewBox->VScrollValue(); sarea.ymax += viewBox->VScrollValue(); if ( sarea.Overlaps(drawBounds) ) DrawItem(data, AS_IS);} // End RedrawItemvoidFieldViewC::DrawItem(const ItemDataC& data){ DrawItem(data, AS_IS);}voidFieldViewC::DrawItem(const VItemC& item, VItemDrawModeT mode){ ItemDataC *data = (ItemDataC *)item.ViewData(); if ( DataValid(data) ) DrawItem(*data, mode);}/*----------------------------------------------------------------------- * Find the item that contains the given coordinate */VItemC*FieldViewC::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, y-ySpacing, 1, ySpacing*2); VItemListC list; PickItems(rect, list); VItemC *item = NULL;//// If there are two items, pick the closest// if ( list.size() == 1 ) item = list[0]; else if ( list.size() > 1 ) { ItemDataC *data0 = (ItemDataC *)list[0]->ViewData(); ItemDataC *data1 = (ItemDataC *)list[1]->ViewData(); if ( y <= data0->bounds.ymax ) item = list[0]; else if ( y >= data1->bounds.ymin ) item = list[1]; else { int dist0 = y - data0->bounds.ymax; int dist1 = data0->bounds.ymin - y; if ( dist0 < dist1 ) item = list[0]; else item = list[1]; } } return item;} // End PickItem/*----------------------------------------------------------------------- * Return the items in the pick rect */voidFieldViewC::PickItems(RectC& pickRect, VItemListC& list){ VItemListC& visItems = viewBox->VisItems(); unsigned count = visItems.size(); for (int i=0; i<count; i++) { VItemC *item = visItems[i]; ItemDataC *data = (ItemDataC *)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 */voidFieldViewC::ChangeItemVis(const VItemC&){ needPlaces = True; viewBox->Changed(True);} // End ChangeItemVis/*----------------------------------------------------------------------- * Change the visibility of unknown items */voidFieldViewC::ChangeItemVis(){ needPlaces = True; viewBox->Changed(True);} // End ChangeItemVis/*----------------------------------------------------------------------- * Flash an item */voidFieldViewC::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 */voidFieldViewC::ScrollToItem(const VItemC& item){ ItemDataC *data = (ItemDataC *)item.ViewData(); if ( DataValid(data) ) ScrollToItem(data);}voidFieldViewC::ScrollToItem(const ItemDataC *data){ if ( !data || !viewBox->Realized() ) return; int ymax = viewBox->VisRect().ymax + viewBox->VScrollValue(); int ymin = viewBox->VisRect().ymin + viewBox->VScrollValue(); if ( data->bounds.ymax > ymax || viewBox->VisRect().ht < data->itemHt ) {//// 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 */voidFieldViewC::FlashProc(FieldViewC *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/*----------------------------------------------------------------------- * Handle a keyboard focus change event in the area */voidFieldViewC::HandleFocusChange(Widget, FieldViewC *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; }} // End HandleFocusChange/*----------------------------------------------------------------------- * Handle an input event */voidFieldViewC::HandleKeyPress(XKeyEvent *ev){ if ( !focusHere || !hlItem ) return; KeySym keysym; Modifiers state; XtTranslateKey(halApp->display, ev->keycode, ev->state, &state, &keysym); VItemListC& visItems = viewBox->VisItems(); int index = visItems.indexOf(hlItem); unsigned size = visItems.size(); switch (keysym) { case (XK_Home): HighlightItem(visItems[0]); break; case (XK_End): HighlightItem(visItems[size-1]); break; case (XK_Up): if ( ev->state & ControlMask ) HighlightItem(visItems[0]); else if ( index > 0 ) HighlightItem(visItems[index-1]); break; case (XK_Down): if ( ev->state & ControlMask ) HighlightItem(visItems[size-1]); else if ( index < size-1 ) HighlightItem(visItems[index+1]); 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 */voidFieldViewC::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 pick rectangle. If this is a shift selection, extend the// rectangle to include the nearest existing selection.// Boolean useRectToPick = False; pickDrawMode = INVERT; pickState = be->state; if ( (pickState & ShiftMask) == ShiftMask ) { VItemListC& selItems = viewBox->SelItems(); unsigned selCount = selItems.size(); if ( selCount == 0 ) { pickRect.Set(0, pickY, viewBox->DAWidth(), 1); } else {//// Find the closest item// int minDist = MAXINT; VItemC *minItem = NULL; for (int i=0; i<selCount; i++) { VItemC *item = selItems[i]; ItemDataC *data = (ItemDataC *)item->ViewData(); int dist1 = data->bounds.ymin - pickY; int dist2 = data->bounds.ymax - pickY; if ( dist1 < 0 ) dist1 = -dist1; if ( dist2 < 0 ) dist2 = -dist2; int dist = MIN(dist1, dist2); if ( dist < minDist ) { minDist = dist; minItem = item; } } // End for each selected item//// Extend the pick rect to include the nearest item// if ( !minItem ) { pickRect.Set(0, pickY, viewBox->DAWidth(), 1); } else { ItemDataC *data = (ItemDataC *)minItem->ViewData(); if ( pickY < data->bounds.ymin ) { pickRect.Set(0, pickY, viewBox->DAWidth(), data->bounds.ymax - pickY); pickY = pickRect.ymax; useRectToPick = True; } else if ( pickY > data->bounds.ymax ) { pickRect.Set(0, data->bounds.ymin, viewBox->DAWidth(), pickY - data->bounds.ymin); pickY = pickRect.ymin; useRectToPick = True; } else pickRect.Set(0, pickY, viewBox->DAWidth(), 1); } } // End if there are any selected items } // End if this is a shift selection else if ( (pickState & ControlMask) == ControlMask ) {//// If this press is over a selected item, we will be turning selections off// VItemC *item = PickItem(pickX, pickY); if ( item && viewBox->SelItems().includes(item) ) pickDrawMode = NORMAL; pickRect.Set(0, pickY, viewBox->DAWidth(), 1); } else { if ( clickCount == 1 ) viewBox->DeselectAllItems(); pickRect.Set(0, pickY, viewBox->DAWidth(), 1); }//// Pick and highlight the new items// pickList.removeAll(); if ( useRectToPick ) { PickItems(pickRect, pickList); pressItem = NULL; } else { pressItem = PickItem(pickX, pickY); if ( pressItem ) { pickList.add(pressItem); HighlightItem(pressItem); } } if ( clickCount == 1 ) { unsigned count = pickList.size(); for (int i=0; i<count; i++) DrawItem(*pickList[i], pickDrawMode); }} // End HandleButton1Press/*----------------------------------------------------------------------- * Handle release of mouse button 1 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -