📄 iconviewc.c
字号:
/* * $Id: IconViewC.C,v 1.6 2000/08/07 10:58:16 evgeny Exp $ * * Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include "HalAppC.h"#include "IconViewC.h"#include "VItemC.h"#include "VBoxC.h"#include "rsrc.h"#include "WArgList.h"#include <X11/keysym.h>#include <values.h>#include <math.h>#include <Xm/ScrollBar.h>#include <Xm/AtomMgr.h>#include <Xm/DragDrop.h>#define BLACK BlackPixel(halApp->display, DefaultScreen(halApp->display))#define WHITE WhitePixel(halApp->display, DefaultScreen(halApp->display))/*----------------------------------------------------------------------- * Method to check data pointer */inline BooleanIconViewC::DataValid(const IconDataC *data){ return (data && (data->view == this));}/*----------------------------------------------------------------------- * Constructor for IconViewC */IconViewC::IconViewC(VBoxC *vb) : ViewC(vb){ maxPmWd = maxPmHt = maxLabelWd = maxLabelHt = maxItemWd = maxItemHt = 0; daRows = daCols = 0; daWd = daHt = 0; focusHere = False; hlItem = NULL; flashItem = NULL; flashTimer = (XtIntervalId)NULL; dropItem = NULL; dragIcon = NULL; pickGC = NULL; scrollTimer = (XtIntervalId)NULL; pressItem = NULL; clickCount = 1; lastClickTime = 0; needPlaces = True;//// Get resources// Widget da = viewBox->ViewDA(); char *cl = "IconViewC"; regFgColor = get_color(cl, da, "foreground", BLACK); regBgColor = get_color(cl, da, "background", WHITE); invFgColor = get_color(cl, da, "selectedForeground", regBgColor); invBgColor = get_color(cl, da, "selectedBackground", regFgColor); hlColor = get_color(cl, da, "highlightColor", regFgColor); dropColor = get_color(cl, da, "validDropColor", hlColor); hlThick = get_int (cl, da, XmNhighlightThickness); xSpacing = get_int (cl, da, "horizSpacing"); ySpacing = get_int (cl, da, "vertSpacing"); labelOffset = get_int (cl, da, "labelOffset"); labelSpacing = get_int (cl, da, "labelSpacing"); itemMarginWd = get_int (cl, da, "itemMarginWidth"); itemMarginHt = get_int (cl, da, "itemMarginHeight"); fontList = viewBox->FontList(); font = viewBox->Font();//// Get keyboard focus policy// unsigned char focusPolicy; Widget shell = XtParent(vb->ViewDA()); while ( !XtIsShell(shell) ) shell = XtParent(shell); XtVaGetValues(shell, XmNkeyboardFocusPolicy, &focusPolicy, NULL); if ( focusPolicy == XmEXPLICIT ) {//// Add event handler for keyboard focus change// XtAddEventHandler(vb->ViewDA(), FocusChangeMask, False, (XtEventHandler)HandleFocusChange, (XtPointer)this); } else { // XmPOINTER XtAddEventHandler(vb->ViewDA(), EnterWindowMask|LeaveWindowMask, False, (XtEventHandler)HandleFocusChange, (XtPointer)this); XtAddEventHandler(vb->ViewDA(), PointerMotionMask|PointerMotionHintMask, False, (XtEventHandler)HandlePointerMotion, (XtPointer)this); }} // End Constructor/*----------------------------------------------------------------------- * Destructor for IconViewC */IconViewC::~IconViewC(){//// Free pixmaps// unsigned count = pixmapFileDict.size(); int i; for (i=0; i<count; i++) { PixmapC *pm = pixmapFileDict[i]->val; delete pm; } count = pixmapDataDict.size(); for (i=0; i<count; i++) { PixmapC *pm = pixmapDataDict[i]->val; delete pm; }//// Delete data// count = dataDict.size(); for (i=0; i<count; i++) { delete dataDict[i]->val; delete dataDict[i]; } if ( halApp->xRunning ) { if ( pickGC ) XtReleaseGC(halApp->appShell, pickGC); }} // End Destructor/*----------------------------------------------------------------------- * Display this view */voidIconViewC::Show(){ shown = True;//// Add any items that aren't yet added// VItemListC& items = viewBox->Items(); unsigned count = items.size(); for (int i=0; i<count; i++) { VItemC *item = items[i];//// Look first at the view data, then in the dictionary// IconDataC *data = dataDict.definitionOf(item); if ( data ) { item->SetViewData(data); //..data->GetLabelSize(font, labelSpacing); //..UpdateMaxSize(*data); } else { _AddItem(*item); } } // End for each item in view needPlaces = True;//// Set the GC values// XtGCMask valMask = GCClipMask | GCFillStyle | GCFunction | GCGraphicsExposures | GCLineStyle | GCLineWidth | GCPlaneMask | GCForeground; XGCValues vals; vals.clip_mask = None; vals.fill_style = FillSolid; vals.function = GXcopy; vals.graphics_exposures = TRUE; vals.line_style = LineSolid; vals.line_width = 0; vals.plane_mask = AllPlanes; vals.foreground = regFgColor; if ( viewBox->GoodFont() ) { valMask |= GCFont; vals.font = font->fid; } XChangeGC(halApp->display, viewBox->ViewGC(), valMask, &vals);//// Create a GC for the rubberband rectangle if necessary// if ( !pickGC ) { Pixel fg, bg; XtVaGetValues(viewBox->ViewDA(), XmNforeground, &fg, XmNbackground, &bg, NULL); XGCValues pickVals; pickVals.foreground = fg ^ bg; pickVals.function = GXxor; pickGC = XtGetGC(viewBox->ViewDA(), GCForeground|GCFunction, &pickVals); } Redraw();} // End Show/*----------------------------------------------------------------------- * Remove this view */voidIconViewC::Hide(){//// Clear view data// VItemListC& items = viewBox->Items(); unsigned count = items.size(); for (int i=0; i<count; i++) { //cout <<"Clearing data for item " <<hex <<(int)items[i] <<dec NL; items[i]->SetViewData(NULL); } shown = False;} // End Hide/*----------------------------------------------------------------------- * Calculate positions */voidIconViewC::PlaceItems(){ fontList = viewBox->FontList(); font = viewBox->Font(); maxPmWd = maxPmHt = maxLabelWd = maxLabelHt = maxItemWd = maxItemHt = 0;//// Loop through items, and get the max pixmap and label sizes.// VItemListC& visItems = viewBox->VisItems(); unsigned count = visItems.size(); int i; for (i=0; i<count; i++) { VItemC *item = visItems[i]; IconDataC *data = (IconDataC *)item->ViewData(); if ( !DataValid(data) ) continue; if ( fontList ) data->GetLabelSize(fontList, labelSpacing); else data->GetLabelSize(font, labelSpacing); if ( data->pixmap ) { if ( data->pixmap->wd > maxPmWd ) maxPmWd = data->pixmap->wd; if ( data->pixmap->ht > maxPmHt ) maxPmHt = data->pixmap->ht; } if ( data->labelWd > maxLabelWd ) maxLabelWd = data->labelWd; if ( data->labelHt > maxLabelHt ) maxLabelHt = data->labelHt; } // End for each item//// Now get max overall size// UpdateMaxItemWd(); UpdateMaxItemHt();//// Get width// daWd = viewBox->DAWidth();//// Figure out how many icons will fit across// if ( maxItemWd > 0 || xSpacing > 0 ) { daCols = daWd / (int)(maxItemWd + xSpacing); if ( daCols < 1 ) daCols = 1; } else { daCols = 1; }//// Figure out how many rows are needed// daRows = (count / daCols); if ( count % daCols ) daRows++;//// Figure out how much space is needed for the rows// daHt = (daRows * maxItemHt) + ((daRows-1) * ySpacing);//// Loop through the items and set their bounds// int row = 0; int col = 0; int x = 0; int y = 0; for (i=0; i<count; i++) { VItemC *item = visItems[i]; IconDataC *data = (IconDataC *)item->ViewData(); if ( !DataValid(data) ) continue; data->bounds.Set(x, y, maxItemWd, maxItemHt); data->row = row; data->col = col;//// Update next position// x += maxItemWd + xSpacing;//// Wrap at end of row// if ( ++col >= daCols ) { y += maxItemHt + ySpacing; x = 0; col = 0; row++; } } // End for each visible item needPlaces = False;} // End PlaceItems/*----------------------------------------------------------------------- * Return size */voidIconViewC::GetSize(int *wd, int *ht){ *wd = daWd; *ht = daHt;}/*----------------------------------------------------------------------- * Public method to add a new item to this view box */voidIconViewC::AddItem(VItemC& item){ if ( !viewBox->Realized() ) return;//// Add the item// _AddItem(item); viewBox->Changed(True);} // End AddItem/*----------------------------------------------------------------------- * Add new items to this view */voidIconViewC::AddItems(const VItemListC& list){ if ( !viewBox->Realized() ) return;//// Add items// unsigned count = list.size(); for (int i=0; i<count; i++) _AddItem(*list[i]); viewBox->Changed(True);} // End AddItems/*----------------------------------------------------------------------- * Private method to add a new item to this view box */voidIconViewC::_AddItem(VItemC& item){//// Create a new icon data structure and add it to the dictionary// IconDataC *data = new IconDataC(item, this); //cout <<"Created data " <<hex <<(int)data <<" for item " // <<(int)&item SP (int)data->item <<dec NL; dataDict.add(&item, data); item.SetViewData(data);//// Load the information about the pixmap and name for this item// /*..if ( viewBox->Realized() )..*/ GetPixmap(*data); //..data->GetLabelSize(font, labelSpacing); //..if ( viewBox->VisItems().includes(&item) ) UpdateMaxSize(*data); needPlaces = True;} // End _AddItem/*----------------------------------------------------------------------- * Redraw the items in this view */voidIconViewC::Redraw(){ Draw(viewBox->VisRect());}/*----------------------------------------------------------------------- * Redraw the items in this view */voidIconViewC::Draw(RectC& area){ if ( !viewBox->Realized() ) return; if ( needPlaces ) { PlaceItems(); viewBox->UpdateScrollBars(); }//// See how many items are visible// VItemListC& visItems = viewBox->VisItems(); unsigned count = visItems.size();//// Highlight the first one if there is none highlighted// if ( !hlItem || !visItems.includes(hlItem) ) hlItem = count ? visItems[0] : (VItemC*)NULL;//// Scroll the area// RectC sarea = area; sarea.xmin += viewBox->HScrollValue(); sarea.xmax += viewBox->HScrollValue(); sarea.ymin += viewBox->VScrollValue(); sarea.ymax += viewBox->VScrollValue(); GC gc = viewBox->ViewGC(); Window window = viewBox->ViewPm();//// Clear the drawing area// XSetForeground(halApp->display, gc, regBgColor); XFillRectangle(halApp->display, window, gc, area.xmin, area.ymin, area.wd, area.ht);//// Loop through item list// for (int i=0; i<count; i++) { VItemC *item = visItems[i]; IconDataC *data = (IconDataC *)item->ViewData(); if ( !DataValid(data) ) continue;//// Only draw this icon if it is at least partially visible// if ( sarea.Overlaps(data->bounds) ) DrawItem(*item, *data, AS_IS, window); } // End for each visible icon XCopyArea(halApp->display, window, viewBox->ViewWin(), gc, 0, 0, viewBox->DAWidth(), viewBox->DAHeight(), 0, 0);} // End Draw/*----------------------------------------------------------------------- * Public method to redraw the specified item */voidIconViewC::RedrawItem(const VItemC& item){ if ( !viewBox->Realized() ) return;//// Get icon data// IconDataC *data = (IconDataC *)item.ViewData(); if ( !DataValid(data) ) return;//// Redraw if item not clipped out// RectC sarea = viewBox->VisRect(); sarea.xmin += viewBox->HScrollValue(); sarea.xmax += viewBox->HScrollValue(); sarea.ymin += viewBox->VScrollValue(); sarea.ymax += viewBox->VScrollValue(); if ( data && sarea.Overlaps(data->bounds) ) DrawItem(item, *data, AS_IS);} // End RedrawItemvoidIconViewC::DrawItem(const VItemC& item, const IconDataC& data){ DrawItem(item, data, AS_IS);}voidIconViewC::DrawItem(const VItemC& item, VItemDrawModeT mode){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -