home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
combobox.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-08
|
10KB
|
392 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
#include "ui/combobox.h"
#include "ui/strseq.h"
#if defined(__MS_WINDOWS__)
#include <windows.h>
#endif
#if defined(__MS_WINDOWS__)
#define COMBOBOX_STYLE WS_CHILD | WS_VISIBLE \
| WS_GROUP | WS_VSCROLL | WS_TABSTOP | \
CBS_AUTOHSCROLL
#elif defined(__OS2__)
#define COMBOBOX_STYLE LS_HORZSCROLL | WS_VISIBLE
#endif
typedef CL_Binding<UI_ComboBox> ComboBoxBind;
#if defined(__GNUC__)
template class CL_Binding<UI_ComboBox>;
#endif
UI_ComboBox::UI_ComboBox
(UI_VObjCollection* p, const UI_Rectangle& shape, UI_ViewID id,
bool editable)
: UI_StringViewSingleSel (p, shape, id)
{
_editable = editable;
_limit = 255;
#if defined(__MS_WINDOWS__)
_style = COMBOBOX_STYLE | (editable ? CBS_DROPDOWN : CBS_DROPDOWNLIST);
#elif defined(__OS2__)
_style = WS_VISIBLE | (editable ? CBS_DROPDOWN : CBS_DROPDOWNLIST);
#endif
ComboBoxBind bind (this, &UI_ComboBox::_EditStringChanged);
_editString.AddDependent (bind, 0);
}
#if defined(__MS_WINDOWS__)
UI_ComboBox::UI_ComboBox
(UI_CompositeVObject* p, UI_ViewID id, UI_ViewHandle h)
: UI_StringViewSingleSel (p, id, h)
{
_model = new UI_StringSequence;
((UI_StringSequence*) _model)->AddClient (this);
}
#endif
void UI_ComboBox::ShowDropDown ()
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_SHOWDROPDOWN, 1, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, CBM_SHOWLIST, (MPARAM) 1, 0);
#endif
}
void UI_ComboBox::HideDropDown ()
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_SHOWDROPDOWN, 0, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, CBM_SHOWLIST, 0, 0);
#endif
}
bool UI_ComboBox::IsDropDownShowing() const
{
#if defined(__MS_WINDOWS__)
return _handle ? SendMessage (_handle, CB_GETDROPPEDSTATE, 0, 0) : FALSE;
#elif defined(__OS2__)
if (!_handle)
return FALSE;
return WinSendMsg (_handle, CBM_ISLISTSHOWING, 0, 0) ? TRUE : FALSE;
#endif
}
#if defined(__MS_WINDOWS__)
static CL_String EditContent (HWND h)
{
char* data = NULL;
short length = 0;
if (h) {
length = GetWindowTextLength (h) + 1;
if (length) {
data = new char [length];
if (data)
GetWindowText (h, data, length);
}
}
CL_String ret = data ? data : "";
if (data)
delete data;
return ret;
}
#elif defined(__OS2__)
static CL_String EditContent (HWND h)
{
if (!h)
return "";
long n = WinQueryWindowTextLength (h);
char* buf = new char[n+1];
if (!buf)
return ""; // No memory
WinQueryWindowText (h, n+1, buf);
CL_String ret (buf);
delete buf;
return ret;
}
#endif
CL_String& UI_ComboBox::EditString ()
{
ComboBoxBind bind (this, &UI_ComboBox::_EditStringChanged);
_editString.RemoveDependent (bind);
if (_handle && _editable) {
// If it's not editable, the edit string is always current because
// UpdateSelection updates it whenever the selection changes.
_editString = EditContent (_handle);
}
_editString.AddDependent (bind, 1);
return _editString;
}
void UI_ComboBox::SetLengthLimit (short limit)
{
_limit = limit;
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_LIMITTEXT, limit, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, EM_SETTEXTLIMIT, MPFROM2SHORT(limit, 0), 0);
#endif
}
long UI_ComboBox::TopIndex () const
{
#if defined(__MS_WINDOWS__)
return (_handle) ? SendMessage (_handle, CB_GETCURSEL, 0, 0)
: -1;
#elif defined(__OS2__)
return _handle ? (long) WinSendMsg (_handle, LM_QUERYTOPINDEX, 0, 0) : -1;
#endif
}
short UI_ComboBox::VisibleCount () const
{
return 1; // Can't really do this. Can we do better at all?
}
void UI_ComboBox::ScrollTo (long index)
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_SETCURSEL, index, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, LM_SETTOPINDEX, (MPARAM) index, 0);
#endif
}
void UI_ComboBox::ItemInserted (long i)
{
CL_String s = (*(UI_StringSequence*) _model) [i+1];
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_INSERTSTRING, i+1, (long)(const char*)s);
#elif defined(__OS2__)
if (_handle)
WinInsertLboxItem (_handle, i, s.AsPtr());
#endif
_UpdateSelection ();
}
void UI_ComboBox::ItemRemoved (long i)
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_DELETESTRING, i, 0L);
#elif defined(__OS2__)
if (_handle)
WinDeleteLboxItem (_handle, i);
#endif
_UpdateSelection ();
}
void UI_ComboBox::ItemChanged (long i)
{
CL_String s = (*(UI_StringSequence*)_model)[i];
#if defined(__MS_WINDOWS__)
SendMessage (_handle, WM_SETREDRAW, FALSE, 0L);
SendMessage (_handle, CB_DELETESTRING, i, 0L);
SendMessage (_handle, CB_INSERTSTRING, i, (long) s.AsPtr());
SendMessage (_handle, WM_SETREDRAW, TRUE, 0L);
#elif defined(__OS2__)
if (_handle) {
WinDeleteLboxItem (_handle, i);
WinInsertLboxItem (_handle, i, s.AsPtr());
}
#endif
}
void UI_ComboBox::ModelEmptied ()
{
#if defined(__MS_WINDOWS__)
if (_handle)
SendMessage (_handle, CB_RESETCONTENT, 0, 0);
#elif defined(__OS2__)
if (_handle)
WinSendMsg (_handle, LM_DELETEALL, 0, 0);
#endif
}
void UI_ComboBox::_PrivateInitialize ()
{
UI_SimpleVObject::_PrivateInitialize ();
UI_StringSequence& theModel = *(UI_StringSequence*) _model;
theModel.AddClient (this);
long n = theModel.Size();
#if defined(__MS_WINDOWS__)
if (n) {
SendMessage (_handle, WM_SETREDRAW, FALSE, 0);
SendMessage (_handle, CB_RESETCONTENT, 0, 0);
for (long i = 0; i < n; i++) {
SendMessage (_handle, CB_ADDSTRING, 0,
(long) theModel[i].AsPtr());
}
SendMessage ((HWND)(long)_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());
#endif
}
UI_WindowClass UI_ComboBox::WindowClass () const
{
#if defined(__MS_WINDOWS__)
return "combobox";
#elif defined(__OS2__)
return WC_COMBOBOX;
#elif defined(__X_MOTIF__)
#error No ComboBox under motif.
#endif
}
bool UI_ComboBox::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_ComboBox::_UpdateSelection ()
{
ComboBoxBind bind (this, &UI_ComboBox::_SelectionChanged);
_selection.RemoveDependent (bind);
ComboBoxBind ebind (this, &UI_ComboBox::_EditStringChanged);
_editString.RemoveDependent (ebind);
long pos = 0;
CL_String editContents;
#if defined(__MS_WINDOWS__)
pos = SendMessage (_handle, CB_GETCURSEL, 0, 0);
if (pos == LB_ERR)
pos = -1;
_selection = pos;
#elif defined(__OS2__)
pos = (long) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM) -1, 0);
if (pos == LIT_NONE)
pos = -1;
#endif
if (_editable)
_editString = EditContent (_handle);
else if (pos >= 0)
_editString = (*(UI_StringSequence*) _model) [pos];
else
_editString = "";
_selection.AddDependent (bind, 1);
_editString.AddDependent (ebind, 1);
}
bool UI_ComboBox::_SelectionChanged (CL_Object&, long)
{
UI_StringSequence& theModel = *(UI_StringSequence*) _model;
if (_selection < 0 || _selection >= theModel.Size()) {
ComboBoxBind bind (this, &UI_ComboBox::_SelectionChanged);
_selection.RemoveDependent (bind);
_selection = -1;
_selection.AddDependent (bind, 1);
}
#if defined(__MS_WINDOWS__)
SendMessage (_handle, CB_SETCURSEL, _selection, 0);
#elif defined(__OS2__)
WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) _selection.Value(),
(MPARAM) TRUE);
#endif
return TRUE;
}
bool UI_ComboBox::_EditStringChanged (CL_Object&, long)
{
#if defined(__MS_WINDOWS__)
SetWindowText (_handle, _editString.AsPtr());
SendMessage (_handle, CB_SETEDITSEL, 0,
MAKELONG (0, _editString.Size()-1));
#elif defined(__OS2__)
WinSetWindowText (_handle, _editString.AsPtr());
#endif
return TRUE;
}