⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmcombo.c

📁 Wxpython Implemented on Windows CE, Source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	XtConfigureWidget(w->combobox.LabelCtrl, 
	                  0, 0, 
			  LabelCtrlWidth, ComboBoxHeight, 
			  BorderWidth);
    }
/* Falls da noch die Liste herumgurkt... */
    if ( w->combobox.StaticList ) {
	Dimension Width, Height;
	
	if ( w->core.height > ComboBoxHeight ) 
	    Height = w->core.height - ComboBoxHeight;
	else
	    Height = 10;
	    
	if ( w->core.width > (Dimension)(ArrowCtrlWidth + EditX) )
	    Width = w->core.width - ArrowCtrlWidth - EditX;
	else
	    Width = 10;
	
	XtConfigureWidget(XtParent(w->combobox.ListCtrl),
	    EditX + ArrowCtrlWidth, ComboBoxHeight, Width, Height, 0);
    } else if ( w->combobox.ListVisible )
	DoDropDownLayout(w); 
} /* DoLayout */

/* --------------------------------------------------------------------
 * Pappi fragt nach, wie gross wir denn sein wollen.
 * Die hier benutzte Vorgehensweise zur Ermittlung der Groesse:
 *   Sobald der Vater uns eine Breite (oder aber Hoehe) vorschlaegt, 
 *   die fuer uns eigentlich zu klein ist, meckern wir und schlagen
 *   die von uns benoetigte Breite (Hoehe) vor.
 * Soweit also zur Theorie... leider sieht es beispielsweise das
 * Motif Form-Widget ueberhaupt nicht ein, uns auch nur ein einziges
 * Mal nach unseren Wuenschen zu fragen! Damit es bei derart unum-
 * gaenglichen Widgets dann doch noch geht, muss ChangedManaged die
 * Kohlen wieder aus dem Feuer holen mit einer Sondertour.
 * Parameter:
 *   *Request	    Vom Vater vorgeschlagene Geometrie
 * Ergebnis:
 *   *Reply	    Unsere Antwort auf die vorgeschlagene Geometrie
 *   sowie XtGeometryYes oder XtGeometryAlmost, je nachdem, wie gut
 *   uns Pappis Vorschlag in den Kram passt.
 */
static XtGeometryResult QueryGeometry(XmComboBoxWidget w, 
                                      XtWidgetGeometry *Request, 
			              XtWidgetGeometry *Reply)
{
    XtGeometryResult result = XtGeometryYes;
    Dimension        minW, minH, editW, labelW;
    
/* Elternteil will nichts weiter aendern, also ist uns das
 * recht so.
 */
    Request->request_mode &= CWWidth | CWHeight;
    if ( Request->request_mode == 0 ) return result;

    DefaultGeometry(w, &minW, &minH, &editW, &labelW);

/* Ueberpruefe, ob uns das in der Breite passt, was Pappi moechte... */
    if ( Request->request_mode & CWWidth ) {
	if ( Request->width < minW ) {
/* Wenn Pappi uns etwas vorschlaegt, was im wahrsten Sinne des Wortes 
 * vorn und hinten nicht reicht, dann versuchen wir ihn entsprechend
 * zu korrigieren. ("Versuchen" deshalb, weil er diesen Vorschlag auch
 * voellig ignorieren kann.)
 */
	    result               = XtGeometryAlmost;
	    Reply->width         = minW;
	    Reply->request_mode |= CWWidth;
	}
    }
/* Die ganze Chose nun noch vertikal */
    if ( Request->request_mode & CWHeight ) {
	if ( Request->height < minH ) {
	    result               = XtGeometryAlmost;
	    Reply->height        = minH;
	    Reply->request_mode |= CWHeight;
	}
    }
    return result;
} /* QueryGeometry */

/* --------------------------------------------------------------------
 * Die Groesse des ComboBox-Widgets hat sich veraendert und deshalb
 * mussen alle Kinder neu positioniert werden.
 * Letzten Endes laeuft hier alles auf ein ordinaeres DoLayout()
 * hinaus, um die Kinder umher zu schieben.
 * Parameter:
 *   w		    Die bereits hinlaenglich bekannte Instanz dieses
 *		    Widgets
 */
static void Resize(XmComboBoxWidget w)
{
    DoLayout(w);
} /* Resize */

/* --------------------------------------------------------------------
 * Dieses Widget hat sich in irgendeiner Form bewegt (und das nicht
 * nur relativ zum Vater, sondern moeglicherweise auch der Vater
 * selbst!) bzw. die Shell, in der sich irgendwo unsere Combo-Box
 * befindet, hat soeben den Fokus verschusselt und kann ihn nicht
 * mehr wiederfinden. Daneben kann es auch sein, dass die Shell
 * ikonisiert wurde. (Welch' Vielfalt! Dieses ist hier halt eine
 * multifunktionale Routine.)
 * 
 * Parameter:
 *   w		    Die naechste Shell in Reichweite ueber unserer
 *		    Combo-Box.
 *   cbw	    Diese Combo-Box.
 *   event	    ^ auf den Event, enthaelt genauerere Informationen
 *		    (naja... sieht so aus, als ob Motif hier auch 
 *		    schon 'mal Schrott 'reinpackt...)
 *   ContDispatch   Auf True setzen, damit dieser Event noch weiter-
 *		    gereicht wird an all' die anderen, die auch noch
 *		    mithoeren.
 */
static void ShellCallback(Widget w, XtPointer pClientData, 
                          XEvent *event, Boolean *ContDispatch)
{
    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
    
    switch ( event->type ) {
	case ConfigureNotify:
	case CirculateNotify:
	    DoDropDownLayout((XmComboBoxWidget) cbw);
	    break;
	case FocusOut:
	    LOG3("ShellCallback: FocusOut, mode: %i, detail: %i\n",
	         (int)event->xfocus.mode, (int)event->xfocus.detail);
	    if ( cbw->combobox.Persistent )
		cbw->combobox.IgnoreFocusOut = True;
	    else if ( (event->xfocus.mode == NotifyGrab) &&
	              cbw->combobox.ListVisible )
	        cbw->combobox.IgnoreFocusOut = True;
	    break;
	case UnmapNotify:
	    ShowHideDropDownList((XmComboBoxWidget) cbw, 
	                         event, False);
	    break;
    }
    *ContDispatch = True;
} /* ShellCallback */

/* --------------------------------------------------------------------
 * Diese Routine sorgt dafuer, dass die Liste nicht irrtuemlich bei
 * manchen Window Managern vom Bildschirm genommen wird, bloss weil
 * diese der OverrideShell den Tastaturfocus schenken bzw. diesen
 * dem Combo-Box-Widget wegnehmen, sobald der Mauszeiger in die Liste
 * bewegt wird.
 */
static void OverrideShellCallback(Widget w, XtPointer pClientData,
                                  XEvent *event, Boolean *ContDispatch)

{
    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
    switch ( event->type ) {
        case EnterNotify:
	    LOG2("OverrideShellCallback: EnterNotify, PendingFO: %s\n", 
	         cbw->combobox.PendingFocusOut ? "True" : "False");
            if ( cbw->combobox.PendingFocusOut )
                cbw->combobox.IgnoreFocusOut = True;
	    if ( cbw->combobox.TwmHandlingOn )
                cbw->combobox.PendingOverrideInOut = True;
            break;
        case LeaveNotify:
            LOG("OverrideShellCallback: LeaveNotify\n");
	    if ( cbw->combobox.TwmHandlingOn )
              cbw->combobox.PendingOverrideInOut = True;
            break;
    }
} /* OverrideShellCallback */

/* --------------------------------------------------------------------
 * Ha! Anscheinend kann man das Problem mit der einklappenden Liste,
 * sobald man den Arrow-Button anklickt, doch loesen! Allerdings geht
 * das auch nur von hinten durch die Brust in's Auge. Hier war die
 * Reihenfolge der Events bislang das Problem: Klickt man den Arrow-
 * Button an, so verliert das Eingabefeld den Focus, dann wird leider
 * schon die WorkProc aktiviert und laesst die Liste verschwinden.
 * Danach erst kommt der Arrow-Button-Callback an die Reihe. Um dieses
 * Dilemma doch noch zu loesen, wird hier darauf gelauert, wann und
 * welcher LeaveNotify kommt. Klickt der Benutzer den Pfeil an, so
 * kommt hier noch rechtzeitig ein LeaveNotify vorbei, der aber durch
 * einen Grab ausgeloest wurde. Und das ist eben nur beim Anklicken
 * der Fall. Damit wissen wir, das der FocusOut getrost ignoriert
 * werden darf.
 * Puhhh -- ist das ein kompliziertes Chaos.
 * Uebrigends...auch wenn manche Befehle zuerst ueberfluessig er-
 * scheinen...sie sind erforderlich, damit die ComboBox auch mit unter-
 * schiedlichen Window Managern zurechtkommt!
 */
static void ArrowCrossingCallback(Widget w, XtPointer pClientData,
                               XEvent *event, Boolean *ContDispatch)

{
    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
    switch ( event->type ) {
        case LeaveNotify:
	    LOG2("ArrowCrossingCallback: LeaveNotify, mode: %i\n", 
	         event->xcrossing.mode);
            if ( event->xcrossing.mode == NotifyGrab )
                cbw->combobox.IgnoreFocusOut = True;
            else
                cbw->combobox.IgnoreFocusOut = False;
            break;
    }
} /* ArrowCrossingCallback */

/* --------------------------------------------------------------------
 * Alle Hilfeaufrufe innerhalb der Kinder gehen an das eigentliche
 * Combo-Box-Widget weiter, so dass auch hier nach aussen hin die
 * Kinder-Widgets nicht in Erscheinung treten.
 */
