//	Zinc Application Framework - M_SCRLL.CPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#include "m_scrll.hpp"

// The default size of a scrollbar is hard-coded in Motif 1.2 to be 11.  For
// more information on the default size see the static Initialize() function
// in ScrollBar.c.
const int ARROW_SIZE = 11;

// ----- MtfSlider widget definition ----------------------------------------

XmOffsetPtr MtfSlider::offsets;

XtActionsRec MtfSlider::action[] =
{
	{ "ZafCallDefault",	(XtActionProc)call_default },
	{ "ZafDragDrop",	(XtActionProc)drag_drop },
	{ "ZafEnter",		(XtActionProc)enter },
	{ "ZafFocusIn",		(XtActionProc)focus_in },
	{ "ZafHelp", 		(XtActionProc)help },
	{ "ZafLeave",		(XtActionProc)leave }
};

char MtfSlider::translations[] =
	"<Key>osfActivate:		ZafCallDefault()\n\
	 <Key>osfSelect:		ZafCallDefault()\n\
	 ~s ~m ~a <Key>Return:	ZafCallDefault()\n\
	 <Btn2Down>:			ZafDragDrop()\n\
	 <Enter>:				ZafEnter()\n\
	 <FocusIn>:				ZafFocusIn()\n\
	 <Key>F1:				ZafHelp()\n\
	 <Key>osfHelp:			ZafHelp()\n\
	 <Leave>:				ZafLeave()";

MtfSliderClassRec MtfSlider::classRecord =
{
	// --- CoreClassPart ---
	{
		(WidgetClass)&xmScaleClassRec,	// superclass
		"ZafSlider", 					// class_name
		sizeof(MtfSliderPart), 				// widget_size (data part)
		MtfSlider::classInitialize,		// class_initialize
		0,								// class_part_initialize
		false,							// class inited
		0,								// initialize
		0,								// initialize_hook
		XtInheritRealize,				// realize
		action,							// actions
		XtNumber(action),				// num_actions
		0, 								// resources
		0, 								// num_resources
		NULLQUARK,						// xrm_class
		true,							// compress_motion
		XtExposeCompressMultiple,		// compress_exposure
		true,							// compress_enterleave
		false,							// visible_interest
		0, 								// destroy
		XtInheritResize,				// resize
		(XtExposeProc)expose,			// expose
		0,								// set_values
		0, 								// set_values_hook
		XtInheritSetValuesAlmost,		// set_values_almost
		0, 								// get_values_hook
		XtInheritAcceptFocus,			// accept_focus
		XtVersionDontCheck,					// version
		0, 								// callback_private
		XtInheritTranslations,			// tm_table
		XtInheritQueryGeometry, 		// query_geometry
		XtInheritDisplayAccelerator,	// display_accelerator
		0 								// extension
	},
	// --- CompositeClassPart ---
	{
		XtInheritGeometryManager,		// geometry_manager
		XtInheritChangeManaged,			// change_managed
		XtInheritInsertChild,			// insert_child
		XtInheritDeleteChild,			// delete_child
		0								// extension
	},
	// --- ConstraintClassPart ---
	{
		0,								// resources
		0,								// num_resources
		0,								// constraint_size
		0,								// initialize
		0,								// destroy
		0,								// set_values
		0								// extension
	},
	// --- XmManagerClassPart ---
	{
		XtInheritTranslations,			// translations
		0,								// syn_resources
		0,								// num_syn_resources
		0,								// syn_constraint_resources
		0,								// num_syn_constraint_resources
		XmInheritParentProcess,			// parent_process
		0								// extension
#ifdef __sgi // Member needed for SGI if running in SGI mode
   	,0
#endif 
	},
	// --- XmScaleClassPart ---
	{
		0								// extension
#ifdef __sgi // Member needed for SGI if running in SGI mode
   	,0
#endif 
	},
	// --- MtfSliderClassPart ---
	{
		0									// extension
	}
};

