📄 multilist.c
字号:
/* * If force columns is set, then always use the number * of columns specified by default_cols. */ MultiListColWidth(mlw) = MultiListLongest(mlw) + MultiListColumnSpace(mlw); MultiListRowHeight(mlw) = FontH(MultiListFont(mlw)) + MultiListRowSpace(mlw); if (MultiListForceCols(mlw)) { MultiListNumCols(mlw) = max(MultiListDefaultCols(mlw),1); if (MultiListNumItems(mlw) == 0) MultiListNumRows(mlw) = 1; else MultiListNumRows(mlw) = (MultiListNumItems(mlw) - 1) / MultiListNumCols(mlw) + 1; if (w_changeable) { *w_ptr = MultiListNumCols(mlw) * MultiListColWidth(mlw); size_changed = True; } else { MultiListColWidth(mlw) = *w_ptr / (Dimension)MultiListNumCols(mlw); } if (h_changeable) { *h_ptr = MultiListNumRows(mlw) * MultiListRowHeight(mlw); size_changed = True; } return(size_changed); } /* * If both width and height are free to change then use * default_cols to determine the number of columns and set * the new width and height to just fit the window. */ if (w_changeable && h_changeable) { MultiListNumCols(mlw) = max(MultiListDefaultCols(mlw),1); if (MultiListNumItems(mlw) == 0) MultiListNumRows(mlw) = 1; else MultiListNumRows(mlw) = (MultiListNumItems(mlw) - 1) / MultiListNumCols(mlw) + 1; *w_ptr = MultiListNumCols(mlw) * MultiListColWidth(mlw); *h_ptr = MultiListNumRows(mlw) * MultiListRowHeight(mlw); return(True); } /* * If the width is fixed then use it to determine the * number of columns. If the height is free to move * (width still fixed) then resize the height of the * widget to fit the current MultiList exactly. */ if (!w_changeable) { MultiListNumCols(mlw) = *w_ptr / MultiListColWidth(mlw); MultiListNumCols(mlw) = max(MultiListNumCols(mlw),1); MultiListNumRows(mlw) = (MultiListNumItems(mlw) - 1) / MultiListNumCols(mlw) + 1; MultiListColWidth(mlw) = *w_ptr / (Dimension)MultiListNumCols(mlw); if (h_changeable) { *h_ptr = MultiListNumRows(mlw) * MultiListRowHeight(mlw); size_changed = True; } return(size_changed); } /* * The last case is xfree and !yfree we use the height to * determine the number of rows and then set the width to * just fit the resulting number of columns. */ MultiListNumRows(mlw) = *h_ptr / MultiListRowHeight(mlw); MultiListNumRows(mlw) = max(MultiListNumRows(mlw),1); MultiListNumCols(mlw) = (MultiListNumItems(mlw) - 1) / MultiListNumRows(mlw) + 1; *w_ptr = MultiListNumCols(mlw) * MultiListColWidth(mlw); return(True);} /* End Layout *//*===========================================================================* R E D R A W R O U T I N E S *===========================================================================*//*---------------------------------------------------------------------------* RedrawAll(mlw) This routine simple calls Redisplay to redraw the entire MultiList widget <mlw>. *---------------------------------------------------------------------------*/static void RedrawAll(mlw)XfwfMultiListWidget mlw;{ Redisplay(mlw,NULL,NULL);} /* End RedrawAll *//*---------------------------------------------------------------------------* RedrawItem(mlw,item_index) This routine redraws the item with index <item_index> in the MultiList widget <mlw>. If the item number is bad, nothing is drawn. *---------------------------------------------------------------------------*/static void RedrawItem(mlw,item_index)XfwfMultiListWidget mlw;int item_index;{ int row,column; if (ItemToRowColumn(mlw,item_index,&row,&column)) { RedrawRowColumn(mlw,row,column); }} /* End RedrawItem *//*---------------------------------------------------------------------------* RedrawRowColumn(mlw,row,column) This routine paints the item in row/column position <row>,<column> on the MultiList widget <mlw>. If the row/column coordinates are outside the widget, nothing is drawn. If the position is empty, blank space is drawn. *---------------------------------------------------------------------------*/static void RedrawRowColumn(mlw,row,column)XfwfMultiListWidget mlw;int row,column;{ GC bg_gc,fg_gc; XfwfMultiListItem *item; int ul_x,ul_y,str_x,str_y,w,h,item_index,has_item,text_h; if (!XtIsRealized((Widget)mlw)) return; has_item = RowColumnToItem(mlw,row,column,&item_index); RowColumnToPixels(mlw,row,column,&ul_x,&ul_y,&w,&h); if (has_item == False) /* No Item */ { if (MultiListShadeSurplus(mlw)) bg_gc = MultiListGrayGC(mlw); else bg_gc = MultiListEraseGC(mlw); } else { item = MultiListNthItem(mlw,item_index); if ((!MultiListSensitive(mlw)) || (!MultiListItemSensitive(item))) /* Insensitive */ { if (MultiListItemHighlighted(item)) /* Selected */ { bg_gc = MultiListGrayGC(mlw); fg_gc = MultiListEraseGC(mlw); } else /* !Selected */ { bg_gc = MultiListEraseGC(mlw); fg_gc = MultiListGrayGC(mlw); } } else /* Sensitive */ { if (MultiListItemHighlighted(item)) /* Selected */ { bg_gc = MultiListHighlightBackGC(mlw); fg_gc = MultiListHighlightForeGC(mlw); } else /* !Selected */ { bg_gc = MultiListEraseGC(mlw); fg_gc = MultiListDrawGC(mlw); } } } XFillRectangle(XtDisplay(mlw),XtWindow(mlw),bg_gc,ul_x,ul_y,w,h); if (has_item == True) { text_h = min(FontH(MultiListFont(mlw)) + (int)MultiListRowSpace(mlw),(int)MultiListRowHeight(mlw)); str_x = ul_x + MultiListColumnSpace(mlw) / 2; str_y = ul_y + FontAscent(MultiListFont(mlw)) + ((int)MultiListRowHeight(mlw) - text_h) / 2; XDrawString(XtDisplay(mlw),XtWindow(mlw),fg_gc, str_x,str_y,MultiListItemString(item), strlen(MultiListItemString(item))); }} /* End RedrawRowColumn */ /*===========================================================================* I T E M L O C A T I O N R O U T I N E S *===========================================================================*//*---------------------------------------------------------------------------* void PixelToRowColumn(mlw,x,y,row_ptr,column_ptr) This routine takes pixel coordinates <x>, <y> and converts the pixel coordinate into a row/column coordinate. This row/column coordinate can then easily be converted into the specific item in the list via the function RowColumnToItem(). If the pixel lies in blank space outside of the items, the row & column numbers will be outside of the range of normal row & columns numbers, but will correspond to the row & column of the item, if an item was actually there. *---------------------------------------------------------------------------*/static void PixelToRowColumn(mlw,x,y,row_ptr,column_ptr)XfwfMultiListWidget mlw;int x,y,*row_ptr,*column_ptr;{ *row_ptr = y / (int)MultiListRowHeight(mlw); *column_ptr = x / (int)MultiListColWidth(mlw);} /* End PixelToRowColumn *//*---------------------------------------------------------------------------* void RowColumnToPixels(mlw,row,col,x_ptr,y_ptr,w_ptr,h_ptr) This routine takes a row/column coordinate <row>,<col> and converts it into the bounding pixel rectangle which is returned. *---------------------------------------------------------------------------*/static void RowColumnToPixels(mlw,row,col,x_ptr,y_ptr,w_ptr,h_ptr)XfwfMultiListWidget mlw;int row,col,*x_ptr,*y_ptr,*w_ptr,*h_ptr;{ *x_ptr = col * MultiListColWidth(mlw); *y_ptr = row * MultiListRowHeight(mlw); *w_ptr = MultiListColWidth(mlw); *h_ptr = MultiListRowHeight(mlw);} /* End RowColumnToPixels *//*---------------------------------------------------------------------------* Boolean RowColumnToItem(mlw,row,column,item_ptr) This routine takes a row number <row> and a column number <column> and tries to resolve this row and column into the index of the item in this position of the MultiList widget <mlw>. The resulting item index is placed through <item_ptr>. If there is no item at this location, False is returned, else True is returned. *---------------------------------------------------------------------------*/static Boolean RowColumnToItem(mlw,row,column,item_ptr)XfwfMultiListWidget mlw;int row,column,*item_ptr;{ register int x_stride,y_stride; if (row < 0 || row >= MultiListNumRows(mlw) || column < 0 || column >= MultiListNumCols(mlw)) { return(False); } if (MultiListRowMajor(mlw)) { x_stride = 1; y_stride = MultiListNumCols(mlw); } else { x_stride = MultiListNumRows(mlw); y_stride = 1; } *item_ptr = row * y_stride + column * x_stride; if (*item_ptr >= MultiListNumItems(mlw)) return(False); else return(True);} /* End RowColumnToItem *//*---------------------------------------------------------------------------* Boolean ItemToRowColumn(mlw,item_index,row_ptr,column_ptr) This routine takes an item number <item_index> and attempts to convert the index into row and column numbers stored through <row_ptr> and <column_ptr>. If the item number does not corespond to a valid item, False is returned, else True is returned. *---------------------------------------------------------------------------*/static Boolean ItemToRowColumn(mlw,item_index,row_ptr,column_ptr)XfwfMultiListWidget mlw;int item_index,*row_ptr,*column_ptr;{ if (item_index < 0 || item_index >= MultiListNumItems(mlw)) { return(False); } if (MultiListRowMajor(mlw)) { *row_ptr = item_index / MultiListNumCols(mlw); *column_ptr = item_index % MultiListNumCols(mlw); } else { *row_ptr = item_index % MultiListNumRows(mlw); *column_ptr = item_index / MultiListNumRows(mlw); } return(True);} /* End ItemToRowColumn *//*===========================================================================* E V E N T A C T I O N H A N D L E R S *===========================================================================*//*---------------------------------------------------------------------------* Select(mlw,event,params,num_params) This action handler is called when a user selects an item in the MultiList. This action first unselects all previously selected items, then selects the item under the mouse, if it is not a background gap, and if it is sensitive. The MultiListMostRecentItem(mlw) variable will be set to the item clicked on, or -1 if the item is background or insensitive. The MultiListMostRecentAct(mlw) variable will be set to XfwfMultiListActionHighlight, in case the selection region is extended. *---------------------------------------------------------------------------*//* ARGSUSED */static void Select(mlw,event,params,num_params)XfwfMultiListWidget mlw;XEvent *event;String *params;Cardinal *num_params;{ int click_x,click_y; int status,item_index,row,column; click_x = event->xbutton.x; click_y = event->xbutton.y; PixelToRowColumn(mlw,click_x,click_y,&row,&column); XfwfMultiListUnhighlightAll(mlw); MultiListMostRecentAct(mlw) = XfwfMultiListActionHighlight; status = RowColumnToItem(mlw,row,column,&item_index); if ((status == False) || (!MultiListItemSensitive(MultiListNthItem(mlw,item_index)))) { MultiListMostRecentItem(mlw) = -1; } else { MultiListMostRecentItem(mlw) = item_index; XfwfMultiListHighlightItem(mlw,item_index); }} /* End Select *//*---------------------------------------------------------------------------* Unselect(mlw,event,params,num_params) This function unselects the single text item pointed to by the mouse, if any. Any remaining selected entries are left selected. The MultiListMostRecentItem(mlw) variable will be set to -1, and the MultiListMostRecentAct(mlw) variable will be set to XfwfMultiListActionUnhighlight, in case the deselection region is extended. *---------------------------------------------------------------------------*//* ARGSUSED */static void Unselect(mlw,event,params,num_params)XfwfMultiListWidget mlw;XEvent *event;String *params;Cardinal *num_params;{ int click_x,click_y; int status,item_index,row,column; click_x = event->xbutton.x; click_y = event->xbutton.y; PixelToRowColumn(mlw,click_x,click_y,&row,&column); MultiListMostRecentItem(mlw) = -1; MultiListMostRecentAct(mlw) = XfwfMultiListActionUnhighlight; status = RowColumnToItem(mlw,row,column,&item_index); if ((status == True) && (MultiListItemSensitive(MultiListNthItem(mlw,item_index)))) XfwfMultiListHighlightItem(mlw,item_index);} /* End Unselect *//*---------------------------------------------------------------------------* Toggle(mlw,event,params,num_params) This action handler implements the toggling of selection status for a single item. Any remaining selected entries are left selected. If the mouse is not over a selectable text item, the MultiListMostRecentAct(mlw) variable is set to XfwfMultiListActionHighlight, in case the region is extended into selectable items later. MultiListMostRecentItem(mlw) is set to -1. If the mouse is over a selectable text item, the item highlight is toggled. If the item is currently selected, it becomes deselected. If unselected, the item becomes selected. At the same time, the MultiListMostRecentAct(mlw) variable is set to XfwfMultiListActionHighlight if the item was not previously selected, or XfwfMultiListActionUnhighlight if the item was previously selected. MultiListMostRecentItem(mlw) is set to the index of the item clicked on if the item is selected, or -1 if it is unselected.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -