home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
WXWIN140.ZIP
/
SRC
/
WX_ITEM.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-19
|
119KB
|
5,098 lines
/*
* File: wx_item.cc
* Purpose: Panel items implementation
*
* wxWindows 1.40
* Copyright (c) 1993 Artificial Intelligence Applications Institute,
* The University of Edinburgh
*
* Author: Julian Smart
* Date: 18-4-93
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice, author statement and this permission
* notice appear in all copies of this software and related documentation.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
* IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
* UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
* DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* When implementing a new item, be sure to:
*
* - add the item to the parent panel
* - set window_parent to the parent
* - NULL any extra child window pointers not created for this item
* (e.g. label control that wasn't needed)
* - delete any extra child windows in the destructor (e.g. label control)
* - implement GetSize and SetSize
* - to find panel position if coordinates are (-1, -1), use GetPosition
* - call AdvanceCursor after creation, for panel layout mechanism.
*
*/
/*
Motif notes
A panel is a form.
Each item is created on a RowColumn or Form of its own, to allow a label to
be positioned. wxListBox and wxMultiText have forms, all the others have RowColumns.
This is to allow labels to be positioned to the top left (can't do it with a
RowColumn as far as I know).
AttachWidget positions widgets relative to one another (left->right, top->bottom)
unless the x, y coordinates are given (more than -1).
*/
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "wx_item.h"
#include "wx_event.h"
#include "wx_utils.h"
#include "wx_main.h"
#include "wx_frame.h"
#include "wx_privt.h"
#ifdef wx_motif
#include <X11/IntrinsicP.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/Label.h>
#include <Xm/Text.h>
#include <Xm/RowColumn.h>
#include <Xm/MainW.h>
#include <Xm/DrawingA.h>
#include <Xm/CascadeBG.h>
#include <Xm/CascadeB.h>
#include <Xm/SeparatoG.h>
#include <Xm/PushBG.h>
#include <Xm/ToggleB.h>
#include <Xm/List.h>
#include <Xm/ArrowB.h>
#include <Xm/Scale.h>
#include <string.h>
void wxMenuItemCallback(Widget w, XtPointer clientData,
XtPointer ptr);
void wxMenuItemArmCallback(Widget w, XtPointer clientData,
XtPointer ptr);
void wxMenuItemDisarmCallback(Widget w, XtPointer clientData,
XtPointer ptr);
#endif
#ifdef wx_xview
#include <xview/panel.h>
#include <xview/openmenu.h>
#include <xview/svrimage.h>
// General purpose item notifier proc
void wxItemProc(Panel_item item, Event *event);
// Menu notifier proc
void wxMenuProc(Menu x_menu, Menu_item menu_item);
void wxMenuBarProc(Menu x_menu, Menu_item menu_item);
void wxCheckBoxProc(Panel_item item, int value, Event *x_event);
void wxChoiceProc(Panel_item item, int value, Event *event);
int wxListProc(Panel_item item, char *string, Xv_opaque client_data,
Panel_list_op op, Event *event, int row);
Panel_setting wxTextProc(Panel_item item, Event *x_event);
void wxSliderProc(Panel_item item, int value, Event *event);
#endif
#ifdef wx_msw
// Find maximum size of window/rectangle
void wxFindMaxSize(HWND hwnd, RECT *rect);
wxList wxScrollBarList(wxKEY_INTEGER);
#endif
// Item members
wxItem::wxItem(void)
{
#ifdef wx_motif
formWidget = 0;
labelWidget = 0;
itemOrientation = wxHORIZONTAL;
#endif
}
wxItem::~wxItem(void)
{
#ifdef wx_motif
if (labelWidget)
XtDestroyWidget(labelWidget);
if (formWidget)
{
wxWidgetHashTable->Delete((long)formWidget);
if (formWidget)
XtDestroyWidget(formWidget);
}
#endif
}
void wxItem::GetSize(int *width, int *height)
{
#ifdef wx_motif
Dimension xx, yy;
XtVaGetValues(formWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
*width = xx; *height = yy;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
Rect *rect = (Rect *)xv_get(item, XV_RECT);
*height = rect->r_height;
*width = rect->r_width;
#endif
#ifdef wx_msw
HWND wnd = (HWND)ms_handle;
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize(wnd, &rect);
*width = rect.right - rect.left;
*height = rect.bottom - rect.top;
#endif
}
void wxItem::GetPosition(int *x, int *y)
{
#ifdef wx_motif
Dimension xx, yy;
XtVaGetValues(formWidget, XmNx, &xx, XmNy, &yy, NULL);
*x = xx; *y = yy;
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*x = (int)xv_get(x_win, XV_X);
*y = (int)xv_get(x_win, XV_Y);
#endif
#ifdef wx_msw
HWND wnd = (HWND)ms_handle;
wxWindow *parent = GetParent();
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize(wnd, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
*x = point.x;
*y = point.y;
#endif
}
void wxItem::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
if (x > -1)
XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF,
XmNx, x,
NULL);
if (y > -1)
XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF,
XmNy, y,
NULL);
if (width > -1)
XtVaSetValues(formWidget, XmNwidth, width,
NULL);
if (height > -1)
XtVaSetValues(formWidget, XmNheight, height,
NULL);
OnSize(width, height);
#endif
}
void wxItem::SetClientSize(int width, int height)
{
SetSize(-1, -1, width, height);
}
void wxItem::SetLabel(char *label)
{
#ifdef wx_motif
XmString text = XmStringCreateSimple(label);
XtVaSetValues(labelWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_LABEL_STRING, label, NULL);
#endif
#ifdef wx_msw
SetWindowText((HWND)ms_handle, label);
#endif
}
char *wxItem::GetLabel(void)
{
#ifdef wx_motif
XmString text;
char *s;
XtVaGetValues(labelWidget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
// XmStringFree(text);
char *val = copystring(s);
XtFree(s);
return val;
}
else
{
// XmStringFree(text);
return NULL;
}
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
#endif
#ifdef wx_msw
char buf[300];
GetWindowText((HWND)ms_handle, buf, 300);
return copystring(buf);
#endif
}
void wxItem::SetDefault(void)
{
#ifdef wx_motif
#endif
#ifdef wx_xview
wxPanel *panel = (wxPanel *)GetParent();
if (panel)
{
Panel p = (Panel)panel->handle;
xv_set(p, PANEL_DEFAULT_ITEM, (Panel_item)handle, 0);
}
#endif
}
void wxItem::SetFocus(void)
{
#ifdef wx_motif
wxWindow::SetFocus();
#endif
#ifdef wx_xview
#endif
#ifdef wx_msw
wxWindow::SetFocus();
#endif
}
int wxItem::GetLabelPosition(void)
{
return labelPosition;
}
void wxItem::SetLabelPosition(int pos)
{
labelPosition = pos;
}
void wxItem::Show(Bool show)
{
#ifdef wx_motif
#endif
#ifdef wx_xview
Xv_opaque window = (Xv_opaque)handle;
xv_set(window, XV_SHOW, show, NULL);
#endif
#ifdef wx_msw
HWND wnd = (HWND)ms_handle;
int cshow;
if (show)
cshow = SW_SHOW;
else
cshow = SW_HIDE;
ShowWindow(wnd, cshow);
if (show)
BringWindowToTop(wnd);
#endif
}
float wxItem::GetTextHeight(void)
{
#ifdef wx_motif
return 0.0;
#endif
#ifdef wx_xview
Xv_Font the_font;
if (!(font && font->x_font))
{
Xv_opaque thing = (Xv_opaque)(GetParent()->handle);
the_font = (Xv_Font)xv_get(thing, XV_FONT);
}
else the_font = font->x_font;
return (float)xv_get(the_font, FONT_DEFAULT_CHAR_HEIGHT);
#endif
#ifdef wx_msw
TEXTMETRIC lpTextMetric;
HWND wnd = (HWND)ms_handle;
HDC dc = GetDC(wnd);
GetTextMetrics(dc, &lpTextMetric);
ReleaseDC(wnd, dc);
return (float)lpTextMetric.tmHeight;
#endif
}
float wxItem::GetTextWidth(void)
{
#ifdef wx_motif
return 0.0;
#endif
#ifdef wx_xview
Xv_Font the_font;
if (!(font && font->x_font))
{
Xv_opaque thing = (Xv_opaque)(GetParent()->handle);
the_font = (Xv_Font)xv_get(thing, XV_FONT);
}
else the_font = font->x_font;
return (float)xv_get(the_font, FONT_DEFAULT_CHAR_WIDTH);
#endif
#ifdef wx_msw
TEXTMETRIC lpTextMetric;
HWND wnd = (HWND)ms_handle;
HDC dc = GetDC(wnd);
GetTextMetrics(dc, &lpTextMetric);
ReleaseDC(wnd, dc);
return (float)lpTextMetric.tmAveCharWidth;
#endif
}
void wxItem::GetTextExtent(char *string, float *x, float *y)
{
#ifdef wx_motif
*x = 0.0; *y = 0.0;
#endif
#ifdef wx_xview
Xv_Font the_font;
if (!(font && font->x_font))
{
Xv_opaque thing = (Xv_opaque)(GetParent()->handle);
the_font = (Xv_Font)xv_get(thing, XV_FONT);
}
else the_font = font->x_font;
Font_string_dims dims;
(void)xv_get(the_font, FONT_STRING_DIMS, string, &dims);
*x = (float)dims.width;
*y = (float)dims.height;
#endif
#ifdef wx_msw
HWND wnd = (HWND)ms_handle;
HDC dc = GetDC(wnd);
SIZE sizeRect;
GetTextExtentPoint(dc, string, strlen(string), &sizeRect);
ReleaseDC(wnd, dc);
*x = (float)sizeRect.cx;
*y = (float)sizeRect.cy;
#endif
}
void wxItem::Centre(int direction)
{
int x, y, width, height, panel_width, panel_height, new_x, new_y;
wxPanel *panel = (wxPanel *)GetParent();
if (!panel)
return;
panel->GetClientSize(&panel_width, &panel_height);
GetSize(&width, &height);
GetPosition(&x, &y);
new_x = x;
new_y = y;
if (direction == wxHORIZONTAL || direction == wxBOTH)
new_x = (int)((panel_width - width)/2);
if (direction == wxVERTICAL || direction == wxBOTH)
new_y = (int)((panel_height - height)/2);
SetSize(new_x, new_y, width, height);
}
/*
* Attach new widget to last widget, or below previous widget of
* previous row if we've had a new line
*/
#ifdef wx_motif
void wxItem::AttachWidget(wxPanel *panel, Widget formWidget,
int x, int y, int width, int height)
{
itemOrientation = panel->label_position;
wxWidgetHashTable->Put((long)formWidget, this);
XtOverrideTranslations(formWidget,
XtParseTranslationTable("<Configure>: resize()"));
XtVaSetValues(formWidget,
XmNleftOffset, panel->hSpacing,
NULL);
if (panel->new_line)
{
if ((x == -1) && (y == -1))
XtVaSetValues(formWidget,
XmNtopAttachment, panel->firstRowWidget ? XmATTACH_WIDGET: XmATTACH_FORM,
XmNtopWidget, panel->firstRowWidget,
XmNtopOffset, panel->vSpacing,
XmNleftAttachment, XmATTACH_FORM,
NULL);
panel->lastWidget = formWidget;
panel->firstRowWidget = formWidget;
panel->new_line = FALSE;
}
else
{
if ((x == -1) && (y == -1))
XtVaSetValues(formWidget,
XmNleftAttachment, panel->lastWidget ? XmATTACH_WIDGET: XmATTACH_FORM,
XmNleftWidget, panel->lastWidget,
XmNtopAttachment, panel->lastWidget ? XmATTACH_OPPOSITE_WIDGET: XmATTACH_FORM,
XmNtopWidget, panel->lastWidget,
XmNtopOffset, panel->lastWidget ? 0: panel->vSpacing,
NULL);
panel->lastWidget = formWidget;
}
SetSize(x, y, width, height);
if (!panel->firstRowWidget)
panel->firstRowWidget = formWidget;
else
{
Dimension hh1, hh2;
XtVaGetValues(formWidget, XmNheight, &hh1, NULL);
XtVaGetValues(panel->firstRowWidget, XmNheight, &hh2, NULL);
if (hh1 > hh2)
panel->firstRowWidget = formWidget;
}
}
#endif
#ifdef wx_msw
// Call this repeatedly for several wnds to find the overall size
// of the widget.
// Call it initially with -1 for all values in rect.
// Keep calling for other widgets, and rect will be modified
// to calculate largest bounding rectangle.
void wxFindMaxSize(HWND wnd, RECT *rect)
{
int left = rect->left;
int right = rect->right;
int top = rect->top;
int bottom = rect->bottom;
GetWindowRect(wnd, rect);
if (left < 0)
return;
if (left < rect->left)
rect->left = left;
if (right > rect->right)
rect->right = right;
if (top < rect->top)
rect->top = top;
if (bottom > rect->bottom)
rect->bottom = bottom;
}
// General Windows item code
// wxWnd (wx_win.cc) catches commands from child items, finds the child
// and sends a Command message to the child.
// Buttons
BOOL wxButton::Command(UINT param)
{
wxFunction fun = callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*this, event);
return TRUE;
}
else return FALSE;
}
BOOL wxCheckBox::Command(UINT param)
{
wxFunction fun = callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*this, event);
return TRUE;
}
else return FALSE;
}
BOOL wxText::Command(UINT param)
{
wxFunction fun = callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*this, event);
return TRUE;
}
else return FALSE;
}
#endif
#ifdef wx_motif
void wxButtonCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxItem *item = (wxItem *)clientData;
wxFunction fun = item->callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*item, event);
}
}
#endif
wxButton::wxButton(wxPanel *panel, wxFunction Function, char *label,
int x, int y, int width, int height)
{
if (panel) panel->AddChild(this);
window_parent = panel;
Callback(Function);
labelPosition = wxHORIZONTAL;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
XmString text = XmStringCreateSimple(label);
formWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, panelForm,
XmNorientation, XmHORIZONTAL,
XmNmarginHeight, 0,
XmNmarginWidth, 0,
NULL);
Widget buttonWidget;
buttonWidget = XtVaCreateManagedWidget("button",
xmPushButtonWidgetClass, formWidget,
XmNlabelString, text,
// XmNdefaultButtonShadowThickness, 1, // See comment for wxButton::SetDefault
NULL);
handle = (char *)buttonWidget;
XmStringFree(text);
XtAddCallback(buttonWidget, XmNactivateCallback, wxButtonCallback,
this);
AttachWidget(panel, formWidget, x, y, width, height);
#endif
#ifdef wx_xview
Panel x_panel = (Panel)(panel->GetHandle());
Panel_item x_button;
if (panel->new_line)
{
x_button = (Panel_item) xv_create(x_panel, PANEL_BUTTON, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_button = (Panel_item) xv_create(x_panel, PANEL_BUTTON, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
xv_set(x_button,
PANEL_LABEL_STRING, label,
PANEL_NOTIFY_PROC, wxItemProc,
PANEL_CLIENT_DATA, (char *)this,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_button, XV_X, x, XV_Y, y, NULL);
if (width > 0)
{ xv_set(x_button, PANEL_LABEL_WIDTH, (int) width, NULL); };
handle = (char *)x_button;
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
panel->GetValidPosition(&x, &y);
RECT rect;
rect.left = 0; rect.top = 0; rect.right = 0; rect.bottom = 0;
windows_id = (int)NewId();
HWND wx_button =
CreateWindowEx(0, "BUTTON", label, BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
ms_handle = (HANDLE)wx_button;
SetSize(x, y, width, height);
ShowWindow(wx_button, SW_SHOW);
panel->AdvanceCursor(this);
#endif
}
wxButton::~wxButton(void)
{
}
// Button item notifier
#ifdef wx_xview
void wxItemProc(Panel_item x_item, Event *x_event)
{
wxItem *item = (wxItem *)xv_get(x_item, PANEL_CLIENT_DATA);
wxEvent event(x_event);
if (item->callback)
{
(void)(*(item->callback))(*item, event);
}
}
#endif
void wxButton::SetLabel(char *label)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
XmString text = XmStringCreateSimple(label);
XtVaSetValues(widget,
XmNlabelString, text,
NULL);
XmStringFree(text);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_LABEL_STRING, label, NULL);
#endif
#ifdef wx_msw
SetWindowText((HWND)ms_handle, label);
#endif
}
char *wxButton::GetLabel(void)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
XmString text;
char *s;
XtVaGetValues(widget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
// XmStringFree(text);
char *val = copystring(s);
XtFree(s);
return val;
}
else
{
// XmStringFree(text);
return NULL;
}
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
#endif
#ifdef wx_msw
char buf[300];
GetWindowText((HWND)ms_handle, buf, 300);
return copystring(buf);
#endif
}
void wxButton::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
wxItem::SetSize(x, y, width, height);
OnSize(width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
if (x > -1)
(void)xv_set(x_win, XV_X, x, NULL);
if (y > -1)
(void)xv_set(x_win, XV_Y, y, NULL);
if (width > 0)
(void)xv_set(x_win, XV_WIDTH, width, NULL);
if (height > 0)
(void)xv_set(x_win, XV_HEIGHT, height, NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
float current_width;
int cx;
int cy;
float cyf;
HWND button = (HWND)ms_handle;
wxGetCharSize(button, &cx, &cy);
if (width < 0)
{
GetWindowText(button, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(button, x, y, (int)(current_width + 3*cx), (int)(cyf*7/4), TRUE);
}
else
MoveWindow(button, x, y, width, height, TRUE);
OnSize(width, height);
#endif
}
void wxButton::SetFocus(void)
{
#ifdef wx_msw
wxPanel *panel = (wxPanel *)GetParent();
if (panel)
{
wxWnd *wnd = (wxWnd *)panel->handle;
SendMessage(wnd->handle, DM_SETDEFID, windows_id, 0L);
}
#endif
wxItem::SetFocus();
}
void wxButton::SetDefault(void)
{
#ifdef wx_motif
// Seems to mess up tab traversal; AND if shadow thickness
// isn't set, resizes the button - not wanted.
// Setting shadow thickness on creation makes a BIG button. Also
// undesirable.
// Can't decide what to do here.
// XtVaSetValues((Widget)handle, XmNshowAsDefault, 1, NULL);
#endif
#ifdef wx_xview
wxPanel *panel = (wxPanel *)GetParent();
if (panel)
{
Panel p = (Panel)panel->handle;
xv_set(p, PANEL_DEFAULT_ITEM, (Panel_item)handle, 0);
}
#endif
#ifdef wx_msw
wxPanel *panel = (wxPanel *)GetParent();
if (panel)
{
wxWnd *wnd = (wxWnd *)panel->handle;
SendMessage(wnd->handle, DM_SETDEFID, windows_id, 0L);
}
#endif
}
// Menus
// Construct a menu with optional title (then use append)
wxMenu::wxMenu(char *Title, wxFunction func)
{
no_items = 0;
menu_bar = NULL;
title = NULL;
#ifdef wx_motif
buttonWidget = NULL;
handle = NULL;
menuId = 0;
menuItems.DeleteContents(TRUE);
#endif
#ifdef wx_xview
Menu x_menu = (Menu) xv_create((Xv_opaque)NULL, MENU, MENU_CLIENT_DATA, (char *)this, NULL);
if (Title)
{
title = copystring(Title);
xv_set(x_menu, MENU_TITLE_ITEM, title, NULL);
}
handle = (char *)x_menu;
Callback(func);
top_level_menu = this;
#endif // wx_xview
#ifdef wx_msw
wxWinType = wxTYPE_HMENU;
ms_handle = (HANDLE)CreatePopupMenu();
#endif
}
// The wxWindow destructor will take care of deleting the submenus.
wxMenu::~wxMenu(void)
{
#ifdef wx_motif
wxNode *node = menuItems.First();
while (node)
{
wxMenuItem *item = (wxMenuItem *)node->Data();
item->menuBar = NULL;
if (item->itemName && (!item->subMenu))
{
XtRemoveCallback(item->buttonWidget, XmNactivateCallback, wxMenuItemCallback, (XtPointer)item);
XtRemoveCallback(item->buttonWidget, XmNarmCallback, wxMenuItemArmCallback, (XtPointer)item);
XtRemoveCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
}
else if (item->itemId == -1)
{
}
else if (item->subMenu)
{
XtRemoveCallback(item->buttonWidget, XmNcascadingCallback, wxMenuItemArmCallback, (XtPointer)item);
// XtRemoveCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
}
delete item;
node = node->Next();
}
#endif
#ifdef wx_xview
if (title)
delete title;
#endif
#ifdef wx_msw
DestroyMenu((HMENU)ms_handle);
ms_handle = NULL;
#endif
}
// Ordinary menu item
void wxMenu::Append(int Id, char *Label)
{
#ifdef wx_motif
wxMenuItem *item = new wxMenuItem;
item->itemId = Id;
item->buttonWidget = NULL;
item->itemName = copystring(Label);
item->subMenu = NULL;
menuItems.Append(item);
#endif
#ifdef wx_xview
Menu menu = (Menu)handle;
wxStripMenuCodes(Label, wxBuffer);
char *p = strcpy(malloc(strlen(wxBuffer) + 1), wxBuffer);
Menu_item mi = (Menu_item)xv_create((Xv_opaque)NULL, MENUITEM,
MENU_RELEASE,
MENU_STRING, p,
MENU_NOTIFY_PROC, wxMenuProc,
MENU_CLIENT_DATA, (char *)Id,
NULL);
if (mi)
xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
#endif // wx_xview
#ifdef wx_msw
AppendMenu((HMENU)ms_handle, MF_STRING, Id, Label);
#endif
no_items ++;
}
void wxMenu::AppendSeparator(void)
{
#ifdef wx_motif
wxMenuItem *item = new wxMenuItem;
item->itemId = -1;
item->buttonWidget = NULL;
menuItems.Append(item);
#endif
#ifdef wx_xview
/* HOW DO WE GET A SEPARATOR IN XVIEW?!
* This makes far too much space.
*/
Menu menu = (Menu)handle;
Menu_item mi = (Menu_item)xv_create((Xv_opaque)NULL,
MENUITEM_SPACE,
NULL);
if (mi)
xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
#endif
#ifdef wx_msw
AppendMenu((HMENU)ms_handle, MF_SEPARATOR, NULL, NULL);
#endif
}
// Pullright item
void wxMenu::Append(int Id, char *Label, wxMenu *SubMenu)
{
SubMenu->top_level_menu = top_level_menu;
SubMenu->window_parent = this;
children->Append(SubMenu); // Store submenu for later deletion
#ifdef wx_motif
wxMenuItem *item = new wxMenuItem;
item->itemId = Id;
item->itemName = copystring(Label);
item->buttonWidget = NULL;
item->subMenu = SubMenu;
menuItems.Append(item);
#endif
#ifdef wx_xview
Menu menu = (Menu)handle;
wxStripMenuCodes(Label, wxBuffer);
Menu x_submenu = (Menu)(SubMenu->GetHandle());
char *p = strcpy(malloc(strlen(wxBuffer) + 1), wxBuffer);
Menu_item mi = (Menu_item)xv_create((Xv_opaque)NULL, MENUITEM,
MENU_RELEASE,
MENU_STRING, p,
MENU_NOTIFY_PROC, wxMenuProc,
MENU_PULLRIGHT, x_submenu,
MENU_CLIENT_DATA, (char *)Id,
NULL);
if (mi)
xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
#endif // wx_xview
#ifdef wx_msw
HMENU menu = (HMENU)ms_handle;
HMENU child = (HMENU)SubMenu->ms_handle;
SubMenu->ms_handle = NULL;
AppendMenu(menu, MF_POPUP | MF_STRING, child, Label);
#endif
no_items ++;
}
void wxMenu::Enable(int Id, Bool Flag)
{
#ifdef wx_motif
Widget w = FindMenuItem(Id);
if (w)
{
XtSetSensitive(w, Flag);
return;
}
#endif
#ifdef wx_xview
Menu menu = (Menu)handle;
int n = (int)xv_get(menu, MENU_NITEMS);
for (int i = 1; i <= n; i++)
{
Menu_item item = FindMenuItem(Id);
if (item)
{
xv_set(item, MENU_INACTIVE, !Flag, NULL);
return;
}
}
#endif
#ifdef wx_msw
int ms_flag;
if (Flag)
ms_flag = MF_ENABLED;
else
ms_flag = MF_GRAYED;
EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
#endif
}
void wxMenu::Check(int Id, Bool Flag)
{
#ifdef wx_motif
#endif
#ifdef wx_xview
// No checking in XView; perhaps could simulate it
// with a bitmap?
#endif
#ifdef wx_msw
int ms_flag;
if (Flag)
ms_flag = MF_CHECKED;
else
ms_flag = MF_UNCHECKED;
EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
#endif
}
#ifdef wx_xview
Menu_item wxMenu::FindMenuItem(int Id)
{
Menu x_menu = (Menu)handle;
int num = (int)xv_get(x_menu, MENU_NITEMS);
for (int i = 1; i <= num; i++)
{
Menu_item item = (Menu_item)xv_get(x_menu, MENU_NTH_ITEM, i);
int id = (int)xv_get(item, MENU_CLIENT_DATA);
if (Id == id)
return item;
}
wxNode *node = children->First();
while (node)
{
wxMenu *child = (wxMenu *)node->Data();
Menu_item item = child->FindMenuItem(Id);
if (item)
return item;
node = node->Next();
}
return 0;
}
#endif
#ifdef wx_motif
Widget wxMenu::FindMenuItem(int Id)
{
if (Id == menuId)
{
return buttonWidget;
}
wxNode *node = menuItems.First();
while (node)
{
wxMenuItem *item = (wxMenuItem *)node->Data();
if (item->itemId == Id)
return item->buttonWidget;
if (item->subMenu)
{
Widget w = item->subMenu->FindMenuItem(Id);
if (w)
return w;
}
node = node->Next();
}
return NULL;
}
#endif
#ifdef wx_xview
void wxMenuProc(Menu x_menu, Menu_item menu_item)
{
wxMenu *item = (wxMenu *)xv_get(x_menu, MENU_CLIENT_DATA);
char *label = (char *)xv_get(menu_item, MENU_STRING);
int index = (int)xv_get(menu_item, MENU_CLIENT_DATA);
// Should find top-level menu and use ITS callback
wxMenu *top_level_menu = item->top_level_menu;
wxFrame *frame = NULL;
// If a menu bar, send a message to the frame
if (top_level_menu && top_level_menu->menu_bar)
{
frame = top_level_menu->menu_bar->menu_bar_frame;
frame->OnMenuCommand(index);
}
else if (top_level_menu && top_level_menu->callback)
{
wxEvent event(NULL);
event.string = label;
event.index = index;
(void)(*(top_level_menu->callback))(*item, event);
}
}
#endif
// Menu Bar
wxMenuBar::wxMenuBar(void)
{
#ifdef wx_msw
wxWinType = wxTYPE_HMENU;
#endif
n = 0;
menus = NULL;
titles = NULL;
menu_bar_frame = NULL;
}
wxMenuBar::wxMenuBar(int N, wxMenu *Menus[], char *Titles[])
{
#ifdef wx_msw
wxWinType = wxTYPE_HMENU;
#endif
n = N;
menus = Menus;
titles = Titles;
menu_bar_frame = NULL;
}
wxMenuBar::~wxMenuBar(void)
{
#ifdef wx_motif
#endif
#ifdef wx_xview
wxFrame *frame = menu_bar_frame;
if (frame)
{
frame->wx_menu_bar = 0;
delete frame->menu_bar_panel;
frame->y_offset = 0;
}
#endif
#ifdef wx_msw
HMENU menu = (HMENU)ms_handle;
if (menu_bar_frame)
{
wxWnd *cframe = (wxWnd *)menu_bar_frame->handle;
switch (menu_bar_frame->frame_type)
{
case wxMDI_PARENT:
case wxMDI_CHILD:
{
int N = GetMenuItemCount(menu);
int i;
for (i = 0; i < N; i++)
{
char buf[100];
int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
if ((chars > 0) && (strcmp(buf, "&Window") == 0))
{
RemoveMenu(menu, i, MF_BYPOSITION);
}
}
break;
}
default:
case wxSDI:
break;
}
}
DestroyMenu(menu);
ms_handle = NULL;
#endif
int i;
for (i = 0; i < n; i++)
{
delete menus[i];
delete titles[i];
}
delete menus;
delete titles;
}
void wxMenuBar::Append(wxMenu *menu, char *title)
{
n ++;
wxMenu **new_menus = new wxMenu *[n];
char **new_titles = new char *[n];
int i;
for (i = 0; i < n - 1; i++)
{
new_menus[i] = menus[i];
menus[i] = NULL;
new_titles[i] = titles[i];
titles[i] = NULL;
}
if (menus)
{
delete menus;
delete titles;
}
menus = new_menus;
titles = new_titles;
menus[n-1] = menu;
titles[n-1] = copystring(title);
menu->menu_bar = this;
}
// Must only be used AFTER menu has been attached to frame,
// otherwise use individual menus to enable/disable items
void wxMenuBar::Enable(int Id, Bool Flag)
{
#ifdef wx_motif
for (int j = 0; j < n; j++)
{
Widget w = menus[j]->FindMenuItem(Id);
if (w)
{
XtSetSensitive(w, Flag);
return;
}
}
#endif
#ifdef wx_xview
for (int j = 0; j < n; j++)
{
Menu_item item = menus[j]->FindMenuItem(Id);
if (item)
{
xv_set(item, MENU_INACTIVE, !Flag, NULL);
return;
}
}
#endif
#ifdef wx_msw
int ms_flag;
if (Flag)
ms_flag = MF_ENABLED;
else
ms_flag = MF_GRAYED;
EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
#endif
}
// Must only be used AFTER menu has been attached to frame,
// otherwise use individual menus
void wxMenuBar::Check(int Id, Bool Flag)
{
#ifdef wx_motif
#endif
#ifdef wx_xview
#endif
#ifdef wx_msw
int ms_flag;
if (Flag)
ms_flag = MF_CHECKED;
else
ms_flag = MF_UNCHECKED;
EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
#endif
}
#ifdef wx_motif
void wxMenuItemCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxMenuItem *item = (wxMenuItem *)clientData;
if (item)
{
if (item->menuBar && item->menuBar->menu_bar_frame)
{
// cout << "Id = " << item->itemId << "\n";
item->menuBar->menu_bar_frame->OnMenuCommand(item->itemId);
}
}
}
void wxMenuItemArmCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxMenuItem *item = (wxMenuItem *)clientData;
if (item)
{
if (item->menuBar && item->menuBar->menu_bar_frame)
{
item->menuBar->menu_bar_frame->OnMenuSelect(item->itemId);
}
}
}
void wxMenuItemDisarmCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxMenuItem *item = (wxMenuItem *)clientData;
if (item)
{
if (item->menuBar && item->menuBar->menu_bar_frame)
{
item->menuBar->menu_bar_frame->OnMenuSelect(-1);
}
}
}
Widget wxMenu::CreateMenu(wxMenuBar *menu_bar, Widget parent, char *title)
{
char mnem = wxFindMnemonic(title);
wxStripMenuCodes(title, wxBuffer);
Widget PullDown = XmCreatePulldownMenu(parent, "PullDown", NULL, 0);
XmString label_str = XmStringCreateSimple(wxBuffer);
Widget menuButton = XtVaCreateManagedWidget(wxBuffer,
xmCascadeButtonWidgetClass, parent,
XmNlabelString, label_str,
XmNsubMenuId, PullDown,
NULL);
/*
* COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
*/
if (strcmp(wxBuffer, "Help") == 0)
XtVaSetValues((Widget)menu_bar->handle, XmNmenuHelpWidget, menuButton, NULL);
if (mnem != 0)
XtVaSetValues(menuButton, XmNmnemonic, mnem, NULL);
XmStringFree(label_str);
wxNode *node = menuItems.First();
while (node)
{
wxMenuItem *item = (wxMenuItem *)node->Data();
item->menuBar = menu_bar;
if (item->itemName && (!item->subMenu))
{
wxStripMenuCodes(item->itemName, wxBuffer);
item->buttonWidget = XtVaCreateManagedWidget(wxBuffer,
xmPushButtonGadgetClass, PullDown, NULL);
mnem = wxFindMnemonic(item->itemName);
if (mnem != 0)
XtVaSetValues(item->buttonWidget, XmNmnemonic, mnem, NULL);
XtAddCallback(item->buttonWidget, XmNactivateCallback, wxMenuItemCallback, (XtPointer)item);
XtAddCallback(item->buttonWidget, XmNarmCallback, wxMenuItemArmCallback, (XtPointer)item);
XtAddCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
}
else if (item->itemId == -1)
{
item->buttonWidget = XtVaCreateManagedWidget("separator",
xmSeparatorGadgetClass, PullDown, NULL);
}
else if (item->subMenu)
{
item->buttonWidget = item->subMenu->CreateMenu(menu_bar, PullDown, item->itemName);
XtAddCallback(item->buttonWidget, XmNcascadingCallback, wxMenuItemArmCallback, (XtPointer)item);
// XtAddCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
}
node = node->Next();
}
handle = (char *)PullDown;
return menuButton;
}
#endif
#ifdef wx_motif
Widget wxFrame::GetMenuBarWidget(void)
{
return (Widget)wx_menu_bar->handle;
}
#endif
void wxFrame::SetMenuBar(wxMenuBar *menu_bar)
{
#ifdef wx_motif
Widget MenuBar = XmCreateMenuBar(frameWidget, "MenuBar", NULL, 0);
menu_bar->handle = (char *)MenuBar;
for (int i = 0; i < menu_bar->n; i ++)
{
wxMenu *menu = menu_bar->menus[i];
menu->buttonWidget = menu->CreateMenu(menu_bar, MenuBar, menu_bar->titles[i]);
}
XtRealizeWidget(MenuBar);
XtManageChild(MenuBar);
#endif
#ifdef wx_xview
y_offset = 0;
menu_bar_panel = new wxPanel(this, 0, 0, -1, MENU_BAR_PANEL_HEIGHT-1);
children->DeleteObject(menu_bar_panel);
y_offset = MENU_BAR_PANEL_HEIGHT;
int i;
for (i = 0; i < menu_bar->n; i ++)
{
wxStripMenuCodes(menu_bar->titles[i], wxBuffer);
Menu x_menu = (Menu)(menu_bar->menus[i]->handle);
(void) xv_create((Panel)(menu_bar_panel->handle), PANEL_BUTTON,
PANEL_LABEL_STRING, wxBuffer,
PANEL_ITEM_MENU, x_menu,
NULL);
}
#endif
#ifdef wx_msw
int i;
HMENU menu = CreateMenu();
for (i = 0; i < menu_bar->n; i ++)
{
HMENU popup = (HMENU)menu_bar->menus[i]->ms_handle;
menu_bar->menus[i]->ms_handle = NULL;
AppendMenu(menu, MF_POPUP | MF_STRING, popup, menu_bar->titles[i]);
}
menu_bar->ms_handle = (HANDLE)menu;
if (wx_menu_bar)
delete wx_menu_bar;
wxWnd *cframe = (wxWnd *)handle;
switch (frame_type)
{
case wxMDI_PARENT:
{
wxMDIFrame *mdi_frame = (wxMDIFrame *)cframe;
// Try to insert Window menu in front of Help, otherwise append it.
int N = GetMenuItemCount(menu);
Bool success = FALSE;
for (i = 0; i < N; i++)
{
char buf[100];
int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
strcmp(buf, "Help") == 0))
{
success = TRUE;
InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
GetSubMenu(mdi_frame->window_menu, 0), "&Window");
break;
}
}
if (!success)
AppendMenu(menu, MF_POPUP,
GetSubMenu(mdi_frame->window_menu, 0),
"&Window");
mdi_frame->parent_frame_active = TRUE;
#ifdef WIN32
SendMessage(mdi_frame->client_hwnd, WM_MDISETMENU, menu,
GetSubMenu(mdi_frame->window_menu, 0));
#else
SendMessage(mdi_frame->client_hwnd, WM_MDISETMENU, 0,
MAKELPARAM(menu, GetSubMenu(mdi_frame->window_menu, 0)));
#endif
DrawMenuBar(mdi_frame->handle);
break;
}
case wxMDI_CHILD:
{
wxMDIFrame *parent = (wxMDIFrame *)GetParent()->handle;
parent->parent_frame_active = FALSE;
// Try to insert Window menu in front of Help, otherwise append it.
int N = GetMenuItemCount(menu);
Bool success = FALSE;
for (i = 0; i < N; i++)
{
char buf[100];
int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
strcmp(buf, "Help") == 0))
{
success = TRUE;
InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
GetSubMenu(parent->window_menu, 0), "&Window");
break;
}
}
if (!success)
AppendMenu(menu, MF_POPUP,
GetSubMenu(parent->window_menu, 0),
"&Window");
#ifdef WIN32
SendMessage(parent->client_hwnd, WM_MDISETMENU, menu,
GetSubMenu(parent->window_menu, 0));
#else
SendMessage(parent->client_hwnd, WM_MDISETMENU, 0,
MAKELPARAM(menu, GetSubMenu(parent->window_menu, 0)));
#endif
DrawMenuBar(parent->handle);
break;
}
default:
case wxSDI:
{
SetMenu(cframe->handle, menu);
break;
}
}
#endif
wx_menu_bar = menu_bar;
menu_bar->menu_bar_frame = this;
}
#ifdef wx_motif
void wxCheckBoxCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxItem *item = (wxItem *)clientData;
wxFunction fun = item->callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*item, event);
}
}
#endif
// Single check box item
wxCheckBox::wxCheckBox(wxPanel *panel, wxFunction func, char *Title,
int x, int y, int width, int height)
{
window_parent = panel;
labelPosition = panel->label_position;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
XmString text = XmStringCreateSimple(Title);
formWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, panelForm,
XmNorientation, XmHORIZONTAL,
NULL);
Widget buttonWidget;
buttonWidget = XtVaCreateManagedWidget("toggle",
xmToggleButtonWidgetClass, formWidget,
XmNlabelString, text,
NULL);
handle = (char *)buttonWidget;
XmStringFree(text);
XtAddCallback(buttonWidget, XmNvalueChangedCallback, wxCheckBoxCallback,
this);
AttachWidget(panel, formWidget, x, y, width, height);
XmToggleButtonSetState(buttonWidget, FALSE, TRUE);
#endif
#ifdef wx_xview
Panel x_panel = (Panel)panel->GetHandle();
Panel_item x_choice;
int label_position;
if (panel->label_position == wxVERTICAL)
label_position = PANEL_VERTICAL;
else
label_position = PANEL_HORIZONTAL;
if (panel->new_line)
{
x_choice = (Panel_item) xv_create(x_panel, PANEL_CHECK_BOX, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_choice = (Panel_item) xv_create(x_panel, PANEL_CHECK_BOX, PANEL_LAYOUT, label_position, NULL);
xv_set(x_choice,
// PANEL_LABEL_STRING, Title,
PANEL_NOTIFY_PROC, wxCheckBoxProc,
PANEL_CLIENT_DATA, (char *)this,
PANEL_VALUE, 0,
PANEL_CHOICE_STRING, 0, Title,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_choice, XV_X, x, XV_Y, y, NULL);
handle = (char *)x_choice;
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)panel->handle;
panel->GetValidPosition(&x, &y);
windows_id = (int)NewId();
HWND wx_button = CreateWindowEx(0, "BUTTON", Title,
BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
ms_handle = (HANDLE)wx_button;
SetSize(x, y, width, height);
panel->AdvanceCursor(this);
ShowWindow(wx_button, SW_SHOW);
#endif
if (panel) panel->AddChild(this);
Callback(func);
}
wxCheckBox::~wxCheckBox(void)
{
}
void wxCheckBox::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
wxItem::SetSize(x, y, width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
if (x > -1)
(void)xv_set(x_win, XV_X, x, NULL);
if (y > -1)
(void)xv_set(x_win, XV_Y, y, NULL);
if (width > 0)
(void)xv_set(x_win, XV_WIDTH, width, NULL);
if (height > 0)
(void)xv_set(x_win, XV_HEIGHT, height, NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
float current_width;
int cx;
int cy;
float cyf;
HWND button = (HWND)ms_handle;
wxGetCharSize(button, &cx, &cy);
if (width < 0)
{
GetWindowText(button, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(button, x, y, (int)(current_width + 3*cx), (int)cyf, TRUE);
}
else
MoveWindow(button, x, y, width, height, TRUE);
OnSize(width, height);
#endif
}
void wxCheckBox::SetValue(Bool val)
{
#ifdef wx_motif
Widget buttonWidget = (Widget)handle;
XmToggleButtonSetState(buttonWidget, val, TRUE);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
int the_val = 0;
if (val)
the_val = 1;
xv_set(item, PANEL_VALUE, the_val, NULL);
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, BM_SETCHECK, val, 0);
#endif
}
Bool wxCheckBox::GetValue(void)
{
#ifdef wx_motif
Widget buttonWidget = (Widget)handle;
return XmToggleButtonGetState(buttonWidget);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return (Bool)xv_get(item, PANEL_VALUE);
#endif
#ifdef wx_msw
return (Bool)(0x003 & SendMessage((HWND)ms_handle, BM_GETSTATE, 0, 0));
#endif
}
#ifdef wx_xview
void wxCheckBoxProc(Panel_item item, int value, Event *x_event)
{
wxCheckBox *choice = (wxCheckBox *)xv_get(item, PANEL_CLIENT_DATA);
char *label = (char *) xv_get(item, PANEL_LABEL_STRING);
wxEvent event(x_event);
event.string = label;
event.index = value;
if (choice->callback)
{
(void)(*(choice->callback))(*choice, event);
}
}
#endif
#ifdef wx_motif
void wxChoiceButtonCallback(Widget menu_item, XtPointer clientData, XButtonPressedEvent *event)
{
if (event->button != 1)
return;
wxChoice *item = (wxChoice *)clientData;
XmMenuPosition(item->menuWidget, event);
XtManageChild(item->menuWidget);
}
void wxChoiceCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxChoice *item = (wxChoice *)clientData;
if (item)
{
XtUnmanageChild(item->menuWidget);
char *s = NULL;
XtVaGetValues(w, XmNuserData, &s, NULL);
if (s)
{
XmString text = XmStringCreateSimple(s);
XtVaSetValues(item->messageWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
}
}
}
#endif
wxChoice::wxChoice(wxPanel *panel, wxFunction func, char *Title,
int x, int y, int width, int height, int N, char **Choices)
{
window_parent = panel;
labelPosition = panel->label_position;
no_strings = N;
#ifdef wx_motif
// char mnem = wxFindMnemonic(Title);
wxStripMenuCodes(Title, wxBuffer);
Widget panelForm = panel->panelWidget;
formWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, panelForm,
XmNorientation, panel->label_position == wxHORIZONTAL ? XmHORIZONTAL: XmVERTICAL,
NULL);
XmString text = XmStringCreateSimple(Title);
/*
* Create the label
*
*/
labelWidget = XtVaCreateManagedWidget("choice",
xmLabelWidgetClass, formWidget,
XmNlabelString, text,
NULL);
/*
* Create row widget for selection and button
*
*/
rowWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, formWidget,
XmNorientation, XmHORIZONTAL,
NULL);
/*
* Create label widget for the selection
*/
messageWidget = XtVaCreateManagedWidget("selection", xmLabelWidgetClass, rowWidget, NULL);
XtManageChild(messageWidget);
/*
* Create button
*/
buttonWidget = XtVaCreateManagedWidget("button",
xmArrowButtonWidgetClass, rowWidget,
XmNarrowDirection, XmARROW_RIGHT,
XmNwidth, 20,
XmNheight, 20,
NULL);
handle = (char *)buttonWidget;
XtAddEventHandler(buttonWidget, ButtonPressMask, False, wxChoiceButtonCallback, this);
XtManageChild(buttonWidget);
/*
* Create the popup menu
*/
menuWidget = XmCreatePopupMenu(panelForm, "popup", NULL, 0);
XmStringFree(text);
XtManageChild(rowWidget);
AttachWidget(panel, formWidget, x, y, width, height);
no_strings = 0;
if (N > 0)
for (int i = 0; i < N; i++)
Append(Choices[i]);
#endif
#ifdef wx_xview
char *title = NULL;
if (Title)
title = Title;
Panel x_panel = (Panel)panel->GetHandle();
Panel_item x_choice;
int label_position;
if (panel->label_position == wxVERTICAL)
label_position = PANEL_VERTICAL;
else
label_position = PANEL_HORIZONTAL;
if (panel->new_line)
{
x_choice = (Panel_item) xv_create(x_panel, PANEL_CHOICE_STACK, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_choice = (Panel_item) xv_create(x_panel, PANEL_CHOICE_STACK, PANEL_LAYOUT, label_position,NULL);
xv_set(x_choice,
PANEL_LABEL_STRING, title,
PANEL_NOTIFY_PROC, wxChoiceProc,
PANEL_CLIENT_DATA, (char *)this,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_choice, XV_X, x, XV_Y, y, NULL);
for (int i = 0; i < N; i ++)
{ char *label = Choices[i];
xv_set(x_choice, PANEL_CHOICE_STRING, i, label, NULL);
}
handle = (char *)x_choice;
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
panel->GetValidPosition(&x, &y);
if (Title)
{
static_label = CreateWindowEx(0, "STATIC", Title,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
}
else
static_label = NULL;
windows_id = (int)NewId();
HWND wx_combo = CreateWindowEx(0, "COMBOBOX", NULL,
WS_CHILD | CBS_DROPDOWNLIST | WS_HSCROLL | WS_VSCROLL
| WS_BORDER | WS_TABSTOP | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
for (int i = 0; i < N; i++)
SendMessage(wx_combo, CB_INSERTSTRING, i, (LONG)Choices[i]);
SendMessage(wx_combo, CB_SETCURSEL, i, 0);
ms_handle = (HANDLE)wx_combo;
SetSize(x, y, width, height);
panel->AdvanceCursor(this);
#endif
if (panel) panel->AddChild(this);
Callback(func);
}
wxChoice::~wxChoice(void)
{
#ifdef wx_motif
XtDestroyWidget(menuWidget);
XtDestroyWidget(rowWidget);
XtDestroyWidget(messageWidget);
#endif
#ifdef wx_msw
if (static_label)
DestroyWindow(static_label);
static_label = NULL;
#endif
}
void wxChoice::Append(char *Item)
{
#ifdef wx_motif
wxStripMenuCodes(Item, wxBuffer);
Widget w = XtVaCreateManagedWidget(wxBuffer,
xmPushButtonWidgetClass, menuWidget, NULL);
char mnem = wxFindMnemonic(Item);
if (mnem != 0)
XtVaSetValues(w, XmNmnemonic, mnem, NULL);
XtAddCallback(w, XmNactivateCallback, wxChoiceCallback, (XtPointer)this);
if (no_strings == 0)
{
XmString text = XmStringCreateSimple(Item);
XtVaSetValues(messageWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
}
wxNode *node = stringList.Add(Item);
XtVaSetValues(w, XmNuserData, node->Data(), NULL);
#endif
#ifdef wx_xview
Panel_item choice_item = (Panel_item)handle;
xv_set(choice_item, PANEL_CHOICE_STRING, no_strings, Item, NULL);
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, CB_ADDSTRING, 0, (LONG)Item);
#endif
no_strings ++;
}
// Unfortunately, under XView it doesn't redisplay until user resizes
// window. Any suggestions folks?
void wxChoice::Clear(void)
{
#ifdef wx_motif
stringList.Clear();
XmString text = XmStringCreateSimple("");
XtVaSetValues(messageWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
XtDestroyWidget(menuWidget);
wxPanel *panel = (wxPanel *)GetParent();
Widget panelForm = panel->panelWidget;
menuWidget = XmCreatePopupMenu(panelForm, "popup", NULL, 0);
#endif
#ifdef wx_xview
Panel_item choice_item = (Panel_item)handle;
Rect *rect = (Rect *)xv_get(choice_item, XV_RECT);
int height = rect->r_height;
int width = rect->r_width;
int x = (int)xv_get(choice_item, XV_X);
int y = (int)xv_get(choice_item, XV_Y);
char *label = GetLabel();
xv_destroy_safe(choice_item);
Panel panel = (Panel)GetParent()->handle;
choice_item = (Panel_item) xv_create(panel, PANEL_CHOICE_STACK,
PANEL_LABEL_STRING, label,
PANEL_NOTIFY_PROC, wxChoiceProc,
PANEL_CLIENT_DATA, (char *)this,
XV_X, x, XV_Y, y, XV_WIDTH, width, XV_HEIGHT, height,
XV_SHOW, TRUE,
NULL);
handle = (char *)choice_item;
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, CB_RESETCONTENT, 0, 0);
#endif
no_strings = 0;
}
int wxChoice::GetSelection(void)
{
#ifdef wx_motif
XmString text;
char *s;
XtVaGetValues(messageWidget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
int i = 0;
wxNode *node = stringList.First();
while (node)
{
char *s1 = (char *)node->Data();
if (strcmp(s1, s) == 0)
{
XtFree(s);
return i;
}
else
{
i ++;
node = node->Next();
}
}
XtFree(s);
return -1;
}
else
{
return -1;
}
#endif
#ifdef wx_xview
Panel_item x_choice = (Panel_item)handle;
return xv_get(x_choice, PANEL_VALUE);
#endif
#ifdef wx_msw
return (int)SendMessage((HWND)ms_handle, CB_GETCURSEL, 0, 0);
#endif
}
void wxChoice::SetSelection(int n)
{
#ifdef wx_motif
wxNode *node = stringList.Nth(n);
if (node)
{
char *s = (char *)node->Data();
XmString text = XmStringCreateSimple(s);
XtVaSetValues(messageWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
}
#endif
#ifdef wx_xview
Panel_item x_choice = (Panel_item)handle;
(void)xv_set(x_choice, PANEL_VALUE, n, NULL);
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, CB_SETCURSEL, n, 0);
#endif
}
char *wxChoice::GetStringSelection(void)
{
int sel = GetSelection();
if (sel > -1)
return this->String(sel);
else
return NULL;
}
Bool wxChoice::SetStringSelection(char *s)
{
int sel = FindString(s);
if (sel > -1)
{
SetSelection(sel);
return TRUE;
}
else return FALSE;
}
int wxChoice::FindString(char *s)
{
#ifdef wx_motif
int i = 0;
wxNode *node = stringList.First();
while (node)
{
char *s1 = (char *)node->Data();
if (strcmp(s1, s) == 0)
{
return i;
}
else
{
i ++;
node = node->Next();
}
}
return -1;
#endif
#ifdef wx_xview
Panel_item choice = (Panel_item)handle;
int max1 = no_strings;
int i = 0;
int found = -1;
while (found == -1 && i < max1)
{
char *label = (char *)xv_get(choice, PANEL_CHOICE_STRING, i);
if (label && strcmp(label, s) == 0)
found = i;
else i ++;
}
return found;
#endif
#ifdef wx_msw
int pos = (int)SendMessage((HWND)ms_handle, CB_FINDSTRING, -1, (LONG)s);
if (pos == LB_ERR)
return -1;
else
return pos;
#endif
}
char *wxChoice::String(int n)
{
#ifdef wx_motif
wxNode *node = stringList.Nth(n);
if (node)
return (char *)node->Data();
else return NULL;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return (char *)xv_get(item, PANEL_CHOICE_STRING, n);
#endif
#ifdef wx_msw
int len = (int)SendMessage((HWND)ms_handle, CB_GETLBTEXT, n, (long)wxBuffer);
wxBuffer[len] = 0;
return wxBuffer;
#endif
}
void wxChoice::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
wxItem::SetSize(x, y, width, height);
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
if (x > -1)
xv_set(list_item, XV_X, x, NULL);
if (y > -1)
xv_set(list_item, XV_Y, y, NULL);
if (width > 0)
xv_set(list_item, XV_WIDTH, width, NULL);
if (height > 0)
xv_set(list_item, XV_HEIGHT, height, NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
int y_offset = y;
int x_offset = x;
float current_width;
int cx;
int cy;
float cyf;
HWND wnd = (HWND)ms_handle;
wxGetCharSize(wnd, &cx, &cy);
if (static_label)
{
GetWindowText(static_label, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(static_label, x_offset, y_offset, (int)(current_width + cx), (int)cyf,
TRUE);
if (labelPosition == wxVERTICAL)
y_offset += cy;
else
x_offset += (int)(current_width + cx);
}
if (width <= 0)
{
// Find the longest string
if (no_strings == 0)
width = 100;
else
{
float len, ht;
float longest = 0.0;
int i;
for (i = 0; i < no_strings; i++)
{
char *s = String(i);
GetTextExtent(s, &len, &ht);
if ( len > longest) longest = len;
}
width = (int)(longest + cx*5);
}
}
// Choice drop-down list depends on number of items (limited to 10)
if (height <= 0)
{
if (no_strings == 0)
height = cy*10;
else height = (int)(cy*(min(10, no_strings) + 2));
}
MoveWindow(wnd, x_offset, y_offset, width, height, TRUE);
OnSize(width, height);
#endif
}
void wxChoice::GetSize(int *width, int *height)
{
#ifdef wx_motif
wxItem::GetSize(width, height);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
Rect *rect = (Rect *)xv_get(item, XV_RECT);
*height = rect->r_height;
*width = rect->r_width;
#endif
#ifdef wx_msw
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
{
wxFindMaxSize(static_label, &rect);
}
*width = rect.right - rect.left;
*height = rect.bottom - rect.top;
#endif
}
void wxChoice::GetPosition(int *x, int *y)
{
#ifdef wx_motif
wxItem::GetPosition(x, y);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*x = (int)xv_get(x_win, XV_X);
*y = (int)xv_get(x_win, XV_Y);
#endif
#ifdef wx_msw
HWND wnd = (HWND)ms_handle;
wxWindow *parent = GetParent();
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize(wnd, &rect);
if (static_label)
wxFindMaxSize(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
*x = point.x;
*y = point.y;
#endif
}
char *wxChoice::GetLabel(void)
{
#ifdef wx_motif
XmString text;
char *s;
XtVaGetValues(labelWidget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
// XmStringFree(text);
char *val = copystring(s);
XtFree(s);
return val;
}
else
{
// XmStringFree(text);
return NULL;
}
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
#endif
#ifdef wx_msw
char buf[300];
if (static_label)
{
GetWindowText(static_label, buf, 300);
return copystring(buf);
}
else return NULL;
#endif
}
void wxChoice::SetLabel(char *label)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
XmString text = XmStringCreateSimple(label);
XtVaSetValues(widget,
XmNlabelString, text,
NULL);
XmStringFree(text);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_LABEL_STRING, label, NULL);
#endif
#ifdef wx_msw
if (static_label)
{
float w, h;
RECT rect;
wxWindow *parent = GetParent();
GetWindowRect(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
GetTextExtent(label, &w, &h);
MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
TRUE);
SetWindowText(static_label, label);
}
#endif
}
#ifdef wx_msw
BOOL wxChoice::Command(UINT param)
{
wxFunction fun = callback;
if (fun && (param == CBN_SELCHANGE))
{
wxEvent event;
event.string = String(GetSelection());
(void)(*(fun))(*this, event);
return TRUE;
}
else return FALSE;
}
#endif
#ifdef wx_xview
void wxChoiceProc(Panel_item item, int value, Event *x_event)
{
wxChoice *choice = (wxChoice *)xv_get(item, PANEL_CLIENT_DATA);
char *label = (char *) xv_get(item, PANEL_CHOICE_STRING, value);
wxEvent event(x_event);
event.string = label;
event.index = value;
if (choice->callback)
{
(void)(*(choice->callback))(*choice, event);
}
}
#endif
#ifdef wx_motif
void wxListBoxCallback(Widget w, XtPointer clientData,
XmListCallbackStruct *cbs)
{
/*
if (cbs->reason == XmCR_EXTENDED_SELECT)
cout << "*** Extend select\n";
else if (cbs->reason == XmCR_SINGLE_SELECT)
cout << "*** Single select\n";
else if (cbs->reason == XmCR_MULTIPLE_SELECT)
cout << "*** Multiple select\n";
else if (cbs->reason == XmCR_BROWSE_SELECT)
cout << "*** Browse select\n";
if (cbs->selection_type == XmMODIFICATION)
cout << "*** Modification\n";
else if (cbs->selection_type == XmINITIAL)
cout << "*** Initial\n";
else if (cbs->selection_type == XmADDITION)
cout << "*** Addition\n";
*/
int n;
XtVaGetValues(w, XmNselectedItemCount, &n, NULL);
if (n == 0)
return;
wxListBox *item = (wxListBox *)clientData;
wxFunction fun = item->callback;
if (fun)
{
wxEvent event;
event.client_data = item->GetClientData(cbs->item_position - 1);
if (!item->multiple)
event.string = item->GetStringSelection();
(void)(*(fun))(*item, event);
}
}
#endif
// Listbox item
wxListBox::wxListBox(wxPanel *panel, wxFunction func,
char *Title, Bool Multiple,
int x, int y, int width, int height,
int N, char **Choices)
#ifdef wx_motif
:clientDataList(wxKEY_INTEGER)
#endif
{
selected = -1;
selections = 0;
multiple = Multiple;
window_parent = panel;
no_items = 0;
labelPosition = panel->label_position;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
formWidget = XtVaCreateManagedWidget("form",
xmFormWidgetClass, panelForm,
NULL);
XmString text = XmStringCreateSimple(Title);
Widget listWidget;
Arg args[2];
XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
if (Multiple)
XtSetArg(args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
else XtSetArg(args[1], XmNselectionPolicy, XmSINGLE_SELECT);
labelWidget = XtVaCreateManagedWidget(Title,
xmLabelWidgetClass, formWidget,
XmNlabelString, text,
NULL);
listWidget = XmCreateScrolledList(formWidget, "list", args, 2);
handle = (char *)listWidget;
if (panel->label_position == wxHORIZONTAL)
{
XtVaSetValues(labelWidget,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XtVaSetValues(XtParent(listWidget),
XmNleftOffset, 4,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, labelWidget,
NULL);
}
else
{
XtVaSetValues(labelWidget,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XtVaSetValues(XtParent(listWidget),
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, labelWidget,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
NULL);
}
XmStringFree(text);
XtManageChild(listWidget);
if (width == -1)
width = 150;
if (height == -1)
height = 80;
XtAddCallback(listWidget, XmNsingleSelectionCallback, wxListBoxCallback,
this);
XtAddCallback(listWidget, XmNextendedSelectionCallback, wxListBoxCallback,
this);
AttachWidget(panel, formWidget, x, y, width, height);
if (N > 0)
for (int i = 0; i < N; i++)
Append(Choices[i]);
#endif
#ifdef wx_xview
char *title = NULL;
int choose_one = !Multiple;
Panel x_panel = (Panel)panel->GetHandle();
Panel_item x_list;
int label_position;
if (panel->label_position == wxVERTICAL)
label_position = PANEL_VERTICAL;
else
label_position = PANEL_HORIZONTAL;
if (panel->new_line)
{
x_list = (Panel_item) xv_create(x_panel, PANEL_LIST, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_list = (Panel_item) xv_create(x_panel, PANEL_LIST, PANEL_LAYOUT, label_position, NULL);
xv_set(x_list,
PANEL_CHOOSE_ONE, choose_one,
PANEL_NOTIFY_PROC, wxListProc,
PANEL_CLIENT_DATA, (char *)this,
PANEL_ITEM_MENU, NULL,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_list, XV_X, x, XV_Y, y, NULL);
handle = (char *)x_list;
SetSize(x, y, width, height);
if (Title)
{ title = Title;
xv_set(x_list, PANEL_LABEL_STRING, title, NULL);
}
if (N > 0)
Set(N, Choices);
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
panel->GetValidPosition(&x, &y);
// If label exists, create a static control for it.
if (Title)
{
static_label = CreateWindowEx(0, "STATIC", Title,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
}
else
static_label = NULL;
DWORD style;
if (Multiple == wxMULTIPLE)
style = WS_VSCROLL | WS_BORDER | LBS_MULTIPLESEL | LBS_NOTIFY | WS_TABSTOP;
else
style = WS_VSCROLL | WS_BORDER | LBS_NOTIFY | WS_TABSTOP;
windows_id = (int)NewId();
HWND wx_list = CreateWindowEx(0, "LISTBOX", NULL,
style | WS_CHILD,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
for (int i = 0; i < N; i++)
SendMessage(wx_list, LB_ADDSTRING, 0, (LONG)Choices[i]);
if (!Multiple)
SendMessage(wx_list, LB_SETCURSEL, 0, 0);
ShowWindow(wx_list, SW_SHOW);
no_items = N;
ms_handle = (HANDLE)wx_list;
SetSize(x, y, width, height);
panel->AdvanceCursor(this);
#endif
if (panel) panel->AddChild(this);
Callback(func);
}
wxListBox::~wxListBox(void)
{
if (selections)
delete selections;
#ifdef wx_msw
if (static_label)
DestroyWindow(static_label);
static_label = NULL;
#endif
}
#ifdef wx_msw
BOOL wxListBox::Command(UINT param)
{
wxFunction fun = callback;
if (fun && (param == LBN_SELCHANGE))
{
HWND listbox = (HWND)ms_handle;
wxEvent event;
if (multiple == wxSINGLE)
{
int sel = (int)SendMessage(listbox, LB_GETCURSEL, 0, 0);
int len = (int)SendMessage(listbox, LB_GETTEXT, sel, (LONG)wxBuffer);
wxBuffer[len] = 0;
event.string = wxBuffer;
event.index = sel;
event.client_data = (char *)SendMessage(listbox, LB_GETITEMDATA, 0, 0);
}
else event.string = NULL;
(void)(*(fun))(*this, event);
return TRUE;
}
else return FALSE;
}
#endif
int wxListBox::Number(void)
{
return no_items;
}
void wxListBox::Delete(int N)
{
#ifdef wx_motif
XmListDeletePos((Widget)handle, N + 1);
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
xv_set(list_item, PANEL_LIST_DELETE, N, NULL);
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, LB_DELETESTRING, N, 0);
#endif
no_items --;
}
void wxListBox::Append(char *Item)
{
#ifdef wx_motif
Widget listBox = (Widget)handle;
int n;
XtVaGetValues(listBox, XmNitemCount, &n, NULL);
XmString text = XmStringCreateSimple(Item);
XmListAddItem(listBox, text, n + 1);
XmStringFree(text);
#endif
#ifdef wx_xview
char *label = Item;
Panel_item list_item = (Panel_item)handle;
int n = (int)xv_get(list_item, PANEL_LIST_NROWS);
xv_set(list_item, PANEL_LIST_INSERT, n,
PANEL_LIST_STRING, n, label,
PANEL_LIST_CLIENT_DATA, n, n,
NULL);
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, LB_ADDSTRING, 0, (LONG)Item);
#endif
no_items ++;
}
void wxListBox::Append(char *Item, char *Client_data)
{
#ifdef wx_motif
Widget listBox = (Widget)handle;
int n;
XtVaGetValues(listBox, XmNitemCount, &n, NULL);
XmString text = XmStringCreateSimple(Item);
XmListAddItem(listBox, text, n + 1);
XmStringFree(text);
clientDataList.Append((long)n, (wxObject *)Client_data);
#endif
#ifdef wx_xview
char *label = Item;
Panel_item list_item = (Panel_item)handle;
int n = (int)xv_get(list_item, PANEL_LIST_NROWS);
xv_set(list_item, PANEL_LIST_INSERT, n,
PANEL_LIST_STRING, n, label,
PANEL_LIST_CLIENT_DATA, n, Client_data,
NULL);
#endif
#ifdef wx_msw
int index = (int)SendMessage((HWND)ms_handle, LB_ADDSTRING, 0, (LONG)Item);
SendMessage((HWND)ms_handle, LB_SETITEMDATA, index, (LONG)Client_data);
#endif
no_items ++;
}
void wxListBox::Set(int n, char *choices[])
{
#ifdef wx_motif
for (int i = 0; i < n; i++)
Append(choices[i]);
#endif
#ifdef wx_xview
Panel_item list = (Panel_item)handle;
if (selections)
{ delete selections; selections = NULL; }
int max1 = (int)xv_get(list, PANEL_LIST_NROWS);
xv_set(list, PANEL_LIST_DELETE_ROWS, 0, max1, NULL);
int i;
for (i = 0; i < n; i++)
{
char *label = choices[i];
xv_set(list, PANEL_LIST_INSERT, i,
PANEL_LIST_STRING, i, label,
PANEL_LIST_CLIENT_DATA, i, i,
NULL);
}
#endif
#ifdef wx_msw
ShowWindow((HWND)ms_handle, SW_HIDE);
for (int i = 0; i < n; i++)
SendMessage((HWND)ms_handle, LB_ADDSTRING, 0, (LONG)choices[i]);
ShowWindow((HWND)ms_handle, SW_SHOW);
#endif
no_items = n;
}
int wxListBox::FindString(char *s)
{
#ifdef wx_motif
XmString str = XmStringCreateSimple(s);
int *positions;
int no_positions;
XmListGetMatchPos((Widget)handle, str, &positions, &no_positions);
XmStringFree(str);
if (no_positions == 0)
return -1;
else
return positions[0] - 1;
#endif
#ifdef wx_xview
Panel_item list = (Panel_item)handle;
int max1 = (int)xv_get(list, PANEL_LIST_NROWS);
int i = 0;
int found = -1;
while (found == -1 && i < max1)
{
char *label = (char *)xv_get(list, PANEL_LIST_STRING, i);
if (label && strcmp(label, s) == 0)
found = i;
else i ++;
}
return found;
#endif
#ifdef wx_msw
int pos = (int)SendMessage((HWND)ms_handle, LB_FINDSTRING, -1, (LONG)s);
if (pos == LB_ERR)
return -1;
else
return pos;
#endif
}
void wxListBox::Clear(void)
{
#ifdef wx_motif
XmListDeleteAllItems((Widget)handle);
clientDataList.Clear();
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
xv_set(list_item, PANEL_LIST_DELETE_ROWS, 0, no_items, NULL);
#endif
#ifdef wx_msw
SendMessage((HWND)ms_handle, LB_RESETCONTENT, 0, 0);
#endif
no_items = 0;
}
void wxListBox::SetSelection(int N)
{
#ifdef wx_motif
XmListSelectPos((Widget)handle, N + 1, TRUE);
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
xv_set(list_item, PANEL_LIST_SELECT, N, TRUE, NULL);
#endif
#ifdef wx_msw
if (multiple == wxMULTIPLE)
SendMessage((HWND)ms_handle, LB_SETSEL, TRUE, N);
else
SendMessage((HWND)ms_handle, LB_SETCURSEL, N, 0);
#endif
}
void wxListBox::Deselect(int N)
{
#ifdef wx_motif
XmListDeselectPos((Widget)handle, N + 1);
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
xv_set(list_item, PANEL_LIST_SELECT, N, FALSE, NULL);
#endif
#ifdef wx_msw
if (multiple == wxMULTIPLE)
SendMessage((HWND)ms_handle, LB_SETSEL, FALSE, N);
else
SendMessage((HWND)ms_handle, LB_SETCURSEL, -N, 0);
#endif
}
char *wxListBox::GetClientData(int N)
{
#ifdef wx_motif
wxNode *node = clientDataList.Find((long)N);
if (node)
return (char *)node->Data();
else return NULL;
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
char *data = (char *)xv_get(list_item, PANEL_LIST_CLIENT_DATA, N);
return data;
#endif
#ifdef wx_msw
return (char *)SendMessage((HWND)ms_handle, LB_GETITEMDATA, N, 0);
#endif
}
// Return number of selections and an array of selected integers
// Use selections field to store data, which will be cleaned up
// by destructor if necessary.
int wxListBox::GetSelections(int **list_selections)
{
#ifdef wx_motif
Widget listBox = (Widget)handle;
int *posList;
int posCnt;
Bool flag = XmListGetSelectedPos(listBox, &posList, &posCnt);
if (flag)
{
if (posCnt > 0)
{
if (selections)
delete selections;
selections = new int[posCnt];
for (int i = 0; i < posCnt; i++)
selections[i] = posList[i] - 1;
XtFree(posList);
return posCnt;
}
else return FALSE;
}
else return FALSE;
#endif
#ifdef wx_xview
Panel_item x_list = (Panel_item)handle;
int i = 0;
int j = 0;
if (selections)
{ delete selections; selections = NULL; }
for (j = 0 ; j < no_items; j++)
if (xv_get(x_list, PANEL_LIST_SELECTED, j))
{ i ++; }
if (i > 0)
{
selections = new int[i];
int k = 0;
for (j = 0; j < no_items; j++)
if (xv_get(x_list, PANEL_LIST_SELECTED, j))
{ selections[k] = j; k ++; }
}
*list_selections = selections;
return i;
#endif
#ifdef wx_msw
HWND listbox = (HWND)ms_handle;
if (selections)
{ delete selections; selections = NULL; };
if (multiple == wxSINGLE)
{
int sel = (int)SendMessage(listbox, LB_GETCURSEL, 0, 0);
if (sel == LB_ERR)
return 0;
selections = new int[1];
selections[0] = sel;
*list_selections = selections;
return 1;
}
else
{
int no_sel = (int)SendMessage(listbox, LB_GETSELCOUNT, 0, 0);
if (no_sel == 0)
return 0;
selections = new int[no_sel];
SendMessage(listbox, LB_GETSELITEMS, no_sel, (LONG)selections);
*list_selections = selections;
return no_sel;
}
#endif
}
// Get single selection, for single choice list items
int wxListBox::GetSelection(void)
{
#ifdef wx_motif
Widget listBox = (Widget)handle;
int *posList;
int posCnt;
Bool flag = XmListGetSelectedPos(listBox, &posList, &posCnt);
if (flag)
{
int id = -1;
if (posCnt > 0)
id = posList[0] - 1;
XtFree(posList);
return id;
}
else return -1;
#endif
#ifdef wx_xview
Panel_item x_list = (Panel_item)handle;
int i = 0;
if (selections)
{ delete selections; selections = NULL; }
int found = -1;
while (found == -1 && i < no_items)
{
if (xv_get(x_list, PANEL_LIST_SELECTED, i))
found = i;
else
i ++;
}
return found;
#endif
#ifdef wx_msw
HWND listbox = (HWND)ms_handle;
if (selections)
{ delete selections; selections = NULL; };
if (multiple == wxSINGLE)
{
int sel = (int)SendMessage(listbox, LB_GETCURSEL, 0, 0);
if (sel == LB_ERR)
return -1;
else
{
return sel;
}
}
else return -1;
#endif
}
// Find string for position
char *wxListBox::String(int N)
{
#ifdef wx_motif
Widget listBox = (Widget)handle;
XmString *strlist;
int n;
XtVaGetValues(listBox, XmNitemCount, &n, XmNitems, &strlist, NULL);
if (N <= n)
{
char *txt;
if (XmStringGetLtoR(strlist[N], "", &txt))
{
strcpy(wxBuffer, txt);
XtFree(txt);
return wxBuffer;
}
else return NULL;
}
else return NULL;
#endif
#ifdef wx_xview
Panel_item x_list = (Panel_item)handle;
return (char *)xv_get(x_list, PANEL_LIST_STRING, N);
#endif
#ifdef wx_msw
int len = (int)SendMessage((HWND)ms_handle, LB_GETTEXT, N, (LONG)wxBuffer);
wxBuffer[len] = 0;
return wxBuffer;
#endif
}
// For single selection items only
char *wxListBox::GetStringSelection(void)
{
int sel = GetSelection();
if (sel > -1)
return this->String(sel);
else
return NULL;
}
Bool wxListBox::SetStringSelection(char *s)
{
int sel = FindString(s);
if (sel > -1)
{
SetSelection(sel);
return TRUE;
}
else return FALSE;
}
void wxListBox::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
if (x > -1)
XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF,
XmNx, x, NULL);
if (y > -1)
XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF,
XmNy, y, NULL);
// Must set the actual listbox to be desired size MINUS label size
Dimension labelWidth, labelHeight, actualWidth, actualHeight;
XtVaGetValues(labelWidget, XmNwidth, &labelWidth, XmNheight, &labelHeight, NULL);
if (itemOrientation == wxHORIZONTAL)
{
actualWidth = width - labelWidth;
actualHeight = height;
}
else
{
actualWidth = width;
actualHeight = height - labelHeight;
}
if (width > -1)
{
XtVaSetValues(XtParent(widget), XmNwidth, actualWidth, NULL);
}
if (height > -1)
{
XtVaSetValues(XtParent(widget), XmNheight, actualHeight, NULL);
}
OnSize(width, height);
#endif
#ifdef wx_xview
Panel_item list_item = (Panel_item)handle;
int row_height = (int)xv_get(list_item, PANEL_LIST_ROW_HEIGHT);
if (x > -1)
xv_set(list_item, XV_X, x, NULL);
if (y > -1)
xv_set(list_item, XV_Y, y, NULL);
if (width > -1)
xv_set(list_item,
PANEL_LIST_WIDTH, width, NULL);
else
xv_set(list_item,
PANEL_LIST_WIDTH, 0, NULL);
if (height > -1)
xv_set(list_item,
PANEL_LIST_DISPLAY_ROWS, (int)((height/row_height)-2),
NULL);
else
xv_set(list_item,
PANEL_LIST_DISPLAY_ROWS, 5,
NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
int y_offset = y;
int x_offset = x;
float current_width;
int cx;
int cy;
float cyf;
HWND wnd = (HWND)ms_handle;
wxGetCharSize(wnd, &cx, &cy);
if (static_label)
{
GetWindowText(static_label, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(static_label, x, y_offset, (int)(current_width + cx), (int)cyf,
TRUE);
if (labelPosition == wxVERTICAL)
y_offset += cy;
else
x_offset += (int)(current_width + cx);
}
if (width < 0)
width = 150;
if (height < 0)
height = 80;
height -= cy;
MoveWindow((HWND)ms_handle, x_offset, y_offset, width, height, TRUE);
OnSize(width, height);
#endif
}
void wxListBox::GetSize(int *width, int *height)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
Dimension xx, yy;
XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
*width = xx; *height = yy;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
Rect *rect = (Rect *)xv_get(item, XV_RECT);
*height = rect->r_height;
*width = rect->r_width;
#endif
#ifdef wx_msw
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
{
wxFindMaxSize(static_label, &rect);
}
*width = rect.right - rect.left;
*height = rect.bottom - rect.top;
#endif
}
void wxListBox::GetPosition(int *x, int *y)
{
#ifdef wx_motif
Dimension xx, yy;
XtVaGetValues(formWidget, XmNx, &xx, XmNy, &yy, NULL);
*x = xx; *y = yy;
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*x = (int)xv_get(x_win, XV_X);
*y = (int)xv_get(x_win, XV_Y);
#endif
#ifdef wx_msw
wxWindow *parent = GetParent();
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
wxFindMaxSize(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
*x = point.x;
*y = point.y;
#endif
}
char *wxListBox::GetLabel(void)
{
#ifdef wx_motif
XmString text;
char *s;
XtVaGetValues(labelWidget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
// XmStringFree(text);
char *val = copystring(s);
XtFree(s);
return val;
}
else
{
// XmStringFree(text);
return NULL;
}
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
#endif
#ifdef wx_msw
char buf[300];
if (static_label)
{
GetWindowText(static_label, buf, 300);
return copystring(buf);
}
else return NULL;
#endif
}
void wxListBox::SetLabel(char *label)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
XmString text = XmStringCreateSimple(label);
XtVaSetValues(widget,
XmNlabelString, text,
NULL);
XmStringFree(text);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_LABEL_STRING, label, NULL);
#endif
#ifdef wx_msw
if (static_label)
{
float w, h;
RECT rect;
wxWindow *parent = GetParent();
GetWindowRect(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
GetTextExtent((LPSTR)label, &w, &h);
MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
TRUE);
SetWindowText(static_label, label);
}
#endif
}
#ifdef wx_xview
int wxListProc(Panel_item item, char *string, Xv_opaque client_data,
Panel_list_op op, Event *x_event, int row)
{
// if (op == PANEL_LIST_OP_SELECT || op == PANEL_LIST_OP_DESELECT)
if (op == PANEL_LIST_OP_SELECT)
{
wxListBox *list = (wxListBox *)xv_get(item, PANEL_CLIENT_DATA);
wxEvent event(x_event);
event.string = string;
event.index = row;
event.client_data = (char *)client_data;
if (list->callback)
{
(void)(*(list->callback))(*list, event);
}
}
return XV_OK;
}
#endif
// Message
wxMessage::wxMessage(wxPanel *panel, char *label, int x, int y)
{
window_parent = panel;
labelPosition = panel->label_position;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
XmString text = XmStringCreateSimple(label);
formWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, panelForm,
NULL);
labelWidget = NULL;
Widget LabelWidget = XtVaCreateManagedWidget("message",
xmLabelWidgetClass, formWidget,
XmNlabelString, text,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
handle = (char *)LabelWidget;
XmStringFree(text);
AttachWidget(panel, formWidget, x, y, -1, -1);
#endif
#ifdef wx_xview
Panel x_panel = (Panel)(panel->GetHandle());
Panel_item x_message;
if (panel->new_line)
{
x_message = (Panel_item) xv_create(x_panel, PANEL_MESSAGE, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_message = (Panel_item) xv_create(x_panel, PANEL_MESSAGE, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
xv_set(x_message,
PANEL_LABEL_STRING, label,
PANEL_CLIENT_DATA, (char *)this,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_message, XV_X, x, XV_Y, y, NULL);
handle = (char *)x_message;
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
HWND static_item = CreateWindowEx(0, "STATIC", label,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
ms_handle = (HANDLE)static_item;
panel->GetValidPosition(&x, &y);
SetSize(x, y, -1, -1);
panel->AdvanceCursor(this);
#endif
if (panel) panel->AddChild(this);
}
wxMessage::~wxMessage(void)
{
}
void wxMessage::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
wxItem::SetSize(x, y, width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
if (x > -1)
(void)xv_set(x_win, XV_X, x, NULL);
if (y > -1)
(void)xv_set(x_win, XV_Y, y, NULL);
if (width > 0)
(void)xv_set(x_win, XV_WIDTH, width, NULL);
if (height > 0)
(void)xv_set(x_win, XV_HEIGHT, height, NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
float current_width;
int cx;
int cy;
float cyf;
wxGetCharSize((HWND)ms_handle, &cx, &cy);
if (width < 0)
{
GetWindowText((HWND)ms_handle, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow((HWND)ms_handle, x, y, (int)(current_width + cx), (int)(cyf), TRUE);
}
else
MoveWindow((HWND)ms_handle, x, y, width, height, TRUE);
OnSize(width, height);
#endif
}
#ifdef wx_xview
Panel_setting wxTextProc(Panel_item item, Event *x_event)
{
wxText *text = (wxText *)xv_get(item, PANEL_CLIENT_DATA);
wxEvent event(x_event);
event.string = (char *)xv_get(item, PANEL_VALUE);
if (text->callback)
{
(void)(*(text->callback))(*text, event);
}
return PANEL_NONE;
}
#endif
#ifdef wx_motif
void wxTextCallback(Widget w, XtPointer clientData,
XtPointer ptr)
{
wxItem *item = (wxItem *)clientData;
wxFunction fun = item->callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*item, event);
}
}
#endif
// Text item
wxText::wxText(void)
{
}
wxText::wxText(wxPanel *panel, wxFunction Function, char *label, char *value,
int x, int y, int width, int height)
{
window_parent = panel;
labelPosition = panel->label_position;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
formWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, panelForm,
XmNorientation, panel->label_position == wxHORIZONTAL ? XmHORIZONTAL: XmVERTICAL,
NULL);
XmString text = XmStringCreateSimple(label);
Widget textWidget;
labelWidget = XtVaCreateManagedWidget(label,
xmLabelWidgetClass, formWidget,
XmNlabelString, text,
NULL);
textWidget = XtVaCreateManagedWidget("text",
xmTextWidgetClass, formWidget,
NULL);
handle = (char *)textWidget;
XmStringFree(text);
XtAddCallback(textWidget, XmNactivateCallback, wxTextCallback,
this);
AttachWidget(panel, formWidget, x, y, width, height);
if (value)
XmTextSetString(textWidget, value);
#endif
#ifdef wx_xview
Panel x_panel = (Panel)(panel->GetHandle());
Panel_item x_text;
int label_position;
if (panel->label_position == wxVERTICAL)
label_position = PANEL_VERTICAL;
else
label_position = PANEL_HORIZONTAL;
if (panel->new_line)
{
x_text = (Panel_item) xv_create(x_panel, PANEL_TEXT,
PANEL_VALUE_DISPLAY_WIDTH, 30,
PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_text = (Panel_item) xv_create(x_panel, PANEL_TEXT,
PANEL_VALUE_DISPLAY_WIDTH, 30,
PANEL_LAYOUT, label_position, NULL);
xv_set(x_text,
PANEL_NOTIFY_PROC, wxTextProc,
PANEL_CLIENT_DATA, (char *)this,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_text, XV_X, x, XV_Y, y, NULL);
if (width <= 0)
width = 80;
xv_set(x_text, PANEL_VALUE_DISPLAY_WIDTH, (int) width, NULL);
if (label)
{ xv_set(x_text, PANEL_LABEL_STRING, label, NULL); };
if (value)
{ xv_set(x_text, PANEL_VALUE, value, NULL); };
handle = (char *)x_text;
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
panel->GetValidPosition(&x, &y);
// If label exists, create a static control for it.
if (label)
{
static_label = CreateWindowEx(0, "STATIC", label,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
}
else
static_label = NULL;
windows_id = (int)NewId();
HWND edit = CreateWindowEx(0, "EDIT", NULL,
ES_AUTOHSCROLL | ES_LEFT | WS_BORDER |
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
ms_handle = (HANDLE)edit;
SetSize(x, y, width, height);
if (value)
SetWindowText(edit, value);
panel->AdvanceCursor(this);
#endif
if (panel) panel->AddChild(this);
Callback(Function);
}
wxText::~wxText(void)
{
#ifdef wx_msw
if (static_label)
DestroyWindow(static_label);
#endif
}
char *wxText::GetLabel(void)
{
#ifdef wx_motif
XmString text;
char *s;
XtVaGetValues(labelWidget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
// XmStringFree(text);
char *val = copystring(s);
XtFree(s);
return val;
}
else
{
// XmStringFree(text);
return NULL;
}
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
#endif
#ifdef wx_msw
char buf[300];
if (static_label)
{
GetWindowText(static_label, buf, 300);
return copystring(buf);
}
else return NULL;
#endif
}
void wxText::SetLabel(char *label)
{
#ifdef wx_motif
XmString text = XmStringCreateSimple(label);
XtVaSetValues(labelWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_LABEL_STRING, label, NULL);
#endif
#ifdef wx_msw
if (static_label)
{
float w, h;
RECT rect;
wxWindow *parent = GetParent();
GetWindowRect(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
GetTextExtent(label, &w, &h);
MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
TRUE);
SetWindowText(static_label, label);
}
#endif
}
char *wxText::GetValue(void)
{
#ifdef wx_motif
char *s = XmTextGetString((Widget)handle);
if (s)
{
strcpy(wxBuffer, s);
XtFree(s);
return copystring(wxBuffer);
}
else return NULL;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_VALUE));
#endif
#ifdef wx_msw
*(LPINT)wxBuffer = 500;
int n = (int)SendMessage((HWND)ms_handle, EM_GETLINE, 0, (LONG)wxBuffer);
wxBuffer[n] = 0;
return copystring(wxBuffer);
#endif
}
void wxText::SetValue(char *value)
{
#ifdef wx_motif
if (value)
XmTextSetString((Widget)handle, value);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_VALUE, value, NULL);
#endif
#ifdef wx_msw
SetWindowText((HWND)ms_handle, value);
#endif
}
void wxText::GetSize(int *width, int *height)
{
#ifdef wx_motif
wxItem::GetSize(width, height);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
Rect *rect = (Rect *)xv_get(item, XV_RECT);
*height = rect->r_height;
*width = rect->r_width;
#endif
#ifdef wx_msw
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
{
wxFindMaxSize(static_label, &rect);
}
*width = rect.right - rect.left;
*height = rect.bottom - rect.top;
#endif
}
void wxText::GetPosition(int *x, int *y)
{
#ifdef wx_motif
wxItem::GetPosition(x, y);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*x = (int)xv_get(x_win, XV_X);
*y = (int)xv_get(x_win, XV_Y);
#endif
#ifdef wx_msw
wxWindow *parent = GetParent();
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
wxFindMaxSize(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
*x = point.x;
*y = point.y;
#endif
}
void wxText::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
if (x > -1)
XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF,
XmNx, x,
NULL);
if (y > -1)
XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF,
XmNy, y,
NULL);
Dimension labelWidth, labelHeight;
int actualWidth, actualHeight;
XtVaGetValues(labelWidget, XmNwidth, &labelWidth, XmNheight, &labelHeight, NULL);
if (itemOrientation == wxHORIZONTAL)
{
actualWidth = width - labelWidth;
actualHeight = height;
}
else
{
actualWidth = width;
actualHeight = height - labelHeight;
}
if (width > -1)
XtVaSetValues((Widget)handle, XmNwidth, width,
NULL);
if (height > -1)
XtVaSetValues((Widget)handle, XmNheight, height,
NULL);
OnSize(width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
if (x > -1)
(void)xv_set(x_win, XV_X, x, NULL);
if (y > -1)
(void)xv_set(x_win, XV_Y, y, NULL);
if (width <= 0)
width = 80;
(void)xv_set(x_win, PANEL_VALUE_DISPLAY_WIDTH, width, NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
int x_offset = x;
int y_offset = y;
float current_width;
int cx;
int cy;
float cyf;
wxGetCharSize((HWND)ms_handle, &cx, &cy);
if (static_label)
{
GetWindowText(static_label, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(static_label, x_offset, y, (int)(current_width + cx), (int)cyf, TRUE);
if (labelPosition == wxVERTICAL)
y_offset += cy;
else
x_offset += (int)(current_width + cx);
}
int text_length = (int)(width - (x_offset - x));
// Text must have a minimum/default length
if (text_length < 0)
text_length = 80;
MoveWindow((HWND)ms_handle, x_offset, y_offset, text_length, (int)(cy*7/4), TRUE);
OnSize(width, height);
#endif
}
void wxText::SetFocus(void)
{
#ifdef wx_motif
#endif
#ifdef wx_xview
wxPanel *panel = (wxPanel *)GetParent();
if (panel)
{
Panel p = (Panel)panel->handle;
xv_set(p, PANEL_CARET_ITEM, (Panel_item)handle, 0);
}
#endif
#ifdef wx_msw
wxItem::SetFocus();
#endif
}
// Multi-line Text item
wxMultiText::wxMultiText(wxPanel *panel, wxFunction Function, char *label, char *value,
int x, int y, int width, int height)
{
window_parent = panel;
labelPosition = panel->label_position;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
formWidget = XtVaCreateManagedWidget("form",
xmFormWidgetClass, panelForm,
NULL);
XmString text = XmStringCreateSimple(label);
Widget textWidget;
labelWidget = XtVaCreateManagedWidget(label,
xmLabelWidgetClass, formWidget,
XmNlabelString, text,
NULL);
textWidget = XmCreateScrolledText(formWidget, "multi_text", NULL, 0);
handle = (char *)textWidget;
XtVaSetValues(textWidget,
XmNeditMode, XmMULTI_LINE_EDIT,
NULL);
XtManageChild(textWidget);
if (panel->label_position == wxHORIZONTAL)
{
XtVaSetValues(labelWidget,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XtVaSetValues(XtParent(textWidget),
XmNleftOffset, 4,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, labelWidget,
NULL);
}
else
{
XtVaSetValues(labelWidget,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XtVaSetValues(XtParent(textWidget),
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, labelWidget,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
}
XmStringFree(text);
XtAddCallback(textWidget, XmNactivateCallback, wxTextCallback,
this);
AttachWidget(panel, formWidget, x, y, width, height);
if (value)
XmTextSetString(textWidget, value);
#endif
#ifdef wx_xview
Panel x_panel = (Panel)(panel->GetHandle());
Panel_item x_text;
int label_position;
if (panel->label_position == wxVERTICAL)
label_position = PANEL_VERTICAL;
else
label_position = PANEL_HORIZONTAL;
if (panel->new_line)
{
x_text = (Panel_item) xv_create(x_panel, PANEL_MULTILINE_TEXT,
PANEL_VALUE_DISPLAY_WIDTH, 120,
PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
panel->new_line = FALSE;
}
else
x_text = (Panel_item) xv_create(x_panel, PANEL_MULTILINE_TEXT,
PANEL_VALUE_DISPLAY_WIDTH, 120,
PANEL_LAYOUT, label_position, NULL);
xv_set(x_text,
PANEL_NOTIFY_PROC, wxTextProc,
PANEL_CLIENT_DATA, (char *)this,
NULL);
if (x > -1 && y > -1)
(void)xv_set(x_text, XV_X, x, XV_Y, y, NULL);
if (width > 0)
{ xv_set(x_text, PANEL_VALUE_DISPLAY_WIDTH, (int) width, NULL); };
Xv_Font font = (Xv_Font)xv_get(x_panel, XV_FONT);
int pixel_height = (int)xv_get(font, FONT_DEFAULT_CHAR_HEIGHT);
if (height > -1)
(void)xv_set(x_text, PANEL_DISPLAY_ROWS, (int)(height/pixel_height), NULL);
if (label)
{ xv_set(x_text, PANEL_LABEL_STRING, label, NULL); };
if (value)
{ xv_set(x_text, PANEL_VALUE, value, NULL); };
handle = (char *)x_text;
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
panel->GetValidPosition(&x, &y);
int x_offset = x;
// If label exists, create a static control for it.
if (label)
{
static_label = CreateWindowEx(0, "STATIC", label,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
}
else
static_label = NULL;
windows_id = (int)NewId();
HWND edit = CreateWindowEx(0, "EDIT", label,
ES_MULTILINE | ES_AUTOHSCROLL | ES_LEFT | ES_WANTRETURN |
WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP |
WS_HSCROLL | WS_VSCROLL,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
ms_handle = (HANDLE)edit;
SetSize(x, y, width, height);
if (value)
SetWindowText(edit, value);
panel->AdvanceCursor(this);
#endif
if (panel) panel->AddChild(this);
Callback(Function);
}
char *wxMultiText::GetValue(void)
{
#ifdef wx_motif
return wxText::GetValue();
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_VALUE));
#endif
#ifdef wx_msw
int buf_len = 1000;
int no_chars = 0;
int no_lines = (int)SendMessage((HWND)ms_handle, EM_GETLINECOUNT, 0, 0L);
for (int i = 0; i < no_lines; i++)
{
*(LPINT)(wxBuffer+no_chars) = buf_len;
int n = (int)SendMessage((HWND)ms_handle, EM_GETLINE, i,
(LONG)(wxBuffer+no_chars));
no_chars += n;
buf_len -= (n + 2);
if (i < (no_lines - 1))
{
wxBuffer[no_chars] = 13;
no_chars ++;
wxBuffer[no_chars] = 10;
no_chars ++;
}
}
wxBuffer[no_chars] = 0;
return copystring(wxBuffer);
#endif
}
void wxMultiText::GetValue(char *buffer, int maxSize)
{
buffer[0] = 0;
#ifdef wx_motif
char *s = XmTextGetString((Widget)handle);
if (s)
{
if (strlen(s) > (maxSize - 1))
{
strncpy(buffer, s, maxSize - 1);
buffer[maxSize-1] = 0;
}
else
strcpy(buffer, s);
XtFree(s);
}
else buffer[0] = 0;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
char *s = (char *)xv_get(item, PANEL_VALUE);
strncpy(buffer, s, strlen(s));
#endif
#ifdef wx_msw
int no_chars = 0;
int no_lines = (int)SendMessage((HWND)ms_handle, EM_GETLINECOUNT, 0, 0L);
for (int i = 0; i < no_lines; i++)
{
*(LPINT)(buffer+no_chars) = maxSize;
int n = (int)SendMessage((HWND)ms_handle, EM_GETLINE, i,
(LONG)(buffer+no_chars));
no_chars += n;
maxSize -= (n + 2);
if (i < (no_lines - 1))
{
buffer[no_chars] = 13;
no_chars ++;
buffer[no_chars] = 10;
no_chars ++;
}
}
buffer[no_chars] = 0;
#endif
}
void wxMultiText::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
wxText::SetSize(x, y, width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
if (x > -1)
(void)xv_set(x_win, XV_X, x, NULL);
if (y > -1)
(void)xv_set(x_win, XV_Y, y, NULL);
if (width <= 0)
width = 120;
(void)xv_set(x_win, PANEL_VALUE_DISPLAY_WIDTH, width, NULL);
Panel panel = (Panel)(GetParent()->handle);
Xv_Font font = (Xv_Font)xv_get(panel, XV_FONT);
int pixel_height = (int)xv_get(font, FONT_DEFAULT_CHAR_HEIGHT);
if (height > -1)
(void)xv_set(x_win, PANEL_DISPLAY_ROWS, (int)(height/pixel_height), NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
int x_offset = x;
int y_offset = y;
float current_width;
int cx;
int cy;
float cyf;
wxGetCharSize((HWND)ms_handle, &cx, &cy);
if (static_label)
{
GetWindowText(static_label, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(static_label, x_offset, y, (int)(current_width + cx), (int)cyf, TRUE);
if (labelPosition == wxVERTICAL)
y_offset += cy;
else
x_offset += (int)(current_width + cx);
}
int text_length = (int)(width - (x_offset - x));
int text_height = (int)height;
if (text_height <= 0)
text_height = (int)(cy*14/4);
// Text must have a minimum/default length
if (text_length < 0)
text_length = 80;
MoveWindow((HWND)ms_handle, x_offset, y_offset, text_length, text_height, TRUE);
OnSize(width, height);
#endif
}
// Slider
#ifdef wx_xview
void wxSliderProc(Panel_item item, int value, Event *x_event)
{
wxSlider *slider = (wxSlider *)xv_get(item, PANEL_CLIENT_DATA);
wxEvent event(x_event);
event.index = value;
if (slider->callback)
{
(void)(*(slider->callback))(*slider, event);
}
}
#endif
#ifdef wx_motif
void wxSliderCallback(Widget widget, XtPointer clientData, XmScaleCallbackStruct *cbs)
{
wxSlider *slider = (wxSlider *)clientData;
wxEvent event;
XtVaGetValues(widget, XmNvalue, &event.index, NULL);
if (slider->callback)
{
(void)(*(slider->callback))(*slider, event);
}
}
#endif
wxSlider::wxSlider(wxPanel *panel, wxFunction func, char *label, int value,
int min_value, int max_value, int width, int x, int y)
{
window_parent = panel;
labelPosition = panel->label_position;
#ifdef wx_motif
Widget panelForm = panel->panelWidget;
XmString text = XmStringCreateSimple(label);
formWidget = XtVaCreateManagedWidget("rowcol",
xmRowColumnWidgetClass, panelForm,
XmNorientation, XmHORIZONTAL,
NULL);
labelWidget = XtVaCreateManagedWidget(label,
xmLabelWidgetClass, formWidget,
XmNlabelString, text,
NULL);
Widget sliderWidget;
sliderWidget = XtVaCreateManagedWidget("slider",
xmScaleWidgetClass, formWidget,
XmNorientation, XmHORIZONTAL,
XmNprocessingDirection, XmMAX_ON_RIGHT,
XmNmaximum, max_value,
XmNminimum, min_value,
XmNvalue, value,
XmNshowValue, True,
NULL);
handle = (char *)sliderWidget;
XtAddCallback(sliderWidget, XmNvalueChangedCallback, wxSliderCallback, this);
XmStringFree(text);
AttachWidget(panel, formWidget, x, y, width, -1);
#endif
#ifdef wx_xview
Panel x_panel = (Panel)(panel->GetHandle());
Panel_item x_slider;
int label_position;
if (panel->label_position == wxVERTICAL)
label_position = PANEL_VERTICAL;
else
label_position = PANEL_HORIZONTAL;
if (x > -1 && y > -1)
{
if (panel->new_line)
{
x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1,
XV_X, x, XV_Y, y, NULL);
panel->new_line = FALSE;
}
else
x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, label_position, XV_X, x, XV_Y, y, NULL);
}
else
{
if (panel->new_line)
{
x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_NEXT_ROW, -1,
NULL);
panel->new_line = FALSE;
}
else
x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
}
xv_set(x_slider,
PANEL_MIN_VALUE, min_value,
PANEL_MAX_VALUE, max_value,
PANEL_NOTIFY_PROC, wxSliderProc,
PANEL_CLIENT_DATA, (char *)this,
PANEL_VALUE, value,
NULL);
if (width > 0)
{ xv_set(x_slider, PANEL_SLIDER_WIDTH, (int) width, NULL); };
if (label)
{ xv_set(x_slider, PANEL_LABEL_STRING, label, NULL); };
handle = (char *)x_slider;
Callback(func);
#endif
#ifdef wx_msw
wxWinType = wxTYPE_HWND;
wxWnd *cparent = NULL;
if (panel)
cparent = (wxWnd *)(panel->handle);
panel->GetValidPosition(&x, &y);
int cx;
int cy;
wxGetCharSize(cparent->handle, &cx, &cy);
// If label exists, create a static control for it.
if (label)
{
static_label = CreateWindowEx(0, "STATIC", label,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
}
else
static_label = NULL;
edit_value = CreateWindowEx(0, "EDIT", NULL,
ES_AUTOHSCROLL | ES_LEFT | WS_VISIBLE | WS_CHILD |
WS_TABSTOP,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
// Now create min static control
sprintf(wxBuffer, "%d", min_value);
static_min = CreateWindowEx(0, "STATIC", wxBuffer,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
// Now create slider
windows_id = (int)NewId();
HWND scroll_bar = CreateWindowEx(0, "SCROLLBAR", wxBuffer,
SBS_HORZ | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
wxhInstance, NULL);
wxScrollBarList.Append((long)scroll_bar, this);
page_size = (int)((max_value-min_value)/10);
s_max = max_value;
s_min = min_value;
SetScrollRange(scroll_bar, SB_CTL, min_value, max_value, FALSE);
SetScrollPos(scroll_bar, SB_CTL, value, FALSE);
ShowWindow(scroll_bar, SW_SHOW);
ms_handle = (HANDLE)scroll_bar;
// Finally, create max value static item
sprintf(wxBuffer, "%d", max_value);
static_max = CreateWindowEx(0, "STATIC", wxBuffer,
SS_LEFT | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
wxhInstance, NULL);
SetSize(x, y, width, -1);
SetValue(value);
panel->AdvanceCursor(this);
#endif
if (panel) panel->AddChild(this);
Callback(func);
}
#ifdef wx_msw
// Called from wx_win.cc: wxWnd::OnHScroll
void wxSliderEvent(HWND bar, WORD wParam, WORD pos)
{
wxNode *node = (wxNode *)wxScrollBarList.Find((long)bar);
if (!node)
return;
wxSlider *slider = (wxSlider *)node->Data();
int position = GetScrollPos(bar, SB_CTL);
int nScrollInc;
switch ( wParam )
{
case SB_LINEUP:
nScrollInc = -1;
break;
case SB_LINEDOWN:
nScrollInc = 1;
break;
case SB_PAGEUP:
nScrollInc = -slider->page_size;
break;
case SB_PAGEDOWN:
nScrollInc = slider->page_size;;
break;
case SB_THUMBTRACK:
nScrollInc = pos - position;
break;
default:
nScrollInc = 0;
}
if (nScrollInc != 0)
{
int new_pos = position + nScrollInc;
if (!(new_pos < slider->s_min || new_pos > slider->s_max))
slider->SetValue(new_pos);
}
}
#endif
wxSlider::~wxSlider(void)
{
#ifdef wx_msw
if (static_min)
{
DestroyWindow(static_min);
}
if (static_max)
{
DestroyWindow(static_max);
}
if (edit_value)
{
DestroyWindow(edit_value);
}
if (static_label)
{
DestroyWindow(static_label);
}
wxScrollBarList.DeleteObject(this);
#endif
}
int wxSlider::GetValue(void)
{
#ifdef wx_motif
int val;
XtVaGetValues((Widget)handle, XmNvalue, &val, NULL);
return val;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return (int)xv_get(item, PANEL_VALUE);
#endif
#ifdef wx_msw
return GetScrollPos((HWND)ms_handle, SB_CTL);
#endif
}
char *wxSlider::GetLabel(void)
{
#ifdef wx_motif
XmString text;
char *s;
XtVaGetValues(labelWidget,
XmNlabelString, &text,
NULL);
if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
{
// XmStringFree(text);
char *val = copystring(s);
XtFree(s);
return val;
}
else
{
// XmStringFree(text);
return NULL;
}
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
#endif
#ifdef wx_msw
char buf[300];
if (static_label)
{
GetWindowText(static_label, buf, 300);
return copystring(buf);
}
else return NULL;
#endif
}
void wxSlider::SetValue(int value)
{
#ifdef wx_motif
XtVaSetValues((Widget)handle, XmNvalue, value, NULL);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_VALUE, value, NULL);
#endif
#ifdef wx_msw
SetScrollPos((HWND)ms_handle, SB_CTL, value, TRUE);
sprintf(wxBuffer, "%d", value);
SetWindowText(edit_value, wxBuffer);
wxEvent event;
event.index = value;
if (callback)
(void)(*callback)(*this, event);
#endif
}
void wxSlider::SetLabel(char *label)
{
#ifdef wx_motif
XmString text = XmStringCreateSimple(label);
XtVaSetValues(labelWidget,
XmNlabelString, text,
NULL);
XmStringFree(text);
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
xv_set(item, PANEL_LABEL_STRING, label, NULL);
#endif
#ifdef wx_msw
if (static_label)
{
float w, h;
RECT rect;
wxWindow *parent = GetParent();
GetWindowRect(static_label, &rect);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
GetTextExtent(label, &w, &h);
MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
TRUE);
SetWindowText(static_label, label);
}
#endif
}
void wxSlider::GetSize(int *width, int *height)
{
#ifdef wx_motif
Widget sliderWidget = (Widget)handle;
Dimension x, y;
XtVaGetValues(sliderWidget, XmNscaleWidth, &x, XmNscaleHeight, &y, NULL);
*width = x;
*height = y;
#endif
#ifdef wx_xview
Panel_item item = (Panel_item)handle;
Rect *rect = (Rect *)xv_get(item, XV_RECT);
*height = rect->r_height;
*width = rect->r_width;
#endif
#ifdef wx_msw
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
{
wxFindMaxSize(static_label, &rect);
}
if (static_min)
{
wxFindMaxSize(static_min, &rect);
}
if (static_max)
{
wxFindMaxSize(static_max, &rect);
}
if (edit_value)
{
wxFindMaxSize(edit_value, &rect);
}
*width = rect.right - rect.left;
*height = rect.bottom - rect.top;
#endif
}
void wxSlider::GetPosition(int *x, int *y)
{
#ifdef wx_motif
wxItem::GetPosition(x, y);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*x = (int)xv_get(x_win, XV_X);
*y = (int)xv_get(x_win, XV_Y);
#endif
#ifdef wx_msw
wxWindow *parent = GetParent();
RECT rect;
rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
wxFindMaxSize((HWND)ms_handle, &rect);
if (static_label)
{
wxFindMaxSize(static_label, &rect);
}
if (static_min)
{
wxFindMaxSize(static_min, &rect);
}
if (static_max)
{
wxFindMaxSize(static_max, &rect);
}
if (edit_value)
{
wxFindMaxSize(edit_value, &rect);
}
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
POINT point;
point.x = rect.left;
point.y = rect.top;
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(cparent->handle, &point);
}
*x = point.x;
*y = point.y;
#endif
}
void wxSlider::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
Widget sliderWidget = (Widget)handle;
if (width > -1)
{
Dimension labelWidth;
XtVaGetValues(labelWidget, XmNwidth, &labelWidth, NULL);
XtVaSetValues(sliderWidget, XmNscaleWidth, max(width-labelWidth, 10), NULL);
}
if (x > -1)
XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF, XmNx, x, NULL);
if (y > -1)
XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF, XmNy, y, NULL);
OnSize(width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
if (x > -1)
(void)xv_set(x_win, XV_X, x, NULL);
if (y > -1)
(void)xv_set(x_win, XV_Y, y, NULL);
if (width > 0)
(void)xv_set(x_win, XV_WIDTH, width, NULL);
if (height > 0)
(void)xv_set(x_win, XV_HEIGHT, height, NULL);
OnSize(width, height);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
char buf[300];
int x_offset = x;
float current_width;
int cx;
int cy;
float cyf;
wxGetCharSize((HWND)ms_handle, &cx, &cy);
if (static_label)
{
GetWindowText(static_label, buf, 300);
GetTextExtent(buf, ¤t_width, &cyf);
MoveWindow(static_label, x_offset, y, (int)(current_width + 2*cx), (int)cyf,
TRUE);
x_offset += (int)(current_width + 2*cx + cx);
}
float min_len;
GetWindowText(static_min, buf, 300);
GetTextExtent(buf, &min_len, &cyf);
float max_len;
GetWindowText(static_max, buf, 300);
GetTextExtent(buf, &max_len, &cyf);
if (edit_value)
{
int new_width = (int)(max(min_len, max_len));
MoveWindow(edit_value, x_offset, y, new_width, (int)cyf, TRUE);
x_offset += new_width + cx;
}
MoveWindow(static_min, x_offset, y, (int)min_len, cy, TRUE);
x_offset += (int)(min_len + cx);
int slider_length = (int)(width - x_offset - max_len - cx);
// Slider must have a minimum/default length
if (slider_length < 0)
slider_length = 100;
MoveWindow((HWND)ms_handle, x_offset, y, slider_length, cy, TRUE);
x_offset += slider_length + cx;
MoveWindow(static_max, x_offset, y, (int)max_len, cy, TRUE);
OnSize(width, height);
#endif
}
// Yeuch! Have to put this here since 'delete menu_bar' is not allowed before
// wxMenuBar has been defined!
#ifdef wx_msw
extern wxList wxModelessWindows;
#endif
wxFrame::~wxFrame(void)
{
if (handle)
Show(FALSE);
if (wx_menu_bar)
delete wx_menu_bar;
if (icon)
delete icon;
#ifdef wx_motif
XtDestroyWidget(workArea);
XtDestroyWidget(frameWidget);
XtDestroyWidget(frameShell);
if (statusTextWidget)
XtDestroyWidget(statusTextWidget);
if (statusLineWidget)
XtDestroyWidget(statusLineWidget);
if (this == wxTheApp->wx_frame)
exit(0);
#endif
#ifdef wx_msw
if (status_window)
{
status_window->DestroyWindow();
delete status_window;
}
if (wxWinType == wxTYPE_MDICHILD)
{
wxMDIChild *child = (wxMDIChild *)handle;
child->DestroyWindow();
delete child;
handle = NULL;
}
if (this == wxTheApp->wx_frame)
{
wxTheApp->wx_frame = NULL;
PostQuitMessage(0);
}
wxModelessWindows.DeleteObject(this);
#endif
}
#ifdef wx_msw
HMENU wxFrame::GetWinMenu(void)
{
if (wx_menu_bar)
return (HMENU)wx_menu_bar->ms_handle;
else return 0;
}
#endif
/*
#ifdef wx_msw
// Not currently used
void wxConvertDialogToPixels(wxWindow *control, int *x, int *y)
{
if (control->window_parent && control->window_parent->is_dialog)
{
DWORD word = GetDialogBaseUnits();
int xs = LOWORD(word);
int ys = HIWORD(word);
*x = (int)(*x * xs/4);
*y = (int)(*y * ys/8);
}
else
{
*x = *x;
*y = *y;
}
}
#endif
*/
#ifdef wx_x
void wxStripMenuCodes(char *in, char *out)
{
int len = strlen(in);
int j = 0;
for (int i = 0; i < len; i++)
{
if (in[i] == '&')
{}
else if (in[i] == '\\' && (i + 1) <= len && in[i+1] == 't')
{
i ++;
out[j] = ' ';
j ++;
}
else
{
out[j] = in[i];
j ++;
}
}
out[j] = 0;
}
// Find the letter corresponding to the mnemonic, for Motif
char wxFindMnemonic(char *s)
{
char mnem = 0;
int len = strlen(s);
for (int i = 0; i < len; i++)
{
if (s[i] == '&')
{
mnem = s[i+1];
break;
}
}
return mnem;
}
#endif
#ifdef wx_xview
void wxPanelEventProc(Panel x_panel, Event *x_event)
{
wxPanel *panel = (wxPanel *)xv_get(x_panel, WIN_CLIENT_DATA);
if (panel)
{
if (event_id(x_event) == KBD_USE)
panel->OnSetFocus();
else if (event_id(x_event) == KBD_DONE)
panel->OnKillFocus();
else if (event_is_ascii(x_event))
{
if (x_event->ie_code == 13)
{
// Find the default item, if any, and execute its callback
Panel_item item = (Panel_item)xv_get(x_panel, PANEL_DEFAULT_ITEM);
if (item)
{
wxItem *wx_item = (wxItem *)xv_get(item, PANEL_CLIENT_DATA);
if (wx_item)
{
wxFunction fun = wx_item->callback;
if (fun)
{
wxEvent event;
(void)(*(fun))(*wx_item, event);
}
}
} else panel->OnChar(x_event->ie_code);
}
else panel->OnChar(x_event->ie_code);
}
else
{
wxEvent event(x_event);
event.x = event_x(x_event);
event.y = event_y(x_event);
panel->OnEvent(event);
}
}
}
#endif