void MtfSlider::classInitialize()
{
	XmResolvePartOffsets((WidgetClass) &(MtfSlider::classRecord),
	 &(MtfSlider::offsets));
}

void MtfSlider::drag_drop(MtfSlider *mtfObject, XEvent *xEvent, String *, Cardinal *)
{
	// Begin the drag/drop operation.
	ZafEventStruct event(S_BEGIN_DRAG, xEvent);
	GetZincObject(mtfObject)->Event(event);
}

void MtfSlider::enter(MtfSlider *mtfObject, XEvent *xEvent, String *param, Cardinal *nparams)
{
	// Perform the motif enter and match with zinc.
	XtCallActionProc((Widget)mtfObject, "ManagerEnter", xEvent, param, *nparams);
	ZafEventStruct event(N_MOUSE_ENTER, xEvent);
	GetZincObject(mtfObject)->Event(event);
}

void MtfSlider::expose(MtfSlider *mtfObject, XEvent *xEvent, Region xRegion)
{
#ifdef __sgi // Needed for SGI if running in SGI mode
	if (!xRegion)
		return;
#endif
	// Draw the object.
	ZafEventStruct event(E_MOTIF, xEvent);
	XRectangle xRect;
	XClipBox(xRegion, &xRect);
  	event.region.Assign(xRect.x, xRect.y, xRect.width, xRect.height, ZAF_PIXEL);
	GetZincObject(mtfObject)->Draw(event, E_MOTIF);
}

void MtfSlider::focus_in(MtfSlider *mtfObject, XEvent *xEvent, String *param, Cardinal *nparams)
{
	// Chain to the base class.
	XtCallActionProc((Widget)mtfObject, "ManagerFocusIn", xEvent, param, *nparams);
	if (!mtfObject->manager.has_focus)
		return; // Object is not really getting the focus.

	// Reflect changes to Zinc.
	ZafScrollBar *zafObject = GetZincObject(mtfObject);
	zafObject->NotifyFocus(zafObject, true);
}

void MtfSlider::leave(MtfSlider *mtfObject, XEvent *xEvent, String *param, Cardinal *nparams)
{
	// Perform the motif enter and match with zinc.
	XtCallActionProc((Widget)mtfObject, "ManagerLeave", xEvent, param, *nparams);
	ZafEventStruct event(N_MOUSE_LEAVE, xEvent);
	GetZincObject(mtfObject)->Event(event);
}

// ----- MtfScrollBar widget definition ----------------------------------------

XmOffsetPtr MtfScrollBar::offsets;

XtActionsRec MtfScrollBar::action[] =
{
	{ "ZafCallDefault",	(XtActionProc)call_default },
	{ "ZafDragDrop",	(XtActionProc)drag_drop },
	{ "ZafEnter",		(XtActionProc)enter },
	{ "ZafFocusIn",		(XtActionProc)focus_in },
	{ "ZafHelp", 		(XtActionProc)help },
	{ "ZafLeave",		(XtActionProc)leave }
};

char MtfScrollBar::translations[] =
	"<Key>osfActivate:		ZafCallDefault()\n\
	 <Key>osfSelect:		ZafCallDefault()\n\
	 ~s ~m ~a <Key>Return:	ZafCallDefault()\n\
	 <Btn2Down>:			ZafDragDrop()\n\
	 <Enter>:				ZafEnter()\n\
	 <FocusIn>:				ZafFocusIn()\n\
	 <Key>F1:				ZafHelp()\n\
	 <Key>osfHelp:			ZafHelp()\n\
	 <Leave>:				ZafLeave()";

