📄 multilist.c
字号:
return(XtGeometryYes);} /* End PreferredGeometry *//*---------------------------------------------------------------------------* Resize(mlw) This function is called when the widget is being resized. It recalculates the layout of the widget. *---------------------------------------------------------------------------*/static void Resize(mlw)XfwfMultiListWidget mlw;{ Dimension width,height; width = MultiListWidth(mlw); height = MultiListHeight(mlw); Layout(mlw,False,False,&width,&height);} /* End Resize *//*---------------------------------------------------------------------------* SetValues(cpl,rpl,npl) This routine is called when the user is changing resources. <cpl> is the current widget before the user's changes have been instituted. <rpl> includes the original changes as requested by the user. <npl> is the new resulting widget with the requested changes and with all superclass changes already made. *---------------------------------------------------------------------------*//*ARGSUSED*/static Boolean SetValues(cpl,rpl,npl)XfwfMultiListWidget cpl,rpl,npl;{ Boolean redraw,recalc; redraw = False; recalc = False; /* Graphic Context Changes */ if ((MultiListFG(cpl) != MultiListFG(npl)) || (MultiListBG(cpl) != MultiListBG(npl)) || (MultiListHighlightFG(cpl) != MultiListHighlightFG(npl)) || (MultiListHighlightBG(cpl) != MultiListHighlightBG(npl)) || (MultiListFont(cpl) != MultiListFont(npl))) { XtDestroyGC(MultiListEraseGC(cpl)); XtDestroyGC(MultiListDrawGC(cpl)); XtDestroyGC(MultiListHighlightForeGC(cpl)); XtDestroyGC(MultiListHighlightBackGC(cpl)); XtDestroyGC(MultiListGrayGC(cpl)); CreateNewGCs(npl); redraw = True; } /* Changes That Require Redraw */ if ((MultiListSensitive(cpl) != MultiListSensitive(npl)) || (MultiListAncesSensitive(cpl) != MultiListAncesSensitive(npl))) { redraw = True; } /* Changes That Require Selection Changes */ if ((MultiListMaxSelectable(cpl) != MultiListMaxSelectable(npl))) { XtWarning("Dynamic change to maxSelectable unimplemented"); } /* Changes That Require Data Initialization */ if ((MultiListList(cpl) != MultiListList(npl)) || (MultiListNumItems(cpl) != MultiListNumItems(npl)) || (MultiListSensitiveArray(cpl) != MultiListSensitiveArray(npl))) { DestroyOldData(cpl); InitializeNewData(npl); recalc = True; redraw = True; } /* Changes That Require Recalculating Coordinates */ if ((MultiListWidth(cpl) != MultiListWidth(npl)) || (MultiListHeight(cpl) != MultiListHeight(npl)) || (MultiListColumnSpace(cpl) != MultiListColumnSpace(npl)) || (MultiListRowSpace(cpl) != MultiListRowSpace(npl)) || (MultiListDefaultCols(cpl) != MultiListDefaultCols(npl)) || ((MultiListForceCols(cpl) != MultiListForceCols(npl)) && (MultiListNumCols(cpl) != MultiListNumCols(npl))) || (MultiListRowMajor(cpl) != MultiListRowMajor(npl)) || (MultiListFont(cpl) != MultiListFont(npl)) || (MultiListLongest(cpl) != MultiListLongest(npl))) { recalc = True; redraw = True; } if (MultiListColWidth(cpl) != MultiListColWidth(npl)) { XtWarning("columnWidth Resource Is Read-Only"); MultiListColWidth(npl) = MultiListColWidth(cpl); } if (MultiListRowHeight(cpl) != MultiListRowHeight(npl)) { XtWarning("rowHeight Resource Is Read-Only"); MultiListRowHeight(npl) = MultiListRowHeight(cpl); } if (recalc) { RecalcCoords(npl,!MultiListWidth(npl),!MultiListHeight(npl)); } if (!XtIsRealized((Widget)cpl)) return(False); else return(redraw);} /* End SetValues *//*===========================================================================* D A T A I N I T I A L I Z A T I O N *===========================================================================*//*---------------------------------------------------------------------------* DestroyOldData(mlw) This routine frees the internal list item array and sets the item count to 0. This is normally done immediately before calling InitializeNewData() to rebuild the internal item array from new user specified arrays. *---------------------------------------------------------------------------*/static void DestroyOldData(mlw)XfwfMultiListWidget mlw;{ int i; if (MultiListItemArray(mlw) != NULL) /* Free Old List */ { for (i = 0; i < MultiListNumItems(mlw); i++) { free(MultiListItemString(MultiListNthItem(mlw,i))); } free((char *)MultiListItemArray(mlw)); } if (MultiListSelArray(mlw) != NULL) free((char *)MultiListSelArray(mlw)); MultiListSelArray(mlw) = NULL; MultiListNumSelected(mlw) = 0; MultiListItemArray(mlw) = NULL; MultiListNumItems(mlw) = 0;} /* End DestroyOldData *//*---------------------------------------------------------------------------* InitializeNewData(mlw) This routine takes a MultiList widget <mlw> and builds up new data item tables based on the string list and the sensitivity array. All previous data should have already been freed. If the number of items is 0, they will be counted, so the array must be NULL terminated. If the list of strings is NULL, this is treated as a list of 0 elements. If the sensitivity array is NULL, all items are treated as sensitive. When this routine is done, the string list and sensitivity array fields will all be set to NULL, and the widget will not reference them again. *---------------------------------------------------------------------------*/static void InitializeNewData(mlw)XfwfMultiListWidget mlw;{ int i; XfwfMultiListItem *item; String *string_array; string_array = MultiListList(mlw); if (string_array == NULL) MultiListNumItems(mlw) = 0; if (MultiListNumItems(mlw) == 0) /* Count Elements */ { if (string_array == NULL) /* No elements */ { MultiListNumItems(mlw) = 0; } else { for (i = 0; string_array[i] != NULL; i++); MultiListNumItems(mlw) = i; } } if (MultiListNumItems(mlw) == 0) /* No Items */ { MultiListItemArray(mlw) = NULL; } else { MultiListItemArray(mlw) = TypeAlloc(XfwfMultiListItem,MultiListNumItems(mlw)); for (i = 0; i < MultiListNumItems(mlw); i++) { item = MultiListNthItem(mlw,i); if (MultiListSensitiveArray(mlw) == NULL || (MultiListSensitiveArray(mlw)[i] == True)) { MultiListItemSensitive(item) = True; } else { MultiListItemSensitive(item) = False; } MultiListItemString(item) = StrCopy(string_array[i]); MultiListItemHighlighted(item) = False; } } if (MultiListMaxSelectable(mlw) == 0) { MultiListSelArray(mlw) = NULL; MultiListNumSelected(mlw) = 0; } else { MultiListSelArray(mlw) = TypeAlloc(int,MultiListMaxSelectable(mlw)); MultiListNumSelected(mlw) = 0; } MultiListList(mlw) = NULL; MultiListSensitiveArray(mlw) = NULL;} /* End InitializeNewData */ /*---------------------------------------------------------------------------* CreateNewGCs(mlw) This routine takes a MultiList widget <mlw> and creates a new set of graphic contexts for the widget based on the colors, fonts, etc. in the widget. Any previous GCs are assumed to have already been destroyed. *---------------------------------------------------------------------------*/static void CreateNewGCs(mlw)XfwfMultiListWidget mlw;{ XGCValues values; unsigned int attribs; attribs = GCForeground | GCBackground | GCFont; values.foreground = MultiListFG(mlw); values.background = MultiListBG(mlw); values.font = MultiListFont(mlw)->fid; MultiListDrawGC(mlw) = XtGetGC((Widget)mlw,attribs,&values); values.foreground = MultiListBG(mlw); MultiListEraseGC(mlw) = XtGetGC((Widget)mlw,attribs,&values); values.foreground = MultiListHighlightFG(mlw); values.background = MultiListHighlightBG(mlw); MultiListHighlightForeGC(mlw) = XtGetGC((Widget)mlw,attribs,&values); values.foreground = MultiListHighlightBG(mlw); values.background = MultiListHighlightBG(mlw); MultiListHighlightBackGC(mlw) = XtGetGC((Widget)mlw,attribs,&values); attribs |= GCTile | GCFillStyle; values.foreground = MultiListFG(mlw); values.background = MultiListBG(mlw); values.fill_style = FillTiled; values.tile = XmuCreateStippledPixmap(XtScreen(mlw),MultiListFG(mlw), MultiListBG(mlw),MultiListDepth(mlw)); MultiListGrayGC(mlw) = XtGetGC((Widget)mlw,attribs,&values);} /* End CreateNewGCs *//*===========================================================================* L A Y O U T A N D G E O M E T R Y M A N A G E M E N T *===========================================================================*//*---------------------------------------------------------------------------* RecalcCoords(mlw,width_changeable,height_changeable) This routine takes a MultiList widget <mlw> and recalculates the coordinates, and item placement based on the current width, height, and list of items. The <width_changeable> and <height_changeable> indicate if the width and/or height can be arbitrarily set. This routine requires that the internal list data be initialized. *---------------------------------------------------------------------------*/#if NeedFunctionPrototypesstatic voidRecalcCoords(XfwfMultiListWidget mlw, Boolean width_changeable, Boolean height_changeable)#elsestatic voidRecalcCoords(mlw,width_changeable,height_changeable)XfwfMultiListWidget mlw;Boolean width_changeable,height_changeable;#endif{ String str; Dimension width,height; register int i,text_width; width = MultiListWidth(mlw); height = MultiListHeight(mlw); if (MultiListNumItems(mlw) != 0 && MultiListLongest(mlw) == 0) { for (i = 0; i < MultiListNumItems(mlw); i++) { str = MultiListItemString(MultiListNthItem(mlw,i)); text_width = FontW(MultiListFont(mlw),str); MultiListLongest(mlw) = max(MultiListLongest(mlw), text_width); } } if (Layout(mlw,width_changeable,height_changeable,&width,&height)) { NegotiateSizeChange(mlw,width,height); }} /* End RecalcCoords *//*---------------------------------------------------------------------------* NegotiateSizeChange(mlw,width,height) This routine tries to change the MultiList widget <mlw> to have the new size <width> by <height>. A negotiation will takes place to try to change the size. The resulting size is not necessarily the requested size. *---------------------------------------------------------------------------*/#if NeedFunctionPrototypesstatic voidNegotiateSizeChange(XfwfMultiListWidget mlw, Dimension width, Dimension height)#elsestatic voidNegotiateSizeChange(mlw,width,height)XfwfMultiListWidget mlw;Dimension width,height;#endif{ int attempt_number; Boolean w_fixed,h_fixed; Dimension *w_ptr,*h_ptr; XtWidgetGeometry request,reply; request.request_mode = CWWidth | CWHeight; request.width = width; request.height = height; for (attempt_number = 1; attempt_number <= 3; attempt_number++) { switch (XtMakeGeometryRequest((Widget)mlw,&request,&reply)) { case XtGeometryYes: case XtGeometryNo: return; case XtGeometryAlmost: switch (attempt_number) { case 1: w_fixed = (request.width != reply.width); h_fixed = (request.height != reply.height); w_ptr = &(reply.width); h_ptr = &(reply.height); Layout(mlw,!w_fixed,!h_fixed,w_ptr,h_ptr); break; case 2: w_ptr = &(reply.width); h_ptr = &(reply.height); Layout(mlw,False,False,w_ptr,h_ptr); break; case 3: return; } break; default: XtAppWarning(XtWidgetToApplicationContext((Widget)mlw), "MultiList Widget: Unknown geometry return."); break; } request = reply; }} /* End NegotiateSizeChange *//*---------------------------------------------------------------------------* Boolean Layout(mlw,w_changeable,h_changeable,w_ptr,h_ptr) This routine tries to generate a layout for the MultiList widget <mlw>. The Layout routine is free to arbitrarily set the width or height if the corresponding variables <w_changeable> and <h_changeable> are set True. Otherwise the original width or height in <w_ptr> and <h_ptr> are used as fixed values. The resulting new width and height are stored back through the <w_ptr> and <h_ptr> pointers. False is returned if no size change was done, True is returned otherwise. *---------------------------------------------------------------------------*/#if NeedFunctionPrototypesstatic BooleanLayout(XfwfMultiListWidget mlw, Boolean w_changeable, Boolean h_changeable, Dimension *w_ptr, Dimension *h_ptr)#elsestatic BooleanLayout(mlw,w_changeable,h_changeable,w_ptr,h_ptr)XfwfMultiListWidget mlw;Boolean w_changeable,h_changeable;Dimension *w_ptr,*h_ptr;#endif{ Boolean size_changed = False;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -