home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
strview.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-04
|
21KB
|
734 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>
#elif defined(__X_MOTIF__)
#include <Xm/Frame.h>
#include <Xm/BulletinB.h>
#include <Xm/List.h>
#endif
#include "ui/strview.h"
#include "ui/cntroler.h"
#include "ui/event.h"
#include "ui/applic.h"
#include "base/intset.h"
#if defined(__MS_WINDOWS__)
#define LISTBOX_STYLE LBS_NOTIFY | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE \
| WS_BORDER | WS_HSCROLL | WS_VSCROLL | WS_TABSTOP
#elif defined(__OS2__)
#define LISTBOX_STYLE LS_HORZSCROLL | WS_VISIBLE
#endif
typedef CL_Binding<UI_StringView> StrViewBind;
#if defined(__GNUC__)
template class CL_Binding<UI_StringView>;
#endif
UI_StringView::UI_StringView
(UI_VObjCollection* p, UI_StringSequence* model,
const UI_Rectangle& shape, bool mult, UI_ViewID id, long s)
: UI_SimpleVObject (p, shape, id, s)
{
_multiple = mult;
_model = model;
_ownModel = FALSE;
#if defined(__MS_WINDOWS__)
if (_style == -1)
_style = LISTBOX_STYLE;
if (_multiple)
_style |= LBS_MULTIPLESEL;
#elif defined(__OS2__)
_style = LISTBOX_STYLE;
if (_multiple)
_style |= LS_MULTIPLESEL | LS_EXTENDEDSEL;
#elif defined(__X_MOTIF__)
_frame = NULL;
#endif
}
UI_StringView::UI_StringView
(UI_VObjCollection* p, const UI_Rectangle& shape,
bool mult, UI_ViewID id, long s
)
: UI_SimpleVObject (p, shape, id, s)
{
_model = new UI_StringSequence;
_multiple = mult;
#if defined(__MS_WINDOWS__)
if ( _style == -1 )
_style = LISTBOX_STYLE;
if ( _multiple )
_style |= LBS_MULTIPLESEL;
#elif defined(__OS2__)
_style = LISTBOX_STYLE;
if (_multiple)
_style |= LS_MULTIPLESEL | LS_EXTENDEDSEL;
#elif defined(__X_MOTIF__)
_frame = NULL;
#endif
}
void UI_StringView::ScrollTo (long index)
{
#if defined(__MS_WINDOWS__)
if (_handle && index >= 0)
SendMessage (_handle, LB_SETTOPINDEX, (WORD) index, 0);
#elif defined(__OS2__)
if (_handle && index >= 0)
WinSendMsg (_handle, LM_SETTOPINDEX, (MPARAM) index, 0);
#elif defined(__X_MOTIF__)
if (_xwidget && index >= 0)
XmListSetPos (_xwidget, index-1);
#endif
}
#if defined(__MS_WINDOWS__)
UI_StringView::UI_StringView
(UI_CompositeVObject* p, UI_ViewID id, UI_ViewHandle h)
: UI_SimpleVObject (p, id, h)
{
_model = new UI_StringSequence;
((UI_StringSequence*) _model)->AddClient (this);
}
#endif
UI_StringView::~UI_StringView ()
{
((UI_StringSequence*) _model)->RemoveClient (this);
#if defined(__X_MOTIF__)
if (_frame)
XtDestroyWidget (_frame);
#endif
}
long UI_StringView::TopIndex () const
{
#if defined(__MS_WINDOWS__)
return _handle ? SendMessage (_handle, LB_GETTOPINDEX, 0, 0) : -1;
#elif defined(__OS2__)
return _handle ? (long) WinSendMsg (_handle, LM_QUERYTOPINDEX, 0, 0) : -1;
#elif defined(__X_MOTIF)
int pos;
XtGetValues (_handle, XmNtopItemPosition, &pos);
return pos-1;
#endif
}
short UI_StringView::VisibleCount () const
{
#if defined(__MS_WINDOWS__)
if (!_handle)
return 0;
long h = SendMessage (_handle, LB_GETITEMHEIGHT, 0, 0);
return h > 0 ? _shape.Height() / h : 0;
#elif defined(__OS2__)
NotImplemented ("VisibleCount");
return 0;
#elif defined(__X_MOTIF)
int size;
XtGetValues (_handle, XmNvisibleItemCount, &size);
return size;
#endif
}
void UI_StringView::MakeVisible ()
{
#if defined(__X_MOTIF__)
if (_frame)
XtManageChild (_frame);
#endif
UI_SimpleVObject::MakeVisible ();
}
void UI_StringView::MakeInvisible ()
{
#if defined(__X_MOTIF__)
if (_frame)
XtUnmanageChild (_frame);
#endif
UI_SimpleVObject::MakeInvisible ();
}
#if defined(__X_MOTIF__)
void UI_StringView::_SetupStyle (void* p, short& argn)
{
Arg* arg = (Arg*) p;
UI_SimpleVObject::_SetupStyle (arg, argn);
// Add more resource specs:
XtSetArg (arg [ argn ], XmNlistSizePolicy, XmCONSTANT); argn++;
XtSetArg (arg [ argn ], XmNselectionPolicy,
_multiple ? XmMULTIPLE_SELECT : XmSINGLE_SELECT); argn++;
// ------------------- ^^^^^^^^ ---------------------
// If I use EXTENDED_SELECT, then the setting of selection under program
// control doesn't seem to work right. If The MultiSel box's Selection()
// is assigned to, only the highest-indexed one of the strings gets
// highlighted, even though the selection set contains several indices.
}
#endif
bool UI_StringView::MakeVisualElement ()
{
#if defined(__MS_WINDOWS__) || defined(__OS2__)
return UI_SimpleVObject::MakeVisualElement();
#elif defined(__X_MOTIF__)
// This code is copied from that of SimpleVObject, except that we use
// XmCreateScrolledList instead of XtCreateWidget, because the scroll
// bar does not seem to be displayed otherwise.
//
// There is one other thing. Motif seems to
// have a strange bug. If we make a List invisible, and create other
// visible widgets in the same area, the latter are not painted! So we
// interpose a dummy frame widget of which the List is made a
// child. This dummy widget is the instance variable _frame.
// GNU C seems to have a strange bug, so we work around it. Instead of
// saying
// Widget pw = (Widget) (_parent->ViewHandle());
// we say
UI_VisualObject* p = _parent;
Widget pw = (Widget) p->ViewHandle();
Arg arg [20];
short argn = 0;
// First, we'll create a Frame widget
CL_String instance_name = InstanceName();
const char* inst_name = instance_name.AsPtr();
CL_String frame_name = instance_name + "_frame";
short x = _shape.Left ();
short y = _shape.Top ();
short w = _shape.Width ();
short 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++;
XtSetArg (arg [argn], XmNmarginWidth, 0); argn++;
XtSetArg (arg [argn], XmNmarginHeight, 0); argn++;
_frame = XtCreateWidget (frame_name.AsPtr(), xmFrameWidgetClass,
pw, arg, argn);
XtRealizeWidget (_frame);
// Next, create the List as child of the frame
_WidgetClassRec* class_name = WindowClass ();
argn = 0;
_SetupStyle (arg, argn); // Set up the X resources
XmString title = XmStringCreate
((char *) _title.AsPtr (), XmSTRING_DEFAULT_CHARSET);
XtSetArg (arg [argn], XmNlabelString, title); argn++;
// _xwidget = XtCreateWidget (inst_name, class_name, pw, arg, argn);
_xwidget = XmCreateScrolledList (_frame, (char*) inst_name, arg, argn);
// XtManageChild (_xwidget);
// XtSetValues (_xwidget, arg, argn);
XmStringFree (title);
return TRUE;
#endif
}
void UI_StringView::ItemInserted (long i)
{
CL_String s = (*(UI_StringSequence*) _model) [i+1];
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, LB_INSERTSTRING, i+1, (long)(const char*)s);
#elif defined(__OS2__)
if (_handle)
WinInsertLboxItem (_handle, i, s.AsPtr());
#elif defined(__X_MOTIF__)
XmString xs;
char* item = (char *) s.AsPtr (); // Not const char* because
// XmStringCreate expects char*
xs = XmStringCreate (item, XmSTRING_DEFAULT_CHARSET);
XmListAddItem (_xwidget, xs, i+2);
XmStringFree (xs);
#endif
_UpdateSelection ();
}
void UI_StringView::ItemRemoved (long i)
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, LB_DELETESTRING, i, 0L);
#elif defined(__OS2__)
if (_handle)
WinDeleteLboxItem (_handle, i);
#elif defined(__X_MOTIF__)
XmListDeletePos (_xwidget, i+1);
#endif
_UpdateSelection ();
}
void UI_StringView::ItemChanged (long i)
{
CL_String s = (*(UI_StringSequence*)_model)[i];
#if defined(__MS_WINDOWS__)
SendMessage (_handle, WM_SETREDRAW, FALSE, 0L);
SendMessage (_handle, LB_DELETESTRING, i, 0L);
SendMessage (_handle, LB_INSERTSTRING, i, (long) s.AsPtr());
SendMessage (_handle, WM_SETREDRAW, TRUE, 0L);
#elif defined(__OS2__)
if (_handle) {
WinDeleteLboxItem (_handle, i);
WinInsertLboxItem (_handle, i, s.AsPtr());
}
#elif defined(__X_MOTIF__)
XmListDeletePos (_xwidget, i+1);
XmString xs;
char* item = (char*) s.AsPtr ();
xs = XmStringCreate (item, XmSTRING_DEFAULT_CHARSET);
XmListAddItem (_xwidget, xs, i+1);
XmStringFree (xs);
#endif
}
void UI_StringView::ModelEmptied ()
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, LB_RESETCONTENT, 0, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, LM_DELETEALL, 0, 0);
#elif defined(__X_MOTIF__)
if (_xwidget)
XmListDeleteAllItems (_xwidget);
#endif
}
void UI_StringView::_PrivateInitialize ()
{
UI_SimpleVObject::_PrivateInitialize ();
UI_StringSequence& theModel = *(UI_StringSequence*) _model;
theModel.AddClient (this);
long n = theModel.Size();
#if defined(__MS_WINDOWS__)
if (!_visible)
ShowWindow (_handle, SW_HIDE);
if (!_enabled)
EnableWindow (_handle, FALSE);
if (n) {
SendMessage (_handle, WM_SETREDRAW, FALSE, 0);
SendMessage (_handle, LB_RESETCONTENT, 0, 0);
for (long i = 0; i < n; i++) {
SendMessage (_handle, LB_ADDSTRING, 0,
(long) theModel[i].AsPtr());
}
SendMessage (_handle, WM_SETREDRAW, TRUE, 0L);
}
#elif defined(__OS2__)
WinSendMsg (_handle, LM_DELETEALL, 0, 0);
for (long i = 0; i < n; i++)
WinInsertLboxItem (_handle, LIT_END, theModel[i].AsPtr());
#elif defined(__X_MOTIF__)
XtAddCallback (_xwidget, XmNbrowseSelectionCallback,
&UI_StringView::Callback, (XtPointer) this);
XtAddCallback (_xwidget, XmNsingleSelectionCallback,
&UI_StringView::Callback, (XtPointer) this);
XtAddCallback (_xwidget, XmNextendedSelectionCallback,
&UI_StringView::Callback, (XtPointer) this);
XtAddCallback (_xwidget, XmNmultipleSelectionCallback,
&UI_StringView::Callback, (XtPointer) this);
XtAddCallback (_xwidget, XmNdefaultActionCallback,
&UI_StringView::Callback, (XtPointer) this);
if (n) {
for (long i = 0; i < n; i++) {
XmString xs = XmStringCreate ((char*) theModel[i],
XmSTRING_DEFAULT_CHARSET);
XmListAddItem (_xwidget, xs, 0);
XmStringFree (xs);
}
}
if (_visible) {
XtManageChild (_frame);
XtManageChild (_xwidget);
}
if (!_enabled) {
XtSetSensitive (_xwidget, FALSE);
XtSetSensitive (_frame, FALSE);
}
#endif
}
UI_WindowClass UI_StringView::WindowClass () const
{
#if defined(__MS_WINDOWS__)
return "listbox";
#elif defined(__OS2__)
return WC_LISTBOX;
#elif defined(__X_MOTIF__)
return xmListWidgetClass;
#endif
}
#if defined (__X_MOTIF__)
void UI_StringView::Callback (Widget w, void* client, void* call)
{
UI_StringView* sv = (UI_StringView *) client;
XmListCallbackStruct* cb = (XmListCallbackStruct*) call;
UI_Event* e;
long pos;
switch (cb->reason) {
case XmCR_SINGLE_SELECT:
case XmCR_BROWSE_SELECT:
case XmCR_MULTIPLE_SELECT:
case XmCR_EXTENDED_SELECT:
e = new UI_Event (Event_Select, sv, sv);
if (e)
_Controller->AddEvent (e);
break;
case XmCR_DEFAULT_ACTION:
e = new UI_Event (Event_LButtonDblClk, sv, sv);
if (e) {
e->curPos.Origin (UI_Point (cb->event->xbutton.x,
cb->event->xbutton.y));
_Controller->AddEvent (e);
}
break;
default:
break;
}
}
#endif
// ----------------- Single selection StringViews ----------------------
UI_StringViewSingleSel::UI_StringViewSingleSel (UI_VObjCollection* parent,
const UI_Rectangle& shape,
UI_ViewID id)
: UI_StringView (parent, shape, FALSE, id), _selection (-1)
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.AddDependent (bind, 1); // Notification code is not used
}
UI_StringViewSingleSel::UI_StringViewSingleSel
(UI_VObjCollection* parent, UI_StringSequence* model,
const UI_Rectangle& shape, UI_ViewID id)
: UI_StringView (parent, model, shape, FALSE, id), _selection (-1)
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.AddDependent (bind, 1); // Notification code is not used
}
#if defined(__MS_WINDOWS__)
UI_StringViewSingleSel::UI_StringViewSingleSel
(UI_CompositeVObject* parent, UI_ViewID id, UI_ViewHandle h)
: UI_StringView (parent, id, h), _selection (-1)
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.AddDependent (bind, 1); // Notification code is not used
}
#endif
bool UI_StringViewSingleSel::Select ()
{
// Called in response to Event_Select generated when the user changes a
// selection
_UpdateSelection ();
return FALSE; // So that the parent gets a chance to handle this event
}
void UI_StringViewSingleSel::_UpdateSelection ()
{
long pos = 0;
#if defined(__MS_WINDOWS__)
pos = SendMessage (_handle, LB_GETCURSEL, 0, 0);
if (pos == LB_ERR)
pos = -1;
#elif defined(__OS2__)
pos = (long) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM) -1, 0);
if (pos == LIT_NONE)
pos = -1;
#elif defined(__X_MOTIF__)
int* pos_list;
int count;
bool b = XmListGetSelectedPos (_xwidget, &pos_list, &count);
pos = b ? pos_list[0] - 1 : -1;
// -----------------^^^^^^ -- Correct for Motif's indexing
if (b)
XtFree ((char*) pos_list);
#endif
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.RemoveDependent (bind);
_selection = pos;
_selection.AddDependent (bind, 1);
}
bool UI_StringViewSingleSel::_SelectionChanged (CL_Object&, long)
{
UI_StringSequence& theModel = *(UI_StringSequence*) _model;
if (_selection < 0 || _selection >= theModel.Size()) {
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.RemoveDependent (bind);
_selection = -1;
_selection.AddDependent (bind, 1);
}
#if defined(__MS_WINDOWS__)
SendMessage (_handle, LB_SETCURSEL, _selection, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) _selection.Value(),
(MPARAM) TRUE);
#elif defined(__X_MOTIF__)
if (_selection >= 0)
XmListSelectPos (_xwidget, _selection+1, FALSE);
else
XmListDeselectAllItems (_xwidget);
#endif
return TRUE;
}
// ----------------- Multiple selection StringViews ----------------------
UI_StringViewMultiSel::UI_StringViewMultiSel (UI_VObjCollection* parent,
const UI_Rectangle& shape,
UI_ViewID id)
: UI_StringView (parent, shape, TRUE, id)
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.AddDependent (bind, 1); // Notification code is not used
}
UI_StringViewMultiSel::UI_StringViewMultiSel
(UI_VObjCollection* parent, UI_StringSequence* model,
const UI_Rectangle& shape, UI_ViewID id)
: UI_StringView (parent, model, shape, TRUE, id)
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.AddDependent (bind, 1); // Notification code is not used
}
#if defined(__MS_WINDOWS__)
UI_StringViewMultiSel::UI_StringViewMultiSel
(UI_CompositeVObject* parent, UI_ViewID id, UI_ViewHandle h)
: UI_StringView (parent, id, h)
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.AddDependent (bind, 1); // Notification code is not used
}
#endif
bool UI_StringViewMultiSel::Select ()
{
// Called in response to Event_Select generated when the user changes a
// selection
_UpdateSelection ();
return FALSE; // So that the parent gets a chance to handle this event
}
void UI_StringViewMultiSel::_UpdateSelection ()
{
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
_selection.RemoveDependent (bind);
_selection.MakeEmpty ();
#if defined(__MS_WINDOWS__)
long count = SendMessage (_handle, LB_GETSELCOUNT, 0, 0);
if (count > 0) {
int* buf = new int [count];
SendMessage (_handle, LB_GETSELITEMS, count, (long)buf);
for (long i = 0; i < count; i++)
_selection.Add (buf[i]);
delete buf;
}
#elif defined(__OS2__)
short index = -1;
short pos;
do {
pos = (short) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM)
index, 0);
if (pos == LIT_NONE) break;
_selection.Add ((long) pos);
index = pos+1;
} while (1);
#elif defined(__X_MOTIF__)
int* pos_list;
int count;
bool b = XmListGetSelectedPos (_xwidget, &pos_list, &count);
if (!b)
count = 0;
for (long i = 0; i < count; i++)
_selection.Add (pos_list[i] - 1);
// ------------------------^^^^ -- Correct for Motif's indexing
if (b)
XtFree ((char*) pos_list);
#endif
_selection.AddDependent (bind, 1);
}
bool UI_StringViewMultiSel::_SelectionChanged (CL_Object&, long)
{
// First, get rid of extraneous indices:
StrViewBind bind (this, &UI_StringView::_SelectionChanged);
UI_StringSequence& theModel = *(UI_StringSequence*) _model;
_selection.RemoveDependent (bind);
_selection *= CL_IntegerSet (0, theModel.Size()-1);
_selection.AddDependent (bind, 1);
// Now update the display:
#if defined(__MS_WINDOWS__)
SendMessage (_handle, WM_SETREDRAW, FALSE, 0);
SendMessage (_handle, LB_SELITEMRANGE, FALSE,
MAKELPARAM (0, theModel.Size()-1));
CL_IntegerSetIterator itr (_selection);
while (itr.More()) {
long l = itr.Next();
SendMessage (_handle, LB_SETSEL, TRUE, MAKELPARAM (l, 0));
}
SendMessage (_handle, WM_SETREDRAW, TRUE, 0);
#elif defined(__OS2__)
short index = -1;
short pos;
CL_IntegerSet oldSelection;
do {
pos = (short) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM)
index, 0);
if (pos == LIT_NONE) break;
oldSelection.Add ((long) pos);
index = pos+1;
} while (1);
CL_IntegerSet tmpSet = oldSelection - _selection;
CL_IntegerSetIterator itr (tmpSet);
while (itr.More())
WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) itr.Next(), FALSE);
tmpSet = _selection - oldSelection;
itr.Reset ();
while (itr.More())
WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) itr.Next(), (MPARAM)
TRUE);
#elif defined(__X_MOTIF__)
XmListDeselectAllItems (_xwidget);
CL_IntegerSetIterator itr (_selection);
while (itr.More()) {
long l = itr.Next();
XmListSelectPos (_xwidget, l+1, FALSE);
}
#endif
return TRUE;
}