MtfScrollBarClassRec MtfScrollBar::classRecord =
{
	// --- CoreClassPart ---
	{
		(WidgetClass)&xmScrollBarClassRec,	// superclass
		"ZafScrollBar", 					// class_name
		sizeof(MtfScrollBarPart), 				// widget_size (data part)
		MtfScrollBar::classInitialize,		// class_initialize
		0,									// class_part_initialize
		false,								// class inited
		0,									// initialize
		0,									// initialize_hook
		XtInheritRealize,					// realize
		action,								// actions
		XtNumber(action),					// num_actions
		0, 									// resources
		0, 									// num_resources
		NULLQUARK,							// xrm_class
		true,								// compress_motion
		XtExposeCompressMultiple,			// compress_exposure
		true,								// compress_enterleave
		false,								// visible_interest
		0, 									// destroy
		XtInheritResize,					// resize
		(XtExposeProc)expose,				// expose
		0,									// set_values
		0, 									// set_values_hook
		XtInheritSetValuesAlmost,			// set_values_almost
		0, 									// get_values_hook
		XtInheritAcceptFocus,				// accept_focus
		XtVersionDontCheck,					// version
		0, 									// callback_private
		XtInheritTranslations,				// tm_table
		XtInheritQueryGeometry, 			// query_geometry
		XtInheritDisplayAccelerator,		// display_accelerator
		0 									// extension
	},
	// --- XmPrimitiveClassPart ---
	{
		XmInheritBorderHighlight,		// border_highlight
		XmInheritBorderUnhighlight,		// border_unhighlight
		XtInheritTranslations,				// translations
		0,									// arm_and_activate
		0,									// syn_resources
		0,									// num_syn_resources
		0									// extension
#ifdef __sgi // Member needed for SGI if running in SGI mode
   	,0
#endif 
	},
	// --- XmScrollBarPart ---
	{	 
		0									// extension
#ifdef __sgi // Member needed for SGI if running in SGI mode
		,0
#endif 
	},
	// --- MtfScrollBarlassPart ---
	{
		0									// extension
	}
};

void MtfScrollBar::classInitialize()
{
	XmResolvePartOffsets((WidgetClass) &(MtfScrollBar::classRecord),
	 &(MtfScrollBar::offsets));
}

void MtfScrollBar::drag_drop(MtfScrollBar *mtfObject, XEvent *xEvent, String *, Cardinal *)
{
	// Begin the drag/drop operation.
	ZafEventStruct event(S_BEGIN_DRAG, xEvent);
	GetZincObject(mtfObject)->Event(event);
}

void MtfScrollBar::enter(MtfScrollBar *mtfObject, XEvent *xEvent, String *param, Cardinal *nparams)
{
	// Perform the motif enter and match with zinc.
	XtCallActionProc((Widget)mtfObject, "PrimitiveEnter", xEvent, param, *nparams);
	ZafEventStruct event(N_MOUSE_ENTER, xEvent);
	GetZincObject(mtfObject)->Event(event);
}

void MtfScrollBar::expose(MtfScrollBar *mtfObject, XEvent *xEvent, Region xRegion)
{
#ifdef __sgi // Needed for SGI if running in SGI mode
	if (!xRegion)
	{
		(*xmScrollBarClassRec.core_class.expose)(GetZincObject(mtfObject)->screenID, xEvent, xRegion);
		return;
	}
#endif
	// Draw the object.
	ZafEventStruct event(E_MOTIF, xEvent);
	XRectangle xRect;
	XClipBox(xRegion, &xRect);
  	event.region.Assign(xRect.x, xRect.y, xRect.width, xRect.height, ZAF_PIXEL);
	GetZincObject(mtfObject)->Draw(event, E_MOTIF);
}

void MtfScrollBar::focus_in(MtfScrollBar *mtfObject, XEvent *xEvent, String *param, Cardinal *nparams)
{
	// Chain to the base class.
	XtCallActionProc((Widget)mtfObject, "PrimitiveFocusIn", xEvent, param, *nparams);
	if (!mtfObject->primitive.have_traversal)
		return; // Object is not really getting the focus.

	// Reflect changes to Zinc.
	ZafScrollBar *zafObject = GetZincObject(mtfObject);
	zafObject->NotifyFocus(zafObject, true);
}

void MtfScrollBar::leave(MtfScrollBar *mtfObject, XEvent *xEvent, String *param, Cardinal *nparams)
{
	// Perform the motif enter and match with zinc.
	XtCallActionProc((Widget)mtfObject, "PrimitiveLeave", xEvent, param, *nparams);
	ZafEventStruct event(N_MOUSE_LEAVE, xEvent);
	GetZincObject(mtfObject)->Event(event);
}

// ----- MtfScrollBar widget definition ----------------------------------------

static void scroll_action(Widget , ZafScrollBar *object, XmScrollBarCallbackStruct *callback)
{
	// Initialize the event based on the type of object. Start with the 
	// scroll delta equal to object's scroll.delta.
	ZafScrollStruct scroll = *object->ScrollData();
	long delta = scroll.delta ? scroll.delta : 1;
	switch (callback->reason)
	{
	case XmCR_INCREMENT:
		break;

	case XmCR_DECREMENT:
		delta *= -1;
		break;

	case XmCR_PAGE_INCREMENT:
		if (scroll.current >= scroll.maximum)
			delta = 0;
		else if (scroll.current + scroll.showing > scroll.maximum)
			delta = scroll.maximum - scroll.current;
		else
			delta = scroll.showing;
		break;

	case XmCR_PAGE_DECREMENT:
		if (scroll.current <= scroll.minimum)
			delta = 0;
		else if (scroll.current - scroll.showing < scroll.minimum)
			delta = scroll.minimum - scroll.current;
		else
			delta = -scroll.showing;
		break;

	case XmCR_TO_BOTTOM:
		delta = scroll.maximum - scroll.current;
		break;

	case XmCR_TO_TOP:
		delta = scroll.minimum - scroll.current;
		break;

	case XmCR_DRAG:
	case XmCR_VALUE_CHANGED:
		// Value changed only occurs on the mouse up-click.  For now
		// both messages are sent so the program can update information
		// on the drag operation as well as the up-click.
		delta = callback->value - scroll.current;
		break;

	default:
		return; // Unknown message.
	}

	// Change the scroll bar offset, then reflect the changes on the parent
	// window.  Motif, by default, does not notify the scroll-bar's parent
	// of changed information. This operation is left to the callback 
	// routine.
	if (!delta)
		return;

	// Change the scroll-bar's information.
	scroll.current += delta;
	if (scroll.current < scroll.minimum)
		scroll.current = scroll.minimum;
	else if (scroll.current > scroll.maximum)
		scroll.current = scroll.maximum;
	object->ScrollData()->SetScroll(scroll);

	// Notify the associated object.
	if (object->SupportObject())
	{
		// If the object is a support object then the parent needs to know
		// the delta.  If we set the delta on scroll.delta we modify the original
		// delta, causing problems for non support scrollbars. To avoid 
		// modifying the original we must create a new ZafScrollStruct and 
		// send it to the parent object.
		ZafScrollStruct scrollInfo;
		scrollInfo.current = scroll.current;
		scrollInfo.delta = delta;
		scrollInfo.maximum = scroll.maximum;
		scrollInfo.minimum = scroll.minimum;
		scrollInfo.showing = scroll.showing;
		ZafEventStruct event(N_VSCROLL, 0, scrollInfo);
		if (object->ScrollType() == ZAF_HORIZONTAL_SCROLL ||
			object->ScrollType() == ZAF_HORIZONTAL_SLIDER)
			event.type = N_HSCROLL;
		object->parent->Event(event);
	}
	else
		object->Event(L_SELECT);
}

// ----- ZafScrollBar -------------------------------------------------------

