This is ScrList.c in view mode; [Download] [Up]
/***************************************************************************** ScrolledList.c This file contains the C code for the ScrolledList widget, which acts as a vertically scrolling list of text, from which, items can be selected. ******************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * * Small fix by Ettore Perazzoli (ettore@comm2000.it), search for [EP]. */ #include <stdio.h> #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/StringDefs.h> #include <X11/IntrinsicP.h> #include <X11/Intrinsic.h> #include <X11/CompositeP.h> #include <X11/Composite.h> #include <X11/Xaw/ViewportP.h> #include <X11/Xaw/Viewport.h> #include "MultiListP.h" #include "MultiList.h" #include "ScrListP.h" #include "ScrList.h" /*---------------------------------------------------------------------------* D E C L A R A T I O N S *---------------------------------------------------------------------------*/ #define SUPERCLASS (&compositeClassRec) #define max(a,b) ((a) > (b) ? (a) : (b)) #define min(a,b) ((a) < (b) ? (a) : (b)) #define abs(a) ((a) < 0 ? -(a) : (a)) #define XtStrlen(s) ((s) ? strlen(s) : 0) #define offset(field) XtOffset(XfwfScrolledListWidget, \ scrolledList.field) #define coffset(field) XtOffset(Widget,core.field) #define MyData(w) ((w)->scrolledList) #define CoreData(w) ((w)->core) #if (!NeedFunctionPrototypes) static void MultiListCallbackHandler(); static void ClassInitialize(); static void Initialize(); static void Realize(); static void Destroy(); static void Resize(); static Boolean SetValues(); static XtGeometryResult GeometryManager(); static XtGeometryResult PreferredGeometry(); static void ReCalcChildren(); #else static void MultiListCallbackHandler(Widget w, Widget self, XfwfMultiListReturnStruct *call_data); static void ClassInitialize(void); static void Initialize(Widget request, Widget new); static void Realize(Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs); static void Destroy(Widget gw); static void Resize(Widget gw); static Boolean SetValues(Widget gcurrent, Widget grequest, Widget gnew); static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply); static XtGeometryResult PreferredGeometry(XfwfScrolledListWidget slw, XtWidgetGeometry *parent_idea, XtWidgetGeometry *our_idea); static void ReCalcChildren(XfwfScrolledListWidget w); #endif /*---------------------------------------------------------------------------* R E S O U R C E I N I T I A L I Z A T I O N *---------------------------------------------------------------------------*/ static XtResource resources[] = { {XtNwidth,XtCWidth,XtRDimension,sizeof(Dimension), coffset(width),XtRString,"200"}, {XtNheight,XtCHeight,XtRDimension,sizeof(Dimension), coffset(height),XtRString,"500"}, {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel), coffset(background_pixel),XtRString,"white"}, {XtNlist,XtCList,XtRPointer,sizeof(char **), offset(item_array),XtRPointer,NULL}, {XtNnumberStrings,XtCNumberStrings,XtRInt,sizeof(int), offset(item_count),XtRInt,0}, {XtNsensitiveArray,XtCList,XtRPointer,sizeof(Boolean *), offset(sensitive_array),XtRPointer,NULL}, {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t), offset(callback), XtRCallback, NULL} }; #undef offset #undef coffset /*---------------------------------------------------------------------------* C L A S S A L L O C A T I O N *---------------------------------------------------------------------------*/ XfwfScrolledListClassRec xfwfScrolledListClassRec = { { /* superclass */ (WidgetClass)SUPERCLASS, /* class_name */ "XfwfScrolledList", /* widget_size */ sizeof(XfwfScrolledListRec), /* class_initialize */ (XtProc)ClassInitialize, /* class_part_initialize*/ NULL, /* class_inited */ FALSE, /* initialize */ (XtInitProc)Initialize, /* initialize_hook */ NULL, /* realize */ (XtRealizeProc)Realize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* resource_count */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ (XtWidgetProc)Destroy, /* resize */ (XtWidgetProc)Resize, /* expose */ NULL, /* set_values */ (XtSetValuesFunc)SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* query_geometry */ (XtGeometryHandler) PreferredGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, /* Core Part */ { /* geometry_manager */ GeometryManager, /* change_managed */ XtInheritChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL }, /* Composite Part */ { /* no extra class data */ 0 } /* XfwfScrolledList Part */ }; WidgetClass xfwfScrolledListWidgetClass = (WidgetClass)&xfwfScrolledListClassRec; /*---------------------------------------------------------------------------* E X P O R T E D M E T H O D S *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------* MultiListCallbackHandler(w,client_data,call_data) This routine gets called when the user clicks on a MultiList item. It in turn calls any callbacks in the ScrolledList widget. *---------------------------------------------------------------*/ static void MultiListCallbackHandler(w,self,call_data) Widget w; Widget self; XfwfMultiListReturnStruct *call_data; { Boolean highlighted,sensitive; XfwfScrolledListReturnStruct ret_value; if (call_data->num_selected) { ret_value.index = call_data->selected_items[0]; XfwfMultiListGetItemInfo((XfwfMultiListWidget)w, ret_value.index,&(ret_value.string), &highlighted,&sensitive); } else { ret_value.index = -1; ret_value.string = NULL; } XtCallCallbacks(self,XtNcallback,(caddr_t)(&ret_value)); } /*---------------------------------------------------------------* ClassInitialize() This procedure is called by the X toolkit to initialize the class. The hook to this routine is in the class_initialize part of the core part of the class. *---------------------------------------------------------------*/ static void ClassInitialize() { } /* End ClassInitialize */ /*---------------------------------------------------------------* Initialize() This procedure is called by the X toolkit to initialize the widget instance. The hook to this routine is in the initialize part of the core part of the class. *---------------------------------------------------------------*/ /* ARGSUSED */ static void Initialize(request,new) Widget request,new; { XfwfScrolledListWidget w; Arg args[10]; /* static char translations[] = "<Btn1Down>: Select()\n\ <Btn1Up>: Notify()\n"; */ w = (XfwfScrolledListWidget)new; if (CoreData(new).width <= 0) CoreData(new).width = 200; if (CoreData(new).height <= 0) CoreData(new).height = 300; XtSetArg(args[0],XtNuseRight,True); XtSetArg(args[1],XtNwidth,CoreData(new).width); XtSetArg(args[2],XtNheight,CoreData(new).height); XtSetArg(args[3],XtNallowVert,True); XtSetArg(args[4],XtNforceBars,True); MyData(w).viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,(Widget)w,args,5); XtSetArg(args[0],XtNlist,MyData(w).item_array); XtSetArg(args[1],XtNnumberStrings,MyData(w).item_count); XtSetArg(args[2],XtNsensitiveArray,MyData(w).sensitive_array); XtSetArg(args[3],XtNdefaultColumns,1); XtSetArg(args[4],XtNborderWidth,0); XtSetArg(args[5],XtNx,1); XtSetArg(args[6],XtNy,1); XtSetArg(args[7],XtNmaxSelectable,1); /* XtSetArg(args[8],XtNtranslations, XtParseTranslationTable(translations)); */ MyData(w).list = XtCreateManagedWidget("multilist", xfwfMultiListWidgetClass,MyData(w).viewport,args,8); XtAddCallback(MyData(w).list,XtNcallback, (XtCallbackProc)MultiListCallbackHandler,(caddr_t)w); } /* End Initialize */ /*---------------------------------------------------------------* Realize() This function is called to realize a ScrolledList widget. *---------------------------------------------------------------*/ static void Realize(gw,valueMask,attrs) Widget gw; XtValueMask *valueMask; XSetWindowAttributes *attrs; { XfwfScrolledListWidget w; w = (XfwfScrolledListWidget)gw; XtCreateWindow(gw,InputOutput,(Visual *)CopyFromParent, *valueMask,attrs); XtRealizeWidget(MyData(w).viewport); Resize(gw); } /* End Realize */ /*---------------------------------------------------------------* Destroy() This function is called to destroy a scrolledList widget. *---------------------------------------------------------------*/ static void Destroy(gw) Widget gw; { /* Removed by [EP] on 98-06-20. */ #if 0 XfwfScrolledListWidget w; w = (XfwfScrolledListWidget)gw; XtDestroyWidget(MyData(w).viewport); XtDestroyWidget(MyData(w).list); #endif } /* End Destroy */ /*---------------------------------------------------------------* Resize() This function is called to resize a scrolledList widget. *---------------------------------------------------------------*/ static void Resize(gw) Widget gw; { XfwfScrolledListWidget w; w = (XfwfScrolledListWidget)gw; ReCalcChildren(w); } /* End Resize */ /*---------------------------------------------------------------* Boolean SetValues(wcurrent,wrequest,wnew) This isn't inplemented yet, meaning you can't change resources dynamically. *---------------------------------------------------------------*/ /* ARGSUSED */ static Boolean SetValues(wcurrent,wrequest,wnew) Widget wcurrent,wrequest,wnew; { Boolean redraw,recalc; XfwfScrolledListWidget csl,rsl,nsl; csl = (XfwfScrolledListWidget)wcurrent; rsl = (XfwfScrolledListWidget)wrequest; nsl = (XfwfScrolledListWidget)wnew; redraw = False; recalc = False; if ((MyData(csl).item_array != MyData(nsl).item_array) || (MyData(csl).item_count != MyData(nsl).item_count) || (MyData(csl).sensitive_array != MyData(nsl).sensitive_array)) { XfwfScrolledListSetList((Widget)csl, MyData(nsl).item_array, MyData(nsl).item_count,True, MyData(nsl).sensitive_array); redraw = recalc = True; } return(redraw); } /* End SetValues */ /*---------------------------------------------------------------* GeometryManager(w,request,reply) This routine acts as the geometry_manager method for the ScrolledList widget. It is called when a child wants to resize/reposition itself. Currently, we allow all requests. *---------------------------------------------------------------*/ /* ARGSUSED */ static XtGeometryResult GeometryManager(w,request,reply) Widget w; XtWidgetGeometry *request; XtWidgetGeometry *reply; { return(XtGeometryYes); } /* End GeometryManager */ /*---------------------------------------------------------------------------* PreferredGeometry(slw,parent_idea,our_idea) This routine is called by the parent to tell us about the parent's idea of our width and/or height. We then suggest our preference through <our_idea> and return the information to the parent. *---------------------------------------------------------------------------*/ static XtGeometryResult PreferredGeometry(slw,parent_idea,our_idea) XfwfScrolledListWidget slw; XtWidgetGeometry *parent_idea,*our_idea; { Arg multilist_args[2],slist_args[2]; Dimension col_width,row_height,num_rows,current_width,current_height; if (!XtIsRealized((Widget)slw)) return(XtGeometryYes); XtSetArg(multilist_args[0],XtNrowHeight,&row_height); XtSetArg(multilist_args[1],XtNcolumnWidth,&col_width); XtSetArg(slist_args[0],XtNwidth,¤t_width); XtSetArg(slist_args[1],XtNheight,¤t_height); XtGetValues(MyData(slw).list,multilist_args,2); XtGetValues((Widget)slw,slist_args,2); row_height = max(1,row_height); num_rows = max(1,(parent_idea->height / row_height)); our_idea->request_mode = (CWWidth | CWHeight); our_idea->width = col_width; our_idea->height = num_rows * row_height; if ((our_idea->width == current_width) && (our_idea->height == current_height)) { return(XtGeometryNo); /* Prefer To Stay As Is */ } if ((our_idea->width == parent_idea->width) && (our_idea->height == parent_idea->height)) { return(XtGeometryYes); /* Proposed Change Is Fine */ } return(XtGeometryAlmost); } /* End PreferredGeometry */ /*---------------------------------------------------------------------------* L O C A L R O U T I N E S *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------* ReCalcChildren(w) This routine takes a ScrolledList widget <w> and updates the widths and positions of the child widgets. *---------------------------------------------------------------*/ static void ReCalcChildren(w) XfwfScrolledListWidget w; { int wid_h,wid_w; wid_w = CoreData(w).width; wid_h = CoreData(w).height; XtResizeWidget(MyData(w).viewport,wid_w,wid_h,1); } /* End ReCalcChildren */ /*===========================================================================* E X P O R T E D F U N C T I O N S *===========================================================================*/ /*---------------------------------------------------------------------------* XfwfScrolledListSetList(w,newlist,items,resize,sensitive_array) This routine tries to set the string array to the new array <newlist>. <items> is the count of strings. If <items> is 0 and the array is NULL terminated, the number of strings will be automatically counted. The <resize> flag indicates if we want the widget to try to resize itself to hold the new array. The <sensitive_array> parameter (if non-NULL) contains an array of Booleans representing the sensitivity of the list items. *---------------------------------------------------------------------------*/ void XfwfScrolledListSetList(w,newlist,items,resize,sensitive_array) Widget w; char **newlist; int items; Boolean resize; Boolean *sensitive_array; { XfwfScrolledListWidget sw; sw = (XfwfScrolledListWidget)w; XfwfMultiListSetNewData((XfwfMultiListWidget)(MyData(sw).list), newlist,items,0,resize,sensitive_array); MyData(sw).item_array = newlist; MyData(sw).item_count = items; MyData(sw).sensitive_array = sensitive_array; } /* End XfwfScrolledListSetList */ /*---------------------------------------------------------------------------* XfwfScrolledListUnhighlightAll(w) This routine unhighlights all highlighted items in the ScrolledList widget <w>. *---------------------------------------------------------------------------*/ void XfwfScrolledListUnhighlightAll(w) Widget w; { XfwfScrolledListWidget sw; sw = (XfwfScrolledListWidget)w; XfwfMultiListUnhighlightAll((XfwfMultiListWidget)(MyData(sw).list)); } /* End XfwfScrolledListUnhighlightAll */ /*---------------------------------------------------------------------------* XfwfScrolledListHighlightItem(w,item_index) This routine highlights the item with index number <item_index>. *---------------------------------------------------------------------------*/ void XfwfScrolledListHighlightItem(w,item_index) Widget w; int item_index; { XfwfScrolledListWidget sw; sw = (XfwfScrolledListWidget)w; XfwfMultiListHighlightItem((XfwfMultiListWidget)(MyData(sw).list), item_index); } /* End XfwfScrolledListHighlightItem */ /*---------------------------------------------------------------------------* XfwfScrolledListGetHighlighted(w) This routine returns the current highlighted item. *---------------------------------------------------------------------------*/ XfwfScrolledListReturnStruct *XfwfScrolledListGetHighlighted(sw) XfwfScrolledListWidget sw; { XfwfMultiListReturnStruct *pl_ret; static XfwfScrolledListReturnStruct sl_ret; /* Added static [BB] */ sl_ret.multilist = MyData(sw).list; pl_ret = XfwfMultiListGetHighlighted((XfwfMultiListWidget) (MyData(sw).list)); if (pl_ret->num_selected != 0) { sl_ret.string = pl_ret->string; sl_ret.index = pl_ret->item; sl_ret.highlighted = True; } else { sl_ret.string = NULL; sl_ret.index = -1; sl_ret.highlighted = False; } return(&sl_ret); } /* End XfwfScrolledListGetHighlighted */ /*---------------------------------------------------------------------------* XfwfScrolledListIsHighlighted(w,item_index) This routine returns a boolean that indicates if the item with index <item_index> was highlighted or not. *---------------------------------------------------------------------------*/ Boolean XfwfScrolledListIsHighlighted(w,item_index) Widget w; int item_index; { XfwfScrolledListWidget sw; sw = (XfwfScrolledListWidget)w; return(XfwfMultiListIsHighlighted((XfwfMultiListWidget) (MyData(sw).list),item_index)); } /* End XfwfScrolledListIsHighlighted */ /*---------------------------------------------------------------------------* XfwfScrolledListGetItem(w,item_index,str_ptr,high_ptr,sens_ptr) This routine returns information about a numbered item including the name of the item, whether it is highlighted, and its sensitivity. If the item index number does not correspond to an item, False is returned, else True is returned. *---------------------------------------------------------------------------*/ Boolean XfwfScrolledListGetItem(w,item_index,str_ptr,high_ptr,sens_ptr) Widget w; int item_index; String *str_ptr; Boolean *high_ptr,*sens_ptr; { XfwfScrolledListWidget sw; sw = (XfwfScrolledListWidget)w; return(XfwfMultiListGetItemInfo((XfwfMultiListWidget)(MyData(sw).list), item_index,str_ptr,high_ptr,sens_ptr)); } /* End XfwfScrolledListGetItem */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.