1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: XmUbTimeSlider 4 -- 5 -- Project: XmUb - Ulle's Motif widgets 6 -- System: 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- This is the implementation of the widget. 12 -- 13 -- For the geometry management, the text widget is set to the width it 14 -- requests, and the scale widths are adjusted depending on the current 15 -- width of the widget. 16 -- 17 -- Filename: XmUbTimeSl.c 18 -- 19 -- Authors: Roger Larsson, Ulrika Bornetun 20 -- Creation date: 1993-09-21 21 -- 22 -- 23 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 24 -- All rights reserved 25 -- 26 -- Permission to use, copy, modify, and distribute this software and its 27 -- documentation for any purpose and without fee is hereby granted, 28 -- provided that the above copyright notice appear in all copies. Ulrika 29 -- Bornetun and Roger Larsson make no representations about the usability 30 -- of this software for any purpose. It is provided "as is" without express 31 -- or implied warranty. 32 ----------------------------------------------------------------------------*/ 33 34 /* SCCS module identifier. */ 35 static char SCCSID[] = "@(#) Module: XmUbTimeSl.c, Version: 1.1, Date: 95/02/18 15:10:16"; 36 37 38 /*---------------------------------------------------------------------------- 39 -- Include files 40 ----------------------------------------------------------------------------*/ 41 42 #include <stdio.h> 43 #include <string.h> 44 #include <X11/Intrinsic.h> 45 #include <X11/StringDefs.h> 46 #include <Xm/XmP.h> 47 48 #include <Xm/Scale.h> 49 #include <Xm/Text.h> 50 51 /* Rogge's tools. */ 52 #include "TimDate.h" 53 54 /* Private widget header file. */ 55 #include "XmUbTimeSlP.h" 56 57 /*---------------------------------------------------------------------------- 58 -- Macro definitions 59 ----------------------------------------------------------------------------*/ 60 61 #ifdef MAX 62 #undef MAX 63 #endif 64 65 #ifdef MIN 66 #undef MIN 67 #endif 68 69 #define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) 70 #define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) 71 72 #define XmUbTS_CHILD_ERROR -1 73 74 #define TEXT_BUFFER_LENGTH 20 75 76 /*---------------------------------------------------------------------------- 77 -- Type declarations 78 ----------------------------------------------------------------------------*/ 79 80 typedef struct { 81 82 Dimension width; 83 Dimension height; 84 Position x; 85 Position y; 86 87 } KidDimensionRec; 88 89 /*---------------------------------------------------------------------------- 90 -- Global definitions 91 ----------------------------------------------------------------------------*/ 92 93 /* Internal Motif functions (how do we know about this....?) */ 94 extern void 95 _XmBackgroundColorDefault(); 96 97 98 /* The time slider resource list. */ 99 static XtResource resources[] = { 100 { 101 XmNactivateCallback, 102 XmCCallback, 103 XmRCallback, sizeof( XtCallbackList ), 104 XtOffset( XmUbTimeSliderWidget, sl.activate_callback ), 105 XmRCallback, 106 NULL 107 }, 108 { 109 XmNvalueChangedCallback, 110 XmCCallback, 111 XmRCallback, sizeof( XtCallbackList ), 112 XtOffset( XmUbTimeSliderWidget, sl.value_changed_callback ), 113 XmRCallback, 114 NULL 115 }, 116 { 117 XmNmarginHeight, 118 XmCMarginHeight, 119 XtRDimension, sizeof( Dimension ), 120 XtOffset( XmUbTimeSliderWidget, sl.margin_height ), 121 XtRImmediate, 122 (XtPointer) 0 123 }, 124 { 125 XmNmarginWidth, 126 XmCMarginWidth, 127 XtRDimension, sizeof( Dimension ), 128 XtOffset( XmUbTimeSliderWidget, sl.margin_width ), 129 XtRImmediate, 130 (XtPointer) 0 131 }, 132 { 133 XmUbNtslRecomputeHeight, 134 XmUbCTslRecomputeHeight, 135 XtRBoolean, sizeof( Boolean ), 136 XtOffset( XmUbTimeSliderWidget, sl.recompute_height ), 137 XtRImmediate, 138 (XtPointer) True 139 }, 140 { 141 XmUbNtslRecomputeWidth, 142 XmUbCTslRecomputeWidth, 143 XtRBoolean, sizeof( Boolean ), 144 XtOffset( XmUbTimeSliderWidget, sl.recompute_width ), 145 XtRImmediate, 146 (XtPointer) True 147 }, 148 { 149 XmUbNtslSpacing, 150 XmCSpacing, 151 XtRDimension, sizeof( Dimension ), 152 XtOffset( XmUbTimeSliderWidget, sl.slider_spacing ), 153 XtRImmediate, 154 (XtPointer) 4 155 }, 156 { 157 XmUbNtslTextSpacing, 158 XmCSpacing, 159 XtRDimension, sizeof( Dimension ), 160 XtOffset( XmUbTimeSliderWidget, sl.text_spacing ), 161 XtRImmediate, 162 (XtPointer) 8 163 }, 164 165 }; /* resources */ 166 167 168 169 170 /*---------------------------------------------------------------------------- 171 -- Function prototypes 172 ----------------------------------------------------------------------------*/ 173 174 /* Core methods. */ 175 static void 176 ChangeManaged( Widget widget ); 177 178 static void 179 DeleteChild( Widget widget ); 180 181 static void 182 Destroy( Widget widget ); 183 184 static XtGeometryResult 185 GeometryManager( Widget widget, 186 XtWidgetGeometry *request, 187 XtWidgetGeometry *reply ); 188 189 static void 190 Initialize( Widget treq, 191 Widget tnew, 192 ArgList args, 193 Cardinal *num_args ); 194 195 static void 196 InsertChild( Widget widget ); 197 198 static XtGeometryResult 199 QueryGeometry( Widget widget, 200 XtWidgetGeometry *proposed, 201 XtWidgetGeometry *answer ); 202 203 static void 204 Resize( Widget widget ); 205 206 static Boolean 207 SetValues( Widget current, 208 Widget request, 209 Widget new, 210 ArgList args, 211 Cardinal *num_args ); 212 213 214 /* Internal functions. */ 215 216 217 static void 218 ActivateCB( Widget tw, 219 XmUbTimeSliderWidget tbox, 220 XmAnyCallbackStruct *call_data ); 221 222 /* If not in the child list, returns XmUbTS_CHILD_ERROR. */ 223 static int 224 ChildIndex( XmUbTimeSliderWidget tsl, 225 Widget child ); 226 227 static Widget 228 CreateSlider( XmUbTimeSliderWidget tsl, 229 char *name, 230 int maximum ); 231 232 /* Fills in the width and height fields in the kids dimension recs. */ 233 static void 234 GetChildPrefSizes( XmUbTimeSliderWidget tsl, 235 Widget initiator, 236 XtWidgetGeometry *request, 237 KidDimensionRec sizes[] ); 238 239 240 /* The sizes array must have been prepared by GetChildPrefSizes before this 241 function is called. */ 242 static void 243 GetOwnPreferredSize( XmUbTimeSliderWidget tsl, 244 KidDimensionRec sizes[], 245 Dimension *pref_width, 246 Dimension *pref_height ); 247 248 /* The sizes array must have been processed by GetChildPrefSizes 249 before DoLayout is called. */ 250 static void 251 DoLayout( XmUbTimeSliderWidget tsl, 252 Widget initiator, 253 XtWidgetGeometry *request, 254 KidDimensionRec sizes[] ); 255 256 static void 257 KidsPreferredGeometry( Widget kid, 258 Widget initiator, 259 XtWidgetGeometry *request, 260 XtWidgetGeometry *desired ); 261 262 static void 263 ScaleValueChangedCB( Widget scale, 264 XmUbTimeSliderWidget tsl, 265 XmScaleCallbackStruct *call_data ); 266 267 /* ResizeIfNeeded fills in the sizes array. Does not have to be initialized. */ 268 static Boolean 269 ResizeIfNeeded( XmUbTimeSliderWidget tsl, 270 KidDimensionRec sizes[] ); 271 272 static void 273 SelectAllTextCB( Widget tw, 274 XmUbTimeSliderWidget tsl, 275 XmAnyCallbackStruct *call_data ); 276 277 static void 278 TextChangedCB( Widget textw, 279 XmUbTimeSliderWidget tsl, 280 XmAnyCallbackStruct *call_data ); 281 282 static void 283 UpdateScales( XmUbTimeSliderWidget tsl, 284 int hour, 285 int minute ); 286 287 static void 288 UpdateTextField( XmUbTimeSliderWidget tsl ); 289 290 static void 291 ValueChangedCB( Widget tw, 292 XmUbTimeSliderWidget tsl, 293 XmAnyCallbackStruct *call_data ); 294 295 static void 296 WarningNoResourceChange( XmUbTimeSliderWidget tsl, 297 String resource ); 298 299 /*---------------------------------------------------------------------------- 300 -- Initialization of the class record. 301 ----------------------------------------------------------------------------*/ 302 303 /* This initialization has to be done after the methods have been declared. */ 304 XmUbTimeSliderClassRec xmUbTimeSliderClassRec = { 305 306 { /* Core class fields. */ 307 /* superclass */ (WidgetClass) &xmManagerClassRec, 308 /* class_name */ "XmUbTimeSlider", 309 /* widget_size */ sizeof( XmUbTimeSliderRec ), 310 /* class_initialize */ NULL, 311 /* class_part_initialize */ NULL, 312 /* class_inited */ False, 313 /* initialize */ Initialize, 314 /* initialize_hook */ NULL, 315 /* realize */ XtInheritRealize, 316 /* actions */ NULL, 317 /* num_actions */ 0, 318 /* resources */ resources, 319 /* num_resources */ XtNumber( resources ), 320 /* xrm_class */ NULLQUARK, 321 /* compress_motion */ True, 322 /* compress_exposure */ True, 323 /* compress_enterleave */ True, 324 /* visible_interest */ False, 325 /* destroy */ Destroy, 326 /* resize */ Resize, 327 /* expose */ NULL, 328 /* set_values */ SetValues, 329 /* set_values_hook */ NULL, 330 /* set_values_almost */ XtInheritSetValuesAlmost, 331 /* get_values_hook */ NULL, 332 /* accept_focus */ NULL, 333 /* version */ XtVersion, 334 /* callback_private */ NULL, 335 /* tm_table */ NULL, 336 /* query_geometry */ QueryGeometry, 337 /* display_accelerator */ XtInheritDisplayAccelerator, 338 /* extension */ NULL 339 }, 340 { /* Composite class part. */ 341 /* geometry_manager */ GeometryManager, 342 /* change_managed */ ChangeManaged, 343 /* insert_child */ InsertChild, 344 /* delete_child */ DeleteChild, 345 /* extension */ NULL 346 }, 347 { /* Constraint class fields. */ 348 /* subresources */ NULL, 349 /* subresource_count */ 0, 350 /* constraint_size */ sizeof( XmUbTimeSliderConstraintsRec ), 351 /* initialize */ NULL, 352 /* destroy */ NULL, 353 /* set_values */ NULL, 354 /* extension */ NULL 355 }, 356 { /* XmManager class part. */ 357 /* translations */ NULL, 358 /* get_resources */ NULL, 359 /* num_get_resources */ 0, 360 /* get_constraint_resources */ NULL, 361 /* num_get_constraint_resources */ 0, 362 /* extension */ NULL 363 }, 364 { /* Time slider class part. */ 365 /* extension */ NULL 366 }, 367 368 }; 369 370 371 /* Class record pointer. */ 372 WidgetClass 373 xmUbTimeSliderWidgetClass = (WidgetClass) &xmUbTimeSliderClassRec; 374 375 376 377 /*---------------------------------------------------------------------------- 378 -- Functions 379 ----------------------------------------------------------------------------*/ 380 381 static void ActivateCB(Widget tw,XmUbTimeSliderWidget tsl,XmAnyCallbackStruct * call_data)382 ActivateCB( Widget tw, 383 XmUbTimeSliderWidget tsl, 384 XmAnyCallbackStruct *call_data ) 385 { 386 /* Variables. */ 387 XmUbTimeSliderCallbackStruct cb; 388 389 /* Code. */ 390 391 if( tsl -> sl.activate_callback == NULL ) 392 return; 393 394 /* Set up callback structure. */ 395 396 cb.reason = XmCR_ACTIVATE; 397 cb.event = call_data -> event; 398 cb.child_index = ChildIndex( tsl, tw ); 399 cb.child = tw; 400 401 XtCallCallbackList( (Widget) tsl, tsl -> sl.activate_callback, 402 (XtPointer) &cb ); 403 404 405 return; 406 407 } /* ActivateCB */ 408 409 410 /*----------------------------------------------------------------------*/ 411 412 static void ChangeManaged(Widget widget)413 ChangeManaged( Widget widget ) 414 { 415 /* Variables. */ 416 Boolean layout_done; 417 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 418 XmUbTimeSliderWidget tsl; 419 420 421 /* Code. */ 422 423 tsl = (XmUbTimeSliderWidget) widget; 424 425 /* ResizeIfNeeded checks the size of all children and resizes the widget. */ 426 layout_done = ResizeIfNeeded( tsl, kids_sizes ); 427 428 /* Do the layout. */ 429 if( !layout_done ) 430 DoLayout( tsl, NULL, NULL, kids_sizes ); 431 432 433 return; 434 435 } /* ChangeManaged */ 436 437 438 /*----------------------------------------------------------------------*/ 439 440 static int ChildIndex(XmUbTimeSliderWidget tsl,Widget child)441 ChildIndex( XmUbTimeSliderWidget tsl, 442 Widget child ) 443 { 444 /* Variables. */ 445 int index; 446 447 /* Code. */ 448 449 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 450 451 if( tsl -> sl.internal_children[ index ] == child ) 452 return index; 453 454 } /* for */ 455 456 457 /* Specified child not found. */ 458 return XmUbTS_CHILD_ERROR; 459 460 } /* ChildIndex */ 461 462 463 /*----------------------------------------------------------------------*/ 464 465 static void CreateInternalWidgets(XmUbTimeSliderWidget tsl)466 CreateInternalWidgets( XmUbTimeSliderWidget tsl ) 467 { 468 /* Variables. */ 469 Arg args[ 5 ]; 470 short columns; 471 int index; 472 Cardinal n; 473 char *name_buffer; 474 char text_buffer[ TEXT_BUFFER_LENGTH ]; 475 TIM_TIME_REF time; 476 String wname; 477 478 /* Code. */ 479 480 /* Get the name of the "parent" widget. */ 481 wname = XtName( (Widget)tsl ); 482 483 name_buffer = XtMalloc( strlen( wname ) + 4 ); 484 485 /* Create the sliders. */ 486 487 /* Hour slider. */ 488 sprintf( name_buffer, "%sHSL", wname ); 489 490 tsl -> sl.internal_children[ XmUbTS_CHILD_HOUR_SLIDER ] = 491 CreateSlider( tsl, name_buffer, 23 ); 492 493 /* Minute slider. */ 494 sprintf( name_buffer, "%sMSL", wname ); 495 496 tsl -> sl.internal_children[ XmUbTS_CHILD_MINUTE_SLIDER ] = 497 CreateSlider( tsl, name_buffer, 59 ); 498 499 /* Create the text field. */ 500 sprintf( name_buffer, "%sTX", wname ); 501 502 /* Find out how many columns wide we should make the widget. */ 503 time = TimMakeTime( 1990, 1, 1, 23, 59, 59 ); 504 TimFormatTime( time, text_buffer, TEXT_BUFFER_LENGTH ); 505 columns = (short) ( strlen( text_buffer ) + 1 ); 506 507 n = 0; 508 XtSetArg( args[ n ], XmNcolumns, columns ); n++; 509 XtSetArg( args[ n ], XmNmaxLength, columns ); n++; 510 tsl -> sl.internal_children[ XmUbTS_CHILD_TEXT_FIELD ] = 511 XmCreateText( (Widget) tsl, name_buffer, args, n ); 512 513 XtAddCallback( tsl -> sl.internal_children[ XmUbTS_CHILD_TEXT_FIELD ], 514 XmNvalueChangedCallback, 515 (XtCallbackProc) TextChangedCB, (XtPointer) tsl ); 516 517 XtAddCallback( tsl -> sl.internal_children[ XmUbTS_CHILD_TEXT_FIELD ], 518 XmNactivateCallback, 519 (XtCallbackProc) ActivateCB, (XtPointer) tsl ); 520 521 XtAddCallback( tsl -> sl.internal_children[ XmUbTS_CHILD_TEXT_FIELD ], 522 XmNvalueChangedCallback, 523 (XtCallbackProc) ValueChangedCB, (XtPointer) tsl ); 524 525 XtAddCallback( tsl -> sl.internal_children[ XmUbTS_CHILD_TEXT_FIELD ], 526 XmNfocusCallback, 527 (XtCallbackProc) SelectAllTextCB, (XtPointer) tsl ); 528 529 /* Manage the created children. */ 530 for( index = XmUbTS_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ){ 531 if( tsl -> sl.internal_children[ index ] != NULL ) 532 XtManageChild( tsl -> sl.internal_children[ index ] ); 533 } 534 535 536 XtFree( name_buffer ); 537 538 539 return; 540 541 } /* CreateInternalWidgets */ 542 543 544 /*----------------------------------------------------------------------*/ 545 546 static Widget CreateSlider(XmUbTimeSliderWidget tsl,char * name,int maximum)547 CreateSlider( XmUbTimeSliderWidget tsl, 548 char *name, 549 int maximum ) 550 { 551 /* Variables. */ 552 Arg args[ 5 ]; 553 Cardinal n; 554 Widget scale; 555 556 /* Code. */ 557 558 n = 0; 559 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 560 XtSetArg( args[ n ], XmNshowValue, False ); n++; 561 XtSetArg( args[ n ], XmNminimum, 0 ); n++; 562 XtSetArg( args[ n ], XmNmaximum, maximum ); n++; 563 scale = XmCreateScale( (Widget) tsl, name, args, n ); 564 565 XtAddCallback( scale, XmNvalueChangedCallback, 566 (XtCallbackProc) ScaleValueChangedCB, (XtPointer) tsl ); 567 XtAddCallback( scale, XmNdragCallback, 568 (XtCallbackProc) ScaleValueChangedCB, (XtPointer) tsl ); 569 570 571 return( scale ); 572 573 } /* CreateSlider */ 574 575 576 /*----------------------------------------------------------------------*/ 577 578 static void DeleteChild(Widget widget)579 DeleteChild( Widget widget ) 580 { 581 582 /* Variables. */ 583 int index; 584 XmUbTimeSliderWidget tsl; 585 586 /* Code. */ 587 588 tsl = (XmUbTimeSliderWidget) XtParent( widget ); 589 590 /* Clear the internal reference. */ 591 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 592 if( tsl -> sl.internal_children[ index ] == widget ){ 593 tsl -> sl.internal_children[ index ] = NULL; 594 break; 595 } 596 } 597 598 /* Perform the actual operation */ 599 (* ( (CompositeWidgetClass) (xmUbTimeSliderWidgetClass -> 600 core_class.superclass) ) -> composite_class.delete_child ) ( widget ); 601 602 603 return; 604 605 } /* DeleteChild */ 606 607 608 /*----------------------------------------------------------------------*/ 609 610 static void Destroy(Widget widget)611 Destroy( Widget widget ) 612 { 613 /* Code. */ 614 615 /* Remove callbacks. */ 616 XtRemoveAllCallbacks( widget, XmNactivateCallback ); 617 XtRemoveAllCallbacks( widget, XmNvalueChangedCallback ); 618 619 620 return; 621 622 } /* Destroy */ 623 624 625 /*----------------------------------------------------------------------*/ 626 627 static void DoLayout(XmUbTimeSliderWidget tsl,Widget initiator,XtWidgetGeometry * request,KidDimensionRec sizes[])628 DoLayout( XmUbTimeSliderWidget tsl, 629 Widget initiator, 630 XtWidgetGeometry *request, 631 KidDimensionRec sizes[] ) 632 { 633 /* Variables. */ 634 int index; 635 Widget kid; 636 int no_managed; 637 Dimension scale_width; 638 Position scale_x_pos; 639 Position scale_y_offset; 640 Dimension total_height; 641 Position y_pos; 642 643 /* Code. */ 644 645 /* Start with the text widget, let it keep its requested size. */ 646 if( ( sizes[ XmUbTS_CHILD_TEXT_FIELD ].width + tsl -> sl.margin_width ) > 647 tsl -> core.width ) 648 sizes[ XmUbTS_CHILD_TEXT_FIELD ].x = 0; 649 else 650 sizes[ XmUbTS_CHILD_TEXT_FIELD ].x = (Position) ( tsl -> core.width - 651 tsl -> sl.margin_width - sizes[ XmUbTS_CHILD_TEXT_FIELD ].width ); 652 653 /* Get the total height of the scales. */ 654 no_managed = 0; 655 total_height = 0; 656 for( index = XmUbTS_CHILD_HOUR_SLIDER; 657 index < XmUbTS_CHILD_MINUTE_SLIDER + 1; index ++ ){ 658 659 /* If not managed, width and height are zero. */ 660 if( sizes[ index ].width > 0 ){ 661 no_managed ++; 662 total_height += sizes[ index ].height; 663 } 664 } /* for */ 665 666 if( no_managed > 1 ) 667 total_height += tsl -> sl.slider_spacing; 668 669 /* Center the scales and the text field vertically. */ 670 if( total_height > sizes[ XmUbTS_CHILD_TEXT_FIELD ].height ){ 671 sizes[ XmUbTS_CHILD_TEXT_FIELD ].y = (Position) ( tsl -> sl.margin_height + 672 ( total_height - sizes[ XmUbTS_CHILD_TEXT_FIELD ].height ) / 2 ); 673 scale_y_offset = 0; 674 } else { 675 sizes[ XmUbTS_CHILD_TEXT_FIELD ].y = 676 (Position) ( tsl -> sl.margin_height ); 677 scale_y_offset = (Position) ( sizes[ XmUbTS_CHILD_TEXT_FIELD ].height - 678 total_height ) / 2; 679 } 680 681 /* Let the scales do with the width that is left. */ 682 if( ( sizes[ XmUbTS_CHILD_TEXT_FIELD ].width + 2 * tsl -> sl.margin_width ) > 683 tsl -> core.width ){ 684 scale_width = 1; 685 scale_x_pos = 0; 686 687 } else { 688 689 scale_width = tsl -> core.width - sizes[ XmUbTS_CHILD_TEXT_FIELD ].width - 690 2 * tsl -> sl.margin_width; 691 scale_x_pos = tsl -> sl.margin_width; 692 } 693 694 y_pos = tsl -> sl.margin_height + scale_y_offset; 695 for( index = XmUbTS_CHILD_HOUR_SLIDER; 696 index < XmUbTS_CHILD_MINUTE_SLIDER + 1; index ++ ){ 697 698 kid = tsl -> sl.internal_children[ index ]; 699 700 if( ( kid != NULL ) && XtIsManaged( kid ) ){ 701 sizes[ index ].width = scale_width; 702 sizes[ index ].x = scale_x_pos; 703 sizes[ index ].y = y_pos; 704 705 y_pos += (Position) ( sizes[ index ].height + tsl -> sl.slider_spacing ); 706 } 707 } /* for */ 708 709 710 /* Configure the children. */ 711 /* All positions and dimensions are now in the sizes array. */ 712 for( index = XmUbTS_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ){ 713 714 kid = tsl -> sl.internal_children[ index ]; 715 716 if( ( kid != NULL ) && XtIsManaged( kid ) ) 717 XtConfigureWidget( kid, sizes[ index ].x, sizes[ index ].y, 718 sizes[ index ].width, sizes[ index ].height, 719 kid -> core.border_width ); 720 } 721 722 723 return; 724 725 } /* DoLayout */ 726 727 728 /*----------------------------------------------------------------------*/ 729 730 static XtGeometryResult GeometryManager(Widget widget,XtWidgetGeometry * request,XtWidgetGeometry * reply)731 GeometryManager( Widget widget, 732 XtWidgetGeometry *request, 733 XtWidgetGeometry *reply ) 734 { 735 736 XtWidgetGeometry own_request; 737 Dimension old_width, old_height; 738 Dimension pref_height; 739 Dimension pref_width; 740 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 741 XtGeometryResult result; 742 XmUbTimeSliderWidget tsl; 743 744 /* Code. */ 745 746 tsl = (XmUbTimeSliderWidget) XtParent( widget ); 747 748 /* Find out how big the widget would be if the resize were allowed. */ 749 GetChildPrefSizes( tsl, NULL, request, kids_sizes ); 750 GetOwnPreferredSize( tsl, kids_sizes, &pref_width, &pref_height ); 751 752 /* If no change in dimensions, allow the request. */ 753 if( ( pref_width == tsl -> core.width ) && 754 ( pref_height == tsl -> core.height )){ 755 DoLayout( tsl, widget, request, kids_sizes ); 756 return XtGeometryYes; 757 } 758 759 /* We must ask our parent to resize us. */ 760 own_request.request_mode = CWWidth | CWHeight; 761 own_request.width = pref_width; 762 own_request.height = pref_height; 763 764 /* Save dimensions. */ 765 old_width = tsl -> core.width; 766 old_height = tsl -> core.height; 767 768 tsl -> sl.resize_called = False; 769 770 /* We are not interested in any compromise geometry. */ 771 result = XtMakeGeometryRequest( (Widget) tsl, &own_request, NULL ); 772 773 /* Reset to old dimensions if request not granted. */ 774 if( result != XtGeometryYes ){ 775 tsl -> core.width = old_width; 776 tsl -> core.height = old_height; 777 778 } else { 779 if( !tsl -> sl.resize_called ) 780 Resize( (Widget) tsl ); 781 } 782 783 /* Always grant child's request. */ 784 return XtGeometryYes; 785 786 } /* GeometryManager */ 787 788 789 /*----------------------------------------------------------------------*/ 790 791 static void GetChildPrefSizes(XmUbTimeSliderWidget tsl,Widget initiator,XtWidgetGeometry * request,KidDimensionRec sizes[])792 GetChildPrefSizes( XmUbTimeSliderWidget tsl, 793 Widget initiator, 794 XtWidgetGeometry *request, 795 KidDimensionRec sizes[] ) 796 { 797 /* Variables. */ 798 XtWidgetGeometry desired; 799 int index; 800 Widget kid; 801 802 /* Code. */ 803 804 /* Initialize. */ 805 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 806 sizes[ index ].width = 0; 807 sizes[ index ].height = 0; 808 sizes[ index ].x = 0; 809 sizes[ index ].y = 0; 810 } 811 812 /* Get the preferred sizes for the children. */ 813 for( index = XmUbTS_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ){ 814 815 kid = tsl -> sl.internal_children[ index ]; 816 817 if( ( kid != NULL ) && XtIsManaged( kid ) ){ 818 819 KidsPreferredGeometry( kid, initiator, request, &desired ); 820 821 sizes[ index ].width = desired.width; 822 sizes[ index ].height = desired.height; 823 824 } 825 826 } /* for */ 827 828 829 return; 830 831 } /* GetChildPrefSizes */ 832 833 834 /*----------------------------------------------------------------------*/ 835 836 static void GetOwnPreferredSize(XmUbTimeSliderWidget tsl,KidDimensionRec sizes[],Dimension * pref_width,Dimension * pref_height)837 GetOwnPreferredSize( XmUbTimeSliderWidget tsl, 838 KidDimensionRec sizes[], 839 Dimension *pref_width, 840 Dimension *pref_height ) 841 { 842 /* Variables. */ 843 int index; 844 Widget kid; 845 Dimension max_scale_width = 0; 846 int no_managed = 0; 847 Dimension total_scale_height = 0; 848 849 /* Code. */ 850 851 /* Check out the dimension of the scales. */ 852 for( index = XmUbTS_CHILD_HOUR_SLIDER; 853 index < XmUbTS_CHILD_MINUTE_SLIDER + 1; index ++ ){ 854 855 kid = tsl -> sl.internal_children[ index ]; 856 857 if( ( kid != NULL ) && XtIsManaged( kid ) ){ 858 859 total_scale_height += sizes[ index ].height; 860 861 if( sizes[ index ].width > max_scale_width ) 862 max_scale_width = sizes[ index ].width; 863 864 no_managed ++; 865 } 866 } /* for */ 867 868 if( no_managed > 1 ) 869 total_scale_height += tsl -> sl.slider_spacing; 870 871 /* We may not be allowed to request the size the children would like. */ 872 if( tsl -> sl.recompute_width ) 873 *pref_width = max_scale_width + sizes[ XmUbTS_CHILD_TEXT_FIELD ].width + 874 2 * tsl -> sl.margin_width + tsl -> sl.text_spacing; 875 else 876 *pref_width = tsl -> core.width; 877 878 if( tsl -> sl.recompute_height ) 879 *pref_height = MAX( total_scale_height, 880 sizes[ XmUbTS_CHILD_TEXT_FIELD ].height ) + 881 2 * tsl -> sl.margin_height; 882 else 883 *pref_height = tsl -> core.height; 884 885 886 return; 887 888 } /* GetOwnPreferredSize */ 889 890 891 /*----------------------------------------------------------------------*/ 892 893 static void Initialize(Widget treq,Widget tnew,ArgList args,Cardinal * num_args)894 Initialize( Widget treq, 895 Widget tnew, 896 ArgList args, 897 Cardinal *num_args ) 898 { 899 /* Variables. */ 900 int index; 901 XmUbTimeSliderWidget new; 902 903 /* Code. */ 904 905 new = (XmUbTimeSliderWidget) tnew; 906 907 /* Initialize private fields. */ 908 for( index = XmUbTS_FIRST_CHILD; index < NO_INTERNAL_CHILDREN; index ++ ) 909 new -> sl.internal_children[ index ] = NULL; 910 911 /* Start size if none supplied. */ 912 if( new -> core.width == 0 ) 913 new -> core.width = 300; 914 else 915 new -> sl.recompute_width = False; 916 917 if( new -> core.height == 0 ) 918 new -> core.height = 100; 919 else 920 new -> sl.recompute_height = False; 921 922 /* Create the internal widgets. */ 923 new -> sl.internal_widgets_created = False; 924 925 CreateInternalWidgets( new ); 926 927 new -> sl.internal_widgets_created = True; 928 929 /* Set the initial value in the text field. */ 930 UpdateTextField( new ); 931 932 933 return; 934 935 } /* Initialize */ 936 937 938 /*----------------------------------------------------------------------*/ 939 940 static void InsertChild(Widget widget)941 InsertChild( Widget widget ) 942 { 943 944 /* Variables. */ 945 Cardinal num_params; 946 String params[ 1 ]; 947 XmUbTimeSliderWidget tsl; 948 949 /* Code. */ 950 951 tsl = (XmUbTimeSliderWidget) XtParent( widget ); 952 953 /* We do not allow the application to create children. */ 954 if( tsl -> sl.internal_widgets_created ){ 955 956 params[ 0 ] = XtClass( (Widget) tsl ) -> core_class.class_name; 957 num_params = 1; 958 XtAppErrorMsg( XtWidgetToApplicationContext( widget ), 959 "childError", "number", "WidgetError", 960 "Applications cannot add children to %s widgets.", 961 params, &num_params ); 962 } 963 964 /* This is an internal child. Adding it is OK. */ 965 (* ( (CompositeWidgetClass) (xmUbTimeSliderWidgetClass -> 966 core_class.superclass) ) -> composite_class.insert_child ) ( widget ); 967 968 969 return; 970 971 } /* InsertChild */ 972 973 974 /*----------------------------------------------------------------------*/ 975 976 static void KidsPreferredGeometry(Widget kid,Widget initiator,XtWidgetGeometry * request,XtWidgetGeometry * desired)977 KidsPreferredGeometry( Widget kid, 978 Widget initiator, 979 XtWidgetGeometry *request, 980 XtWidgetGeometry *desired ) 981 { 982 983 /* Code. */ 984 985 if( ( kid == initiator ) && ( request != NULL ) ){ 986 /* The initiator should not be queried. */ 987 if( request -> request_mode & CWWidth ) 988 desired -> width = request -> width; 989 else 990 desired -> width = (Dimension) kid -> core.width; 991 992 if( request -> request_mode & CWHeight ) 993 desired -> height = request -> height; 994 else 995 desired -> height = (Dimension) kid -> core.height; 996 997 } else 998 (void) XtQueryGeometry( kid, NULL, desired ); 999 1000 1001 return; 1002 1003 } /* KidsPreferredGeometry */ 1004 1005 1006 /*----------------------------------------------------------------------*/ 1007 1008 static void Resize(Widget widget)1009 Resize( Widget widget ) 1010 { 1011 /* Variables. */ 1012 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 1013 XmUbTimeSliderWidget tsl; 1014 1015 /* Code. */ 1016 1017 tsl = (XmUbTimeSliderWidget) widget; 1018 1019 tsl -> sl.resize_called = True; 1020 1021 /* We have to get the preferred size of the children before we organize 1022 the layout. */ 1023 GetChildPrefSizes( tsl, NULL, NULL, kids_sizes ); 1024 DoLayout( tsl, NULL, NULL, kids_sizes ); 1025 1026 1027 return; 1028 1029 } /* Resize */ 1030 1031 1032 /*----------------------------------------------------------------------*/ 1033 1034 static Boolean ResizeIfNeeded(XmUbTimeSliderWidget tsl,KidDimensionRec sizes[])1035 ResizeIfNeeded( XmUbTimeSliderWidget tsl, 1036 KidDimensionRec sizes[] ) 1037 { 1038 1039 /* Variables. */ 1040 Boolean layout_done; 1041 Dimension pref_height; 1042 Dimension pref_width; 1043 XtWidgetGeometry request; 1044 XtGeometryResult result; 1045 1046 /* Code. */ 1047 1048 /* Initialize. */ 1049 layout_done = False; 1050 1051 /* Get the preferred dimensions of the time box widget. */ 1052 GetChildPrefSizes( tsl, NULL, NULL, sizes ); 1053 GetOwnPreferredSize( tsl, sizes, &pref_width, &pref_height ); 1054 1055 /* If we want the same dimensions, no resizing is needed. */ 1056 if(( pref_width == tsl -> core.width ) && 1057 ( pref_height == tsl -> core.height )) 1058 return False; 1059 1060 /* Dimensions are different. Try to resize. */ 1061 request.request_mode = CWWidth | CWHeight; 1062 1063 request.width = pref_width; 1064 request.height = pref_height; 1065 1066 tsl -> sl.resize_called = False; 1067 1068 do { 1069 1070 result = XtMakeGeometryRequest( (Widget) tsl, &request, &request ); 1071 1072 } while( result == XtGeometryAlmost ); 1073 1074 if( result == XtGeometryNo ) 1075 return False; 1076 1077 /* Resize done. Core fields have already been updated. */ 1078 return( tsl -> sl.resize_called ); 1079 1080 } /* ResizeIfNeeded */ 1081 1082 1083 /*----------------------------------------------------------------------*/ 1084 1085 static XtGeometryResult QueryGeometry(Widget widget,XtWidgetGeometry * proposed,XtWidgetGeometry * answer)1086 QueryGeometry( Widget widget, 1087 XtWidgetGeometry *proposed, 1088 XtWidgetGeometry *answer ) 1089 { 1090 1091 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 1092 Dimension pref_height; 1093 Dimension pref_width; 1094 XmUbTimeSliderWidget tsl; 1095 1096 /* Code. */ 1097 1098 1099 tsl = (XmUbTimeSliderWidget) widget; 1100 1101 /* Get dimensions that we *really* want. */ 1102 GetChildPrefSizes( tsl, NULL, NULL, kids_sizes ); 1103 GetOwnPreferredSize( tsl, kids_sizes, &pref_width, &pref_height ); 1104 1105 answer -> request_mode = CWWidth | CWHeight; 1106 answer -> width = pref_width; 1107 answer -> height = pref_height; 1108 1109 1110 if( proposed == NULL ){ 1111 /* This is a query for the requested geometry. */ 1112 1113 if(( answer -> height == (int) tsl -> core.height ) && 1114 ( answer -> width == (int) tsl -> core.width )) 1115 return XtGeometryNo; 1116 else 1117 return XtGeometryAlmost; 1118 } 1119 1120 /* The parent supplied a geometry suggestion. */ 1121 if(( answer -> height == proposed -> height ) && 1122 ( answer -> width == proposed -> width )) 1123 return XtGeometryYes; 1124 1125 if( ( proposed -> height <= 1 ) || 1126 ( proposed -> width <= 1 ) ) 1127 /* That's too small ! */ 1128 return XtGeometryNo; 1129 1130 1131 /* Only a compromise left. */ 1132 return XtGeometryAlmost; 1133 1134 } /* QueryGeometry */ 1135 1136 1137 /*----------------------------------------------------------------------*/ 1138 1139 static void ScaleValueChangedCB(Widget scale,XmUbTimeSliderWidget tsl,XmScaleCallbackStruct * call_data)1140 ScaleValueChangedCB( Widget scale, 1141 XmUbTimeSliderWidget tsl, 1142 XmScaleCallbackStruct *call_data ) 1143 { 1144 /* Code. */ 1145 1146 UpdateTextField( tsl ); 1147 1148 1149 return; 1150 1151 } /* ScaleValueChangedCB */ 1152 1153 1154 /*----------------------------------------------------------------------*/ 1155 1156 static void SelectAllTextCB(Widget tw,XmUbTimeSliderWidget tsl,XmAnyCallbackStruct * call_data)1157 SelectAllTextCB( Widget tw, 1158 XmUbTimeSliderWidget tsl, 1159 XmAnyCallbackStruct *call_data ) 1160 { 1161 /* Variables. */ 1162 XmTextPosition last; 1163 1164 /* Code. */ 1165 1166 /* Select all text in the text widget. */ 1167 1168 last = XmTextGetLastPosition( tw ); 1169 1170 if( last > 0 ) 1171 XmTextSetSelection( tw, 0, last, CurrentTime ); 1172 1173 /* Set the insertion position to the start of the widget. */ 1174 XmTextSetInsertionPosition( tw, 0 ); 1175 1176 1177 return; 1178 1179 } /* SelectAllTextCB */ 1180 1181 1182 /*----------------------------------------------------------------------*/ 1183 1184 static Boolean SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * num_args)1185 SetValues( Widget current, 1186 Widget request, 1187 Widget new, 1188 ArgList args, 1189 Cardinal *num_args ) 1190 { 1191 #ifdef Differs 1192 #undef Differs 1193 #endif 1194 1195 #define Differs( field ) ( curW -> field != newW -> field ) 1196 1197 /* Variables. */ 1198 XmUbTimeSliderWidget curW; 1199 Arg local_args[ 2 ]; 1200 Cardinal n; 1201 XmUbTimeSliderWidget newW; 1202 Boolean visual_changed = False; 1203 1204 /* Code. */ 1205 1206 curW = (XmUbTimeSliderWidget) current; 1207 newW = (XmUbTimeSliderWidget) new; 1208 1209 /* Width and height. */ 1210 /* Resizing is handled higher up. */ 1211 1212 if( Differs( sl.recompute_width ) && newW -> sl.recompute_width ) 1213 visual_changed = True; 1214 else if( Differs( core.width ) ) 1215 newW -> sl.recompute_width = False; 1216 1217 if( Differs( sl.recompute_height ) && newW -> sl.recompute_height ) 1218 visual_changed = True; 1219 else if( Differs( core.height ) ) 1220 newW -> sl.recompute_height = False; 1221 1222 /* Margins and spacings. */ 1223 if( Differs( sl.slider_spacing ) || 1224 Differs( sl.text_spacing ) || 1225 Differs( sl.margin_width ) || 1226 Differs( sl.margin_height ) ) 1227 visual_changed = True; 1228 1229 /* These changes affect the child widgets. */ 1230 if( Differs( manager.foreground ) || 1231 Differs( core.background_pixel ) ){ 1232 1233 n = 0; 1234 1235 if( Differs( manager.foreground ) ){ 1236 XtSetArg( local_args[ n ], XmNforeground, 1237 newW -> manager.foreground ); n++; 1238 } 1239 if( Differs( core.background_pixel ) ){ 1240 XtSetArg( local_args[ n ], XmNbackground, 1241 newW -> core.background_pixel ); n++; 1242 } 1243 1244 XtSetValues( newW -> sl.internal_children[ XmUbTS_CHILD_HOUR_SLIDER ], 1245 local_args, n ); 1246 XtSetValues( newW -> sl.internal_children[ XmUbTS_CHILD_MINUTE_SLIDER ], 1247 local_args, n ); 1248 XtSetValues( newW -> sl.internal_children[ XmUbTS_CHILD_TEXT_FIELD ], 1249 local_args, n ); 1250 } 1251 1252 1253 if( visual_changed ){ 1254 1255 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 1256 Boolean resized; 1257 1258 /* Code. */ 1259 1260 resized = ResizeIfNeeded( newW, kids_sizes ); 1261 1262 /* If the widget was resized, the layout has already been done. */ 1263 if( !resized ) 1264 DoLayout( newW, NULL, NULL, kids_sizes ); 1265 1266 } 1267 1268 return( visual_changed ); 1269 1270 #undef Differs 1271 1272 } /* SetValues */ 1273 1274 1275 /*----------------------------------------------------------------------*/ 1276 1277 static void TextChangedCB(Widget textw,XmUbTimeSliderWidget tsl,XmAnyCallbackStruct * call_data)1278 TextChangedCB( Widget textw, 1279 XmUbTimeSliderWidget tsl, 1280 XmAnyCallbackStruct *call_data ) 1281 { 1282 /* Variables. */ 1283 int hour; 1284 int minute; 1285 TIM_STATUS_TYPE status; 1286 String str; 1287 TIM_TIME_REF time; 1288 1289 /* Code. */ 1290 1291 /* Get the current text string. */ 1292 str = XmTextGetString( 1293 XmUbTimeSliderGetChild( (Widget) tsl, XmUbTS_CHILD_TEXT_FIELD ) ); 1294 1295 /* Get the hour and minute values. */ 1296 status = TimMakeTimeFromString( &time, str ); 1297 1298 if( status == TIM_OK ){ 1299 1300 hour = TimHour( time ); 1301 minute = TimMinute( time ); 1302 1303 UpdateScales( tsl, hour, minute ); 1304 } 1305 1306 /* Cleanup.*/ 1307 XtFree( str ); 1308 1309 1310 return; 1311 1312 } /* TextChangedCB */ 1313 1314 1315 /*----------------------------------------------------------------------*/ 1316 1317 static void UpdateScales(XmUbTimeSliderWidget tsl,int hour,int minute)1318 UpdateScales( XmUbTimeSliderWidget tsl, 1319 int hour, 1320 int minute ) 1321 { 1322 /* Variables. */ 1323 Widget scale; 1324 1325 /* Code. */ 1326 1327 /* Set the scale values. */ 1328 scale = XmUbTimeSliderGetChild( (Widget) tsl, XmUbTS_CHILD_HOUR_SLIDER ); 1329 if( scale != NULL ) 1330 XmScaleSetValue( scale, hour ); 1331 1332 scale = XmUbTimeSliderGetChild( (Widget) tsl, XmUbTS_CHILD_MINUTE_SLIDER ); 1333 if( scale != NULL ) 1334 XmScaleSetValue( scale, minute ); 1335 1336 1337 return; 1338 1339 } /* UpdateScales */ 1340 1341 1342 /*----------------------------------------------------------------------*/ 1343 1344 static void UpdateTextField(XmUbTimeSliderWidget tsl)1345 UpdateTextField( XmUbTimeSliderWidget tsl ) 1346 { 1347 /* Variables. */ 1348 int hour = 0; 1349 int minute = 0; 1350 char text_buffer[ TEXT_BUFFER_LENGTH ]; 1351 TIM_TIME_REF time; 1352 Widget tmp_widget; 1353 1354 /* Code. */ 1355 1356 /* Get the value from the sliders one at a time. */ 1357 1358 tmp_widget = XmUbTimeSliderGetChild( (Widget) tsl, 1359 XmUbTS_CHILD_HOUR_SLIDER ); 1360 if( tmp_widget != NULL ) 1361 XmScaleGetValue( tmp_widget, &hour ); 1362 1363 tmp_widget = XmUbTimeSliderGetChild( (Widget) tsl, 1364 XmUbTS_CHILD_MINUTE_SLIDER ); 1365 if( tmp_widget != NULL ) 1366 XmScaleGetValue( tmp_widget, &minute ); 1367 1368 1369 /* Create a time string to display in the text field. */ 1370 time = TimMakeTime( 1990, 1, 1, hour, minute, 0 ); 1371 TimFormatTime( time, text_buffer, TEXT_BUFFER_LENGTH ); 1372 1373 XmTextSetString( 1374 XmUbTimeSliderGetChild( (Widget) tsl, XmUbTS_CHILD_TEXT_FIELD ), 1375 text_buffer ); 1376 1377 1378 return; 1379 1380 } /* UpdateTextField */ 1381 1382 1383 /*----------------------------------------------------------------------*/ 1384 1385 static void ValueChangedCB(Widget tw,XmUbTimeSliderWidget tsl,XmAnyCallbackStruct * call_data)1386 ValueChangedCB( Widget tw, 1387 XmUbTimeSliderWidget tsl, 1388 XmAnyCallbackStruct *call_data ) 1389 { 1390 /* Variables. */ 1391 XmUbTimeSliderCallbackStruct cb; 1392 1393 /* Code. */ 1394 1395 if( tsl -> sl.value_changed_callback == NULL ) 1396 return; 1397 1398 /* Set up callback structure. */ 1399 1400 cb.reason = XmCR_VALUE_CHANGED; 1401 cb.event = call_data -> event; 1402 cb.child_index = ChildIndex( tsl, tw ); 1403 cb.child = tw; 1404 1405 XtCallCallbackList( (Widget) tsl, tsl -> sl.value_changed_callback, 1406 (XtPointer) &cb ); 1407 1408 1409 return; 1410 1411 } /* ValueChangedCB */ 1412 1413 1414 /*----------------------------------------------------------------------*/ 1415 1416 static void WarningNoResourceChange(XmUbTimeSliderWidget tsl,String resource)1417 WarningNoResourceChange( XmUbTimeSliderWidget tsl, 1418 String resource ) 1419 { 1420 /* Variables. */ 1421 Cardinal num_params; 1422 String params[ 2 ]; 1423 1424 /* Code. */ 1425 1426 params[ 0 ] = resource; 1427 params[ 1 ] = XtClass( tsl ) -> core_class.class_name; 1428 num_params = 2; 1429 XtAppWarningMsg( XtWidgetToApplicationContext( (Widget) tsl ), 1430 "resourceError", "setValues", "WidgetError", 1431 "Resource %s may not be changed in %s widgets.", 1432 params, &num_params ); 1433 1434 return; 1435 1436 } /* WarningNoResourceChange */ 1437 1438 1439 /*----------------------------------------------------------------------*/ 1440 1441 Widget XmUbCreateTimeSlider(Widget parent,String name,ArgList arglist,Cardinal argcount)1442 XmUbCreateTimeSlider( Widget parent, 1443 String name, 1444 ArgList arglist, 1445 Cardinal argcount ) 1446 { 1447 1448 /* Code. */ 1449 1450 return XtCreateWidget( name, xmUbTimeSliderWidgetClass, 1451 parent, arglist, argcount ); 1452 1453 } /* XmUbCreateTimeSlider */ 1454 1455 1456 /*----------------------------------------------------------------------*/ 1457 1458 Widget XmUbTimeSliderGetChild(Widget widget,int child)1459 XmUbTimeSliderGetChild( Widget widget, 1460 int child ) 1461 { 1462 1463 /* Variables. */ 1464 XmUbTimeSliderWidget tsl; 1465 1466 /* Code. */ 1467 1468 tsl = (XmUbTimeSliderWidget) widget; 1469 1470 1471 return( tsl -> sl.internal_children[ child ] ); 1472 1473 } /* XmUbTimeSliderGetChild */ 1474 1475 1476 /*----------------------------------------------------------------------*/ 1477 1478 time_t XmUbTimeSliderGetTime(Widget widget)1479 XmUbTimeSliderGetTime( Widget widget ) 1480 { 1481 /* Variables. */ 1482 int hour = 0; 1483 int minute = 0; 1484 TIM_TIME_REF time; 1485 Widget tmp_widget; 1486 1487 /* Code. */ 1488 1489 /* Get the value from the sliders one at a time. */ 1490 1491 tmp_widget = XmUbTimeSliderGetChild( widget, XmUbTS_CHILD_HOUR_SLIDER ); 1492 if( tmp_widget != NULL ) 1493 XmScaleGetValue( tmp_widget, &hour ); 1494 1495 tmp_widget = XmUbTimeSliderGetChild( widget, XmUbTS_CHILD_MINUTE_SLIDER ); 1496 if( tmp_widget != NULL ) 1497 XmScaleGetValue( tmp_widget, &minute ); 1498 1499 /* Create the time from the fetched values. */ 1500 time = TimMakeTime( 1970, 1, 1, hour, minute, 0 ); 1501 1502 1503 return time; 1504 1505 } /* XmUbTimeSliderGetTime */ 1506 1507 1508 /*----------------------------------------------------------------------*/ 1509 1510 char XmUbTimeSliderGetTimeString(Widget widget)1511 *XmUbTimeSliderGetTimeString( Widget widget ) 1512 { 1513 /* Variables. */ 1514 Widget textw; 1515 1516 /* Code. */ 1517 textw = XmUbTimeSliderGetChild( widget, XmUbTS_CHILD_TEXT_FIELD ); 1518 if( textw == NULL ) 1519 return( NULL ); 1520 1521 1522 return( XmTextGetString( textw ) ); 1523 1524 } /* XmUbTimeSliderGetTimeString */ 1525 1526 1527 /*----------------------------------------------------------------------*/ 1528 1529 void XmUbTimeSliderSetTime(Widget widget,time_t time)1530 XmUbTimeSliderSetTime( Widget widget, 1531 time_t time ) 1532 { 1533 /* Variables. */ 1534 int hour; 1535 int minute; 1536 XmUbTimeSliderWidget tsl; 1537 1538 /* Code. */ 1539 1540 tsl = (XmUbTimeSliderWidget) widget; 1541 1542 hour = TimHour( time ); 1543 minute = TimMinute( time ); 1544 1545 UpdateScales( tsl, hour, minute ); 1546 1547 /* If the widget is not mapped, the value changed callback will 1548 not be called. */ 1549 UpdateTextField( tsl ); 1550 1551 return; 1552 1553 } /* XmUbTimeSliderSetTime */ 1554