#if defined(ZAF_DEFAULT_DRAW)
ZafEventType ZafScrollBar::Draw(const ZafEventStruct &event, ZafEventType ccode)
{
	// Check for draw errors.
	if (!screenID)
		return (S_ERROR);

	// Defer drawing to the OS.
	if (XmIsScale(screenID))
		(*xmScaleClassRec.core_class.expose)
			(screenID, event.osEvent.type ? (XEvent *)&event.osEvent : ZAF_NULLP(XEvent), (_XRegion *)event.data);
	else if (XmIsScrollBar(screenID))
		(*xmScrollBarClassRec.core_class.expose)
			(screenID, event.osEvent.type ? (XEvent *)&event.osEvent : ZAF_NULLP(XEvent), (_XRegion *)event.data);

	// Return the control code.
	return (ccode);
}
#endif

ZafEventType ZafScrollBar::Event(const ZafEventStruct &event)
{
	// Check for zinc events.
	ZafEventType ccode = event.type;
	switch (ccode)
	{
	// ----- Create messages -----
	case S_COMPUTE_SIZE:
		// Determine the scroll-bar size.
		if (RegionType() != ZAF_INSIDE_REGION)
   			zafRegion = parent->MaxRegion(this, ZAF_VT_BOTTOM);

		// Adjust the vertical size.
		if (scrollType == ZAF_VERTICAL_SCROLL && SupportObject())
		{
			if (DynamicPtrCast(parent, ZafWindow)->Temporary())
				zafRegion.Assign(-1, -1, -1, -1, ZAF_PIXEL);
	 		zafRegion.left = zafRegion.right - ARROW_SIZE - 2 * ZAF_SHADOW_SIZE + 1;
		}
		else if (scrollType == ZAF_CORNER_SCROLL)
			zafRegion.left = zafRegion.right - ARROW_SIZE - 2 * ZAF_SHADOW_SIZE + 1;
		else if ((scrollType == ZAF_VERTICAL_SCROLL || scrollType == ZAF_VERTICAL_SLIDER) && (AutoSize() || zafRegion.Width() <= 0))
		{
			int width = ARROW_SIZE + 2 * ZAF_SHADOW_SIZE;
			zafRegion.right = zafRegion.left + width - 1;
		}

		// Adjust the horizontal size.
		if (scrollType == ZAF_HORIZONTAL_SCROLL && SupportObject())
			zafRegion.top = zafRegion.bottom - ARROW_SIZE - 2 * ZAF_SHADOW_SIZE + 1;
		else if (scrollType == ZAF_CORNER_SCROLL)
			zafRegion.top = zafRegion.bottom - ARROW_SIZE - 2 * ZAF_SHADOW_SIZE + 1;
		else if ((scrollType == ZAF_HORIZONTAL_SCROLL || scrollType == ZAF_HORIZONTAL_SLIDER) && (AutoSize() || zafRegion.Height() <= 0))
		{
			int height = ARROW_SIZE + 2 * ZAF_SHADOW_SIZE;
			zafRegion.bottom = zafRegion.top + height - 1;
		}
		break;

	case S_REGISTER_OBJECT:
		// Don't register combo-box scroll-bars.
		if (!DynamicPtrCast(parent, ZafWindow)->Temporary())
			RegisterObject();
		break;

	// ----- Actions -----
	case L_SELECT:
		ccode = (this->*memberUserFunction)(event, ccode);
		break;

	// ----- Drag & Drop -----
	case S_DROP_COPY:
		// Check for scroll data.
		{
		ZafWindowObject *object = event.windowObject;
		if (AcceptDrop() && object->IsA(ID_ZAF_SCROLL_BAR))
		{
			ZafScrollBar *dragObject = DynamicPtrCast(object, ZafScrollBar);
			*scrollData = *dragObject->scrollData;
		}
		else
			ccode = S_ERROR;
		}
		break;

	// ----- Base class messages -----
	default:
		ccode = ZafWindowObject::Event(event);
		break;
	}

	// Return the control code.
	return (ccode);
}

ZafEventType ZafScrollBar::ScrollEvent(const ZafEventStruct &event)
{
	// Process the scrolling request.  Scrolling at the window level is 
	// based on pixel boundaries.
	ZafEventType ccode = event.type;
	switch (ccode)
	{
	case S_VSCROLL:
	case S_HSCROLL:
		// Scroll the window contents <delta> pixels in the direction 
		// indicated by the type of scrolling operation.
		{
		ZafScrollStruct value = *scrollData;
		value.current += event.scroll.delta;
		if (value.current < value.minimum)
			value.current = value.minimum;
		else if (value.current > value.maximum - value.showing)
			value.current = value.maximum - value.showing;

		// Reset the Scrollbar values if currently visible.
		if (screenID)
			XtVaSetValues(screenID, XmNvalue, value.current, 0);

		scrollData->SetScroll(value);
		}
		break;

	case S_VSCROLL_SET:
	case S_HSCROLL_SET:
		scrollData->SetScroll(event.scroll);
		break;

	default:
		// No other messages apply to the scrollbar object.
		return (S_ERROR);
	}

	// Return the control code.
	return (ccode);
}

bool ZafScrollBar::SetFocus(bool setFocus)
{
	// Defer to the base class.
	return (ZafWindowObject::SetFocus(setFocus));
}

bool ZafScrollBar::SetVisible(bool setVisible)
{
	// Defer to the base class.
	return (ZafWindowObject::SetVisible(setVisible));
}

// ----- OS Specific Functions ----------------------------------------------

ZafEventType ZafScrollBar::OSEvent(const ZafEventStruct &)
{
	return (S_ERROR);
}

ZafError ZafScrollBar::OSGetScroll(void)
{
	return (ZAF_ERROR_NONE);
}

void ZafScrollBar::OSMapPalette(ZafPaletteStruct &palette, ZafPaletteType type, ZafPaletteState state)
{
	// Determine the proper palette.
	if (scrollType == ZAF_VERTICAL_SLIDER || scrollType == ZAF_HORIZONTAL_SLIDER)
		ZafWindow::OSMapPalette(palette, type, state);
	else if (scrollType == ZAF_VERTICAL_SCROLL || scrollType == ZAF_HORIZONTAL_SCROLL)
		ZafWindowObject::OSMapPalette(palette, type, state);
}

ZafError ZafScrollBar::OSSetScroll(void)
{
	// Reset the Scrollbar values if currently visible.
	if (screenID && SystemObject())
	{
		ZafScrollStruct value = *scrollData;
		if (value.showing <= 0)
			value.showing = 1;
		if (scrollType != ZAF_HORIZONTAL_SLIDER && scrollType != ZAF_VERTICAL_SLIDER)
			value.maximum += value.showing;
		if (value.showing > value.maximum - value.minimum)
			value.maximum = value.minimum + value.showing;
		if (value.current < value.minimum)
			value.current = value.minimum;
		else if (value.current > value.maximum)
			value.current = value.maximum;

		XtVaSetValues(screenID,
			XmNminimum, (int)value.minimum,
			XmNmaximum, (int)value.maximum,
			XmNvalue, (int)value.current,
			XmNsliderSize, (int)value.showing,
			XmNpageIncrement, (int)value.showing,
			0);
	}
	else if (screenID)
		RedisplayData();
	return (ZAF_ERROR_NONE);
}

OSWindowID ZafScrollBar::OSScreenID(ZafScreenIDType type) const
{
	// Return the client widget.
	return (ZafWindowObject::OSScreenID(type));
}

void ZafScrollBar::OSRegisterObject(void)
{
	char *name = zafCodeSet->ConvertToOSString(stringID, 0, false);
	if (scrollType == ZAF_VERTICAL_SLIDER || scrollType == ZAF_HORIZONTAL_SLIDER)
	{
#if defined(__sgi) // These are members need to be ininialized for for SGIMode.
		if (!MtfSlider::classRecord.managerClassPart._SG_vendorExtension)
			MtfSlider::classRecord.managerClassPart._SG_vendorExtension =
			 xmScaleClassRec.manager_class._SG_vendorExtension;
		if (!MtfSlider::classRecord.scaleClassPart._SG_vendorExtension)
			MtfSlider::classRecord.scaleClassPart._SG_vendorExtension =
			 xmScaleClassRec.scale_class._SG_vendorExtension;
#endif 

		// Create the slider.
		screenID = parent->OSScreenID(ZAF_CLIENTID);
		screenID = XtVaCreateWidget(name,
			(WidgetClass)&MtfSlider::classRecord, screenID,
			// user information
			XmNuserData, this,
			// miscellaneous
			XmNsensitive, Disabled(false) ? false : true,
			XmNtraversalOn, Noncurrent() ? false : true,
			XmNorientation, (scrollType == ZAF_VERTICAL_SLIDER) ? XmVERTICAL : XmHORIZONTAL,
			0);
		OSSetScroll();

		// additional translations
		XtTranslations translationTable = XtParseTranslationTable(MtfSlider::translations);
		XtOverrideTranslations(screenID, translationTable);

		// Register the callbacks.
		XtAddCallback(screenID, XmNvalueChangedCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNdragCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);

		// Add edit mode overrides.
		ZafEditModeRegister(this);

		// Add drag/drop capabilities.
		ZafDropSiteRegister(this);
	}
	else if (scrollType == ZAF_VERTICAL_SCROLL || scrollType == ZAF_HORIZONTAL_SCROLL)
	{
		// Special scrolled windows don't register scroll-bars.
		if (SupportObject() && XmIsScrolledWindow(parent->OSScreenID(ZAF_FRAMEID)))
			return;

#if defined(__sgi) // These are members need to be ininialized for for SGIMode.
		if (!MtfScrollBar::classRecord.primitiveClassPart._SG_vendorExtension)
			MtfScrollBar::classRecord.primitiveClassPart._SG_vendorExtension =
			 xmScrollBarClassRec.primitive_class._SG_vendorExtension;
		if (!MtfScrollBar::classRecord.scrollBarClassPart._SG_vendorExtension)
			MtfScrollBar::classRecord.scrollBarClassPart._SG_vendorExtension =
			 xmScrollBarClassRec.scrollBar_class._SG_vendorExtension;
#endif 

		// Create the scroll-bar.
		if (SupportObject())
		{
			screenID = parent->OSScreenID(ZAF_FRAMEID);
			screenID = XtVaCreateManagedWidget(name,
				(WidgetClass)&MtfScrollBar::classRecord, screenID,
				// user information
				XmNuserData, this,
				// miscellaneous
				XmNorientation, (scrollType == ZAF_VERTICAL_SCROLL) ? XmVERTICAL : XmHORIZONTAL,
				XmNsensitive, Disabled(false) ? false : true,
				XmNtraversalOn, Noncurrent() ? false : true,
				0);

			// Add edit mode overrides.
			editMode = parent->EditMode();
		}
		else
		{
			screenID = parent->OSScreenID(ZAF_CLIENTID);
			screenID = XtVaCreateWidget(name,
				(WidgetClass)&MtfScrollBar::classRecord, screenID,
				// user information
				XmNuserData, this,
				// miscellaneous
				XmNorientation, scrollType == ZAF_VERTICAL_SCROLL ? XmVERTICAL : XmHORIZONTAL,
				XmNsensitive, Disabled(false) ? false : true,
				XmNtraversalOn, Noncurrent() ? false : true,
				0);

			// Add edit mode overrides.
			ZafEditModeRegister(this);
		}
		OSSetScroll();

		// Add drag/drop capabilities.
		ZafDropSiteRegister(this);

		// Register the callbacks.
		XtAddCallback(screenID, XmNvalueChangedCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNdragCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNincrementCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNdecrementCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNpageIncrementCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNpageDecrementCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNtoTopCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
		XtAddCallback(screenID, XmNtoBottomCallback,
			(XtCallbackProc)scroll_action, (XtPointer)this);
	}
}

void ZafScrollBar::OSSize(void)
{
	// Default to the base class.
		ZafWindowObject::OSSize();
}

