1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /*
- * DtWidget/ComboBox.c
- */
- /*
- * (c) Copyright 1996 Digital Equipment Corporation.
- * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company
- * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
- * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
- * (c) Copyright 1993, 1994, 1996 Novell, Inc.
- * (c) Copyright 1996 FUJITSU LIMITED.
- * (c) Copyright 1996 Hitachi.
- */
- #ifdef REV_INFO
- #ifndef lint
- static char rcsid[] =
- "$XConsortium: ComboBox.c /main/15 1996/10/29 12:48:08 cde-hp $"
- #endif
- #endif
- /***********************************************************
- Copyright 1993 Interleaf, Inc.
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose without fee is granted,
- provided that the above copyright notice appear in all copies
- and that both copyright notice and this permission notice appear
- in supporting documentation, and that the name of Interleaf not
- be used in advertising or publicly pertaining to distribution of
- the software without specific written prior permission.
- Interleaf makes no representation about the suitability of this
- software for any purpose. It is provided "AS IS" without any
- express or implied warranty.
- ******************************************************************/
- /*
- * (C) Copyright 1991,1992, 1993
- * Interleaf, Inc.
- * 9 Hillside Avenue,
- * Waltham, MA 02154
- *
- * ComboBox.c (DtComboBoxWidget):
- *
- * I wanted a margin around the widget (outside the shadow, like buttons),
- * so that the combo-box could be made the same size as a
- * push-button, etc. The bulletin-board widget always puts the shadow at
- * the outside edge of the widget, so combo-box is a sublcass of
- * manager, and we do everything ourselves.
- *
- * One must be carefull when using Dimension (for core width and height).
- * Dimension is an unsigned short. This causes problems when subtracting
- * and ending up with what should be a negative number (but it doesn't).
- * All child widget positioning is done by the combo_box. We don't
- * use any heavy-weight forms, etc. to help us out.
- *
- * There is no padding when editable. If using a label given it a
- * small margin, so it doesn't run up against the side of our
- * shadow or the arrow.
- *
- * Make some of the ComboBox functions common, so they can be shared
- * with SpinButton.
- *
- * The label-string resource got out of control. Its role kept getting
- * expanded; now the whole thing is a mess. Currently it shadows the
- * label's label-string. If the user sets it explicitly it will
- * take affect for as long as update-label is false. If update-label
- * is true, it will take affect until the end-user makes a selection
- * off the list.
- *
- * Known bugs:
- * Changing margin_width or margin_height resources when the
- * combo_box has focus will probably result in display glitches.
- *
- */
- /*
- * The DtComboBox widget is rigged with the Motif widget binary compatibilit
- * mechanism. All Motif-specific changes for this mechanism are preceded
- * by a comment including the string "MotifBc".
- *
- * For a description of the Motif widget binary compatibility mechanism
- * see the reference manual entry on XmResolveAllPartOffsets().
- *
- */
- /* _NO_PROTO support no longer required: */
- #include <Xm/XmP.h> /* for fast subclassing in XmIsComboBox */
- #include <Xm/XmosP.h> /* for INT_MAX */
- #include <Dt/DtMsgsP.h>
- #include "ComboBoxP.h"
- #include <Xm/DrawP.h>
- #include <Xm/DisplayP.h>
- #include <Xm/List.h>
- #include <Xm/ComboBox.h> /* for redirecting utility functions */
- #include "DtWidgetI.h" /* for _Dt thread-safety macros */
- /* some unpublished Motif interfaces */
- #include <Xm/XmPrivate.h>
- /* From MenuUtilP.h */
- extern int _XmGrabKeyboard(Widget widget, int owner_events, int pointer_mode,
- int keyboard_mode, Time time) ;
- /*
- * MotifBc
- */
- #define DtComboBoxIndex (XmManagerIndex + 1)
- static XmOffsetPtr ipot; /* Instance part offset table */
- static XmOffsetPtr cpot; /* Constraint part offset table */
- #define ScrollBarVisible( wid) (wid && XtIsManaged( wid))
- static void ClassInitialize (void);
- static void Initialize (DtComboBoxWidget request,
- DtComboBoxWidget new, ArgList given_args,
- Cardinal *num_args);
- static XmNavigability WidgetNavigable (DtComboBoxWidget combo);
- static void _ComboBoxFocusIn (DtComboBoxWidget combo, XEvent *event,
- char **params, Cardinal *num_params);
- static void _ComboBoxFocusOut (DtComboBoxWidget combo, XEvent *event,
- char **params, Cardinal *num_params);
- static void DrawHighlight (DtComboBoxWidget combo, Boolean clear);
- static void _ComboBoxActivate (Widget w, XEvent *event, char **params,
- Cardinal *num_params);
- static void _ComboBoxKbdCancel (Widget w, XEvent *event, char **params,
- Cardinal *num_params);
- static void _ComboBoxPrevTabGroup (Widget w, XEvent *event,
- char **params, Cardinal *num_params);
- static void _ComboBoxNextTabGroup (Widget w, XEvent *event,
- char **params, Cardinal *num_params);
- static void CheckResources (DtComboBoxWidget combo);
- static void Destroy (DtComboBoxWidget combo);
- static void Resize (DtComboBoxWidget combo);
- static void Redisplay (DtComboBoxWidget w, XEvent *event,
- Region region);
- static XtGeometryResult GeometryManager (Widget w,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply);
- static void SetComboBoxSize (DtComboBoxWidget combo);
- static void ForceChildSizes (DtComboBoxWidget combo);
- static void LayoutChildren (DtComboBoxWidget combo);
- static Boolean SetValues (DtComboBoxWidget current,
- DtComboBoxWidget request, DtComboBoxWidget new);
- static void ClearShadow (DtComboBoxWidget w, Boolean all);
- static void DrawShadow (DtComboBoxWidget w);
- static char* GetTextString (XmString xm_string);
- static void SetTextFieldData (DtComboBoxPart *combo_p, XmString item);
- static void SetMaximumLabelSize (DtComboBoxPart *combo_p);
- static void SetLabelData (DtComboBoxPart *combo_p, XmString item,
- Boolean force_label_string);
- static void select_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void shell_event_handler (Widget widget, XtPointer client_data,
- XEvent* event, Boolean *dispatch);
- static void list_event_handler (Widget widget, XtPointer client_data,
- XEvent* event, Boolean *dispatch);
- static void TextFieldActivate (DtComboBoxPart *combo_p, XtPointer call_data);
- static void activate_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void arrow_expose_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void text_losing_focus_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void text_activate_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void text_focus_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void SyncWithList (DtComboBoxPart *combo_p);
- static XmImportOperator _XmSetSyntheticResForChild (Widget widget,
- int offset,
- XtArgVal * value);
- /* Converter */
- static Boolean _CvtStringToType (Display *dpy, XrmValuePtr args,
- Cardinal *num_args, XrmValuePtr from, XrmValuePtr to, XtPointer *data);
- /* Grab and Ungrab processing */
- static void input_ungrab ( DtComboBoxWidget combo, int ungrab_mask);
- /* Resolution Independent Processing */
- void _DtComboBoxGetArrowSize( Widget w,
- int resource_offset,
- XtArgVal *value);
- void _DtComboBoxGetListMarginHeight( Widget w,
- int resource_offset,
- XtArgVal *value);
- void _DtComboBoxGetListMarginWidth( Widget w,
- int resource_offset,
- XtArgVal *value);
- void _DtComboBoxGetListSpacing( Widget w,
- int resource_offset,
- XtArgVal *value);
- static XmString InitLabel = NULL;
- /*
- * MotifBc
- */
- #define Arrow(w) XmField(w,ipot,DtComboBox,arrow,Widget)
- #define Shell(w) XmField(w,ipot,DtComboBox,shell,Widget)
- #define Frame(w) XmField(w,ipot,DtComboBox,frame,Widget)
- #define Label(w) XmField(w,ipot,DtComboBox,label,Widget)
- #define Sep(w) XmField(w,ipot,DtComboBox,sep,Widget)
- #define OldWidth(w) XmField(w,ipot,DtComboBox,old_width,Dimension)
- #define OldHeight(w) XmField(w,ipot,DtComboBox,old_height,Dimension)
- #define LabelMaxLength(w) XmField(w,ipot,DtComboBox,label_max_length,Dimension)
- #define LabelMaxHeight(w) XmField(w,ipot,DtComboBox,label_max_height,Dimension)
- #define MaxShellWidth(w) XmField(w,ipot,DtComboBox,max_shell_width,Dimension)
- #define MaxShellHeight(w) XmField(w,ipot,DtComboBox,max_shell_height,Dimension)
- #define MarginHeight(w) XmField(w,ipot,DtComboBox,margin_height,Dimension)
- #define MarginWidth(w) XmField(w,ipot,DtComboBox,margin_width,Dimension)
- #define SelectedItem(w) XmField(w,ipot,DtComboBox,selected_item,XmString)
- #define SelectedPosition(w) XmField(w,ipot,DtComboBox,selected_position,int)
- #define SelectionCallback(w) \
- XmField(w,ipot,DtComboBox,selection_callback,XtCallbackList)
- #define Type(w) XmField(w,ipot,DtComboBox,type,unsigned char)
- #define ArrowSpacing(w) XmField(w,ipot,DtComboBox,arrow_spacing,Dimension)
- #define ArrowSize(w) XmField(w,ipot,DtComboBox,arrow_size,Dimension)
- #define ActivateCallback(w) \
- XmField(w,ipot,DtComboBox,activate_callback,XtCallbackList)
- #define Alignment(w) XmField(w,ipot,DtComboBox,alignment,unsigned char)
- #define ArrowType(w) XmField(w,ipot,DtComboBox,arrow_type,unsigned char)
- #define TextColumns(w) XmField(w,ipot,DtComboBox,text_columns,short)
- #define FocusCallback(w) XmField(w,ipot,DtComboBox,focus_callback,XtCallbackList)
- #define HorizontalSpacing(w) XmField(w,ipot,DtComboBox,horizontal_spacing,Dimension)
- #define ItemCount(w) XmField(w,ipot,DtComboBox,item_count,int)
- #define Items(w) XmField(w,ipot,DtComboBox,items,XmStringTable)
- #define ListItems(w) XmField(w,ipot,DtComboBox,list_items,XmStringTable)
- #define LabelString(w) XmField(w,ipot,DtComboBox,label_string,XmString)
- #define List(w) XmField(w,ipot,DtComboBox,list,Widget)
- #define ListFontList(w) XmField(w,ipot,DtComboBox,list_font_list,XmFontList)
- #define ListMarginHeight(w) XmField(w,ipot,DtComboBox,list_margin_height,Dimension)
- #define ListMarginWidth(w) XmField(w,ipot,DtComboBox,list_margin_width,Dimension)
- #define ListSpacing(w) XmField(w,ipot,DtComboBox,list_spacing,Dimension)
- #define LosingFocusCallback(w) XmField(w,ipot,DtComboBox,losing_focus_callback,XtCallbackList)
- #define TextMaxLength(w) XmField(w,ipot,DtComboBox,text_max_length,unsigned int)
- #define MenuPostCallback(w) XmField(w,ipot,DtComboBox,menu_post_callback,XtCallbackList)
- #define Orientation(w) XmField(w,ipot,DtComboBox,orientation,unsigned char)
- #define PoppedUp(w) XmField(w,ipot,DtComboBox,popped_up,Boolean)
- #define RecomputeSize(w) XmField(w,ipot,DtComboBox,recompute_size,Boolean)
- #define Text(w) XmField(w,ipot,DtComboBox,text,Widget)
- #define TopItemPosition(w) XmField(w,ipot,DtComboBox,top_item_position,int)
- #define UpdateLabel(w) XmField(w,ipot,DtComboBox,update_label,Boolean)
- #define VerticalSpacing(w) XmField(w,ipot,DtComboBox,vertical_spacing,Dimension)
- #define VisibleItemCount(w) XmField(w,ipot,DtComboBox,visible_item_count,int)
- /*
- * DtComboBoxWidget specific defines.
- */
- #define PUnitType(w) w->primitive.unit_type
- #define ShellPoppedUp(w) w->shell.popped_up
- #define MUnitType(w) w->manager.unit_type
- #define COMBO_SHADOW(w) w->manager.shadow_thickness
- #define LayoutDirection(w) w->manager.string_direction
- #define NavigationType(w) w->manager.navigation_type
- #define TraversalOn(w) w->manager.traversal_on
- #define BackgroundGC(w) w->manager.background_GC
- #define HighlightGC(w) w->manager.highlight_GC
- #define TopShadowGC(w) w->manager.top_shadow_GC
- #define BottomShadowGC(w) w->manager.bottom_shadow_GC
- #define BackgroundPixel(w) w->core.background_pixel
- #define X(w) w->core.x
- #define Y(w) w->core.y
- #define Width(w) w->core.width
- #define Height(w) w->core.height
- #define BorderWidth(w) w->core.border_width
- #define Sensitive(w) w->core.sensitive
- #define AncestorSensitive(w) w->core.ancestor_sensitive
- #define Parent(w) w->core.parent
- #define COMBO_MARGIN_W(w) MarginWidth(w)
- #define COMBO_MARGIN_H(w) MarginHeight(w)
- #define COMBO_H_SPACING(w) HorizontalSpacing(w)
- #define COMBO_V_SPACING(w) VerticalSpacing(w)
- #define GRAB_POINTER 1 << 0
- #define GRAB_KEYBOARD 1 << 1
- #define DtNonePopup 0
- #define DtPopup 1 << 0
- #define DtButtonPressPopup 1 << 1
- #define DtKeyPressPopup 1 << 2
- #define LIST_EVENTS (ButtonReleaseMask | FocusChangeMask | EnterWindowMask)
- #define SHELL_EVENTS (ButtonPressMask | ButtonReleaseMask)
- #define INVALID_DIMENSION (0xFFFF)
- static char ComboBoxTranslationTable[] = "\
- <FocusIn>: ComboBoxFocusIn() \n\
- <FocusOut>: ComboBoxFocusOut() \n\
- <Key>osfDown: ComboBoxActivate() \n\
- <Btn1Down>: ComboBoxActivate() \n\
- <Key>osfSelect: ComboBoxActivate() \n\
- ~s ~m ~a <Key>space: ComboBoxActivate() \n\
- ";
- static char ComboBoxLabelTranslationTable[] = "\
- <Key>osfDown: ComboBoxActivate(label) \n\
- <Btn1Down>: ComboBoxActivate(label) \n\
- <Key>osfSelect: ComboBoxActivate(label) \n\
- ~s ~m ~a <Key>space: ComboBoxActivate(label) \n\
- ";
- /* Keyboard Only Traversing During Editable-Mode */
- static char ComboBoxTextTranslationTable[] = "\
- <Key>osfUp: ComboBoxActivate(label) \n\
- <Key>osfDown: ComboBoxActivate(label) \n\
- ";
- static char ComboBoxButtonTranslationTable[] = "\
- <Key>osfDown: ComboBoxActivate(label) \n\
- <Btn1Down>: ComboBoxActivate(label) \n\
- ~s ~m ~a <Key>space: ComboBoxActivate(label) \n\
- s ~m ~a <Key>Tab: ComboBoxPrevTabGroup()\n\
- ~m ~a <Key>Tab: ComboBoxNextTabGroup()\n\
- ";
- static char ComboBoxListTranslationTable[] = "\
- <Key>osfCancel: ListKbdCancel() ComboBoxKbdCancel() \n\
- ";
- static XtActionsRec ComboBoxActionTable[] = {
- {"ComboBoxFocusIn", (XtActionProc)_ComboBoxFocusIn},
- {"ComboBoxFocusOut", (XtActionProc)_ComboBoxFocusOut},
- {"ComboBoxActivate", (XtActionProc)_ComboBoxActivate},
- {"ComboBoxKbdCancel", (XtActionProc)_ComboBoxKbdCancel},
- {"ComboBoxPrevTabGroup", (XtActionProc)_ComboBoxPrevTabGroup},
- {"ComboBoxNextTabGroup", (XtActionProc)_ComboBoxNextTabGroup},
- };
- /*
- * DtComboBoxWidget resources
- */
- #define offset(field) XtOffset(DtComboBoxWidget, field)
- #define DtOffset(field) XmPartOffset(DtComboBox,field)
- static XmPartResource resources[] = {
- {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
- sizeof(Dimension), offset(manager.shadow_thickness),
- XmRImmediate, (XtPointer)TEXT_FIELD_SHADOW},
- /*
- * ComboBox specific resources
- */
- {DtNactivateCallback, DtCCallback, XmRCallback, sizeof(XtCallbackList),
- DtOffset(activate_callback), XmRCallback,
- (XtPointer)NULL},
- {DtNalignment, DtCAlignment, XmRAlignment, sizeof(unsigned char),
- DtOffset(alignment), XmRImmediate,
- (XtPointer)DtALIGNMENT_END},
- {DtNarrowSpacing, DtCArrowSpacing, XmRHorizontalDimension,
- sizeof(Dimension), DtOffset(arrow_spacing),
- XmRImmediate, (XtPointer)0},
- {DtNarrowType, DtCArrowType, DtRArrowType, sizeof(unsigned char),
- DtOffset(arrow_type), XmRImmediate, (XtPointer)DtMOTIF},
- {DtNcolumns, DtCColumns, XmRShort, sizeof(short),
- DtOffset(text_columns), XmRImmediate, (XtPointer)20},
- {DtNfocusCallback, DtCCallback, XmRCallback, sizeof(XtCallbackList),
- DtOffset(focus_callback), XmRCallback,
- (XtPointer)NULL},
- {DtNhorizontalSpacing, DtCHorizontalSpacing, XmRHorizontalDimension,
- sizeof(Dimension), DtOffset(horizontal_spacing),
- XmRImmediate, (XtPointer)INVALID_DIMENSION},
- {DtNitemCount, DtCItemCount, XmRInt, sizeof(int),
- DtOffset(item_count), XmRImmediate, (XtPointer)0},
- /*
- * items is used only for seeing if the user changed the list. It
- * is only a pointer that reflects the current list's items.
- */
- {DtNitems, DtCItems, XmRXmStringTable, sizeof(XmStringTable),
- DtOffset(items), XmRImmediate, (XtPointer)NULL},
- {DtNlabelString, DtCXmString, XmRXmString, sizeof(XmString),
- DtOffset(label_string), XmRImmediate, (XtPointer)NULL},
- {DtNlist, DtCList, XmRWidget, sizeof(Widget),
- DtOffset(list), XmRImmediate, (XtPointer)NULL},
- {DtNlistFontList, DtCListFontList, XmRFontList, sizeof(XmFontList),
- DtOffset(list_font_list), XmRImmediate, (XtPointer)NULL},
- {DtNlistMarginHeight, DtCListMarginHeight, XmRVerticalDimension,
- sizeof(Dimension), DtOffset(list_margin_height),
- XmRImmediate, (XtPointer)MARGIN},
- {DtNlistMarginWidth, DtCListMarginWidth, XmRHorizontalDimension,
- sizeof(Dimension), DtOffset(list_margin_width),
- XmRImmediate, (XtPointer)MARGIN},
- {DtNlistSpacing, DtCListSpacing, XmRVerticalDimension,sizeof(Dimension),
- DtOffset(list_spacing), XmRImmediate, (XtPointer)0},
- {DtNlosingFocusCallback, DtCCallback, XmRCallback, sizeof(XtCallbackList),
- DtOffset(losing_focus_callback), XmRCallback,
- (XtPointer)NULL},
- {DtNmarginHeight, DtCMarginHeight, XmRVerticalDimension,
- sizeof(Dimension), DtOffset(margin_height),
- XmRImmediate, (XtPointer)MARGIN},
- {DtNmarginWidth, DtCMarginWidth, XmRHorizontalDimension, sizeof(Dimension),
- DtOffset(margin_width), XmRImmediate, (XtPointer)MARGIN},
- {DtNmaxLength, DtCMaxLength, XmRInt, sizeof(unsigned int),
- DtOffset(text_max_length), XmRImmediate, (XtPointer)INT_MAX},
- {DtNmenuPostCallback, DtCCallback, XmRCallback, sizeof(XtCallbackList),
- DtOffset(menu_post_callback), XmRCallback, (XtPointer)NULL},
- {DtNorientation, DtCOrientation, XmROrientation, sizeof(unsigned char),
- DtOffset(orientation), XmRImmediate, (XtPointer)DtRIGHT},
- {DtNpoppedUp, DtCPoppedUp, XmRBoolean, sizeof(Boolean),
- DtOffset(popped_up), XmRImmediate, (XtPointer)FALSE},
- {DtNrecomputeSize, DtCRecomputeSize, XmRBoolean, sizeof(Boolean),
- DtOffset(recompute_size), XmRImmediate, (XtPointer)TRUE},
- {DtNselectedItem, DtCXmString, XmRXmString, sizeof(XmString),
- DtOffset(selected_item), XmRImmediate, (XtPointer)NULL},
- {DtNselectedPosition, DtCSelectedPosition, XmRInt, sizeof(int),
- DtOffset(selected_position), XmRImmediate, (XtPointer)0},
- {DtNselectionCallback, DtCCallback, XmRCallback, sizeof(XtCallbackList),
- DtOffset(selection_callback), XmRCallback, (XtPointer)NULL},
- {DtNtextField, DtCTextField, XmRWidget, sizeof(Widget),
- DtOffset(text), XmRImmediate, (XtPointer)NULL},
- {DtNtopItemPosition, DtCTopItemPosition, XmRInt, sizeof(int),
- DtOffset(top_item_position), XmRImmediate, (XtPointer)1},
- {DtNcomboBoxType, DtCComboBoxType, DtRComboBoxType, sizeof(unsigned char),
- DtOffset(type), XmRImmediate,(XtPointer)DtDROP_DOWN_LIST},
- {DtNupdateLabel, DtCUpdateLabel, XmRBoolean, sizeof(Boolean),
- DtOffset(update_label), XmRImmediate, (XtPointer)TRUE},
- {DtNvisibleItemCount, DtCVisibleItemCount, XmRInt, sizeof(int),
- DtOffset(visible_item_count), XmRImmediate, (XtPointer)10},
- {DtNverticalSpacing, DtCVerticalSpacing, XmRVerticalDimension,
- sizeof(Dimension), DtOffset(vertical_spacing),
- XmRImmediate, (XtPointer)INVALID_DIMENSION},
- };
- /*
- * List resources (used for GetValues).
- */
- static XmSyntheticResource syn_resources[] = {
- {DtNarrowSpacing, sizeof(Dimension), DtOffset(arrow_spacing),
- XmeFromHorizontalPixels, XmeToHorizontalPixels},
- {DtNhorizontalSpacing, sizeof(Dimension), DtOffset(horizontal_spacing),
- XmeFromHorizontalPixels, XmeToHorizontalPixels},
- {DtNverticalSpacing, sizeof(Dimension), DtOffset(vertical_spacing),
- XmeFromVerticalPixels, XmeToVerticalPixels},
- {DtNmarginWidth, sizeof(Dimension), DtOffset(margin_width),
- XmeFromHorizontalPixels, XmeToHorizontalPixels},
- {DtNmarginHeight, sizeof(Dimension), DtOffset(margin_height),
- XmeFromVerticalPixels, XmeToVerticalPixels},
- {DtNarrowSize, sizeof(Dimension), DtOffset(arrow_size),
- _DtComboBoxGetArrowSize, XmeToHorizontalPixels},
- {DtNlabelString, sizeof(XmString), DtOffset(label_string),
- _DtComboBoxGetLabelString, _XmSetSyntheticResForChild},
- {DtNitemCount, sizeof(int), DtOffset(item_count),
- _DtComboBoxGetListItemCount, _XmSetSyntheticResForChild},
- {DtNitems, sizeof(XmStringTable), DtOffset(items),
- _DtComboBoxGetListItems, _XmSetSyntheticResForChild},
- {DtNlistFontList, sizeof(XmFontList), DtOffset(list_font_list),
- _DtComboBoxGetListFontList, _XmSetSyntheticResForChild},
- {DtNlistMarginHeight, sizeof(Dimension),
- DtOffset(list_margin_height),
- _DtComboBoxGetListMarginHeight, XmeToVerticalPixels},
- {DtNlistMarginWidth, sizeof(Dimension),DtOffset(list_margin_width),
- _DtComboBoxGetListMarginWidth, XmeToHorizontalPixels},
- {DtNlistSpacing, sizeof(Dimension), DtOffset(list_spacing),
- _DtComboBoxGetListSpacing, XmeToVerticalPixels},
- {DtNtopItemPosition, sizeof(int), DtOffset(top_item_position),
- _DtComboBoxGetListTopItemPosition, _XmSetSyntheticResForChild},
- {DtNvisibleItemCount, sizeof(int), DtOffset(visible_item_count),
- _DtComboBoxGetListVisibleItemCount, _XmSetSyntheticResForChild},
- };
- #undef DtOffset
- #undef offset
- /* Need Class Extension for widget navigation */
- static XmBaseClassExtRec baseClassExtRec = {
- NULL,
- NULLQUARK,
- XmBaseClassExtVersion,
- sizeof(XmBaseClassExtRec),
- (XtInitProc)NULL, /* InitializePrehook */
- (XtSetValuesFunc)NULL, /* SetValuesPrehook */
- (XtInitProc)NULL, /* InitializePosthook */
- (XtSetValuesFunc)NULL, /* SetValuesPosthook */
- NULL, /* secondaryObjectClass */
- (XtInitProc)NULL, /* secondaryCreate */
- (XmGetSecResDataFunc)NULL, /* getSecRes data */
- { 0 }, /* fastSubclass flags */
- (XtArgsProc)NULL, /* getValuesPrehook */
- (XtArgsProc)NULL, /* getValuesPosthook */
- (XtWidgetClassProc)NULL, /* classPartInitPrehook */
- (XtWidgetClassProc)NULL, /* classPartInitPosthook*/
- NULL, /* ext_resources */
- NULL, /* compiled_ext_resources*/
- 0, /* num_ext_resources */
- FALSE, /* use_sub_resources */
- (XmWidgetNavigableProc)WidgetNavigable,
- /* widgetNavigable */
- (XmFocusChangeProc)NULL, /* focusChange */
- (XmWrapperData)NULL /* wrapperData */
- };
- /*
- * Define Class Record.
- */
- externaldef(dtcomboBoxclassrec) DtComboBoxClassRec dtComboBoxClassRec =
- {
- { /* core_class fields */
- (WidgetClass)&(xmManagerClassRec), /* superclass */
- (String)"DtComboBox", /* class_name */
- (Cardinal)sizeof(DtComboBoxPart), /* widget_size */
- (XtProc)ClassInitialize, /* class_initialize */
- (XtWidgetClassProc)NULL, /* class_part_init */
- (XtEnum)FALSE, /* class_inited */
- (XtInitProc)Initialize, /* initialize */
- (XtArgsProc)NULL, /* initialize_hook */
- (XtRealizeProc)XtInheritRealize, /* realize */
- (XtActionList)ComboBoxActionTable, /* actions */
- (Cardinal)XtNumber(ComboBoxActionTable), /* num_actions */
- (XtResourceList)resources, /* resources */
- (Cardinal)XtNumber(resources), /* num_resources */
- (XrmClass)NULLQUARK, /* xrm_class */
- (Boolean)TRUE, /* compress_motion */
- (XtEnum)XtExposeCompressMaximal, /* compress_exposure */
- (Boolean)TRUE, /* compress_enterleave*/
- (Boolean)FALSE, /* visible_interest */
- (XtWidgetProc)Destroy, /* destroy */
- (XtWidgetProc)Resize, /* resize */
- (XtExposeProc)Redisplay, /* expose */
- (XtSetValuesFunc)SetValues, /* set_values */
- (XtArgsFunc)NULL, /* set values hook */
- (XtAlmostProc)XtInheritSetValuesAlmost, /* set values almost */
- (XtArgsProc)NULL, /* get values hook */
- (XtAcceptFocusProc)NULL, /* accept_focus */
- (XtVersionType)XtVersionDontCheck, /* Version */
- (XtPointer)NULL, /* PRIVATE cb list */
- (String)XtInheritTranslations, /* tm_table */
- (XtGeometryHandler)XtInheritQueryGeometry, /* query_geom */
- (XtStringProc)XtInheritDisplayAccelerator, /* display_accelerator*/
- (XtPointer)&baseClassExtRec /* extension */
- },
- { /* composite_class fields */
- (XtGeometryHandler)GeometryManager, /* geometry_manager */
- (XtWidgetProc)XtInheritChangeManaged, /* change_managed */
- (XtWidgetProc)XtInheritInsertChild, /* insert_child */
- (XtWidgetProc)XtInheritDeleteChild, /* delete_child */
- (XtPointer)NULL /* extension */
- },
- { /* constraint_class fields */
- (XtResourceList)NULL, /* resources */
- (Cardinal)0, /* num_resources */
- (Cardinal)0, /* constraint_size */
- (XtInitProc)NULL, /* initialize */
- (XtWidgetProc)NULL, /* destroy */
- (XtSetValuesFunc)NULL, /* set_values */
- (XtPointer)NULL /* extension */
- },
- { /* manager class */
- (String)XtInheritTranslations, /* translations */
- (XmSyntheticResource*)syn_resources, /* syn resources */
- (int)XtNumber(syn_resources), /* num syn_resources */
- (XmSyntheticResource*)NULL, /* get_cont_resources */
- (int)0, /* num_get_cont_resources */
- (XmParentProcessProc)XmInheritParentProcess,/* parent_process */
- (XtPointer)NULL /* extension */
- },
- { /* combo_box_class fields */
- (Boolean)0,
- }
- };
- externaldef(dtcomboBoxwidgetclass) WidgetClass dtComboBoxWidgetClass =
- (WidgetClass)&dtComboBoxClassRec;
- /* Parse the translation tables only once for the whole class
- */
- static XtTranslations trans;
- static XtTranslations list_trans;
- static XtTranslations label_trans;
- static XtTranslations text_trans;
- static XtTranslations button_trans;
- /*
- * Must set up the record type for the class extensions to work.
- */
- static void
- ClassInitialize(void)
- {
- baseClassExtRec.record_type = XmQmotif;
- /*
- * MotifBc
- */
- XmResolveAllPartOffsets(dtComboBoxWidgetClass, &ipot, &cpot);
- /* Parse the translation tables here
- */
- trans = XtParseTranslationTable(ComboBoxTranslationTable);
- list_trans = XtParseTranslationTable(ComboBoxListTranslationTable);
- label_trans = XtParseTranslationTable(ComboBoxLabelTranslationTable);
- text_trans = XtParseTranslationTable(ComboBoxTextTranslationTable);
- button_trans =XtParseTranslationTable(ComboBoxButtonTranslationTable);
- /* Add a type converter for String to DtRComboBoxType
- */
- XtSetTypeConverter("String","ComboBoxType", _CvtStringToType, NULL, 0,
- XtCacheAll, NULL);
- InitLabel = XmStringCreateLocalized(CB_LABEL);
- }
- /*
- * ComboBox initialization function. This builds the widgets inside
- * our widget, to get the correct layout. If the type resource
- * is DtDROP_DOWN_COMBO_BOX, we create a textField; if FALSE, we create a
- * label. If the user changes this resource later, we will create the
- * other widget (textField or Label). We don't want to carry backage from
- * both widgets if the user never changes the type resource.
- */
- static void
- Initialize( DtComboBoxWidget request,
- DtComboBoxWidget new,
- ArgList given_args,
- Cardinal *num_args)
- {
- /* use the address of the first element of DtComboBoxPart structure
- * as of DtComboBoxPart
- */
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(new,ipot,DtComboBox,arrow,Widget));
- Boolean force_label_string = FALSE;
- Arg args[15];
- int n;
- /* Resolution Independent */
- unsigned char unit_type = MUnitType(new);
- /* Overwrite the manager's focusIn and focusOut translations */
- XtOverrideTranslations((Widget)new, trans);
- /*
- * force_label_string usage if it is specified and items is not.
- * This will be the perminant label string only if update-label
- * is false, else it is only used until the user picks something
- * new off the list.
- */
- if (LabelString(new) == NULL)
- LabelString(new) = InitLabel;
- else if (!Items(new))
- force_label_string = TRUE;
- /* Copy given label-string. */
- if (LabelString(new))
- LabelString(new) = XmStringCopy(LabelString(new));
- Text(new) = (Widget)NULL;
- Label(new) = (Widget)NULL;
- Sep(new) = (Widget)NULL;
- OldWidth(new) = 0;
- OldHeight(new) = 0;
- CheckResources(new);
- /*
- * Create the text or label depending on the type resource.
- * When part of X-Designer, we create both at initialization to
- * avoid later crashes.
- */
- if (Type(new) == DtDROP_DOWN_COMBO_BOX)
- {
- n = 0;
- XtSetArg(args[n], XmNcolumns, TextColumns(new)); n++;
- XtSetArg(args[n], XmNmaxLength, TextMaxLength(new)); n++;
- XtSetArg(args[n], XmNmarginWidth, TEXT_CONTEXT_MARGIN); n++;
- XtSetArg(args[n], XmNmarginHeight, 2); n++;
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
- }
- Text(new) = XtCreateManagedWidget("Text",
- xmTextFieldWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(Text(new), XmNlosingFocusCallback,
- text_losing_focus_cb, (XtPointer)new);
- XtAddCallback(Text(new), XmNactivateCallback,
- text_activate_cb, (XtPointer)new);
- XtAddCallback(Text(new), XmNfocusCallback,
- text_focus_cb, (XtPointer)new);
- XtOverrideTranslations(Text(new), text_trans);
- if (HorizontalSpacing(new) == INVALID_DIMENSION)
- HorizontalSpacing(new) = 0;
- if (VerticalSpacing(new) == INVALID_DIMENSION)
- VerticalSpacing(new) = 0;
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(Text(new), args, 1);
- }
- }
- else
- {
- XmStringDirection new_direction =
- XmDirectionToStringDirection(LayoutDirection(new));
- COMBO_SHADOW(new) = LABEL_SHADOW;
- n = 0;
- XtSetArg(args[n], XmNalignment, Alignment(new)); n++;
- XtSetArg(args[n], XmNrecomputeSize, FALSE); n++;
- XtSetArg(args[n], XmNlabelString, InitLabel); n++;
- XtSetArg(args[n], XmNmarginLeft, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginRight, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginWidth, TEXT_CONTEXT_MARGIN); n++;
- XtSetArg(args[n], XmNmarginHeight, 0); n++;
- XtSetArg(args[n], XmNstringDirection, new_direction); n++;
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
- }
- Label(new) = XtCreateManagedWidget("Label",
- xmLabelWidgetClass,
- (Widget)new, args, n);
- XtOverrideTranslations(Label(new), label_trans);
- if (HorizontalSpacing(new) == INVALID_DIMENSION)
- HorizontalSpacing(new) = 1;
- if (VerticalSpacing(new) == INVALID_DIMENSION)
- VerticalSpacing(new) = 2;
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(Label(new), args, 1);
- }
- }
- /*
- * Create the separator used if non-editable combo-box.
- */
- if (Type(new) == DtDROP_DOWN_LIST)
- {
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
- }
- Sep(new) = XtCreateManagedWidget("ComboBoxSeparator",
- xmSeparatorWidgetClass,
- (Widget)new, args, n);
- XtOverrideTranslations((Widget)Sep(new), button_trans);
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(Sep(new), args, 1);
- }
- }
- /*
- * Create the ArrowWidget.
- */
- n = 0;
- XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
- XtSetArg(args[n], XmNhighlightThickness, 0); n++;
- XtSetArg(args[n], XmNshadowThickness, 0); n++;
- if (ArrowType(new) == DtMOTIF) {
- XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++;
- XtSetArg(args[n], XmNforeground, BackgroundPixel(new)); n++;
- Arrow(new) = XtCreateManagedWidget("ComboBoxArrow",
- xmArrowButtonWidgetClass,
- (Widget)new, args, n);
- }
- else {
- Arrow(new) = XtCreateManagedWidget("ComboBoxArrow",
- xmDrawnButtonWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(Arrow(new), XmNexposeCallback, arrow_expose_cb,
- (XtPointer)new);
- }
- XtAddCallback(Arrow(new), XmNactivateCallback, activate_cb,
- (XtPointer)new);
- XtOverrideTranslations((Widget)Arrow(new), button_trans);
- /*
- * Create the shell and associated list widgets.
- */
- n = 0;
- XtSetArg(args[n], XtNoverrideRedirect, TRUE); n++;
- XtSetArg(args[n], XtNallowShellResize, TRUE); n++;
- XtSetArg(args[n], XtNsaveUnder, TRUE); n++;
- Shell(new) = XtCreatePopupShell("ComboBoxMenuShell",
- topLevelShellWidgetClass,
- (Widget)new, args, n);
-
- n = 0;
- Frame(new) = XtCreateManagedWidget("ComboBoxRowColumn",
- xmFrameWidgetClass,
- Shell(new), args, n);
- n = 0;
- /* Store combo widget in list for later use */
- XtSetArg(args[n], XmNuserData, (XtPointer)new); n++;
- if (ListFontList(new)) {
- XtSetArg(args[n], XmNfontList, ListFontList(new)); n++;
- }
- /* to disable double click */
- XtSetArg(args[n], XmNdoubleClickInterval, 0); n++;
- XtSetArg(args[n], XmNitemCount, ItemCount(new)); n++;
- XtSetArg(args[n], XmNitems, Items(new)); n++;
- XtSetArg(args[n], XmNlistMarginHeight, ListMarginHeight(new)); n++;
- XtSetArg(args[n], XmNlistMarginWidth, ListMarginWidth(new)); n++;
- XtSetArg(args[n], XmNlistSpacing, ListSpacing(new)); n++;
- {
- XmStringDirection new_direction =
- XmDirectionToStringDirection(LayoutDirection(new));
- XtSetArg(args[n], XmNstringDirection, new_direction); n++;
- }
- XtSetArg(args[n], XmNtopItemPosition, TopItemPosition(new)); n++;
- XtSetArg(args[n], XmNvisibleItemCount, VisibleItemCount(new)); n++;
- XtSetArg(args[n], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE); n++;
- XtSetArg(args[n], XmNselectionPolicy, XmBROWSE_SELECT); n++;
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
- }
- List(new) = XmCreateScrolledList(Frame(new), "List", args, n);
- XtOverrideTranslations((Widget)List(new), list_trans);
- n = 0;
- XtSetArg(args[n], XmNshadowThickness, (XtArgVal) 0); n++;
- XtSetValues(XtParent(List(new)), args, n);
- /* selected_item resource used before selected_position */
- if (SelectedItem(new) && XmeStringIsValid(SelectedItem(new)) ) {
- SelectedItem(new) =XmStringCopy(SelectedItem(new));
- DtComboBoxSelectItem((Widget)new, SelectedItem(new));
- }
- else {
- SelectedItem(new) = (XmString) NULL;
- if (SelectedPosition(new)<0 || SelectedPosition(new)>=ItemCount(new))
- SelectedPosition(new) = 0;
- if ( ItemCount(new))
- XmListSelectPos(List(new), SelectedPosition(new) + 1, FALSE);
- }
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(List(new), args, 1);
- }
- SyncWithList(combo_p);
- XtManageChild(List(new));
- XtRealizeWidget(Shell(new));
- MaxShellWidth(new) = Width(((Widget) Shell(new)));
- MaxShellHeight(new) = Height(((Widget) Shell(new)));
- XtAddCallback(List(new), XmNdefaultActionCallback, select_cb, new);
- XtAddCallback(List(new), XmNbrowseSelectionCallback, select_cb, new);
- /*
- * Set up event handlers needed for handling grab states.
- */
- XtInsertEventHandler(List(new), LIST_EVENTS, TRUE,
- (XtEventHandler)list_event_handler,
- (XtPointer)new, XtListHead);
- XtInsertEventHandler(Shell(new), SHELL_EVENTS, TRUE,
- (XtEventHandler)shell_event_handler,
- (XtPointer)new, XtListHead);
- /*
- * Set initial value in text or label if items was specified
- */
- if (Type(new) == DtDROP_DOWN_LIST) {
- SetMaximumLabelSize(combo_p);
- SetLabelData(combo_p, NULL, force_label_string);
- }
- else
- SetTextFieldData(combo_p, NULL);
- SetComboBoxSize(new);
- LayoutChildren(new);
- }
- /*
- * Allow the manager to gain focus if not editable. If editable (using
- * text-field), then let the toolkit give focus to the text-field.
- */
- static XmNavigability
- WidgetNavigable(DtComboBoxWidget combo)
- {
- XmNavigationType nav_type = NavigationType(((XmManagerWidget)combo));
- if (Sensitive(combo) && AncestorSensitive(combo) &&
- TraversalOn(((XmManagerWidget)combo))) {
- if ((nav_type == XmSTICKY_TAB_GROUP) ||
- (nav_type == XmEXCLUSIVE_TAB_GROUP) ||
- ((nav_type == XmTAB_GROUP) &&
- !_XmShellIsExclusive((Widget)combo))) {
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- return(XmDESCENDANTS_TAB_NAVIGABLE);
- else
- return(XmTAB_NAVIGABLE);
- }
- return(XmDESCENDANTS_NAVIGABLE);
- }
- return(XmNOT_NAVIGABLE);
- }
- /*
- * The combo_box gets focus.
- */
- static void
- _ComboBoxFocusIn( DtComboBoxWidget combo,
- XEvent *event,
- char **params,
- Cardinal *num_params)
- {
- DrawHighlight(combo, FALSE);
- }
- /*
- * The combo_box loses focus. Only happens if not editable.
- */
- static void
- _ComboBoxFocusOut( DtComboBoxWidget combo,
- XEvent *event,
- char **params,
- Cardinal *num_params)
- {
- DrawHighlight(combo, TRUE);
- }
- /*
- * This function gets called whenever we draw or clear the shadow (to
- * redraw highlight during resize, etc), as well as during focus_in
- * and focus_out events.
- */
- static void
- DrawHighlight( DtComboBoxWidget combo,
- Boolean clear)
- {
- XRectangle rect[4] ;
- if (XtIsRealized((Widget)combo)) {
- if (clear) {
- rect[0].x = rect[1].x = rect[2].x = 0;
- rect[3].x = OldWidth(combo) - COMBO_MARGIN_W(combo);
- rect[0].y = rect[2].y = rect[3].y = 0 ;
- rect[1].y = OldHeight(combo) - COMBO_MARGIN_H(combo);
- rect[0].width = rect[1].width = OldWidth(combo);
- rect[2].width = rect[3].width = COMBO_MARGIN_W(combo);
- rect[0].height = rect[1].height = COMBO_MARGIN_H(combo);
- rect[2].height = rect[3].height = OldHeight(combo);
- XFillRectangles(XtDisplayOfObject((Widget)combo),
- XtWindowOfObject((Widget)combo),
- BackgroundGC(combo), rect, 4);
- }
- else if (XmGetFocusWidget((Widget)combo) == (Widget)combo) {
- rect[0].x = rect[1].x = rect[2].x = 0;
- rect[3].x = XtWidth(combo) - COMBO_MARGIN_W(combo);
- rect[0].y = rect[2].y = rect[3].y = 0 ;
- rect[1].y = XtHeight(combo) - COMBO_MARGIN_H(combo);
- rect[0].width = rect[1].width = XtWidth(combo);
- rect[2].width = rect[3].width = COMBO_MARGIN_W(combo);
- rect[0].height = rect[1].height = COMBO_MARGIN_H(combo);
- rect[2].height = rect[3].height = XtHeight(combo);
- XFillRectangles(XtDisplayOfObject((Widget)combo),
- XtWindowOfObject((Widget)combo),
- HighlightGC(combo), rect, 4);
- }
- }
- }
- /* Add a global variable to avoid the handler to process the
- * the ButtonPress which popup the shell
- */
- static int popup_shell_init=DtNonePopup;
- /*
- * osfSelect virtual key hit. Simulate hitting the arrow.
- */
- static void
- _ComboBoxActivate( Widget w,
- XEvent *event,
- char **params,
- Cardinal *num_params)
- {
- DtComboBoxWidget combo;
- XmAnyCallbackStruct cb;
- if (*num_params == 0) /* no params means combo */
- combo = (DtComboBoxWidget)w;
- else /* params means label */
- {
- combo = (DtComboBoxWidget)XtParent(w);
- }
- _DtProcessLock();
- if (event->type == KeyPress)
- popup_shell_init = DtKeyPressPopup;
- else if (event->type == ButtonPress)
- popup_shell_init = DtButtonPressPopup;
- else
- popup_shell_init = DtPopup;
- _DtProcessUnlock();
- cb.reason = XmCR_ACTIVATE;
- cb.event = event;
- activate_cb((Widget)Arrow(combo), (XtPointer)combo, (XtPointer)&cb);
- }
- /*
- * osfCancel virtual key hit.
- */
- static void
- _ComboBoxKbdCancel( Widget w,
- XEvent *event,
- char **params,
- Cardinal *num_params)
- {
- DtComboBoxWidget combo;
- XtPointer data;
- Arg args[1];
- /* Get combo-box off list data */
- XtSetArg(args[0], XmNuserData, &data);
- XtGetValues(w, args, 1);
-
- combo = (DtComboBoxWidget)data;
- input_ungrab( combo, GRAB_POINTER | GRAB_KEYBOARD );
- }
- /* #7
- * Tab Group Action for Buttons
- */
- static void
- _ComboBoxPrevTabGroup( Widget w,
- XEvent *event,
- char **params,
- Cardinal *num_params)
- {
- XmProcessTraversal ((Widget)XtParent(w), XmTRAVERSE_PREV_TAB_GROUP);
- }
- static void
- _ComboBoxNextTabGroup( Widget w,
- XEvent *event,
- char **params,
- Cardinal *num_params)
- {
- XmProcessTraversal ((Widget)XtParent(w), XmTRAVERSE_NEXT_TAB_GROUP);
- }
- /*
- * This function goes through most of the resources and makes sure
- * they have legal values.
- */
- static void
- CheckResources( DtComboBoxWidget combo)
- {
- if ((Alignment(combo) != DtALIGNMENT_CENTER) &&
- (Alignment(combo) != DtALIGNMENT_BEGINNING) &&
- (Alignment(combo) != DtALIGNMENT_END)) {
- XtWarning(CB_ALIGNMENT);
- Alignment(combo) = DtALIGNMENT_CENTER;
- }
- if ((Orientation(combo) != DtLEFT) &&
- (Orientation(combo) != DtRIGHT)) {
- XtWarning(CB_ORIENTATION);
- Orientation(combo) = DtRIGHT;
- }
- if (ItemCount(combo) < 0) {
- XtWarning(CB_ITEM_COUNT);
- ItemCount(combo) = 0;
- }
- if ((SelectedPosition(combo) < 0) ||
- ((SelectedPosition(combo) >= ItemCount(combo)) &&
- (ItemCount(combo) > 0))) {
- XtWarning(CB_VISIBLE_ITEM);
- SelectedPosition(combo) = 0;
- }
- /* NEW: to adjust the size of the list to its content *
- if (ItemCount(combo) < VisibleItemCount(combo))
- VisibleItemCount(combo) = ItemCount(combo); */
- }
- /*
- * Destroy procedure called by the toolkit. Free local resources
- */
- static void
- Destroy(DtComboBoxWidget combo)
- {
- if (LabelString(combo))
- XmStringFree(LabelString(combo));
- if (SelectedItem(combo))
- XmStringFree( SelectedItem(combo) );
- }
- /*
- * Resize function called by toolkit. The size of our combo-box
- * has already been changed. That is why we must store
- * old_width and old_height.
- */
- static void
- Resize(DtComboBoxWidget combo)
- {
- ClearShadow(combo, TRUE);
- LayoutChildren(combo);
- DrawShadow(combo);
- OldWidth(combo) = Width(combo);
- OldHeight(combo) = Height(combo);
- }
- /*
- * Redisplay function called by toolkit. The widget didn't change size,
- * so just redisplay the shadow.
- */
- static void
- Redisplay( DtComboBoxWidget w,
- XEvent *event,
- Region region)
- {
- DrawShadow(w);
- }
- /*
- * GeometryManager function called by toolkit when a child resizes/moves.
- * We are not allowing any changes but width/height of the text-field.
- * this is because the user can retrieve the text-field and make changes
- * that we want to honor. If they mess around with the label or arrow,
- * then we won't honor the request.
- * If the text-field requests a change, then make the change, and allow
- * our SetComboBoxSize() and LayoutChildren() figure out what size will
- * be allowed.
- * Returning GeometryDone was suppose to tell the toolkit
- * that we resized the child ourselves, but the text-field had trouble
- * with this (its' geometry_manager wasn't called or working right?), so
- * we return GeometryYes.
- */
- static XtGeometryResult
- GeometryManager(Widget w,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget) Parent(w);
- /* Ignore everything but text-field */
- if (w != Text(combo))
- return(XtGeometryNo);
- /* Only allow width/height changes */
- if (!(request->request_mode & (CWWidth | CWHeight)))
- return(XtGeometryNo);
-
- /* Set the text-field to the requested size */
- if (request->request_mode & CWWidth)
- Width(w) = request->width;
- if (request->request_mode & CWHeight)
- Height(w) = request->height;
- XtResizeWidget(w, Width(w), Height(w), BorderWidth(w));
-
- ClearShadow(combo, TRUE);
- if (RecomputeSize(combo))
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- return(XtGeometryYes);
- }
- /*
- * This function sets the size of the combo_box widget based on the
- * current size of the children. Don't worry if it doesn't work, the
- * children will be squeezed in later.
- */
- static void
- SetComboBoxSize(DtComboBoxWidget combo)
- {
- Widget text_holder = ((Type(combo) == DtDROP_DOWN_COMBO_BOX) ?
- Text(combo) : Label(combo));
- Dimension shadow = COMBO_SHADOW(combo) * 2;
- Dimension h_spacing = COMBO_H_SPACING(combo) * 2;
- Dimension v_spacing = COMBO_V_SPACING(combo) * 2;
- Dimension arrow_width, text_width, text_height;
- Dimension sep_width = 0;
- XtGeometryResult ResizeResult;
- Arg args[3];
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent */
- if (MUnitType(combo) != XmPIXELS) {
- unit_type = MUnitType(combo);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- XtSetValues(text_holder, args, 1);
- if (Type(combo) == DtDROP_DOWN_LIST)
- XtSetValues((Widget)Sep(combo), args, 1);
- }
- /*
- * Find out how big the arrow can be (needed to get
- * available_width for text_holder).
- */
- /* MotifBc */
- XtSetArg(args[0], XmNwidth, &text_width);
- XtSetArg(args[1], XmNheight, &text_height);
- XtGetValues(text_holder, args, 2);
- arrow_width = (Dimension)((float)text_height * ARROW_MULT);
- arrow_width = (arrow_width < ARROW_MIN) ? ARROW_MIN : arrow_width;
- if (Type(combo) == DtDROP_DOWN_LIST) {
- XtSetArg(args[0], XmNwidth, &sep_width);
- XtGetValues((Widget)Sep(combo), args, 1);
- }
- ResizeResult=XtMakeResizeRequest((Widget)combo, arrow_width + sep_width +
- ArrowSpacing(combo) +
- text_width + shadow + h_spacing +
- (COMBO_MARGIN_W(combo) * 2),
- text_height + shadow + v_spacing +
- (COMBO_MARGIN_H(combo) * 2),
- NULL, NULL);
- if (ResizeResult==XtGeometryNo || ResizeResult==XtGeometryAlmost) {
- XtWarning(CB_RESIZE);
- }
- OldWidth(combo) = Width(combo);
- OldHeight(combo) = Height(combo);
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(text_holder, args, 1);
- if (Type(combo) == DtDROP_DOWN_LIST)
- XtSetValues((Widget)Sep(combo), args, 1);
- }
- }
- /*
- * This function makes the text_holder (label or text-field) smaller
- * if the combo_box couldn't grow to the needed full size. It will
- * also make the text_holder grow if there is space. The textfield will
- * grow with the combo_box, but the label will only grow to its'
- * maximum size. The label will also shrink down to nothing, but the
- * text-field will always keep its' core height.
- */
- static void
- ForceChildSizes(DtComboBoxWidget combo)
- {
- Dimension full_available_height, available_height, available_width;
- Dimension arrow_width;
- Dimension sep_width = 0;
- Dimension tmp_width, tmp_height, tmp_borderwidth;
- Arg args[3];
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent */
- if (MUnitType(combo) != XmPIXELS) {
- unit_type = MUnitType(combo);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- if (Type(combo) == DtDROP_DOWN_LIST) {
- XtSetValues(Sep(combo), args, 1);
- XtSetValues(Label(combo), args, 1);
- }
- else
- XtSetValues(Text(combo), args, 1);
- XtSetValues(Arrow(combo), args, 1);
- }
- /* Calculate available height for children */
- if ((available_height = Height(combo) - (COMBO_SHADOW(combo) * 2) -
- (COMBO_MARGIN_H(combo) * 2) - (COMBO_V_SPACING(combo) * 2)) <= 0) {
- full_available_height = available_height = 1;
- }
- else {
- /* Separator need available_height plus the vertical_spacing */
- full_available_height = (available_height +
- (COMBO_V_SPACING(combo) * 2));
- }
- /* Get initial available width for children */
- available_width = (Width(combo) - (COMBO_SHADOW(combo) * 2) -
- (COMBO_MARGIN_W(combo) * 2) -
- (COMBO_H_SPACING(combo) * 2));
-
- /* label only grows to maximum width needed */
- if ((Type(combo) == DtDROP_DOWN_LIST) &&
- ((int)available_height > (int)LabelMaxHeight(combo)))
- available_height = LabelMaxHeight(combo);
- else if (Type(combo) == DtDROP_DOWN_COMBO_BOX) {
- XtSetArg(args[0], XmNheight, &available_height);
- XtGetValues((Widget)Text(combo), args, 1);
- }
-
- /*
- * Find out how big the arrow can be (needed to get
- * available_width for text_holder).
- */
- arrow_width = (Dimension)((float)available_height * ARROW_MULT);
- arrow_width = (arrow_width < ARROW_MIN) ? ARROW_MIN : arrow_width;
-
- if (Type(combo) == DtDROP_DOWN_LIST) {
- XtSetArg(args[0], XmNwidth, &sep_width);
- XtGetValues((Widget)Sep(combo), args, 1);
- }
- /* Make sure width isn't too small or too big */
- if ((available_width -=
- (arrow_width + sep_width + ArrowSpacing(combo) )) <= (Dimension)0)
- available_width = 1;
- /* Motif BC */
- XtSetArg(args[0], XmNwidth, &tmp_width);
- XtSetArg(args[1], XmNheight, &tmp_height);
- XtSetArg(args[2], XmNborderWidth, &tmp_borderwidth);
- if (Type(combo) == DtDROP_DOWN_LIST) { /** label **/
- if ((int)available_width > (int)LabelMaxLength(combo))
- available_width = LabelMaxLength(combo);
- /* Motif BC */
- XtGetValues((Widget)Label(combo), args, 3);
- if ((available_width != tmp_width) ||
- (available_height != tmp_height))
- XtResizeWidget(Label(combo), available_width, available_height,
- tmp_borderwidth);
- /* Motif BC */
- XtGetValues((Widget)Sep(combo), args, 3);
- if (full_available_height != tmp_height)
- XtResizeWidget(Sep(combo), tmp_width, full_available_height,
- tmp_borderwidth);
- }
- else {
- /* Motif BC */
- XtGetValues((Widget)Text(combo), args, 3);
- if ( Width(((Widget)Text(combo))) != available_width) /** TextField **/
- XtResizeWidget(Text(combo), available_width,
- tmp_height, tmp_borderwidth);
- }
- /* Motif BC */
- XtGetValues((Widget)Arrow(combo), args, 3);
- if ((arrow_width != tmp_width) || (tmp_height != available_height)) {
- available_height = (available_height < ARROW_MIN) ? ARROW_MIN :
- available_height;
- XtResizeWidget(Arrow(combo), arrow_width, available_height,
- tmp_borderwidth);
- }
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- if (Type(combo) == DtDROP_DOWN_LIST) {
- XtSetValues(Sep(combo), args, 1);
- XtSetValues(Label(combo), args, 1);
- }
- else
- XtSetValues(Text(combo), args, 1);
- XtSetValues(Arrow(combo), args, 1);
- }
- }
- /*
- * This function positions the children within the combo_box widget.
- * It calls ForceChildSizes() to make sure the children fit within the
- * combo_box widget, but it will not try to resize the combo_box widget.
- */
- static void
- LayoutChildren(DtComboBoxWidget combo)
- {
- Widget text_holder = ((Type(combo) == DtDROP_DOWN_COMBO_BOX)
- ? Text(combo) : Label(combo));
- Position start_x = (COMBO_SHADOW(combo) + COMBO_MARGIN_W(combo) +
- COMBO_H_SPACING(combo));
- Position start_y = (COMBO_SHADOW(combo) + COMBO_MARGIN_H(combo) +
- COMBO_V_SPACING(combo));
- short available_height = Height(combo) - (start_y * 2);
- Position y, arrow_y;
- unsigned char unit_type = XmPIXELS;
- Dimension tmp_width, tmp_height, sep_width;
- Arg args[3];
-
- ForceChildSizes(combo);
- /* Resolution Independent */
- if (MUnitType(combo) != XmPIXELS) {
- unit_type = MUnitType(combo);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- XtSetValues(text_holder, args, 1);
- XtSetValues(Arrow(combo), args, 1);
- if (Type(combo) == DtDROP_DOWN_LIST)
- XtSetValues(Sep(combo), args, 1);
- }
- /* Center text_holder within combo_box */
- /* MotifBc */
- XtSetArg(args[0], XmNheight, &tmp_height);
- XtGetValues(text_holder, args, 1);
- y = available_height - tmp_height;
- y = ((y < 0) ? 0 : y)/2 + start_y;
-
- /* Center arrow within combo_box */
- /* MotifBc */
- XtSetArg(args[1], XmNwidth, &tmp_width);
- XtGetValues(Arrow(combo), args, 2);
- arrow_y = available_height - tmp_height;
- arrow_y = ((arrow_y < 0) ? 0 : arrow_y)/2 + start_y;
- /* MotifBc */
- if (Type(combo) == DtDROP_DOWN_LIST) {
- XtSetArg(args[0], XmNwidth, &sep_width);
- XtGetValues(Sep(combo), args, 1);
- }
- if (Orientation(combo) == DtLEFT) {
- XtMoveWidget(Arrow(combo), start_x, arrow_y);
- start_x += tmp_width;
- if (Type(combo) == DtDROP_DOWN_LIST) {
- XtMoveWidget(Sep(combo), start_x, start_y -
- COMBO_V_SPACING(combo));
- start_x += sep_width;
- }
- start_x += ArrowSpacing(combo);
- XtMoveWidget(text_holder, start_x, y);
- }
- else {
- XtMoveWidget(text_holder, start_x, y);
- /*
- * We want the arrow at the end of the combo_box, so
- * the user can use recompute_size more effectively.
- */
- start_x = Width(combo) - start_x - tmp_width;
- if (Type(combo) == DtDROP_DOWN_LIST) {
- start_x -= sep_width;
- XtMoveWidget(Sep(combo), start_x, start_y -
- COMBO_V_SPACING(combo));
- start_x += sep_width;
- }
- XtMoveWidget(Arrow(combo), start_x, arrow_y);
- }
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(text_holder, args, 1);
- XtSetValues(Arrow(combo), args, 1);
- if (Type(combo) == DtDROP_DOWN_LIST)
- XtSetValues(Sep(combo), args, 1);
- }
- }
- /*
- * SetValues() routine for ComboBox widget.
- */
- static Boolean
- SetValues( DtComboBoxWidget current,
- DtComboBoxWidget request,
- DtComboBoxWidget new)
- {
- DtComboBoxPart *new_p = (DtComboBoxPart*)
- &(XmField(new,ipot,DtComboBox,arrow,Widget));
- Boolean label_size_changed = FALSE;
- Boolean force_label_string = FALSE;
- Arg args[10];
- int n;
- unsigned char new_unit_type = XmPIXELS, curr_unit_type = XmPIXELS;
- CheckResources(new);
- /* Resolution Independent */
- if (MUnitType(new) != XmPIXELS) {
- new_unit_type = MUnitType(new);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- if (Arrow(new)) XtSetValues(Arrow(new), args, 1);
- if (List(new)) XtSetValues(List(new), args, 1);
- if (Shell(new)) XtSetValues(Shell(new), args, 1);
- if (Label(new)) XtSetValues(Label(new), args, 1);
- if (Text(new)) XtSetValues(Text(new), args, 1);
- if (Sep(new)) XtSetValues(Sep(new), args, 1);
- }
- if (MUnitType(current) != XmPIXELS) {
- curr_unit_type = MUnitType(current);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- if (Arrow(current)) XtSetValues(Arrow(current), args, 1);
- if (List(current)) XtSetValues(List(current), args, 1);
- if (Shell(current)) XtSetValues(Shell(current), args, 1);
- if (Label(current)) XtSetValues(Label(current), args, 1);
- if (Text(current)) XtSetValues(Text(current), args, 1);
- if (Sep(current)) XtSetValues(Sep(current), args, 1);
- }
- if (Text(new) != Text(current)) {
- XtWarning(CB_TEXT);
- Text(new) = Text(current);
- }
- /*
- * Pass any list specific resources on to our List Widget.
- * Check each one, since it's too costly to always set them.
- */
- n = 0;
- if (ItemCount(new) != ItemCount(current)){
- if (Items(new) && (ItemCount(new) < 0)) {
- XtWarning(CB_ITEM_COUNT);
- ItemCount(new) = 0;
- }
- XtSetArg(args[n], XmNitemCount, ItemCount(new)); n++;
- }
- if (Items(new) != ListItems(current)) {
- XtSetArg(args[n], XmNitems, Items(new)); n++;
- /* Make sure itemCount will get sent to list */
- if (ItemCount(new) == ItemCount(current)) {
- XtSetArg(args[n], XmNitemCount, ItemCount(new)); n++;
- }
- }
- if (ListFontList(new) != ListFontList(current)) {
- XtSetArg(args[n], XmNfontList, ListFontList(new)); n++;
- }
- if (ListMarginHeight(new) != ListMarginHeight(current)) {
- XtSetArg(args[n], XmNlistMarginHeight, ListMarginHeight(new)); n++;
- }
- if (ListMarginWidth(new) != ListMarginWidth(current)) {
- XtSetArg(args[n], XmNlistMarginWidth, ListMarginWidth(new)); n++;
- }
- if (ListSpacing(new) != ListSpacing(current)) {
- XtSetArg(args[n], XmNlistSpacing, ListSpacing(new)); n++;
- }
- if (LayoutDirection(new) != LayoutDirection(current)) {
- XmStringDirection new_direction =
- XmDirectionToStringDirection(LayoutDirection(new));
- XtSetArg(args[n], XmNstringDirection, new_direction); n++;
- }
- if (TopItemPosition(new) != TopItemPosition(current)) {
- XtSetArg(args[n], XmNtopItemPosition, TopItemPosition(new)); n++;
- }
- if (VisibleItemCount(new) != VisibleItemCount(current)) {
- XtSetArg(args[n], XmNvisibleItemCount, VisibleItemCount(new)); n++;
- }
- if (n > 0) {
- /* MotifBc */
- Arg tmp_arg[2];
- Dimension tmp_width, tmp_height;
- XtSetValues(List(new), args, n);
- /* MotifBc */
- XtSetArg(tmp_arg[0], XmNwidth, &tmp_width);
- XtSetArg(tmp_arg[1], XmNheight, &tmp_height);
- XtGetValues(((Widget) Shell(new)), tmp_arg, 2);
- MaxShellWidth(new) = tmp_width;
- MaxShellHeight(new) = tmp_height;
- }
- /* If arrow type changes delete the old one and create the new one */
- if (ArrowType(new) != ArrowType(current)) {
- XtRemoveCallback(Arrow(new), XmNactivateCallback, activate_cb,
- (XtPointer)new);
- if (ArrowType(current) == DtWINDOWS)
- XtRemoveCallback(Arrow(new), XmNexposeCallback,
- arrow_expose_cb, (XtPointer)new);
- XtDestroyWidget(Arrow(new));
- n = 0;
- XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
- XtSetArg(args[n], XmNhighlightThickness, 0); n++;
- XtSetArg(args[n], XmNshadowThickness, 0); n++;
- if (ArrowType(new) == DtMOTIF) {
- XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++;
- XtSetArg(args[n], XmNforeground, BackgroundPixel(new)); n++;
- Arrow(new) = XtCreateManagedWidget("ComboBoxArrow",
- xmArrowButtonWidgetClass,
- (Widget)new, args, n);
- }
- else {
- Arrow(new) = XtCreateManagedWidget("ComboBoxArrow",
- xmDrawnButtonWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(Arrow(new), XmNexposeCallback, arrow_expose_cb,
- (XtPointer)new);
- }
- XtAddCallback(Arrow(new), XmNactivateCallback, activate_cb,
- (XtPointer)new);
- }
- /*
- * Type resource changed. If the widget (textField or Label)
- * doesn't exist, then create it. Always reset orientation
- * constraint resources when type changes; otherwise, the
- * text_holder widget positioning could be screwed up. We don't
- * reset both widgets if the orientation changes (because we might
- * not have created both widgets).
- * If label must be created, also create the separator widget.
- */
- if (Type(new) != Type(current)) {
- if (Type(new) == DtDROP_DOWN_COMBO_BOX) {
- if (Text(new) == NULL) {
- n = 0;
- XtSetArg(args[n], XmNcolumns, TextColumns(new)); n++;
- XtSetArg(args[n], XmNmaxLength, TextMaxLength(new)); n++;
- XtSetArg(args[n], XmNmarginWidth, 2); n++;
- XtSetArg(args[n], XmNmarginHeight, 2); n++;
- Text(new) = XtCreateWidget("ComboBoxTextField",
- xmTextFieldWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(Text(new), XmNlosingFocusCallback,
- text_losing_focus_cb, (XtPointer)new);
- XtAddCallback(Text(new), XmNactivateCallback,
- text_activate_cb, (XtPointer)new);
- XtAddCallback(Text(new), XmNfocusCallback,
- text_focus_cb, (XtPointer)new);
- if (HorizontalSpacing(new) == HorizontalSpacing(current))
- HorizontalSpacing(new) = 0;
- if (VerticalSpacing(new) == VerticalSpacing(current))
- VerticalSpacing(new) = 0;
- }
- XtUnmanageChild(Sep(new));
- XtUnmanageChild(Label(new));
- XtManageChild(Text(new));
- }
- else {
- if (Label(new) == NULL) {
- XmStringDirection new_direction =
- XmDirectionToStringDirection(LayoutDirection(new));
- XtTranslations label_trans =
- XtParseTranslationTable(ComboBoxLabelTranslationTable);
- n = 0;
- XtSetArg(args[n], XmNalignment, Alignment(new)); n++;
- XtSetArg(args[n], XmNrecomputeSize, FALSE); n++;
- XtSetArg(args[n], XmNmarginLeft, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginRight, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginWidth, TEXT_CONTEXT_MARGIN); n++;
- XtSetArg(args[n], XmNmarginHeight, 0); n++;
- XtSetArg(args[n], XmNstringDirection, new_direction); n++;
- Label(new) = XtCreateWidget("ComboBoxLabel",
- xmLabelWidgetClass,
- (Widget)new, args, n);
- XtOverrideTranslations((Widget)Label(new), label_trans);
- if (HorizontalSpacing(new) == HorizontalSpacing(current))
- HorizontalSpacing(new) = 1;
- if (VerticalSpacing(new) == VerticalSpacing(current))
- VerticalSpacing(new) = 2;
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
- Sep(new) = XtCreateWidget("ComboBoxSeparator",
- xmSeparatorWidgetClass,
- (Widget)new, args, n);
- }
- else if (LayoutDirection(new) != LayoutDirection(current)) {
- XmStringDirection new_direction =
- XmDirectionToStringDirection(LayoutDirection(new));
- XtSetArg(args[0], XmNstringDirection, new_direction);
- XtSetValues(Label(new), args, 1);
- }
- XtUnmanageChild(Text(new));
- XtManageChild(Label(new));
- XtManageChild(Sep(new));
- }
- /*
- * Text-fields and labels have different shadows. Only
- * change if user didn't change the shadow resource.
- */
- if (COMBO_SHADOW(new) == COMBO_SHADOW(current))
- COMBO_SHADOW(new) = ((Type(new) == DtDROP_DOWN_COMBO_BOX) ?
- TEXT_FIELD_SHADOW : LABEL_SHADOW);
- }
- if (Text(new) && (Text(new) == Text(current))) {
- n = 0;
- if (TextColumns(new) != TextColumns(current)) {
- XtSetArg(args[n], XmNcolumns, TextColumns(new)); n++;
- }
- if (TextMaxLength(new) != TextMaxLength(current) ) {
- XtSetArg(args[n], XmNmaxLength, TextMaxLength(new)); n++;
- }
- if (n > 0)
- XtSetValues(Text(new), args, n);
- }
- /*
- * LabelWidget alignment has changed.
- */
- if (Label(new) && (Alignment(new) != Alignment(current))) {
- XtSetArg(args[0], XmNalignment, Alignment(new));
- XtSetValues(Label(new), args, 1);
- }
- if (Label(new) && ((Items(new) != ListItems(current)) ||
- (ItemCount(new) != ItemCount(current)) ||
- (Label(new) != Label(current)))) {
- SetMaximumLabelSize(new_p);
- label_size_changed = TRUE;
- }
- /* Copy and free label-string */
- if (LabelString(new) != LabelString(current)) {
- if (LabelString(new))
- LabelString(new) = XmStringCopy(LabelString(new));
- if (LabelString(current))
- XmStringFree(LabelString(current));
- /*
- * force_label_string usage if it is specified and items is not.
- * This will be the perminant label string only if update-label
- * is false, else it is only used until the user picks something
- * new off the list.
- */
- if (Items(new) == ListItems(current))
- force_label_string = TRUE;
- }
- if ((Items(new) != ListItems(current)) ||
- (Alignment(new) != Alignment(current)) ||
- (Type(new) != Type(current)) ||
- (ItemCount(new) != ItemCount(current)) ||
- (SelectedPosition(new) != SelectedPosition(current)) ||
- (XmStringByteCompare(SelectedItem(new), SelectedItem(current))!=True) ||
- (Label(new) != Label(current)) ||
- (UpdateLabel(new) != UpdateLabel(current)) ||
- (LabelString(new) != LabelString(current))) {
- /* selected_item resource used before selected_position */
- if (SelectedItem(new) && XmeStringIsValid(SelectedItem(new)) &&
- (XmStringByteCompare(SelectedItem(new),
- SelectedItem(current))!=True) ){
- if (SelectedItem(current)) {
- XmStringFree(SelectedItem(current));
- SelectedItem(current) = NULL;
- }
- SelectedItem(new) = XmStringCopy(SelectedItem(new));
- DtComboBoxSelectItem((Widget)new, SelectedItem(new));
- }
- else {
- if (SelectedPosition(new)<0||SelectedPosition(new)>=ItemCount(new))
- SelectedPosition(new) = 0;
- if ((ItemCount(new)) &&
- (SelectedPosition(new) != SelectedPosition(current))) {
-
- XmListSelectPos(List(new), SelectedPosition(new) + 1, FALSE);
- if (SelectedItem(current)) {
-
- XmStringFree(SelectedItem(current));
- SelectedItem(current) = NULL;
- }
- SyncWithList(new_p);
- SelectedItem(new) =
- XmStringCopy((ListItems(new))[SelectedPosition(new)]);
- }
- /* Else, same item selected as last time */
- else {
- SelectedItem(new) = XmStringCopy(SelectedItem(new));
- if ((SelectedItem(new) != NULL) && (ListItems(new) != NULL))
- DtComboBoxSelectItem((Widget)new, SelectedItem(new));
- if (SelectedItem(current)) {
- XmStringFree(SelectedItem(current));
- SelectedItem(current) = NULL;
- }
- }
- }
- if (Type(new) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(new_p, NULL);
- else
- SetLabelData(new_p, NULL, force_label_string);
- }
- /* Else, same item selected as last time */
- else {
- SelectedItem(new) = XmStringCopy(SelectedItem(new));
- if ((SelectedItem(new) != NULL) && (ListItems(new) != NULL))
- DtComboBoxSelectItem((Widget)new, SelectedItem(new));
- if (SelectedItem(current)) {
- XmStringFree(SelectedItem(current));
- SelectedItem(current) = NULL;
- }
- }
- /*
- * Must recalculate the combo_box and re-layout the children.
- * If this is not editable, then set the label to its' maximum
- * size; it will get chopped if it is too big. This is needed
- * because we shrink the label down, and SetComboBoxSize() uses
- * the label's core sizes to figure what size to become.
- */
- if ((Type(new) != Type(current)) ||
- (ArrowType(new) != ArrowType(current)) ||
- (COMBO_MARGIN_W(new) != COMBO_MARGIN_W(current)) ||
- (COMBO_MARGIN_H(new) != COMBO_MARGIN_H(current)) ||
- (COMBO_H_SPACING(new) != COMBO_H_SPACING(current)) ||
- (COMBO_V_SPACING(new) != COMBO_V_SPACING(current)) ||
- (COMBO_SHADOW(new) != COMBO_SHADOW(current)) ||
- (Orientation(new) != Orientation(current)) ||
- (ArrowSpacing(new) != ArrowSpacing(current)) ||
- ((Type(new) == DtDROP_DOWN_LIST) && label_size_changed)) {
- ClearShadow(current, TRUE);
- if (RecomputeSize(new))
- SetComboBoxSize(new);
- LayoutChildren(new);
- DrawShadow(new);
- }
- SyncWithList(new_p);
- /* Resolution Independent */
- if (new_unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, new_unit_type);
- if (Arrow(new)) XtSetValues(Arrow(new), args, 1);
- if (List(new)) XtSetValues(List(new), args, 1);
- if (Shell(new)) XtSetValues(Shell(new), args, 1);
- if (Label(new)) XtSetValues(Label(new), args, 1);
- if (Text(new)) XtSetValues(Text(new), args, 1);
- if (Sep(new)) XtSetValues(Sep(new), args, 1);
- }
- if (curr_unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, curr_unit_type);
- if (Arrow(current)) XtSetValues(Arrow(current), args, 1);
- if (List(current)) XtSetValues(List(current), args, 1);
- if (Shell(current)) XtSetValues(Shell(current), args, 1);
- if (Label(current)) XtSetValues(Label(current), args, 1);
- if (Text(current)) XtSetValues(Text(current), args, 1);
- if (Sep(current)) XtSetValues(Sep(current), args, 1);
- }
- return(FALSE);
- }
- /*
- * This function clears the shadow around our widget. If all is TRUE,
- * then clear all 4 sides; otherwise, only clear the right and bottom
- * sides (during resize).
- */
- static void
- ClearShadow( DtComboBoxWidget w,
- Boolean all)
- {
- Dimension shadow = COMBO_SHADOW(w);
- Dimension margin_w = COMBO_MARGIN_W(w);
- Dimension margin_h = COMBO_MARGIN_H(w);
- if ((shadow > 0) && XtIsRealized((Widget)w)) {
- if (all) {
- XClearArea(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w),
- margin_w, margin_h,
- OldWidth(w) - (margin_w * 2),
- shadow, FALSE);
- XClearArea(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w),
- margin_w, margin_h, shadow,
- OldHeight(w) - (margin_h * 2), FALSE);
- }
- XClearArea(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w), margin_w,
- OldHeight(w) - margin_h - shadow,
- OldWidth(w) - (margin_w * 2), shadow, FALSE);
- XClearArea(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w),
- OldWidth(w) - margin_w - shadow,
- margin_h, shadow,
- OldHeight(w) - (margin_h * 2), FALSE);
- }
- DrawHighlight(w, TRUE);
- }
- /*
- * This functions draws the shadow around our combo-box.
- */
- static void
- DrawShadow(DtComboBoxWidget w)
- {
- Dimension shadow = COMBO_SHADOW(w);
- Dimension margin_w = COMBO_MARGIN_W(w);
- Dimension margin_h = COMBO_MARGIN_H(w);
-
- if ((shadow > 0) && XtIsRealized((Widget)w)) {
- XmeDrawShadows(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w),
- TopShadowGC(w),
- BottomShadowGC(w),
- margin_w, margin_h,
- Width(w) - (margin_w * 2),
- Height(w) - (margin_h * 2),
- shadow, XmSHADOW_OUT);
- }
- DrawHighlight(w, FALSE);
- }
- /*
- * Take the string out of the list and put it into the text-field.
- * text-fields don't handle xm-strings, so we must get the char*
- * out of it (only getting the first segment). This is slower than
- * storing the text-strings (char*) ourselves, but that would take
- * up a lot of memory. Since this setting happens during a user
- * action, speed isn't a problem.
- */
- static void
- SetTextFieldData(DtComboBoxPart *combo_p, XmString item)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- XmStringContext context;
- Boolean done = FALSE;
- Arg args[2];
- XmStringComponentType type;
- char *text;
- XmStringCharSet charset;
- XmStringDirection direction;
- XmStringComponentType unknown_tag;
- unsigned short ul;
- unsigned char *uv;
- XmStringTable list_items;
- int item_count;
- Boolean isItemCopied = FALSE;
- /* MotifBc
- */
- XtSetArg(args[0], XmNitemCount, &item_count);
- XtSetArg(args[1], XmNitems, &list_items);
- XtGetValues((Widget)list, args, 2);
- if (item_count && item_count>combo_p->selected_position &&
- !item && list_items) {
- item = XmStringCopy(list_items[combo_p->selected_position]);
- isItemCopied = TRUE;
- }
- if (!item) {
- combo_p->selected_item = NULL;
- XtSetArg(args[0], XmNvalue, "");
- XtSetValues(combo_p->text, args, 1);
- }
- else {
- if (combo_p->selected_item != item)
- {
- if (combo_p->selected_item)
- XmStringFree (combo_p->selected_item);
- combo_p->selected_item = XmStringCopy(item);
- }
- XmStringInitContext(&context, item);
-
- /* Loop until 1st char* found */
- while (!done) {
- type = XmStringGetNextComponent(context, &text, &charset,
- &direction, &unknown_tag,
- &ul, &uv);
- switch (type) {
- case XmSTRING_COMPONENT_END:
- done = TRUE;
- break;
- case XmSTRING_COMPONENT_TEXT:
- case XmSTRING_COMPONENT_LOCALE_TEXT:
- XtSetArg(args[0], XmNvalue, text);
- XtSetValues(combo_p->text, args, 1);
- XtFree(text);
- done = TRUE;
- break;
- default:
- break;
- }
- }
- XmStringFreeContext(context);
- if (isItemCopied)
- XmStringFree(item);
- }
- }
- /*
- * Set the maximum size of the label, depending on the
- * characteristics of the list of items.
- */
- static void
- SetMaximumLabelSize(DtComboBoxPart *combo_p)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- XmFontList font_list;
- Dimension width, height, border_width;
- Dimension longest = 0;
- Dimension highest = 0;
- Arg args[5];
- int i, item_count;
- XmStringTable list_items;
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent */
- XtSetArg(args[0], XmNunitType, &unit_type);
- XtGetValues(combo_p->list, args, 1); /* Assume list/Combo has same uniType*/
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- XtSetValues(combo_p->label, args, 1);
- XtSetValues(combo_p->list, args, 1);
- }
-
- /* Get font info from the widget */
- XtSetArg(args[0], XmNfontList, &font_list);
- XtGetValues(combo_p->label, args, 1);
- /* MotifBc
- */
- XtSetArg(args[0], XmNitems, &list_items);
- XtSetArg(args[1], XmNitemCount, &item_count);
- XtGetValues((Widget)list, args, 2);
- if ( item_count && item_count >= combo_p->item_count &&
- list_items && combo_p->update_label) {
- /*
- * Loop through all the items to find the biggest dimensions
- */
- for (i = 0; i < combo_p->item_count; i++) {
- XmStringExtent(font_list, list_items[i], &width, &height);
- longest = (width > longest) ? width : longest;
- highest = (height > highest) ? height : highest;
- }
- }
- else {
- XmStringExtent(font_list, combo_p->label_string, &longest, &highest);
- }
-
- combo_p->label_max_length = longest + ((LABEL_PADDING+TEXT_CONTEXT_MARGIN) * 2);
- combo_p->label_max_height = highest;
- /* MotifBc */
- XtSetArg(args[0], XmNborderWidth, &border_width);
- XtGetValues(combo_p->label, args, 1);
- XtResizeWidget(combo_p->label, combo_p->label_max_length, highest,
- border_width);
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(combo_p->label, args, 1);
- XtSetValues(combo_p->list, args, 1);
- }
- }
- /*
- * Put the current list item into the label.
- * This could probably be faster if we see if the label is the
- * same as the new item?
- */
- static void
- SetLabelData( DtComboBoxPart *combo_p,
- XmString item,
- Boolean force_label_string)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- int index = combo_p->selected_position;
- Arg args[2];
- XmStringTable list_items;
- int item_count;
- /*
- * If the item is empty, get the current item from the list, or
- * use label_string if update_label is FALSE. If that is empty,
- * use InitLabel.
- */
- if (force_label_string || (combo_p->update_label == FALSE))
- item = combo_p->label_string ? combo_p->label_string : InitLabel;
- else {
- if (!item) {
- /* MotifBc
- */
- XtSetArg(args[0], XmNitemCount, &item_count);
- XtSetArg(args[1], XmNitems, &list_items);
- XtGetValues((Widget)list, args, 2);
- if (item_count && item_count>index && list_items)
- item = list_items[index];
- else
- item = InitLabel;
- }
-
- /* Keep label_string in sync with item picked */
- if (combo_p->label_string)
- XmStringFree(combo_p->label_string);
- combo_p->label_string = XmStringCopy(item);
- }
- combo_p->selected_item = XmStringCopy(item);
- XtSetArg(args[0], XmNlabelString, item);
- XtSetValues(combo_p->label, args, 1);
- }
- /*
- * This is the browseSelect and defaultAction callback handler for the
- * ListWidget. If using the textWidget, we only take the first
- * segment of the XmString (TextWidgets don't handle XmStrings). If we
- * are using a label, then just set the labelString resource.
- */
- static void
- select_cb( Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo_w,ipot,DtComboBox,arrow,Widget));
- XmListCallbackStruct *info = (XmListCallbackStruct*)call_data;
- DtComboBoxCallbackStruct cb;
-
- SelectedPosition(combo_w) = info->item_position - 1;
- if (SelectedItem(combo_w))
- XmStringFree(SelectedItem(combo_w));
- SelectedItem(combo_w) = XmStringCopy(info->item);
- if (Type(combo_w) == DtDROP_DOWN_COMBO_BOX) {
- SetTextFieldData(combo_p, SelectedItem(combo_w));
- }
- else { /* Set the labelWidget string */
- SetLabelData(combo_p, SelectedItem(combo_w), FALSE);
- }
-
- /*
- * Only popdown if this is the defaultAction callback. We don't
- * want to popdown with browseSelect callback; that would cause the
- * menu to popdown when the user moved selection with the keyboard.
- * Doing it this way, allows the menu to stay up during
- * keyboard navigation. When menu goes away, make sure input
- * focus goes back into the textField (if editable).
- */
- /* This is one of three places to popdown the menu and here is
- * to pop it down by Keyboard input: KSelect
- * Another place using keyboard input to popdown the menu is
- * in _ComboBoxKbdCancel() by <Key>osfEsc
- * the last place is in shell_event_handler and that is for
- * poping down through Button operation: BSelect
- */
- if (info->reason == XmCR_DEFAULT_ACTION)
- input_ungrab( combo_w, GRAB_POINTER | GRAB_KEYBOARD );
- if ( ShellPoppedUp(((ShellWidget)Shell(combo_w))) == FALSE) {
- /* The list will free info->item */
- /* The semantic of a DtNselectionCallback is:
- * a callback to here + ShellPoppedUp==False
- * In reality, there are two scenario for this:
- * 1. XmList's XmNdefaultActionCallback which is activated by
- * KSelect, will first pop down the shell (see above) and
- * and then get here.
- * 2. BSelect on XmList, which first call the list_event_handler()
- * (for the handler is registered as LIST_HEAD) to pop down
- * the shell, and then call XmList's XmNbrowseSelectionCallback
- * which in turn get here
- */
- cb.reason = DtCR_SELECT;
- cb.event = info->event;
- cb.item_or_text = XmStringCopy(info->item);
- cb.item_position = SelectedPosition(combo_w);
- XtCallCallbackList((Widget)combo_w, SelectionCallback(combo_w),
- (XtPointer)&cb);
- if (cb.item_or_text != NULL) {
- XmStringFree(cb.item_or_text);
- cb.item_or_text = NULL;
- }
- }
- }
- /*
- * This is the event_handler for our shell widget. The grab happens
- * on the shell while the user is not doing anything inside the list.
- * This allows us to know if the user pressed a button outside our
- * application. If the user pressed a button anywhere but inside
- * the shell, then popdown the menu and ungrab everything.
- */
- static void
- shell_event_handler( Widget widget,
- XtPointer client_data,
- XEvent* event,
- Boolean *dispatch)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- XmScrolledWindowWidget sw = (XmScrolledWindowWidget)XtParent(List(combo_w));
- XmScrollBarWidget v_scrollbar;
- XmScrollBarWidget h_scrollbar;
- Window window = event->xbutton.window;
- Arg args[2];
- _DtProcessLock();
- if (popup_shell_init) {
- if (popup_shell_init != DtKeyPressPopup) {
- /* Menu popped up by ButtonPress */
- popup_shell_init = DtNonePopup;
- _DtProcessUnlock();
- return;
- }
- else
- /* Menu popped up by KActivate */
- popup_shell_init = DtNonePopup;
- }
- _DtProcessUnlock();
- /* MotifBc */
- XtSetArg(args[0], XmNverticalScrollBar, &v_scrollbar);
- XtSetArg(args[1], XmNhorizontalScrollBar, &h_scrollbar);
- XtGetValues((Widget)sw, args, 2);
- /* condition : Shell is popped up;
- * ButtonPress event;
- * the cursor is Not inside the XmList area,
- * the horizontal scrollbar or the vertical one;
- * action: remove all the grabs by DtComboBox
- */
- if ( ShellPoppedUp(((ShellWidget)Shell(combo_w))) &&
- (event->type == ButtonPress &&
- (window != XtWindowOfObject(List(combo_w))) &&
- !(ScrollBarVisible((Widget)h_scrollbar) &&
- (window == XtWindowOfObject((Widget)h_scrollbar))) &&
- !(ScrollBarVisible((Widget)v_scrollbar) &&
- (window == XtWindowOfObject((Widget)v_scrollbar))))
- )
- input_ungrab( combo_w, GRAB_POINTER | GRAB_KEYBOARD );
- /* condition : ButtonRelease event
- * the cursor is outside the scrollbar(horizontal or vertical)
- * action: call action routine "Release" of ScrollBar to release
- * possible pressed slider arrow (up/down)
- */
- if (event->type == ButtonRelease) {
- if ( ScrollBarVisible((Widget)h_scrollbar) &&
- window != XtWindowOfObject((Widget)h_scrollbar) )
- XtCallActionProc((Widget)h_scrollbar, "Release", event,NULL,0);
- if ( ScrollBarVisible((Widget)v_scrollbar) &&
- window != XtWindowOfObject((Widget)v_scrollbar) )
- XtCallActionProc((Widget)v_scrollbar, "Release", event,NULL,0);
- }
- }
- /*
- * This is the event_handler for our list widget. Getting the pointer
- * grabbing to work correctly was not very easy. In order for everything
- * to work correctly, we only do grab-pointer, for the shell, while not
- * doing anything inside the list. If doing something inside the list
- * we remove the grab on the shell. This is the only way that the
- * list will get the ButtonRelease if doing browse while outside the
- * list. The toolkit automatically does a grab in between ButtonPress
- * and ButtonRelease; therefore, the shell ungrab can't be done inside
- * the ButtonPress event.
- */
- static void
- list_event_handler( Widget widget,
- XtPointer client_data,
- XEvent* event,
- Boolean *dispatch) /* call remaining event handlers */
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- Arg args[5];
- int num_args;
- int top_item_position;
- int visible_item_count;
- int item_count;
- XmScrolledWindowWidget sw = (XmScrolledWindowWidget)XtParent(widget);
- XmScrollBarWidget v_scrollbar;
- XmScrollBarWidget h_scrollbar;
- switch (event->type) {
- case ButtonRelease:
- /*
- * Pop down the menu when Button is released inside the menu.
- */
- /* Doing the popdown here upon receiving ButtonRelease event,
- * rather than in shell_even_hanlder(), is
- * essential to allow select_cb() to recognize that this
- * XmNbrowseSelectionCallback is the last one in this popup session
- * and must treat it as a DtNselectionCallback
- */
- input_ungrab( combo_w, GRAB_KEYBOARD );
- /* condition : ButtonRelease event
- * cursor is outside the scrollbar(horizontal or vertical)
- * action: call action routine "Release" of ScrollBar to release
- * possible pressed slider arrow (up/down)
- */
- /* MotifBc */
- XtSetArg(args[0], XmNverticalScrollBar, &v_scrollbar);
- XtSetArg(args[1], XmNhorizontalScrollBar, &h_scrollbar);
- XtGetValues((Widget)sw, args, 2);
- if ( ScrollBarVisible((Widget)h_scrollbar) )
- XtCallActionProc((Widget)h_scrollbar, "Release", event,NULL,0);
- if ( ScrollBarVisible((Widget)v_scrollbar) )
- XtCallActionProc((Widget)v_scrollbar, "Release", event,NULL,0);
- break;
- case FocusOut:
- /*
- * There is interaction conflict between the list and the
- * scrollbars in terms of Focus. We always want our list
- * to have focus, so grab it back if we lose it.
- */
- if ( ShellPoppedUp(((ShellWidget)(Shell(combo_w)))) ) {
- _XmGrabKeyboard(widget, False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
- XtSetKeyboardFocus(List(combo_w), None);
- }
- break;
- case EnterNotify:
- /* call ListBeginSelect() action directly to simulate Btn1Down*/
- {Display *disp = XtDisplay(List(combo_w));
- Window win = XtWindow(List(combo_w));
- Window root;
- Window child;
- XmListWidget list;
- int root_x, root_y, win_x, win_y, item_pos;
- unsigned int keys_buttons;
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent */
- if ( MUnitType(combo_w) != XmPIXELS) {
- unit_type = MUnitType(combo_w);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- XtSetValues(List(combo_w), args, 1);
- }
- root = XDefaultRootWindow( disp );
- XQueryPointer ( disp, win, &root,
- &child, &root_x, &root_y,
- &win_x, &win_y, &keys_buttons );
- if ( keys_buttons & Button1Mask ) {
- item_pos = XmListYToPos(List(combo_w), event->xbutton.y);
- list = (XmListWidget)List(combo_w);
- /* MotifBc
- */
- num_args = 0;
- XtSetArg(args[num_args],XmNtopItemPosition,&top_item_position);
- num_args ++;
- XtSetArg(args[num_args], XmNvisibleItemCount,
- &visible_item_count);
- num_args ++;
- XtSetArg(args[num_args], XmNitemCount, &item_count);
- num_args ++;
- XtGetValues((Widget)list, args, num_args);
- /* Adjust top_item_position value to its' internal form */
- if (top_item_position)
- top_item_position--;
- else
- top_item_position = item_count - 1;
- if((item_pos<1 ) ||
- (item_pos>=(top_item_position + visible_item_count))||
- (item_pos < top_item_position) ||
- (item_pos >= item_count) )
- {
- Position item_x, item_y;
- Dimension item_height, item_width;
-
- XmListPosToBounds((Widget)list,
- ((top_item_position + visible_item_count )>
- item_count)? item_count:
- (top_item_position + visible_item_count ),
- &item_x, &item_y, &item_width, &item_height);
- if ( item_pos ==0 && event->xbutton.y<(int)(item_height/2) )
- event->xbutton.y = item_height/2;
- else
- event->xbutton.y = item_y + item_height/2;
- event->xbutton.x = item_x;
- }
-
- XtCallActionProc(List(combo_w), "ListBeginSelect",
- /* XEvent */ event,
- /* params */NULL,
- /* num_params */0);
- }
- /* Resolution Independent */
- if ( unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(List(combo_w), args, 1);
- }
- }
- break;
- }
- }
- /* Caller must free string */
- static char*
- GetTextString(XmString xm_string)
- {
- XmStringContext context;
- XmStringComponentType type;
- XmStringCharSet charset;
- XmStringDirection direction;
- XmStringComponentType unknown_tag;
- unsigned short ul;
- unsigned char *uv;
- char *text = NULL;
- Boolean done = FALSE;
- XmStringInitContext(&context, xm_string);
-
- /* Loop until 1st char* found */
- while (!done) {
- type = XmStringGetNextComponent(context, &text, &charset,
- &direction, &unknown_tag,
- &ul, &uv);
- switch (type) {
- case XmSTRING_COMPONENT_END:
- done = TRUE;
- break;
- case XmSTRING_COMPONENT_TEXT:
- case XmSTRING_COMPONENT_LOCALE_TEXT:
- done = TRUE;
- break;
- default:
- break;
- }
- }
- XmStringFreeContext(context);
- return(text);
- }
- static void
- TextFieldActivate(DtComboBoxPart *combo_p, XtPointer call_data)
- {
- XmTextFieldWidget w = (XmTextFieldWidget)(combo_p->text);
- XmListWidget list = (XmListWidget)combo_p->list;
- XmAnyCallbackStruct cb;
- char *data = NULL;
- char *text = NULL;
- Arg arg;
- XmStringTable list_items;
-
- XtSetArg(arg, XmNvalue, &data);
- XtGetValues((Widget)w, &arg, 1);
- /* MotifBc
- */
- XtSetArg(arg, XmNitems, &list_items);
- XtGetValues((Widget)list, &arg, 1);
- if ( list_items)
- text = GetTextString(list_items[combo_p->selected_position]);
- if (text && data && (strcmp(text, data) == 0)) {
- XtFree(text);
- }
- /* Only send callback if both are not NULL */
- else if (!((text == NULL) && (data == NULL))) {
- XmAnyCallbackStruct *local_cb = (XmAnyCallbackStruct *)call_data;
- cb.reason = XmCR_ACTIVATE;
- cb.event = local_cb ? local_cb->event : NULL;
- /* MotifBc
- */
- if (XtHasCallbacks((Widget)w, XmNactivateCallback)==XtCallbackHasSome)
- XtCallCallbacks((Widget)w, XmNactivateCallback,
- (XtPointer) &cb);
- if (text)
- XtFree(text);
- }
- if ( data )
- XtFree (data);
- }
- /*
- * This is the activate callback for the arrow button. This
- * sets the shell position and width, does the correct grabs, and
- * puts the shell on the screen.
- */
- static void
- activate_cb( Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo_w,ipot,DtComboBox,arrow,Widget));
- Display *disp = XtDisplayOfObject((Widget)combo_w);
- XmDisplay xmdisp = (XmDisplay) XmGetXmDisplay(disp);
- int screen;
- Dimension width, height;
- Dimension disp_width, disp_height;
- Position root_x, root_y, root_y0;
- Arg args[5];
- int n;
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent Handling */
- XtSetArg(args[0], XmNunitType, &unit_type);
- XtGetValues((Widget)combo_w, args, 1);
- /* Getting Focus */
- if ( !_XmFocusIsHere( (Widget)combo_w) )
- XmProcessTraversal((Widget)combo_w,
- (XmTraversalDirection) XmTRAVERSE_CURRENT);
- if (Type(combo_w) == DtDROP_DOWN_COMBO_BOX)
- TextFieldActivate(combo_p, call_data);
- /*
- * Don't popup if no items in the list.
- */
- /* MotifBc
- */
- XtSetArg(args[0], XmNitemCount, &n);
- XtGetValues(((Widget)List(combo_w)), args, 1);
- if ( n != ItemCount(combo_w) )
- SyncWithList(combo_p);
- if ( !n )
- return;
- screen = DefaultScreen(disp);
- disp_width = DisplayWidth(disp, screen);
- disp_height = DisplayHeight(disp, screen);
- /*
- * Call the menu-post callback if requested. This allows the
- * user to change the items, instead of using the losing-focus callback.
- * If the user used the losing-focus callback to change the items, the
- * size of the list/shell will change while it is popped up. We
- * could disallow SetValues while the menu is posted, but let's see
- * how things go first.
- */
- if (MenuPostCallback(combo_w)) {
- XmAnyCallbackStruct info;
- info.reason = DtCR_MENU_POST;
- info.event = (XEvent*)NULL;
- XtCallCallbackList((Widget)combo_w, MenuPostCallback(combo_w),
- (XtPointer)&info);
- }
- width = MaxShellWidth(combo_w);
- height = MaxShellHeight(combo_w);
- /* Get root coords of ComboBox */
- XtTranslateCoords((Widget)combo_w, X(combo_w), Y(combo_w),
- &root_x, &root_y);
- root_y0 = root_y;
- /*
- * Make necessary adjustments for offset of our widget
- * inside its' parent. Calculate the width of the shell.
- * This must be done every time the shell gets popped up, because
- * the x/y can change as well as the width (from list's visibleItemCount
- * or geometry management changes).
- */
- root_x -= X(combo_w);
- root_y -= Y(combo_w);
- root_y += (Height(combo_w) - COMBO_MARGIN_H(combo_w));
- /*
- * Make sure the shell is at least as big as our combo-box, and
- * make sure it stays on the screen.
- */
- /* to enforce a scrollbar with Shell */
- if (width < Width(combo_w))
- {
- Dimension sb_width, spacing, list_width;
- Widget sb;
- n = 0;
- XtSetArg(args[n], XmNverticalScrollBar, &sb); n++;
- XtSetArg(args[n], XmNspacing, &spacing); n++;
- XtGetValues(XtParent(List(combo_w)), args, n);
- /* Resolution Independent Resource */
- if ( unit_type != XmPIXELS) {
- n = XmConvertUnits(List(combo_w), XmHORIZONTAL,
- (int)unit_type, spacing, XmPIXELS);
- spacing = n;
- }
- if (sb && XtIsWidget(sb) ) {
- n = 0;
- XtSetArg(args[n], XmNwidth, &sb_width); n++;
- XtGetValues(sb, args, n);
- /* Resolution Independent Resource */
- if (unit_type != XmPIXELS) {
- n = XmConvertUnits(sb, XmHORIZONTAL,
- (int)unit_type, sb_width, XmPIXELS);
- sb_width = n;
- }
- }
- else
- sb_width = 0;
- n = 0;
- width = Width(combo_w);
- list_width = ( ScrollBarVisible(sb) ?
- (width - sb_width - spacing)
- :(width - spacing) );
- if (unit_type != XmPIXELS) {
- n = XmConvertUnits(sb, XmHORIZONTAL,
- XmPIXELS, list_width, (int)unit_type);
- list_width = n; n=0;
- }
- XtSetArg(args[n], XmNwidth, list_width); n++;
- XtSetValues(List(combo_w), args, n);
- }
- if ((int)(root_x + width) > (int)disp_width)
- root_x = (disp_width - width);
- else if (root_x <=0)
- root_x = 0;
- else
- ;
- if ((int)(root_y + height) > (int)disp_height)
- root_y = root_y0 - Y(combo_w) - height;
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- XtSetValues(Shell(combo_w), args, 1);
- }
- n = 0;
- XtSetArg(args[n], XmNx, root_x); n++;
- XtSetArg(args[n], XmNy, root_y); n++;
- XtSetValues(Shell(combo_w), args, n);
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(Shell(combo_w), args, 1);
- }
- PoppedUp(combo_w) = TRUE;
- XtPopup(Shell(combo_w), XtGrabNone);
- /*
- * Set up the grab for the shell and list. The shell gets the
- * pointer grab so that events will go into the list and scrollbars
- * correctly, but events outside the shell will go to the shell.
- * See shell and list event handlers for details about grabs.
- */
- _XmAddGrab(Shell(combo_w), True, True);
- _XmGrabPointer(Shell(combo_w), True, ButtonPressMask |ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync, None,
- XmGetMenuCursor(disp), CurrentTime);
- _XmGrabKeyboard(List(combo_w), False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
- xmdisp->display.userGrabbed = True;
-
- /*
- * Where to define the cursor for the list widget. It would be
- * nice to do it in the list's realize function, but that's not
- * possible. We can't use the ComboBox realize function, because
- * the list isn't realized at that point. This is the simpliest
- * way to get this done. This is needed to make sure the list has the
- * correct menu during browse scrolling, etc.
- */
- XDefineCursor(disp, XtWindowOfObject(Shell(combo_w)),
- XmGetMenuCursor(disp));
- }
- /*
- * Make sure arrow is symetrical. 45 degree angle. I'm not sure how
- * inefficient get/releasing the GC every time is (they are cached by
- * the toolkit)?
- */
- static void
- arrow_expose_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- Display *disp = XtDisplayOfObject(w);
- Window win = XtWindowOfObject(w);
- XGCValues values;
- short center_w;
- short center_h;
- XPoint points[10];
- Arg args[3];
- GC gc;
- Dimension arrow_width, arrow_height;
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent */
- if ( MUnitType(combo_w) != XmPIXELS ) {
- unit_type = MUnitType(combo_w);
- XtSetArg(args[0], XmNunitType, XmPIXELS);
- XtSetValues(w, args, 1);
- }
- /* MotifBc */
- XtSetArg(args[0], XmNwidth, &arrow_width);
- XtSetArg(args[1], XmNheight, &arrow_height);
- XtSetArg(args[2], XmNforeground, &(values.foreground));
- XtGetValues(w, args, 3);
- center_w = arrow_width/2;
- center_h = (int) (arrow_height -3.)/2;
- values.line_width = 0;
- values.line_style = LineSolid;
- values.fill_style = FillSolid;
- gc = XtGetGC(w, GCForeground | GCFillStyle | GCLineStyle | GCLineWidth,
- &values);
- XDrawLine(disp, win, gc, 1, center_h + center_w + 1, Width(w) - 2,
- center_h + center_w + 1);
- /* A - bottom point */
- points[0].x = center_w;
- points[0].y = center_h + (int)(center_w * .8);
- /* B - far left point */
- points[1].x = center_w - (int)(center_w * .8);
- points[1].y = center_h;
- /* C - inner left point */
- points[2].x = center_w - (int)(center_w * .3);
- points[2].y = points[1].y;
- /* D - top left point */
- points[3].x = points[2].x;
- points[3].y = center_h - (int)(center_w * .8);
- /* E - top right point */
- points[4].x = center_w + (int)(center_w * .3);
- points[4].y = points[3].y;
- /* F - inner right point */
- points[5].x = points[4].x;
- points[5].y = points[1].y;
- /* G - far right point */
- points[6].x = center_w + (int)(center_w * .8);
- points[6].y = points[1].y;
- /* A - bottom point */
- points[7].x = points[0].x;
- points[7].y = points[0].y;
- XDrawLines(disp, win, gc, points, 8, CoordModeOrigin);
- XFillPolygon(disp, win, gc, points, 8, Convex, CoordModeOrigin);
- XtReleaseGC(w, gc);
- /* Resolution Independent */
- if ( unit_type != XmPIXELS ) {
- XtSetArg(args[0], XmNunitType, unit_type);
- XtSetValues(w, args, 1);
- }
- }
- /*
- * We get the text-field losing-focus callback, so pass it on to
- * the user if they requested it. Our losing-focus callback
- * is just a convenience callback, so that the user doesn't
- * have to get the text-field first. This make our integration
- * with XDesigner a little easier.d
- */
- static void
- text_losing_focus_cb( Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo,ipot,DtComboBox,arrow,Widget));
- XmTextFieldWidget wt=(XmTextFieldWidget) Text(combo);
- XmString xmStr;
- Arg arg;
- String text_string;
- int i, need_sync_flag=1;
- /* MotifBc
- */
- XtSetArg(arg, XmNvalue, &text_string);
- XtGetValues((Widget)wt, &arg, 1);
- xmStr = (XmString) XmStringCreateLocalized(text_string?text_string:"");
- if ( text_string )
- XtFree (text_string);
- if (LosingFocusCallback(combo))
- XtCallCallbackList((Widget)combo, LosingFocusCallback(combo),
- (XtPointer)call_data);
- /* To synchronize the ComboBox record with XmList */
- XtVaGetValues(List(combo), XmNitemCount, &i, NULL);
- if (i != ItemCount(combo) ) {
- SyncWithList(combo_p);
- need_sync_flag = 0;
- }
-
- for (i = 0; i < ItemCount(combo); i++) {
- if ( need_sync_flag &&
- !( (ListItems(combo))[i] && XmeStringIsValid((ListItems(combo))[i]) )) {
- SyncWithList(combo_p);
- need_sync_flag = 0;
- }
- if (XmStringCompare(xmStr, (ListItems(combo))[i]))
- break;
- }
- if (i < ItemCount(combo) && i != SelectedPosition(combo) ) {
- SelectedPosition(combo) = i;
- if (SelectedItem(combo))
- XmStringFree(SelectedItem(combo));
- SelectedItem(combo) = xmStr;
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListSetPos(List(combo), SelectedPosition(combo) + 1);
- XmListSelectPos(List(combo), SelectedPosition(combo) + 1, True);
-
- XtVaGetValues(List(combo), XmNtopItemPosition,
- &(combo_p->top_item_position), NULL);
- }
- else
- XmStringFree( xmStr );
- }
- /*
- * We get the text-field activate callback, so pass it on to
- * the user if they requested it. Our activate callback
- * is just a convenience callback, so that the user doesn't
- * have to get the text-field first. This make our integration
- * with XDesigner a little easier.
- */
- static void
- text_activate_cb( Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo,ipot,DtComboBox,arrow,Widget));
- XmTextFieldWidget wt=(XmTextFieldWidget) Text(combo);
- XmString xmStr;
- Arg arg;
- String text_string;
- int i, need_sync_flag=1;
- /* MotifBc
- */
- XtSetArg(arg, XmNvalue, &text_string);
- XtGetValues((Widget)wt, &arg, 1);
- xmStr = (XmString) XmStringCreateLocalized(text_string?text_string:"");
- if ( text_string )
- XtFree (text_string);
- if (ActivateCallback(combo))
- XtCallCallbackList((Widget)combo,
- ActivateCallback(combo),
- (XtPointer)call_data);
- /* To synchronize the ComboBox record with XmList */
- XtVaGetValues(List(combo), XmNitemCount, &i, NULL);
- if (i != ItemCount(combo) ) {
- SyncWithList(combo_p);
- need_sync_flag = 0;
- }
-
- for (i = 0; i < ItemCount(combo); i++) {
- if ( need_sync_flag &&
- !( (ListItems(combo))[i] &&
- XmeStringIsValid((ListItems(combo))[i]) )) {
- SyncWithList(combo_p);
- need_sync_flag = 0;
- }
- if (XmStringCompare(xmStr, (ListItems(combo))[i]))
- break;
- }
- if (i < ItemCount(combo) && i != SelectedPosition(combo) ) {
- SelectedPosition(combo) = i;
- if (SelectedItem(combo))
- XmStringFree(SelectedItem(combo));
- SelectedItem(combo) = xmStr;
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListSetPos(List(combo), SelectedPosition(combo) + 1);
- XmListSelectPos(List(combo), SelectedPosition(combo) + 1, True);
- XtVaGetValues(List(combo), XmNtopItemPosition,
- &(combo_p->top_item_position), NULL);
- }
- else
- XmStringFree( xmStr );
- }
- /*
- * We get the text-field focus callback, so pass it on to
- * the user if they requested it. Our focus callback
- * is just a convenience callback, so that the user doesn't
- * have to get the text-field first. This make our integration
- * with XDesigner a little easier.
- */
- static void
- text_focus_cb( Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)client_data;
- if (FocusCallback(combo))
- XtCallCallbackList((Widget)combo, FocusCallback(combo),
- (XtPointer)call_data);
- }
- /*
- * Try and keep our list related rsources in sync with the list widget.
- * This is not always possible, depending on if the programmer makes
- * list widget calls directly. If we get out of sync with the
- * list widget, our SetValues() may not work correctly (when the
- * comparisons are done). Should do get values in case list widget
- * names are changed?
- */
- static void
- SyncWithList(DtComboBoxPart *combo_p)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- Arg args[10];
- int num_args;
- unsigned char unit_type = XmPIXELS;
- /* Resolution Independent */
- XtSetArg(args[0],XmNunitType,&unit_type);
- XtGetValues((Widget)list, args, 1);
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0],XmNunitType,XmPIXELS);
- XtSetValues((Widget)list, args, 1);
- }
- /* MotifBc
- */
- num_args = 0;
- XtSetArg(args[num_args],XmNitems,&(combo_p->list_items)); num_args ++;
- XtSetArg(args[num_args],XmNitems,&(combo_p->items)); num_args ++;
- XtSetArg(args[num_args],XmNitemCount,&(combo_p->item_count)); num_args ++;
- XtSetArg(args[num_args],XmNfontList,&(combo_p->list_font_list));
- num_args ++;
- XtSetArg(args[num_args],XmNlistMarginHeight,&(combo_p->list_margin_height));
- num_args ++;
- XtSetArg(args[num_args],XmNlistMarginWidth,&(combo_p->list_margin_width));
- num_args ++;
- XtSetArg(args[num_args],XmNlistSpacing,&(combo_p->list_spacing));
- num_args ++;
- XtSetArg(args[num_args],XmNtopItemPosition,&(combo_p->top_item_position));
- num_args ++;
- XtSetArg(args[num_args],XmNvisibleItemCount,&(combo_p->visible_item_count));
- num_args ++;
- XtGetValues((Widget)list, args, num_args);
- /* Adjustment with empty list */
- if (! combo_p->item_count) {
- combo_p->items = NULL;
- combo_p->list_items = NULL;
- }
- /* Resolution Independent */
- if (unit_type != XmPIXELS) {
- XtSetArg(args[0],XmNunitType,unit_type);
- XtSetValues((Widget)list, args, 1);
- }
- }
- /*
- * Routines which manipulate the ComboBox list. These are external
- * for use by users of our widget.
- */
- Widget
- DtCreateComboBox(Widget parent,
- char *name,
- ArgList arglist,
- Cardinal num_args)
- {
- return(XtCreateWidget(name, dtComboBoxWidgetClass, parent,
- arglist, num_args));
- }
- void
- DtComboBoxAddItem( Widget combow,
- XmString item,
- int pos,
- Boolean unique)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combow;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo,ipot,DtComboBox,arrow,Widget));
- XmStringTable list_items;
- int i;
- Arg arg;
- _DtWidgetToAppContext(combow);
- _DtAppLock(app);
- /* Try to help confused applications. */
- if (XmIsComboBox(combow))
- {
- XmComboBoxAddItem(combow, item, pos, unique);
- _DtAppUnlock(app);
- return;
- }
- /* MotifBc
- */
- XtSetArg(arg, XmNitems, &list_items);
- XtGetValues(((Widget)List(combo)), &arg, 1);
- if (item && list_items) {
- for (i = 0; i < ItemCount(combo); i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if ((i < ItemCount(combo)) && unique)
- {
- _DtAppUnlock(app);
- return;
- }
- }
- XmListAddItemUnselected(List(combo), item, pos);
- SyncWithList(combo_p);
- if (Label(combo)) {
- SetMaximumLabelSize(combo_p);
- if (Type(combo) == DtDROP_DOWN_LIST) {
- ClearShadow(combo, TRUE);
- if (RecomputeSize(combo))
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- }
- }
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- _DtAppUnlock(app);
- }
- void
- DtComboBoxDeletePos( Widget combow,
- int pos)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combow;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo,ipot,DtComboBox,arrow,Widget));
- int selection_changed = 0;
- _DtWidgetToAppContext(combow);
- _DtAppLock(app);
- /* Try to help confused applications. */
- if (XmIsComboBox(combow))
- {
- XmComboBoxDeletePos(combow, pos);
- _DtAppUnlock(app);
- return;
- }
- if ( pos <= 0 || pos >combo_p->item_count ) {
- XtWarning(CB_DEL_POS);
- _DtAppUnlock(app);
- return;
- }
- XmListDeletePos(List(combo), pos);
- if ( pos == (combo_p->selected_position+1) ) {
- /* Since we delete the current item, we have to set one */
- if ( pos == combo_p->item_count && combo_p->selected_position>0) {
- combo_p->selected_position--;
- selection_changed ++;
- }
- XmListSelectPos(List(combo), combo_p->selected_position+1, True);
- }
- else if ( pos <= combo_p->selected_position) {
- combo_p->selected_position--;
- selection_changed ++;
- }
- SyncWithList(combo_p);
- if ( selection_changed ) {
- if ( combo_p->selected_item )
- XmStringFree(combo_p->selected_item );
- combo_p->selected_item =
- ItemCount(combo)?
- XmStringCopy(combo_p->list_items[combo_p->selected_position]):
- (XmString) NULL;
- }
- if (Label(combo)) {
- SetMaximumLabelSize(combo_p);
- if (Type(combo) == DtDROP_DOWN_LIST) {
- ClearShadow(combo, TRUE);
- if (RecomputeSize(combo))
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- }
- }
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- _DtAppUnlock(app);
- }
- void
- DtComboBoxSetItem( Widget combow,
- XmString item)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combow;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo,ipot,DtComboBox,arrow,Widget));
- XmStringTable list_items;
- int i;
- Arg arg;
- _DtWidgetToAppContext(combow);
- _DtAppLock(app);
- /* Try to help confused applications. */
- if (XmIsComboBox(combow))
- {
- XmComboBoxSetItem(combow, item);
- _DtAppUnlock(app);
- return;
- }
- /* MotifBc
- */
- XtSetArg(arg, XmNitems, &list_items);
- XtGetValues(((Widget)List(combow)), &arg, 1);
- if (item && list_items) {
- for (i = 0; i < ItemCount(combo); i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if (i < ItemCount(combo)) {
- SelectedPosition(combo) = i;
- if (SelectedItem(combo))
- XmStringFree(SelectedItem(combo));
- SelectedItem(combo) = XmStringCopy(item);
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListSetItem(List(combo), item);
- XmListSelectItem(List(combo), item, FALSE);
- SyncWithList(combo_p);
- }
- else
- XtWarning(CB_SET_ITEM);
- }
- else
- XtWarning(CB_SET_ITEM);
- _DtAppUnlock(app);
- }
- void
- DtComboBoxSelectItem( Widget combow,
- XmString item)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combow;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)
- &(XmField(combo,ipot,DtComboBox,arrow,Widget));
- XmStringTable list_items;
- XmString tmpStr;
- int i;
- Arg arg;
- _DtWidgetToAppContext(combow);
- _DtAppLock(app);
- /* Try to help confused applications. */
- if (XmIsComboBox(combow))
- {
- XmComboBoxSelectItem(combow, item);
- _DtAppUnlock(app);
- return;
- }
- /* MotifBc
- */
- XtSetArg(arg, XmNitems, &list_items);
- XtGetValues(((Widget)List(combo)), &arg, 1);
- if (item && list_items) {
- for (i = 0; i < ItemCount(combo); i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if (i < ItemCount(combo)) {
- SelectedPosition(combo) = i;
- tmpStr=SelectedItem(combo);
- SelectedItem(combo) = XmStringCopy(item);
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListDeselectAllItems(List(combo));
- XmListSelectItem(List(combo), item, FALSE);
- if(tmpStr)
- XmStringFree(tmpStr);
- SyncWithList(combo_p);
- }
- else
- XtWarning(CB_SELECT_ITEM);
- }
- else
- XtWarning(CB_SELECT_ITEM);
- _DtAppUnlock(app);
- }
- /*
- * Synthetic GetValues for List resources.
- */
- static XmImportOperator
- _XmSetSyntheticResForChild( Widget widget,
- int offset,
- XtArgVal * value)
- {
- return(XmSYNTHETIC_LOAD);
- }
- void
- _DtComboBoxGetArrowSize(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
- XtSetArg(arg, XmNheight, &data);
- XtGetValues(Arrow(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetLabelString( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- if (LabelString(combo))
- *value = (XtArgVal)XmStringCopy(LabelString(combo));
- else
- *value = (XtArgVal)NULL;
- }
- void
- _DtComboBoxGetListItemCount( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- int data;
- Arg arg;
- XtSetArg(arg, XmNitemCount, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListItems(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- XmStringTable data;
- Arg arg;
- XtSetArg(arg, XmNitems, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListFontList( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- XmFontList data;
- Arg arg;
- XtSetArg(arg, XmNfontList, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListMarginHeight( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
- XtSetArg(arg, XmNmarginHeight, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListMarginWidth( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
- XtSetArg(arg, XmNmarginWidth, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListSpacing( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
- XtSetArg(arg, XmNspacing, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListTopItemPosition( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- int data;
- Arg arg;
- XtSetArg(arg, XmNtopItemPosition, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- void
- _DtComboBoxGetListVisibleItemCount( Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- int data;
- Arg arg;
- XtSetArg(arg, XmNvisibleItemCount, &data);
- XtGetValues(List(combo), &arg, 1);
- *value = (XtArgVal)data;
- }
- static Boolean
- _CvtStringToType(
- Display *dpy,
- XrmValuePtr args,
- Cardinal *num_args,
- XrmValuePtr from,
- XrmValuePtr to,
- XtPointer *data)
- {
- char *from_str;
- static unsigned char to_value;
- if(*num_args !=0 ) {
- XtError(CB_CVTSTRING);
- }
- from_str = (char *)from->addr;
- if(strcmp(from_str, "DROP_DOWN_LIST")==0 ||
- strcmp(from_str, "drop_down_list")==0 ||
- strcmp(from_str, "DtDROP_DOWN_LIST")==0)
- to_value = DtDROP_DOWN_LIST;
- else if (strcmp(from_str, "DROP_DOWN_COMBO_BOX")==0 ||
- strcmp(from_str, "drop_down_combo_box")==0 ||
- strcmp(from_str, "DtDROP_DOWN_COMBO_BOX")==0)
- to_value = DtDROP_DOWN_COMBO_BOX;
- else {
- XtDisplayStringConversionWarning(dpy, from->addr, "ComboBoxType");
- return False;
- }
- if (to->addr == NULL) to->addr = (caddr_t) &to_value;
- else if (to->size <sizeof(unsigned char)) {
- XtDisplayStringConversionWarning(dpy, from->addr, "ComboBoxType");
- return False;
- }
- else
- *(unsigned char *) to->addr = to_value;
- to->size = sizeof(unsigned char);
- return True;
- }
- static void
- input_ungrab ( DtComboBoxWidget combo, int ungrab_mask)
- {
- XmDisplay disp = (XmDisplay) XmGetXmDisplay(XtDisplay(combo));
- if ( ungrab_mask & GRAB_POINTER )
- XtUngrabPointer(Shell(combo), CurrentTime);
- if ( ungrab_mask & GRAB_KEYBOARD )
- XtUngrabKeyboard(List(combo), CurrentTime);
- _XmRemoveGrab(Shell(combo));
-
- /* We move XtPopdown() here and do _XmRemoveGrab first.
- * This is a fix to solve an MR in Desktop which over a time period
- * develope a possible core-dump due to duplicated removeGrab() calls
- */
- PoppedUp(combo) = FALSE;
- XtPopdown(Shell(combo));
- if (Type(combo) == DtDROP_DOWN_COMBO_BOX)
- XmProcessTraversal(Text(combo), XmTRAVERSE_CURRENT);
- /* This is to enable the Drag-and-Drop operation */
- disp->display.userGrabbed = False;
- }
|