home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
composit.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-04
|
30KB
|
1,025 lines
/*
*
* Copyright (C) 1994, M. A. Sridhar
*
*
* This software is Copyright M. A. Sridhar, 1994. You are free
* to copy, modify or distribute this software as you see fit,
* and to use it for any purpose, provided this copyright
* notice and the following disclaimer are included with all
* copies.
*
* DISCLAIMER
*
* The author makes no warranties, either expressed or implied,
* with respect to this software, its quality, performance,
* merchantability, or fitness for any particular purpose. This
* software is distributed AS IS. The user of this software
* assumes all risks as to its quality and performance. In no
* event shall the author be liable for any direct, indirect or
* consequential damages, even if the author has been advised
* as to the possibility of such damages.
*
*/
#if defined(__GNUC__)
#pragma implementation
#endif
#if defined(__MS_WINDOWS__)
# include <windows.h>
# include <ctl3d.h>
# include <string.h>
BOOL CALLBACK _export EnumCallback (HWND hwnd, LPARAM param);
# define WINDOW_STYLE WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | \
WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
#elif defined(__OS2__)
# define DEFAULT_COMPOSITE_STYLE \
FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MINMAX | FCF_TASKLIST
#elif defined(__X_MOTIF__)
# include <Xm/BulletinB.h>
# include <X11/Shell.h>
# include <Xm/Xm.h>
# include <Xm/Protocols.h>
# include <Xm/AtomMgr.h>
# include <Xm/MwmUtil.h>
# include <iostream.h> // DEBUG only
#endif
#include "ui/composit.h"
#include "ui/cntroler.h"
#include "ui/pushbtn.h"
#include "ui/toglbtn.h"
#include "ui/xrtglbtn.h"
#include "ui/stred.h"
#include "ui/dialog.h"
#include "ui/label.h"
#include "ui/strview.h"
#include "ui/textedit.h"
#include "ui/scrolbar.h"
#include "ui/menu.h"
#include "ui/orbtngrp.h"
#include "ui/xrbtngrp.h"
// ---------------------- UI_CompositeVObject code --------------------
UI_CompositeVObject :: UI_CompositeVObject
( UI_CompositeVObject* parent, const UI_Rectangle& shape, UI_ViewID id)
: UI_VObjCollection (parent, shape, id)
{
_stickToParent = FALSE; // Non-sticky by default
_Init ();
}
UI_CompositeVObject :: UI_CompositeVObject
( UI_CompositeVObject* parent, UI_ViewDescriptor* vd, bool sticky,
const UI_Rectangle& shape, UI_ViewID id
)
: UI_VObjCollection (parent, shape, id)
{
_stickToParent = sticky;
_Init ();
if (vd) {
for (short i = 0; vd[i].type != View_None; i++) {
if ( !CreateChild (vd[i]) )
break;
}
}
}
typedef CL_Binding<UI_CompositeVObject> CompositeBind;
#if defined(__GNUC__)
template class CL_Binding<UI_CompositeVObject>;
#endif
void UI_CompositeVObject::_Init ()
{
_menuBar = NULL;
_currentChild = -1;
_isTabStop = _stickToParent;
_iconified = FALSE;
if (!_parent) {
// Make a font for the main window
_font = new UI_Font (this);
_ownFont = TRUE;
}
CompositeBind bind (this, &UI_CompositeVObject::_EventOccurred);
#if defined(__MS_WINDOWS__)
_3dLook = _stickToParent ? _parent->Has3DLook() : FALSE;
if (_parent == NULL) {
// Set the style of the root window
_style = WINDOW_STYLE;
}
else {
// Non-root window
if (_stickToParent) {
_style = WS_CHILD;
if (_visible)
_style |= WS_VISIBLE;
if (_borderShown)
_style |= WS_BORDER;
}
else
_style = WINDOW_STYLE;
}
if (!_parent || !_stickToParent)
_id = 0;
_titleBarShown = _style & WS_CAPTION;
#elif defined(__OS2__)
_style = _stickToParent ? WS_VISIBLE | WS_CLIPCHILDREN
: DEFAULT_COMPOSITE_STYLE;
_cursor = UICursor_Arrow;
#endif
#if defined (__MS_WINDOWS__) || defined(__OS2__)
// Need focus management under Windows and OS/2
AddEventDependent (Event_ChildCreated, bind, 1);
AddEventDependent (Event_LButtonRelease, bind, 1);
AddEventDependent (Event_KeyTyped, bind, 1);
#endif
AddEventDependent (Event_Iconify, bind, 1);
AddEventDependent (Event_Deiconify, bind, 1);
_model = new CL_IntPtrMap;
}
#if defined(__MS_WINDOWS__)
static UI_VObjCollection* _CurrentGroup = NULL;
static UI_ViewID _CurrentGroupId = 0;
static UI_ViewHandle _CurrentGroupHandle = 0;
UI_CompositeVObject::UI_CompositeVObject
(UI_CompositeVObject* parent, const char *rsrc, UI_ViewID id)
: UI_VObjCollection (parent, UI_Rectangle(), id)
{
_menuBar = NULL;
_stickToParent = FALSE;
_currentChild = -1;
_rname = rsrc;
_CurrentGroup = NULL; // Used only in CreateResourceChild
_CurrentGroupId = 0; // Ditto
_model = new CL_IntPtrMap;
_3dLook = FALSE;
CompositeBind bind (this, &UI_CompositeVObject::_EventOccurred);
AddEventDependent (Event_ChildCreated, bind, 1);
AddEventDependent (Event_LButtonRelease, bind, 1);
AddEventDependent (Event_KeyTyped, bind, 1);
AddEventDependent (Event_Iconify, bind, 1);
AddEventDependent (Event_Deiconify, bind, 1);
}
#endif
#if defined(__MS_WINDOWS__)
void UI_CompositeVObject::Set3DLook ()
{
_3dLook = TRUE;
}
bool UI_CompositeVObject::Has3DLook () const
{
return _3dLook ? TRUE : (_parent ? _parent->Has3DLook() : FALSE);
}
#endif
CL_Object& UI_CompositeVObject::Model ()
{
// Update all the models. This is needed so that the component objects
// can update their model values from the underlying window system.
CL_IntPtrMap& model_map = *(CL_IntPtrMap*) _model;
CL_IntPtrMapIterator itr (_objMap);
while (itr.More()) {
CL_IntPtrAssoc assoc = itr.Next();
UI_VisualObject* v = (UI_VisualObject*) assoc.value;
UI_ViewID id = v->ViewID();
if (model_map.IncludesKey (id))
model_map[id] = & (v->Model());
}
return *_model;
}
bool UI_CompositeVObject::MakeVisualElement ()
{
#ifdef __MS_WINDOWS__
HANDLE hInst = _Application->ProcessId();
const char* label = (_title.Length() > 0) ? _title.AsPtr() : NULL;
if(_rname.Size ()) {
// Resource-based dialog
_handle = CreateDialogParam
(hInst, _rname.AsPtr(), _parent ? _parent->ViewHandle() : NULL,
(FARPROC) YACLDialogProc, 0L);
SendMessage (_handle, WM_SETTEXT, 0, (long) label);
_style = GetWindowLong (_handle, GWL_STYLE);
_visible = (_style & WS_VISIBLE) ? TRUE : FALSE;
return TRUE;
}
// Generic window
RECT shapeRect = _shape.AsMSRect ();
if (!_parent || !_stickToParent)
AdjustWindowRect (&shapeRect, _style, FALSE);
short x = shapeRect.left;
short y = shapeRect.top;
short w = shapeRect.right - shapeRect.left;
short h = shapeRect.bottom - shapeRect.top;
const char* class_name = WindowClass ();
if (!_visible)
_style &= ~WS_VISIBLE;
HWND parentHandle = _parent ? _parent->ViewHandle() : 0;
_handle = CreateWindow (class_name, label, _style, x, y, w, h,
parentHandle, _id, (HANDLE) hInst, NULL);
if (!_handle) {
CL_Error::Warning
("YACL: VisualObject CreateWindow failed:\nClass %s ID %d",
class_name, _id);
return FALSE;
}
return TRUE;
#elif defined(__X_MOTIF__)
CL_String xname (InstanceName ());
Arg args [9];
short argn = 0;
XtSetArg (args[argn], XmNresizePolicy, XmRESIZE_NONE); argn++;
_SetupStyle (args, argn);
struct _WidgetClassRec *wname = WindowClass ();
if ( wname == NULL )
wname = xmBulletinBoardWidgetClass;
if (!_parent && !_shell)
CL_Error::Fatal ("Root Window Not Created");
Widget real_parent = _parent && _stickToParent
? _parent->ViewHandle() : _shell;
if (!_parent || _stickToParent)
_popup = NULL;
if (!_parent) { // Creating the root window
_xwidget = XtCreateManagedWidget
((const char*) xname, wname, real_parent, args, argn);
if (! XtIsRealized (_shell) )
XtRealizeWidget (_shell);
}
else if (_stickToParent) { // Creating a non-root sticky child
_xwidget = XtCreateWidget
((const char*) xname, wname, real_parent, args, argn);
}
else {
XtSetArg (args [argn], XmNtitle, (char*) _title.AsPtr()); argn++;
// Set the title of the shell widget
XtSetArg (args [argn], XmNdeleteResponse, XmDO_NOTHING); argn++;
// Do not destroy the shell widget in response to user
// requests; the library will take care of it.
_popup = XtCreatePopupShell ((const char*) (xname + "_shell"),
vendorShellWidgetClass,
_parent->ViewHandle(),
args, argn);
_xwidget = XtCreateManagedWidget
((const char*) xname, wname, _popup, args, 2);
XtPopup (_popup, XtGrabNone);
};
if (!_stickToParent) {
UI_VisualObject::ViewSize minSize = MinSize();
UI_VisualObject::ViewSize maxSize = MaxSize();
XtVaSetValues (XtParent (_xwidget),
XmNminWidth, minSize._width,
XmNmaxWidth, maxSize._width,
XmNminHeight, minSize._height,
XmNmaxHeight, maxSize._height,
NULL
);
}
return TRUE;
#elif defined(__OS2__)
if (_parent && _stickToParent)
return UI_VObjCollection::MakeVisualElement ();
// So now let's worry about stand-alone windows
HWND parentHandle = HWND_DESKTOP;
_frameHandle = WinCreateStdWindow
(HWND_DESKTOP, 0, &_style,
WindowClass(), _title.AsPtr(), 0, 0, _id, &_handle);
// Compute the required frame rectangle; remember that _shape is
// specified assuming that YACL uses origin at top left corner, but
// OS/2 uses origin at bottom left corner.
long parentHeight = _YACLWindowHeight (parentHandle);
RECTL boundary;
long left = _shape.Left(), top = _shape.Top ();
long height = _shape.Height(), width = _shape.Width ();
boundary.xLeft = left;
boundary.yBottom = parentHeight - top - height;
boundary.xRight = left + width - 1;
boundary.yTop = parentHeight - top;
WinMapWindowPoints (_handle, parentHandle, (PPOINTL) &boundary, 2);
WinCalcFrameRect (_frameHandle, &boundary, FALSE);
// Now set up and show the window
WinSetWindowPos (_frameHandle, HWND_TOP,
boundary.xLeft, boundary.yBottom,
boundary.xRight - boundary.xLeft + 1,
boundary.yTop - boundary.yBottom + 1,
SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW
);
return TRUE;
#endif
}
UI_Rectangle UI_CompositeVObject::Area () const
{
#if defined(__OS2__)
if (_stickToParent)
return UI_VisualObject::Area ();
RECTL rect;
WinQueryWindowRect (_frameHandle, &rect);
return _Application->YACLRect (_parent ? _parent->ViewHandle()
: HWND_DESKTOP,
rect);
#else
return UI_VisualObject::Area ();
#endif
}
bool UI_CompositeVObject::DestroyVisualElement ()
{
DestroyDisplaySurface ();
#if defined (__MS_WINDOWS__)
if (_handle > 0) {
DestroyWindow (_handle);
return TRUE;
}
return FALSE;
#elif defined(__X_MOTIF__)
if( _xwidget !=NULL )
XtDestroyWidget (_xwidget);
if (_popup)
XtPopdown (_popup);
#elif defined(__OS2__)
WinDestroyWindow (_frameHandle);
return TRUE;
#endif
}
UI_VisualObject* UI_CompositeVObject::CreateChild (const UI_ViewDescriptor& vd)
{
if (_objMap.IncludesKey (vd.id)) {
CL_Error::Warning ("YACL: Duplicate child id %ld for composite",
vd.id);
return NULL;
}
UI_VisualObject* p;
UI_Rectangle shape (vd.shape.x, vd.shape.y, vd.shape.w,
vd.shape.h);
switch (vd.type) {
case View_OrButtonGroup:
p = new UI_OrButtonGroup (this, shape, vd.id, vd.enclosed);
p->Title () = vd.title;
break;
case View_ExOrButtonGroup:
p = new UI_ExOrButtonGroup (this, shape, vd.id, vd.enclosed);
p->Title () = vd.title;
break;
case View_PushButton:
p = new UI_PushButton (this, shape, vd.id);
p->Title()= vd.title;
break;
case View_ToggleButton:
p = new UI_ToggleButton (this, shape, vd.id);
p->Title() = vd.title;
break;
case View_ExOrToggleButton:
p = new UI_ExOrToggleButton (this, shape, vd.id);
p->Title() = vd.title;
break;
case View_Label:
p = new UI_Label (this, shape, vd.id);
(CL_String&) (((UI_Label*) p)->Model ()) = vd.title;
break;
case View_StringEditor:
p = new UI_StringEditor (this, shape, vd.id);
(CL_String&) (((UI_SimpleVObject*) p)->Model ()) = vd.title;
break;
case View_TextView:
p = new UI_TextEditor (this, shape, vd.id);
(CL_String&) (((UI_SimpleVObject*) p)->Model ()) = vd.title;
break;
case View_StringView:
p = new UI_StringViewSingleSel (this, shape, vd.id);
break;
case View_HScrollBar:
p = new UI_HScrollBar (this, shape, vd.id);
break;
case View_VScrollBar:
p = new UI_VScrollBar (this, shape, vd.id);
break;
case View_MultiSelectStringView:
p = new UI_StringViewMultiSel (this, shape, vd.id);
break;
case View_Composite:
p = new UI_CompositeVObject (this, vd.enclosed, TRUE, shape,
vd.id);
break;
default:
p = NULL;
break;
} // end of switch
if ( p && vd.type != View_Composite ) {
UI_ViewID id = p->ViewID();
if (id > 0 && id <= 32767) {
((CL_IntPtrMap*) _model)->Add (id, &(p->Model()));
if (vd.type != View_OrButtonGroup &&
vd.type != View_ExOrButtonGroup)
((UI_SimpleVObject*) p)->TabStop (vd.tab_stop);
}
}
return p;
}
UI_CompositeVObject::~UI_CompositeVObject()
{
if (_model)
delete _model;
}
void UI_CompositeVObject::ShowTitleBar ()
{
#if defined(__MS_WINDOWS__)
if (!_stickToParent) {
long l = GetWindowLong (_handle, GWL_STYLE);
SetWindowLong (_handle, GWL_STYLE, l | WS_CAPTION);
SetWindowPos (_handle, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED |
SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER); // Force re-draw
_titleBarShown = TRUE;
}
#elif defined(__X_MOTIF__)
if (!_stickToParent) {
Arg arg[1];
XtSetArg (arg[0], XtNtransient, FALSE);
XtSetValues (XtParent (_xwidget), arg, 1);
}
#endif
}
void UI_CompositeVObject::HideTitleBar ()
{
#if defined(__MS_WINDOWS__)
if (!_stickToParent) {
long l = GetWindowLong (_handle, GWL_STYLE);
SetWindowLong (_handle, GWL_STYLE, l & ~WS_CAPTION);
SetWindowPos (_handle, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED |
SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER); // Force re-draw
_titleBarShown = FALSE;
}
#elif defined(__X_MOTIF__)
if (!_stickToParent) {
Arg arg[1];
XtSetArg (arg[0], XtNtransient, FALSE);
XtSetValues (XtParent (_xwidget), arg, 1);
}
#endif
}
bool UI_CompositeVObject::IsTitleBarShown ()
{
return !_stickToParent && _titleBarShown;
}
void UI_CompositeVObject::_PrivateInitialize()
{
UI_VisualObject::_PrivateInitialize ();
#if defined(__MS_WINDOWS__)
if ( _menuBar && _menuBar->ViewHandle() > 0 )
DrawMenuBar ( _menuBar->ViewHandle() );
if(_rname.Size() > 0 && _handle)
EnumChildWindows (_handle, (FARPROC) EnumCallback, (long) this);
#elif defined(__X_MOTIF__)
Arg args [2];
XmString xmtitle;
xmtitle = XmStringCreate ((char*)_title.AsPtr(), XmSTRING_DEFAULT_CHARSET);
XtSetArg (args [0], XmNdialogTitle, xmtitle);
XtSetArg (args [1], XmNlabelString, xmtitle);
XtSetValues (_xwidget, args, 2);
if (!_parent || !_stickToParent) {
Atom a = XmInternAtom (XtDisplay(_shell), "WM_DELETE_WINDOW",
FALSE);
XmAddWMProtocolCallback
(XtParent (_xwidget), a,
(XtCallbackProc) &UI_CompositeVObject::DeleteWindowCallback,
(XtPointer) this);
}
XmStringFree (xmtitle); // No leaks allowed
// Invalidate ();
#endif
if (!_visible)
MakeInvisible();
}
#if defined (__X_MOTIF__)
void UI_CompositeVObject::DeleteWindowCallback
(Widget w, void* client, void* call)
{
UI_CompositeVObject* v = (UI_CompositeVObject*) client;
v->_Controller->AddEvent (new UI_Event (Event_CloseDown, v, v));
}
#endif
//
//------------------Composite Methods------------------------------
//
bool UI_CompositeVObject::HandleChildEvent (const UI_Event&)
{
return FALSE;
}
bool UI_CompositeVObject::_EventOccurred (CL_Object& o, long)
{
UI_Event& e = (UI_Event&) o;
UI_EventType type = e.Type();
UI_VisualObject* v = e.Origin();
switch (type) {
#if defined(__MS_WINDOWS__) || defined(__OS2__)
// Focus management is only needed under Windows and OS/2
case Event_ChildCreated: {
if (v->Parent() != this)
break;
short pos = -1;
if (v->IsTabStop()) {
pos = _tabSequence.Add (v);
if (_currentChild == -1 && v->IsVisible() && v->IsEnabled()) {
_currentChild = pos;
v->TakeFocus();
}
}
break;
}
case Event_LButtonRelease:
MoveFocusTo (e.Origin());
break;
case Event_KeyTyped:
if (e.Type () == Event_KeyTyped && e.key == '\011') {
if (e.Destination() == this)
return !AdvanceFocus (e._shiftKey ? -1 : 1);
else
return FALSE;
}
else
return TRUE;
#endif // Windows or OS2
case Event_Iconify:
_iconified = TRUE;
break;
case Event_Deiconify:
_iconified = FALSE;
break;
};
return TRUE;
}
UI_WindowClass UI_CompositeVObject::WindowClass () const
{
#if defined(__MS_WINDOWS__)
return _YACLWindowClassName;
#elif defined(__OS2__)
return _YACLWindowClassName;
#elif defined(__X_MOTIF__)
return xmBulletinBoardWidgetClass;
#endif
}
#if defined(__MS_WINDOWS__)
BOOL CALLBACK _export EnumCallback (HWND hwnd, LPARAM param)
{
if (!hwnd)
return FALSE;
char buffer[30];
if ((GetClassName (hwnd, buffer, 30)) == 0)
return FALSE;
((UI_CompositeVObject*) param)->CreateResourceChild (hwnd, buffer);
return TRUE;
}
bool UI_CompositeVObject::CreateResourceChild
(UI_ViewHandle hndl, const CL_String& ctrl_name)
{
long n;
n = GetWindowTextLength (hndl);
char* buf = "";
CL_String mdl;
if (n) {
buf = new char[n+1];
GetWindowText (hndl,buf,n+1);
mdl = buf;
delete buf;
}
// Begin construction:
UI_ViewID id = GetWindowWord (hndl, GWW_ID);
CL_String name = ctrl_name.InLowerCase ();
long ctrl_style = GetWindowLong (hndl, GWL_STYLE);
RECT clientRect;
GetClientRect (hndl, &clientRect);
UI_Rectangle shape (clientRect.left, clientRect.top,
clientRect.right - clientRect.left+1,
clientRect.bottom - clientRect.top + 1);
if (name == "button") {
long style_bits = 0xff; // Depends on Windows 3.1!!
long style = ctrl_style & style_bits;
if (style != BS_GROUPBOX &&
style != BS_RADIOBUTTON && style != BS_AUTORADIOBUTTON &&
style != BS_CHECKBOX && style != BS_AUTOCHECKBOX) {
_CurrentGroup = NULL;
_CurrentGroupId = 0;
}
if (style == BS_GROUPBOX) {
_CurrentGroup = NULL;
_CurrentGroupId = id;
_CurrentGroupHandle = hndl;
}
else if (style == BS_AUTOCHECKBOX || style == BS_CHECKBOX) {
if (!_CurrentGroup && _CurrentGroupId) {
_CurrentGroup = new UI_OrButtonGroup
(this, _CurrentGroupId, _CurrentGroupHandle);
initSimple (_CurrentGroup);
}
UI_ToggleButton* v = new UI_ToggleButton
(_CurrentGroup ? _CurrentGroup : this, id, hndl);
initSimple (v);
}
else if (style == BS_AUTORADIOBUTTON || style == BS_RADIOBUTTON) {
if (!_CurrentGroup && _CurrentGroupId) {
_CurrentGroup = new UI_ExOrButtonGroup
(this, _CurrentGroupId, _CurrentGroupHandle);
initSimple (_CurrentGroup);
}
UI_ExOrToggleButton* v = new UI_ExOrToggleButton
(_CurrentGroup ? (UI_CompositeVObject*) _CurrentGroup :
this, id, hndl);
initSimple (v);
}
else {
// Must be a push button
UI_PushButton *v;
v = new UI_PushButton (this, id, hndl);
initSimple (v);
}
}
else if (name == "static") {
UI_Label* v = new UI_Label (this, id, hndl);
initSimple (v);
}
else if (name == "edit") {
UI_StringEditor* v = new UI_StringEditor (this, id, hndl);
initSimple (v);
}
else if (name == "listbox") {
UI_StringView* v;
if (ctrl_style & LBS_MULTIPLESEL)
v = new UI_StringViewMultiSel (this, id, hndl);
else
v = new UI_StringViewSingleSel (this, id, hndl);
initSimple (v);
}
return TRUE;
}
#endif
void UI_CompositeVObject::initSimple (UI_VisualObject* s)
{
if (s) {
((UI_SimpleVObject*) s)->SetStyleParam();
if (s->Parent() == this) {
UI_ViewID id = s->ViewID();
if (id > 0 && id <= 32767) {
_objMap.Add (id, s);
((CL_IntPtrMap*) _model)->Add (id, &(s->Model()));
}
if (s->IsTabStop()) {
long pos = _tabSequence.Add (s);
if (_currentChild == -1)
_currentChild = pos;
}
}
}
}
bool UI_CompositeVObject::UseMenuBar (UI_MenuBar* menu)
{
#if defined(__MS_WINDOWS__)
if (!_menuBar) {
RECT rect = _shape.AsMSRect();
AdjustWindowRect (&rect, _style, TRUE);
}
#endif
_menuBar = menu;
_Controller->DispatchPendingEvents (); // So that the menu is created,
// and its handle is available
#if defined(__MS_WINDOWS__)
UI_ViewHandle hmenu = menu ? menu->ViewHandle() : 0;
SetMenu (_handle, hmenu);
// Now recompute the client rectangle
RECT msrec;
GetClientRect (_handle, &msrec);
POINT ms_pt;
ms_pt.x = ms_pt.y = 0;
ClientToScreen (_handle, &ms_pt);
UI_Rectangle rec (ms_pt.x, ms_pt.y, msrec.right - msrec.left + 1,
msrec.bottom - msrec.top + 1);
_SetShapeRectangle (rec);
#endif
return TRUE;
}
// Return the menu used by this composite. Return NULL if there is no
// associated menu.
UI_MenuBar* UI_CompositeVObject::MenuBar () const
{
return _menuBar;
}
#if defined(__MS_WINDOWS__) || defined(__OS2__)
void UI_CompositeVObject::TakeFocus ()
{
if (_currentChild >= 0) {
UI_VisualObject* v = (UI_VisualObject*) _tabSequence[_currentChild];
if (v)
v->TakeFocus();
}
}
void UI_CompositeVObject::MoveFocusTo (UI_VisualObject* child)
{
if (!(child && child->IsTabStop() && child->IsVisible() &&
child->IsEnabled()))
return;
short pos = _tabSequence.LinearSearch (child);
if (pos) {
_currentChild = pos;
child->TakeFocus();
}
}
bool UI_CompositeVObject::AdvanceFocus (short n)
{
long size = _tabSequence.Size();
if (n != 1 && n != -1 || size <= 1)
return FALSE;
short pos = _currentChild == -1 ? 0 : _currentChild + n;
UI_VisualObject* v = NULL;
if (_stickToParent) {
// Stop if hit end of sequence in either direction
for (short i = pos; i >= 0 && i < size; i += n) {
v = (UI_VisualObject*) _tabSequence[pos];
if (v->IsVisible() && v->IsEnabled() && v->IsTabStop())
break;
}
if (i < 0 || i >= size)
return FALSE;
v->TakeFocus ();
_currentChild = i;
return TRUE;
}
// We don't stick to our parent, so we manage all tabbing within
// ourselves.
if (pos == size)
pos = 0;
else if (pos == -1)
pos = size-1;
while (pos != _currentChild) {
v = (UI_VisualObject*) _tabSequence[pos];
if (v->IsVisible() && v->IsEnabled() && v->IsTabStop())
break;
pos = (pos + n) % size;
if (pos == -1)
pos += size;
}
if (pos != _currentChild) {
v->TakeFocus();
_currentChild = pos;
}
return TRUE;
}
#endif
UI_VisualObject* UI_CompositeVObject::RemoveChild (UI_VisualObject* view)
{
if (view) {
short index = _tabSequence.LinearSearch (view);
if (index >= 0)
_tabSequence.Remove (index);
}
UI_VObjCollection::RemoveChild (view);
return view;
}
void UI_CompositeVObject::AddChild (UI_VisualObject* child)
{
// Called from child->UI_VisualObject::_Init
if (!child)
return;
UI_VObjCollection::AddChild (child);
UI_ViewID id = child->ViewID();
if (id > 0 && id <= 32767) {
CL_IntPtrMap& modelMap = *(CL_IntPtrMap*) _model;
modelMap.Add (id, &(child->Model()));
}
}
bool UI_CompositeVObject::_ShapeRectChanged (CL_Object& o, long v)
{
#if defined(__MS_WINDOWS__)
return UI_VisualObject::_ShapeRectChanged (o, v);
#elif defined(__OS2__)
if (_stickToParent || _handle <= 0)
return UI_VObjCollection::_ShapeRectChanged (o, v);
long ht = _YACLWindowHeight (_parent ? _parent->ViewHandle()
: HWND_DESKTOP);
SWP swp, frameSwp;
WinQueryWindowPos (_handle, &swp);
WinQueryWindowPos (_frameHandle, &frameSwp);
long newX = _shape.Left() - swp.x;
long newY = ht - _shape.Bottom () - swp.y;
long newW = _shape.Width() + frameSwp.cx - swp.cx;
long newH = _shape.Height() + frameSwp.cy - swp.cy;
WinSetWindowPos (_frameHandle, HWND_TOP, newX, newY, newW, newH,
SWP_SIZE | SWP_MOVE);
WinQueryWindowPos (_frameHandle, &frameSwp);
return TRUE;
#elif defined (__X_MOTIF__)
if (!_xwidget || _stickToParent)
return UI_VisualObject::_ShapeRectChanged (o, v);
// Need to do this only for non-sticky children under X: they have a
// dialog shell, and its shape must be changed, not that of the
// Composite.
Arg arg[4];
short argn = 0;
long x = _shape.Origin().XCoord();
long y = _shape.Origin().YCoord();
long w = _shape.Width();
long h = _shape.Height();
XtSetArg (arg [ argn ], XtNx, x); argn++;
XtSetArg (arg [ argn ], XtNy, y); argn++;
XtSetArg (arg [ argn ], XtNheight,h); argn++;
XtSetArg (arg [ argn ], XtNwidth, w); argn++;
XtSetValues (XtParent (_xwidget), arg, argn);
return TRUE;
#endif
}
bool UI_CompositeVObject::_TitleChanged (CL_Object& o, long v)
{
#if defined(__MS_WINDOWS__)
return UI_VisualObject::_TitleChanged (o, v);
#elif defined(__OS2__)
if (_stickToParent)
return UI_VisualObject::_TitleChanged (o, v);
if (_frameHandle)
return (WinSetWindowText (_frameHandle, _title.AsPtr()) ? TRUE :
FALSE);
return TRUE;
#elif defined(__X_MOTIF__)
if (!_xwidget || _stickToParent)
return UI_VisualObject::_TitleChanged (o, v);
// Need to do this only for non-sticky children under X: they have a
// dialog shell, and its title must be changed, not that of the
// Composite.
Arg args [2];
XmString xmtitle;
xmtitle = XmStringCreate ((char*)_title.AsPtr(), XmSTRING_DEFAULT_CHARSET);
XtSetArg (args [0], XmNdialogTitle, xmtitle);
XtSetArg (args [1], XmNlabelString, xmtitle);
XtSetValues (XtParent (_xwidget), args, 2);
XmStringFree (xmtitle); // No leaks allowed
XtVaSetValues (XtParent (_xwidget), XmNtitle,
(char*) _title.AsPtr(), NULL);
return TRUE;
#endif
}