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

📄 newtoggleb.c

📁 安装DDD之前
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * NewToggleB.c - Sieht nicht nur einfach besser aus als das Original aus der *                Motif-Mottenkiste, sondern darueberhinaus koennen die *                einzelnen Zustaende der "Ankreuzkaestchen" und "Radio- *                schalter" von den Anwender einfacher erfasst werden. Warum *                eigentlich nicht gleich so?! *                Und wer hat da denn vor einiger Zeit in den NetNews auf *                die Anfrage eines gestressten Programmierers gesuelzt, dass *                man ToggleButtons nicht ableiten kann und soll...? Ha! Es *                geht eben doch (Greetings to Leonardo DaVinci...) Alles *                zwar mangels Dokumentation eines der letzten wahren Aben- *                teuer unserer Zeit, aber das Ergebnis kann sich doch sehen *                lassen, oder?! * * Version 0.91b * Aktueller Zustand: *   16.05.1994  ToggleButton-Klasse mit 3 Zustaenden sowie einem besseren *               Aussehen implementiert. Ausserdem ist der ToggleButton auch *               in Menues einsetzbar! Arbeitet auch mit XmNradioBehavior *               in RowColumn-Widgets! *  * (c) 1994 Harald Albrecht * Institut fuer Geometrie und Praktische Mathematik * RWTH Aachen, Germany * albrecht@igpm.rwth-aachen.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING for more details); * if not, write to the Free Software Foundation, Inc., 675 Mass Ave,  * Cambridge, MA 02139, USA. * */#include "NewToggleBP.h"#include <Xm/BaseClassP.h>#include <Xm/DrawP.h>#include <Xm/MenuUtilP.h>/* --------------------------------------------------------------------------- * Resourcen-Liste... * Hier werden diejenigen Resourcen definiert, die von "aussen" - also * fuer den Programmierer oder Anwender - benutzbar und veraenderbar   * sind. *  * Der Aufbau der einzelnen Eintraege ist immer wieder gleich: * Resourcen-Name       XmN... oder XtN * Resourcen-Klasse     XmC... oder XtC * Resourcen-Type       XmR... oder XtR (Datentyp der Variable in der *                      struct der jeweiligen Widgetinstanz) * Resourcen-Groesse    aktuelle Groesse dieses Datentyps    * Resourcen-Offset     Lage der Variable innerhalb der struct der *                      Widgetinstanz * Defaultwert-Type     Typ des Defaultwertes * Defaultwert          (normalerweise) Zeiger auf den Defaultwert */#define offset(field) XtOffsetOf(XmNewToggleButtonRec, field)static XtResource resources[] = {    { /* Ist es ein normaler Toggle-Button (bzw. Radio-Button) oder hat       * er 3 Zustaende (= Kompatibilitaet zu anderen Oberflaechen) ?       */        XmNtriState, XmCTriState, XmRBoolean, sizeof(Boolean),        offset(new_toggle.TriState), XmRString, "False"    },/*    {        XmNselectColor, XmCSelectColor, XmRPixel, sizeof(Pixel),        offset(toggle.select_color), XtRCallProc, _XmForegroundColorDefault    }, */    {        XmNshowReflection, XmCShowReflection, XmRBoolean, sizeof(Boolean),        offset(new_toggle.ShowReflection), XmRString, "True"    },    {        XmNswapShadows, XmCSwapShadows, XmRBoolean, sizeof(Boolean),        offset(new_toggle.SwapShadows), XmRString, "True"    }}; /* resources */                                                       /* --------------------------------------------------------------------------- * Funktions-Prototypen fuer die 'Methoden' des ComboBox-Widgets. Eigentlich * sind das in unserem Falle gar nicht allzu viele. Die meiste Arbeit wird * spaeter von den einzelnen Action-Routinen geleistet, die durch bestimmte * Ereignisse (oder Ereignistransitionen) ausgeloest werden. */static void             ClassPartInit(WidgetClass);static void             Repaint(XmNewToggleButtonWidget, XEvent *, Region);static Boolean          SetValues(XmNewToggleButtonWidget,                                   XmNewToggleButtonWidget,                                   XmNewToggleButtonWidget,                                   ArgList, Cardinal *);/* --------------------------------------------------------------------------- * Diese Funktions-Prototypen stellen neue "Methoden" dar, die erstmalig von * dieser ToggleButton-Ersatzklasse eingefuehrt werden. */static void             DrawIndicator(XmNewToggleButtonWidget);static void             DrawText(XmNewToggleButtonWidget);/* --------------------------------------------------------------------------- * Hier versammeln sich alle Translations, die entweder neu hinzukommen oder * aber von XmLabel ererbt wurden. Zu beachten ist, dass diejenigen Trans- * lationen, die bereits XmPrimitive kennt, zumindest innerhalb der Klassen- * struktur geerbt werden. Allerdings werden nichts desto trotz bei allen * Nachkommen von XmLabel moeglicherweise einige Translationen von XmPri- * mitive wieder ueberschrieben. * Schluck: in der Tat koennen wir einfach diejenigen Translationen von * XmToggleButton uebernehmen, wir muessen lediglich dafuer Sorge tragen, * neue Action-Prozeduren zu registrieren. In diesem Fall werden dann * praktischerweise gleich die neuen Routinen benutzt. Ergo: es folgt hier * keine Translation-Tabelle... *//* --------------------------------------------------------------------------- * Hier werden nun alle sog. Action-Routinen aufgezaehlt, die diese Widget- * klasse neu definiert. Dabei werden zum Teil bereits bestehende Action- * routinen der Vorfahrenklasse ueberschrieben. * Zuvor (vor der Zuordnung) sind aber noch ein Prototypen vonnoeten, damit * der Compiler nicht meckert. */#define ACTIONPROC(proc) \    static void proc(XmNewToggleButtonWidget, XEvent *, String *, Cardinal *)ACTIONPROC(EnterWidget);ACTIONPROC(LeaveWidget);ACTIONPROC(ArmWidget);ACTIONPROC(DisarmWidget);ACTIONPROC(SelectWidget);ACTIONPROC(ArmAndActivateWidget);ACTIONPROC(BtnUpWidget);static XtActionsRec actions[] = {	{ "Enter",          (XtActionProc) EnterWidget          },	{ "Leave",          (XtActionProc) LeaveWidget          },	{ "Arm",            (XtActionProc) ArmWidget            },	{ "Disarm",         (XtActionProc) DisarmWidget         },	{ "Select",         (XtActionProc) SelectWidget         },	{ "ArmAndActivate", (XtActionProc) ArmAndActivateWidget },	{ "BtnUp",          (XtActionProc) BtnUpWidget          }}; /* actions *//* --------------------------------------------------------------------------- * Klassen-Definition unserer neuen ToggleButton-Klasse. */XmNewToggleButtonClassRec xmNewToggleButtonClassRec = {    { /*** core-Klasse ***/    /* superclass		    */	(WidgetClass) &xmToggleButtonClassRec,    /* class_name		    */	"XmNewToggleButton",    /* widget_size		    */	sizeof(XmNewToggleButtonRec),    /* class_initialize   	    */	NULL,    /* class_part_initialize	    */	(XtWidgetClassProc) ClassPartInit,    /* class_inited       	    */	False, /* IMMER mit FALSE initialisieren !! */    /* initialize	  	    */	NULL,    /* initialize_hook		    */	NULL,    /* realize		  	    */	(XtRealizeProc) XmInheritRealize,    /* actions		  	    */	actions,    /* num_actions	  	    */	XtNumber(actions),    /* resources	  	    */	resources,    /* num_resources	  	    */	XtNumber(resources),    /* xrm_class	  	    */	NULLQUARK,    /* compress_motion	  	    */	True,    /* compress_exposure  	    */	XtExposeCompressMultiple,    /* compress_enterleave	    */	True,    /* visible_interest	  	    */	False,    /* destroy		  	    */	NULL,    /* resize		  	    */	(XtWidgetProc) XmInheritResize,    /* expose		  	    */	(XtExposeProc) Repaint,    /* set_values	  	    */	(XtSetValuesFunc) SetValues,    /* set_values_hook		    */	NULL,    /* set_values_almost	    */	XtInheritSetValuesAlmost,    /* get_values_hook		    */	NULL,    /* accept_focus	 	    */	NULL,    /* version			    */	XtVersion,    /* callback_private   	    */	NULL,    /* tm_table		   	    */	NULL,    /* query_geometry		    */	XtInheritQueryGeometry,    /* display_accelerator	    */	XtInheritDisplayAccelerator,    /* extension          	    */	NULL    },     { /*** xmPrimitive-Klasse ***/    /* border_highlight		    */	(XtWidgetProc) _XtInherit,    /* border_unhighlight	    */	(XtWidgetProc) _XtInherit,    /* translations		    */  XtInheritTranslations,    /* arm_and_activate		    */  NULL,    /* syn_resources		    */  NULL,    /* num_syn_resources	    */  0,    /* extension		    */	NULL    },     { /*** xmLabel-Klasse ***/    /* setOverrideCallback	    */	(XtWidgetProc) XmInheritSetOverrideCallback,    /* menuProcs		    */  NULL,    /* translations		    */  XtInheritTranslations,    /* extension                    */  NULL    },     { /*** xmToggleButton-Klasse ***/    /* foo			    */  0    },     { /*** xmNewToggleButton-Klasse ***/    /* DrawIndicator		    */  XmInheritNewToggleButtonIndicatorDrawProc,    /* DrawText                     */  XmInheritNewToggleButtonTextDrawProc    }}; /* xmNewToggleButtonClassRec */WidgetClass xmNewToggleButtonWidgetClass = (WidgetClass) &xmNewToggleButtonClassRec;#include <stdio.h>/* --------------------------------------------------------------------------- * Diese Initialisierungsroutine wird immer dann aufgerufen, wenn entweder * diese Widgetklasse oder aber eine davon abgeleitete Klasse erstmalig in * "Betrieb" genommen wird. Hier sorgen wir dafuer, dass abgeleitete Klassen * die neu eingefuehrten Methoden erben koennen. Dabei handelt es sich um * Methoden, um sowohl den "Indikator" als auch den Text/Pixmap zu zeichnen. * Leider hat die OSF sowas naemlich bei ihrer ToggleButton-Klasse total * vergessen! Daher ja auch der ganze Aufwand hier!! * * Parameter: *   wc			Diejenige Widgetklasse, die erstmalig in Betrieb ge- *			nommen werden soll. Dieses ist entweder die hier neu *			eingefuehrte Klasse oder aber moeglicherweise eine *			davon abgeleitete. */static void ClassPartInit(WidgetClass wc){    /* Sorge dafuer, dass die neu definierten Methoden von den Nachkommen     * geerbt werden koennen.     */    if ( ((XmNewToggleButtonClassRec *) wc)->newtoggle_class.DrawIndicator ==           XmInheritNewToggleButtonIndicatorDrawProc )        ((XmNewToggleButtonClassRec *) wc)->newtoggle_class.DrawIndicator =            (XmNewToggleButtonIndicatorDrawProc) DrawIndicator;    if ( ((XmNewToggleButtonClassRec *) wc)->newtoggle_class.DrawText ==           XmInheritNewToggleButtonTextDrawProc )        ((XmNewToggleButtonClassRec *) wc)->newtoggle_class.DrawText =            (XmNewToggleButtonTextDrawProc) DrawText;    /* ...eigentlich ja ueberfluessig, da bereits in den vorherigen Klassen     * durchgefuehrt... aber schaden tut's auch nicht!     */    _XmFastSubclassInit(wc, XmTOGGLE_BUTTON_BIT | XmLABEL_BIT |                             XmPRIMITIVE_BIT);} /* ClassPartInit *//* --------------------------------------------------------------------------- * Mit Hilfe dieser Routine kann anhand des aktuellen Zustands ermittelt * werden, in welchen Zustand der Button als naechstes uebergehen wird. * * Parameter: *   w			Widget, fuer den der naechste Zustand erfragt werden *			soll. *   State		Der aktuelle Zustand. Hierzu bitte den folgenden *			Zustand ermitteln. * * Ergebnis: *   Der naechste Zustand des Buttons. */static Boolean ToggleButtonNextState(XmNewToggleButtonWidget w,                                     Boolean State){    if ( w->new_toggle.TriState )        switch ( State ) {            case XmTOGGLE_ON      : return XmTOGGLE_OFF;            case XmTOGGLE_OFF     : return XmTOGGLE_DONTKNOW;            case XmTOGGLE_DONTKNOW: default: return XmTOGGLE_ON;        }    switch ( State ) {        case XmTOGGLE_ON      : return XmTOGGLE_OFF;        case XmTOGGLE_OFF     : return XmTOGGLE_ON;        case XmTOGGLE_DONTKNOW: default: return XmTOGGLE_ON;    }} /* ToggleButtonNextState *//* --------------------------------------------------------------------------- * Zeichne den Indikator, das ist entweder ein Ankreuzkaestchen oder aber ein * runder Radioschalter. (Ach, waren das noch Zeiten, als man sich an den * Roehren die Finger waermen konnte und man noch zum Betrieb so richtig * Spannung brauchte -- nicht so laeppische 3,3V!!!) * * Parameter: *   w			Dasjenige Widget, fuer das der Indikator zu zeichnen *			ist. Den aktuellen Zustand erfaehrt man aus der *			Instanz-Struktur dieses Widgets aus der Variable *			w->toggle.visual_state. */static void DrawIndicator(XmNewToggleButtonWidget w){    Display   *Dsp = XtDisplay((Widget) w);    Window    Win = XtWindow((Widget) w);    GC        TopGC, BottomGC;    Position  x, y;    Dimension size;    Boolean   State = w->toggle.visual_set;    if ( !XtIsRealized(w) ) return;        /* Zuerst muessen wir uns hier einmal die geeigneten GCs zusammenstellen,     * mit deren Hilfe wir den sog. Indikator zeichnen.     */    if ( (State == XmTOGGLE_OFF) || !(w->new_toggle.SwapShadows) ||         (w->label.menu_type != XmWORK_AREA) ) {        TopGC    = w->primitive.top_shadow_GC;        BottomGC = w->primitive.bottom_shadow_GC;    } else {        TopGC    = w->primitive.bottom_shadow_GC;        BottomGC = w->primitive.top_shadow_GC;    }        /* Jetzt muessen wir noch berechnen, wo denn der Indikator zu zeichnen     * ist.     */    size = w->toggle.indicator_dim - 3 ;    if ( w->label.menu_type != XmWORK_AREA ) size += 2;    if ( size < 4 ) size = 4;    x = w->label.margin_width + w->primitive.highlight_thickness;    if ( w->label.string_direction == XmSTRING_DIRECTION_R_TO_L )        x = w->core.width - x - size;    y = ((w->core.height - size) >> 1);/*    XClearArea(Dsp, Win, x, y, size, size, False); */    /* Wir muessen hier dafuer sorgen, dass ein evtl. doch noch von     * XtSetValues gezeichneter alter Indikator entsorgt wird!     */    XClearArea(Dsp, Win,                x, w->label.TextRect.y,               w->toggle.indicator_dim, w->label.TextRect.height,               False);        if ( w->toggle.ind_type != XmONE_OF_MANY ) {            /* Es ist ein sog. Ankreuzkaestchen. Hiervon koennen jeweils be-         * liebig viele angekreuzt oder auch nicht angekreuzt sein. Dar-         * gestellt werden sie konsequenterweise als Kaestchen.         */        XDrawLine(Dsp, Win, TopGC, x, y, x + size, y);        XDrawLine(Dsp, Win, TopGC, x, y, x, y + size);        XDrawLine(Dsp, Win, BottomGC, x + size, y + 1, x + size, y + size);        XDrawLine(Dsp, Win, BottomGC, x + 1, y + size, x + size, y + size);        if ( State != XmTOGGLE_OFF )            if ( State != XmTOGGLE_ON )                XFillRectangle(Dsp, Win, w->label.insensitive_GC,                               x + 2, y + 2, size - 3, size - 3);

⌨️ 快捷键说明

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