static void HelpCallback(Widget w, XtPointer cbw, XtPointer CallData)
{
    XtCallCallbacks((Widget) cbw, XmNhelpCallback, CallData);
} /* HelpCallback */

/* --------------------------------------------------------------------
 * Wenn der Benutzer im Eingabefeld osfActivate drueckt, dann dieses
 * Ereignis offiziell bekanntgeben.
 */
static void ActivateCallback(Widget w, XtPointer cbw, XtPointer CallData)
{
    XtCallCallbacks((Widget) cbw, XmNactivateCallback, CallData);
} /* ActivateCallback */

/* --------------------------------------------------------------------
 * Ein Kind moechte sein Groesse veraendern und fragt deshalb hier bei
 * uns an.
 * Parameter:
 *   w		    Naja...
 *   *Request	    Vorschlag des Kindes
 * Ergebnis:
 *   *Reply	    Unsere Antwort darauf
 *   XtGeometryNo, da es uns bislang grundsaetzlich nie passt, es sei
 *   denn, es ist das Label... Naja, jetzt darf auch schon einmal das
 *   Listenfeld quengeln (aber nur, wenn es staendig sichtbar ist, 
 *   ansonsten wird es nicht beruecksichtigt!).
 */
static XtGeometryResult GeometryManager(Widget w, 
                                        XtWidgetGeometry *Request, 
				        XtWidgetGeometry *Reply)
{
    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
    XtGeometryResult Result = XtGeometryNo;
    
    /*
     * Falls das Listenfeld statisch dargestellt wird, muessen wir seine
     * Wuensche doch beruecksichtigen. Was fuer ein Aufwand...
     */
    if ( (w == XtParent(cbw->combobox.ListCtrl)) && cbw->combobox.StaticList ) {
        Dimension TotalWidth, TotalHeight, EditWidth, LabelWidth;
        XtWidgetGeometry MyRequest, YourReply, EditGeom;
        
        XtQueryGeometry(cbw->combobox.EditCtrl, NULL, &EditGeom);
        DefaultGeometry(cbw, &TotalWidth, &TotalHeight,
                             &EditWidth, &LabelWidth);
      	CheckDropDownOffset(cbw);
	
        if ( Request->request_mode && CWWidth )
            if ( (Dimension)(LabelWidth + cbw->combobox.DropDownOffset + 
                             Request->width) > TotalWidth )
                TotalWidth = LabelWidth + cbw->combobox.DropDownOffset + 
                             Request->width;
        
        if ( Request->request_mode && CWHeight )
            TotalHeight = EditGeom.height + Request->height;
    /*
     * Bastele nun eine Anfrage an Pappi zusammen und geh' ihm damit auf den
     * Keks. Wenn er zustimmt, ist sofort alles gut, wir muessen dann nur
     * noch das Layout aufpolieren, damit das Listenfeld die neue Groesse
     * bekommt. Wenn Pappi nur halb zustimmt, akzeptieren wir das und fragen
     * ihn damit noch einmal....
     */
        MyRequest.request_mode = CWWidth | CWHeight;
        MyRequest.width        = TotalWidth;
        MyRequest.height       = TotalHeight;
        Result = XtMakeGeometryRequest((Widget) cbw, &MyRequest, &YourReply);
	if ( Result == XtGeometryAlmost ) {
	    MyRequest.width  = YourReply.width;
	    MyRequest.height = YourReply.height;
	    Result = XtMakeGeometryRequest((Widget) cbw, &MyRequest, &YourReply);
	}
	if ( Result == XtGeometryYes )
	    DoLayout(cbw);
    } else 
    /*
     * Ansonsten darf nur noch das Schriftfeld Ansprueche anmelden.
     */
    if ( w != cbw->combobox.LabelCtrl )
        return XtGeometryNo; /* Was ICH hier vorgegeben habe, gilt! */
    else if ( cbw->combobox.ShowLabel ) { /* Naja, 'mal schauen! */
        Dimension TotalWidth, TotalHeight, EditWidth, LabelWidth;
        XtWidgetGeometry MyRequest;
        
        if ( Request->request_mode & CWWidth ) {
            DefaultGeometry(cbw, &TotalWidth, &TotalHeight,
                                 &EditWidth, &LabelWidth);
            TotalWidth = TotalWidth - LabelWidth + 
                         Request->width;
            
            MyRequest.request_mode = CWWidth;
            MyRequest.width        = TotalWidth;
            Result = XtMakeGeometryRequest((Widget) cbw, &MyRequest, NULL);

            if ( Result == XtGeometryYes )
		DoLayout(cbw);
        }
    }
    return Result;
} /* GeometryManager */

/* --------------------------------------------------------------------
 * Hier werden auf Wunsch diejenigen Farben, die bei der Combo-Box neu
 * gesetzt wurden, an alle Kinder weitergegeben.
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -