/* Motif WidgetSet category for implementation of Scoller class
 *
 * Copyright (C)  1993  The Board of Trustees of  
 * The Leland Stanford Junior University.  All Rights Reserved.
 *
 * Authors: Paul Kunz, Imran Qureshi, and Libing Wang
 *
 * This file is part of an Objective-C class library for X/Motif
 *
 * xmScroller.m,v 1.5 1995/04/17 22:45:13 fedor Exp
 */


#include "Scroller.h"
#include "xtResponder.h"

/* Required for implementation: */
#include "Motif.h"
#include <Xm/ScrollBar.h>
#include "stdmacros.h"

/* For range and knob size, the following is scale factor used
 * by this implementation
 */
 
#define OS_SCALE_FACTOR 100

static void
theCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
    Scroller *scrol = (Scroller *) client_data;
    XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *) call_data;
    
    switch (cb->reason) {
    case XmCR_DRAG :
	[scrol trackKnob:NULL];
	break;
    case XmCR_INCREMENT :
        [scrol _setHitPart: NX_INCLINE];
	[scrol trackScrollButtons:NULL];
	break;
    case XmCR_DECREMENT :
        [scrol _setHitPart: NX_DECLINE];
	[scrol trackScrollButtons:NULL];
	break;
    case XmCR_PAGE_INCREMENT :
        [scrol _setHitPart: NX_INCPAGE];
	[scrol trackScrollButtons:NULL];
	break;
    case XmCR_PAGE_DECREMENT :
        [scrol _setHitPart: NX_DECPAGE];
	[scrol trackScrollButtons:NULL];
	break;
    default:
    	[scrol _setHitPart:NX_NOPART];
	break;
    }
}

char *ScrollerInstanceName(void)
{
    return "Scroller";
}

@interface View(WidgetSet)
- _init;
@end

@implementation Scroller(WidgetSet)

- _init
{
    [super _init];
    instancename = ScrollerInstanceName();
    classname = xmScrollBarWidgetClass;
    return self;
}

- (float)_floatValue
{
    float	f;
    int		value;
    
    [self _getArg:XmNvalue into:(XtArgVal *)&value];
    f = OS_SCALE_FACTOR - perCent;
    f = value / f;
    curValue = f * OS_SCALE_FACTOR;
    return f;
}

- _setFloatValue:(float)aFloat
{
    int		value;
    
    curValue = aFloat * OS_SCALE_FACTOR;
    value =  aFloat * (OS_SCALE_FACTOR - perCent);  /* edge of bar */
    [self _setArg:XmNvalue to:value];
    return self;
}


- _setFloatValue:(float)aFloat :(float)percent
{
    int		oldCent = perCent;
    
    perCent = percent * OS_SCALE_FACTOR;
    perCent = MAX(perCent, 1);
    if ( perCent < oldCent ) {
	[self _setArg:XmNsliderSize to:perCent];
	[self _setFloatValue:aFloat];
    } else {
	[self _setFloatValue:aFloat];
	[self _setArg:XmNsliderSize to:perCent];
    }
    return self;
}

- _addCallback
{
    XtAddCallback(widgetid, XmNdragCallback,          theCallback, self);
    XtAddCallback(widgetid, XmNincrementCallback,     theCallback, self);
    XtAddCallback(widgetid, XmNdecrementCallback,     theCallback, self);
    XtAddCallback(widgetid, XmNpageIncrementCallback, theCallback, self);
    XtAddCallback(widgetid, XmNpageDecrementCallback, theCallback, self);
    return self;
}

- _managedBy:parent wid:(void *)widget
{
    int	value;

    if ( isHoriz ) {
	value = XmHORIZONTAL;
    } else {
	value = XmVERTICAL;
    }
    [self _addArg:XmNorientation :value];
    value = OS_SCALE_FACTOR;
    [self _addArg:XmNmaximum :value];
    [super _managedBy:parent wid:widget];
    return self;
}

@end
