📄 newtoggleb.c
字号:
else { if ( w->label.menu_type != XmWORK_AREA ) { x -= 2; y -= 2; size += 4; } XDrawLine(Dsp, Win, w->toggle.select_GC, x + 2, y + 2, x + size - 2, y + size - 2); XDrawLine(Dsp, Win, w->toggle.select_GC, x + 3, y + 2, x + size - 2, y + size - 3); XDrawLine(Dsp, Win, w->toggle.select_GC, x + 2, y + 3, x + size - 3, y + size - 2); XDrawLine(Dsp, Win, w->toggle.select_GC, x + size - 2, y + 2, x + 2, y + size - 2); XDrawLine(Dsp, Win, w->toggle.select_GC, x + size - 3, y + 2, x + 2, y + size - 3); XDrawLine(Dsp, Win, w->toggle.select_GC, x + size - 2, y + 3, x + 3, y + size - 2); } } else { /* Sonst zeichnen wir einen Radio-Button. Hiervon kann jeweils * immer nur einer aus einer Menge "gedrueckt" sein. Wie der Name * bereits anklingen laesst, sind die Radio-Buttons rund. Ist * der Button im gedrueckten Zustand, so wird das Innere ausge- * malt. */ XDrawArc(Dsp, Win, BottomGC, x, y, size, size, (45 + 180) * 64, 180 * 64); XDrawArc(Dsp, Win, TopGC, x, y, size, size, 45 * 64, 180 * 64); if ( State != XmTOGGLE_OFF ) { XFillArc(Dsp, Win, State == XmTOGGLE_ON ? w->toggle.select_GC : w->label.insensitive_GC, x + 1, y + 1, size - 2, size - 2, 0, 360 * 64); if ( w->new_toggle.ShowReflection ) XFillArc(Dsp, Win, w->primitive.top_shadow_GC, x + 3, y + 3, (size >> 1) - 2, (size >> 1) - 2, 0, 360 * 64); } }} /* DrawIndicator *//* --------------------------------------------------------------------------- * Auf Anfrage hin entweder den Text des Buttons oder aber das passende Pixmap * ausgeben. */static void DrawText(XmNewToggleButtonWidget w){ Pixmap pixmap; if ( !XtIsRealized(w) ) return; if ( w->label.label_type == XmPIXMAP ) { pixmap = XmUNSPECIFIED_PIXMAP; if ( w->toggle.set ) { if ( XtIsSensitive((Widget)w) ) pixmap = w->toggle.on_pixmap != XmUNSPECIFIED_PIXMAP ? w->toggle.on_pixmap : w->label.pixmap; else pixmap = w->toggle.insen_pixmap != XmUNSPECIFIED_PIXMAP ? w->toggle.insen_pixmap : w->label.pixmap_insen; } else if ( !XtIsSensitive((Widget)w) ) pixmap = w->label.pixmap_insen; if ( pixmap == XmUNSPECIFIED_PIXMAP ) pixmap = w->label.pixmap; if ( pixmap == XmUNSPECIFIED_PIXMAP ) XClearArea(XtDisplay(w), XtWindow(w), 0, 0, w->label.TextRect.width, w->label.TextRect.height, False); else XCopyArea(XtDisplay(w), pixmap, XtWindow(w), w->label.normal_GC, 0, 0, w->label.TextRect.width, w->label.TextRect.height, w->label.TextRect.x, w->label.TextRect.y); } else _XmStringDrawMnemonic(XtDisplay(w), XtWindow(w), w->label.font, w->label._label, XtIsSensitive((Widget)w) ? w->label.normal_GC : w->label.insensitive_GC, w->label.TextRect.x, w->label.TextRect.y, w->label.TextRect.width, w->label.alignment, w->label.string_direction, NULL, XKeysymToString(w->label.mnemonic), w->label.mnemonicCharset); /* In jedem Fall wird aber ein eventueller Accelerator ausgegeben! */ if ( w->label._acc_text && !_XmStringEmpty(w->label._acc_text) ) _XmStringDraw(XtDisplay(w), XtWindow(w), w->label.font, w->label._acc_text, XtIsSensitive((Widget)w) ? w->label.normal_GC : w->label.insensitive_GC, w->label.acc_TextRect.x, w->label.acc_TextRect.y, w->label.acc_TextRect.width, w->label.alignment, w->label.string_direction, NULL);} /* DrawText *//* --------------------------------------------------------------------------- * Muss ein Teil des Widgets neu gezeichnet werden, so rufe dazu einfach die * passenden Methoden dieser Widgetklasse auf. Nachkommen duerfen die Methoden * auf Wunsch auch austauschen. * * Parameter: * w Das von Neuzeichnen betroffene Widget * event Naehere Informationen darueber, was neu zu zeichnen * ist... * region Wo ist was neu zu zeichnen... */static void Repaint(XmNewToggleButtonWidget w, XEvent *event, Region region){ CallDrawIndicatorMethod(w); CallDrawTextMethod(w);} /* Repaint *//* --------------------------------------------------------------------------- * Rufe eine der beliebten Callbacks des ToggleButtons auf, nachdem irgend- * etwas passiert ist... */static void CallCallbacks(XmNewToggleButtonWidget w, XEvent *event, int reason){ XmToggleButtonCallbackStruct CBData; CBData.reason = reason; CBData.event = event; CBData.set = w->toggle.set; if ( w->label.skipCallback && (reason == XmCR_VALUE_CHANGED) ) { CBData.reason = XmCR_ACTIVATE; XtCallCallbacks(XtParent(w), XmNentryCallback, (XtPointer) &CBData); } else XtCallCallbacks((Widget) w, reason == XmCR_ARM ? XmNarmCallback : reason == XmCR_DISARM ? XmNdisarmCallback : XmNvalueChangedCallback, (XtPointer) &CBData);} /* CallCallbacks *//* --------------------------------------------------------------------------- * Irgendwie hat die OSF doch ziemlich kraeftig herumgepfuscht...von klarer * OOP keine Rede! Hier muessen wir ggf. dafuer sorgen, dass alle Widgets in * einem RowColumn-Widgets das Radio-Verhalten verpasst bekommen. Nicht etwa, * dass das RowColumn-Widget das selbst taete...nein, dass muessen wir schon * selbst tun! */static void CheckRadioBehavior(XmNewToggleButtonWidget w){ Widget Parent = XtParent(w), Child; WidgetList Children; Cardinal NumChildren, i; Boolean RadioBehavior, RadioAlwaysOne; if ( XmIsRowColumn(Parent) ) { XtVaGetValues(Parent, XmNradioBehavior, &RadioBehavior, XmNradioAlwaysOne, &RadioAlwaysOne, XmNchildren, &Children, XmNnumChildren, &NumChildren, NULL); if ( RadioBehavior ) { for ( i = 0; i < NumChildren; ++i ) { Child = Children[i]; if ( (Child != (Widget) w) && XtIsManaged(w) ) XtVaSetValues(Children[i], XmNset, False, NULL); } if ( RadioAlwaysOne && w->toggle.set == XmTOGGLE_OFF ) { w->toggle.set = XmTOGGLE_ON; w->toggle.visual_set = w->toggle.set; } } }} /* CheckRadioBehavior *//* --------------------------------------------------------------------------- * Holla - Der Mauszeiger kommt, um uns zu besuchen in unserem bescheidenen * Widget. In diesem Fall schauen wir zuerst nach, ob denn der ToggleButton im * "geladenen" Zustand ist. Nur in diesem Fall muessen wir ueberhaupt von * diesen Ereignissen Notiz nehmen und den Button in demjenigen Zustand * zeichnen, in den er uebergehen wuerde, liesse der Benutzer die Maustaste * *innerhalb* des Widgets wieder los (= umschalten). Ausnahme von der * soeben genannten Regel: wir befinden uns in einem Pulldown- oder Popup- * Menu. */static void EnterWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ XtCallActionProc((Widget) w, "PrimitiveEnter", event, Params, *NumParams); if ( w->label.menu_type != XmWORK_AREA ) { /* Wir sitzen in einem Menu und muessen nun noch wissen, ob die * Tastaturbedienung abgeschaltet wurde. Dann bedeutet dies, dass * der Fokus dem Mauszeiger folgt und der ToggleButton immer dann * im "geladenen" Zustand dargestellt werden muss, wenn der Maus- * zeiger hier auftaucht. */ if ( _XmGetInDragMode((Widget) w) ) { _XmDrawShadows(XtDisplay((Widget) w), XtWindow((Widget) w), w->primitive.top_shadow_GC, w->primitive.bottom_shadow_GC, 0, 0, w->core.width, w->core.height, w->primitive.shadow_thickness, XmSHADOW_OUT); w->toggle.Armed = True; CallCallbacks(w, event, XmCR_ARM); } } else if ( w->toggle.Armed ) { w->toggle.visual_set = ToggleButtonNextState(w, w->toggle.set); CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_ARM); }} /* EnterWidget *//* --------------------------------------------------------------------------- * Sollte der Mauszeiger uns wieder verlassen, so muessen wir u.U. wieder den * alten Zustand wiederherstellen. Dieses ist immer dann erforderlich, wenn * der ToggleButton noch im "geladenen" Zustand ist, sobald der Mauszeiger das * Fenster des Widgets verlaesst. Da der Button zumindestens fuer den Be- * nutzer in den ungeladenen Zustand uebergeht, wird der entsprechende Call- * back noch flugs aufgerufen. */static void LeaveWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ XtCallActionProc((Widget) w, "PrimitiveLeave", event, Params, *NumParams); if ( w->label.menu_type != XmWORK_AREA ) { if ( _XmGetInDragMode((Widget) w) ) { _XmClearBorder(XtDisplay((Widget) w), XtWindow((Widget) w), 0, 0, w->core.width, w->core.height, w->primitive.shadow_thickness); w->toggle.Armed = False; CallCallbacks(w, event, XmCR_DISARM); } } else if ( w->toggle.Armed ) { w->toggle.visual_set = w->toggle.set; CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_DISARM); }} /* LeaveWidget *//* --------------------------------------------------------------------------- * Wenn der Benutzer auf den ToggleButton mit der linken Maustaste klickt, so * nimmt sich zum Einen der Button einfach den Tastaturfokus, zum anderen * geht er in den "geladenen" Zustand ueber. Darin verharrt er dann, um darauf * zu lauern, wann er denn losgehen darf. Mit Hilfe der Variablen Armed laesst * sich im folgenden bei jedem EnterNotify oder LeaveNotify Ereignis auf * einfache Weise klaeren, ob visual_set wieder an "set" angepasst werden muss * (falls im Zustand "armed"). Diese Routine wird aber dann nicht aufgerufen, * wenn wir uns innerhalb eines Menus befinden...! */static void ArmWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ XmProcessTraversal((Widget) w, XmTRAVERSE_CURRENT); w->toggle.visual_set = ToggleButtonNextState(w, w->toggle.set); w->toggle.Armed = True; CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_ARM);} /* ArmWidget */static void DisarmWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ w->toggle.visual_set = w->toggle.set; w->toggle.Armed = False; CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_DISARM);} /* DisarmWidget */static void SelectWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ /* Nur wenn die Maustaste innerhalb des eigentlichen Widgetfensters * losgelassen wurde, wird dieses als Aufforderung interpretiert, den * Zustand des ToggleButtons zu wechseln. */ if ( w->toggle.set != w->toggle.visual_set ) { w->toggle.set = w->toggle.visual_set; w->toggle.Armed = False; CheckRadioBehavior(w); CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_VALUE_CHANGED); }} /* SelectWidget *//* --------------------------------------------------------------------------- * Waehrend die Tastaturbedienung innerhalb des Menues ausgeschaltet war, * liess der Anwender die Maustaste ueber unserem Widget los. Das bedeutet, * dass es seinen Zustand wechseln soll! Dieses Ereignis tritt nur dann auf, * wenn der ToggleButton sich in einem Menue befindet, ansonsten wird die * zum Ausloesen erforderliche Transition ueberhaupt nicht angemeldet bei * den Intrinsics. */static void BtnUpWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ w->toggle.set = ToggleButtonNextState(w, w->toggle.set); w->toggle.visual_set = w->toggle.set; w->toggle.Armed = False; CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_VALUE_CHANGED); CallCallbacks(w, event, XmCR_DISARM);} /* BtnUpWidget *//* --------------------------------------------------------------------------- * Bei Tastaturbedienung erfolgt der Aufruf dieser Routine, um den Zustand des * ToggleButtons zu wechseln. */static void ArmAndActivateWidget(XmNewToggleButtonWidget w, XEvent *event, String *Params, Cardinal *NumParams){ w->toggle.set = ToggleButtonNextState(w, w->toggle.set); w->toggle.visual_set = w->toggle.set; w->toggle.Armed = False; if ( w->label.menu_type ) XtCallActionProc(XtParent((Widget) w) , "MenuShellPopdownDone", event, Params, *NumParams); CheckRadioBehavior(w); CallDrawIndicatorMethod(w); CallCallbacks(w, event, XmCR_ARM); CallCallbacks(w, event, XmCR_VALUE_CHANGED); CallCallbacks(w, event, XmCR_DISARM);} /* ArmAndActivateWidget *//* --------------------------------------------------------------------------- * Der Programmierer moechte eine Variable (aka Ressource) einer Instanz * dieses ToggleButtons veraendern. Wir muessen nun nachschauen, ob das * irgendwelche Konsequenzen nach sich zieht und ggf. den ToggleButton neu * zeichnen. */static Boolean SetValues(XmNewToggleButtonWidget cur, XmNewToggleButtonWidget req, XmNewToggleButtonWidget new, ArgList args, Cardinal *NumArgs){ Boolean Redraw = False; if ( (new->new_toggle.SwapShadows != cur->new_toggle.SwapShadows) || (new->new_toggle.ShowReflection != cur->new_toggle.ShowReflection ) || (new->new_toggle.TriState != cur->new_toggle.TriState) ) Redraw = True; new->toggle.visual_set = new->toggle.set; if ( cur->toggle.set != new->toggle.set ) CallDrawIndicatorMethod(new); return Redraw;} /* SetValues *//* Ende von NewToggleB.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -