📄 xmcombo.c
字号:
#define BOTTOMSHADOWCOLOR 0x0001
#define TOPSHADOWCOLOR 0x0002
#define FOREGROUND 0x0004
#define BACKGROUND 0x0008
static struct { String Resource; int Flag; }
ColorResources[] = {
{ XmNbottomShadowColor, BOTTOMSHADOWCOLOR },
{ XmNtopShadowColor, TOPSHADOWCOLOR },
{ XmNforeground, FOREGROUND },
{ XmNbackground, BACKGROUND }
};
static int UpdateColors(XmComboBoxWidget w, int flags)
{
Pixel Color, White, Black, EditCol;
int i, size = XtNumber(ColorResources);
Widget ScrolledWin, ScrollBar;
ScrolledWin = XtParent(w->combobox.ListCtrl);
XtVaGetValues(ScrolledWin, XmNverticalScrollBar, &ScrollBar, NULL);
White = WhitePixel(XtDisplay(w), WidgetToScreen((Widget) w));
Black = BlackPixel(XtDisplay(w), WidgetToScreen((Widget) w));
for ( i=0; i<size; i++ )
if ( flags & ColorResources[i].Flag ) {
if ( ColorResources[i].Flag == BACKGROUND )
EditCol = White;
else if ( ColorResources[i].Flag == FOREGROUND )
EditCol = Black;
else
EditCol = Color;
XtVaGetValues((Widget) w, ColorResources[i].Resource, &Color,
NULL);
XtVaSetValues(ScrollBar,
ColorResources[i].Resource, Color, NULL);
XtVaSetValues(w->combobox.ListCtrl,
ColorResources[i].Resource, EditCol, NULL);
XtVaSetValues(w->combobox.EditCtrl,
ColorResources[i].Resource, EditCol, NULL);
XtVaSetValues(ScrolledWin,
ColorResources[i].Resource, Color, NULL);
XtVaSetValues(w->combobox.LabelCtrl,
ColorResources[i].Resource, Color, NULL);
XtVaSetValues(w->combobox.ArrowCtrl,
ColorResources[i].Resource, Color, NULL);
if ( ColorResources[i].Flag & BACKGROUND )
XtVaSetValues(ScrollBar, XmNtroughColor, Color, NULL);
}
return 1;
} /* UpdateColors */
/* --------------------------------------------------------------------
* Liste aller vorgespiegelten Resourcen, die automatisch verarbeitet
* werden koennen, ohne weiter darueber nachdenken zu muessen...
*/
typedef enum { EDITCTRL, LISTCTRL, LABELCTRL } CHILDCTRL;
typedef enum { RO, RW, RWS, RWL, RWI, RWIGNORE } aUniqueName;
typedef struct {
String rsc;
CHILDCTRL ctrl;
/* enum { RO, RW, RWS, RWL, RWI, RWIGNORE } dir; */
aUniqueName dir;
/* nur lesen, lesen&schreiben, lesen&schreiben spezial,
lesen&schreiben label, lesen&schreiben items */
} MIRROR;
/* Alle mit !!! gekennzeichneten Eintraege werden auf die richtigen
* Namen des entsprechenden Widgets umgesetzt.
*/
static MIRROR MirroredResources[] = {
{ XmNitems, LISTCTRL, RWI }, /* Urgs! */
{ XmNitemCount, LISTCTRL, RWIGNORE }, /* dto. */
{ XmNlistMarginHeight, LISTCTRL, RW },
{ XmNlistMarginWidth, LISTCTRL, RW },
{ XmNlistSpacing, LISTCTRL, RW },
{ XmNstringDirection, LISTCTRL, RO }, /* Naja? */
{ XmNtopItemPosition, LISTCTRL, RO },
{ XmNblinkRate, EDITCTRL, RW },
{ XmNcolumns, EDITCTRL, RW },
{ XmNcursorPosition, EDITCTRL, RW },
{ XmNcursorPositionVisible, EDITCTRL, RW },
{ XmNmarginHeight, EDITCTRL, RW },
{ XmNmarginWidth, EDITCTRL, RW },
{ XmNmaxLength, EDITCTRL, RW },
{ XmNselectThreshold, EDITCTRL, RW },
{ XmNvalue, EDITCTRL, RWS },
{ XmNalignment, LABELCTRL, RW },
{ XmNmnemonic, LABELCTRL, RW },
{ XmNmnemonicCharSet, LABELCTRL, RW },
{ XmNlabelPixmap, LABELCTRL, RW },
{ XmNlabelInsensitivePixmap, LABELCTRL, RW },
{ XmNlabelString, LABELCTRL, RW },
{ XmNlabelType, LABELCTRL, RW },
{ XmNlabelMarginBottom, LABELCTRL, RWL }, /* !!! */
{ XmNlabelMarginHeight, LABELCTRL, RWL }, /* !!! */
{ XmNlabelMarginLeft, LABELCTRL, RWL }, /* !!! */
{ XmNlabelMarginRight, LABELCTRL, RWL }, /* !!! */
{ XmNlabelMarginTop, LABELCTRL, RWL }, /* !!! */
{ XmNlabelMarginWidth, LABELCTRL, RWL }, /* !!! */
{ XmNlabelFontList, LABELCTRL, RWL }, /* !!! */
};
typedef struct {
char *from, *to;
} TRANSFORMATION;
static TRANSFORMATION Transformations[] = {
{ XmNlabelMarginBottom, XmNmarginBottom },
{ XmNlabelMarginHeight, XmNmarginHeight },
{ XmNlabelMarginLeft, XmNmarginLeft },
{ XmNlabelMarginRight, XmNmarginRight },
{ XmNlabelMarginTop, XmNmarginTop },
{ XmNlabelMarginWidth, XmNmarginWidth },
{ XmNlabelFontList, XmNfontList },
};
/* --------------------------------------------------------------------
* Sobald irgendeine Resource veraendert wird, erfolgt der Aufruf
* hierin als Benachrichtigung, einmal nach dem rechten zu sehen.
* Parameter:
* current Kopie der Widget-Instanz, bevor irgendwelche
* Resourcen veraendert oder set_values()-Methoden
* aufgerufen wurden.
* req Kopie der Widget-Instanz, aber bereits mit den
* durch XtSetValues veraenderten Werten
* new aktuellster Zustand der Widget-Instanz mit
* veraenderten Werten (entweder durch XtSetValues
* oder set_values()-Methoden der Superklasse)
* args Argumentenliste beim Aufruf von XtSetValues()
* NumArgs Anzahl der Argumente in der Liste
* Ergebnis:
* True, falls Widget neu gezeichnet werden soll.
*/
static Boolean SetValues(XmComboBoxWidget current, XmComboBoxWidget req,
XmComboBoxWidget newW,
ArgList args, Cardinal *NumArgs)
{
Boolean Update = False;
int i, j, MirrorSize = XtNumber(MirroredResources);
int k, TransformationSize = XtNumber(Transformations);
Arg arg;
int Flags;
/*
* Alle Resourcen, die nicht mehr nach dem Erstellen der Widget-Instanz
* veraendert werden koennen.
*/
newW->combobox.Editable = current->combobox.Editable;
newW->combobox.ListCtrl = current->combobox.ListCtrl;
newW->combobox.EditCtrl = current->combobox.EditCtrl;
newW->combobox.LabelCtrl = current->combobox.LabelCtrl;
newW->combobox.SelectionPolicy = current->combobox.SelectionPolicy;
newW->combobox.ListSizePolicy = current->combobox.ListSizePolicy;
newW->combobox.StaticList = current->combobox.StaticList;
/*
* Kontrolliere nun alle Resourcen, die sich veraendert haben koennten
* und gebe die neuen Einstellungen entsprechend weiter...
*
* Hat sich der Sensitive-Zustand veraendert? Dann muessen wir hier dafuer
* sorgen, dass alle Kinder ebenfalls den neuen Zustand annehmen.
*/
if ( current->core.sensitive != newW->core.sensitive ) {
XtSetSensitive(newW->combobox.ListCtrl, newW->core.sensitive);
XtSetSensitive(newW->combobox.EditCtrl, newW->core.sensitive);
XtSetSensitive(newW->combobox.ArrowCtrl, newW->core.sensitive);
XtSetSensitive(newW->combobox.ListCtrl, newW->core.sensitive);
if ( !newW->core.sensitive )
ShowHideDropDownList(newW, NULL, False);
}
/*
* Die ScrollBarPolicy kann nur dann geaendert werden, wenn das Listenfeld
* dauerhaft dargestellt wird.
*/
if ( newW->combobox.ScrollBarDisplayPolicy !=
current->combobox.ScrollBarDisplayPolicy ) {
if ( newW->combobox.StaticList )
XtVaSetValues(newW->combobox.ListCtrl,
XmNscrollBarDisplayPolicy, newW->combobox.ScrollBarDisplayPolicy,
NULL);
else
XtWarning(
"XmComboBox: ScrollBarDisplayPolicy can not be changed when StaticList == False."
);
}
/* Anzahl der in der Liste gleichzeitig darstellbaren Eintraege */
if ( current->combobox.VisibleItemCount !=
newW->combobox.VisibleItemCount ) {
XtVaSetValues(newW->combobox.ListCtrl,
XmNvisibleItemCount, newW->combobox.VisibleItemCount,
NULL);
Update = True;
}
if ( current->combobox.AutomaticSelection !=
newW->combobox.AutomaticSelection ) {
XtVaSetValues(newW->combobox.ListCtrl,
XmNautomaticSelection, newW->combobox.AutomaticSelection,
NULL);
}
/*
* benutzter Font: hier erhalten Liste und Eingabefeld jeweils die
* gleiche Fontliste, wohingegen das Label getrennt behandelt wird.
* Das macht auch Sinn, denn Liste und Eingabefeld beinhalten gleich-
* artigen Text, so dass hier auch tunlichst der gleiche Font zu
* benutzen ist.
*/
if ( current->combobox.Font != newW->combobox.Font ) {
XtVaSetValues(newW->combobox.ListCtrl,
XmNfontList, newW->combobox.Font, NULL);
XtVaSetValues(newW->combobox.EditCtrl,
XmNfontList, newW->combobox.Font, NULL);
Update = True;
}
Flags = 0;
if ( newW->manager.top_shadow_color !=
current->manager.top_shadow_color ) Flags |= TOPSHADOWCOLOR;
if ( newW->manager.bottom_shadow_color !=
current->manager.bottom_shadow_color ) Flags |= BOTTOMSHADOWCOLOR;
if ( newW->manager.foreground !=
current->manager.foreground ) Flags |= FOREGROUND;
if ( newW->core.background_pixel !=
current->core.background_pixel ) Flags |= BACKGROUND;
if ( Flags ) { UpdateColors(newW, Flags); Update = True; }
if ( newW->combobox.ArrowCursor != current->combobox.ArrowCursor ) {
if ( newW->combobox.ListVisible )
XDefineCursor(XtDisplay(newW->combobox.PopupShell),
XtWindow(newW->combobox.PopupShell),
newW->combobox.ArrowCursor);
}
/* Hier werden die vorgespiegelten Resourcen verwaltet, die in
* Wirklichkeit zu einem unserer Kinder gehoeren.
*/
for ( i = 0; i < *NumArgs; i++ ) {
/* Ist es eine vorgespiegelte Resource ? Wenn ja, dann leite die
* Anfrage an das entsprechende Kind-Widget weiter.
*/
for ( j = 0; j < MirrorSize; j++ ) {
if ( (strcmp(args[i].name, MirroredResources[j].rsc) == 0) ) {
switch ( MirroredResources[j].dir ) {
case RW: /* schreibender Zugriff erlaubt */
XtSetValues(MirroredResources[j].ctrl == LISTCTRL ?
newW->combobox.ListCtrl :
(MirroredResources[j].ctrl == EDITCTRL ?
newW->combobox.EditCtrl :
newW->combobox.LabelCtrl),
&(args[i]), 1);
break;
case RWS: /* schreibender Zugriff unter Kontrolle */
if ( strcmp(args[i].name, XmNvalue) == 0 ) {
if ( newW->combobox.Editable )
XtSetValues(newW->combobox.EditCtrl,
&(args[i]), 1);
}
break;
case RWL: /* Transformation in andere Resource beim
Label-Widget */
for ( k = 0; k < TransformationSize; k++ )
if ( strcmp(args[i].name, Transformations[k].from) == 0 ) {
arg.value = args[i].value;
arg.name = Transformations[k].to;
XtSetValues(newW->combobox.LabelCtrl,
&arg, 1);
break;
}
break;
case RWIGNORE: /* Zugriff auf XmNitemCount */
/* Wird von XmNitems erledigt! */
break;
case RWI: /* Zugriff auf XmNitems */
for ( k = 0; k < *NumArgs; k++ )
if ( strcmp(args[k].name, XmNitemCount) == 0 ) {
Arg MyArgs[2];
MyArgs[0].name = XmNitems;
MyArgs[0].value = args[i].value;
MyArgs[1].name = XmNitemCount;
MyArgs[1].value = args[k].value;
XtSetValues(newW->combobox.ListCtrl,
args, 2);
/*XtVaSetValues(newW->combobox.ListCtrl,
XmNitems, args[i].value,
XmNitemCount, args[k].value,
NULL);*/
break;
}
break;
case RO:
break;
} /* case write mode */
goto ScanForNextResource;
} /* if entry found */
} /* for every mirrored entry */
ScanForNextResource: ;
} /* for every Arg */
if ( (newW->combobox.SquareArrow != current->combobox.SquareArrow) ||
(newW->combobox.ArrowSpacingOn != current->combobox.ArrowSpacingOn) ) {
Update = False;
DoLayout(newW);
}
return Update;
} /* SetValues */
/* --------------------------------------------------------------------
* Werden irgendwelche Resourcen abgefragt, so muessen wir hier erst
* noch vor der Rueckkehr zum Frager klaeren, ob davon eine Resource
* betroffen ist, die nur vorgespiegelt ist, da sie eigentlich einem
* der Widgets gehoert, die von uns hier verwaltet werden, um daraus
* eine ordentlich
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -