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 >
C/C++ Source or Header  |  1993-04-19  |  119KB  |  5,098 lines

  1. /*
  2.  * File:     wx_item.cc
  3.  * Purpose:  Panel items implementation
  4.  *
  5.  *                       wxWindows 1.40
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 18-4-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29.  
  30. /* When implementing a new item, be sure to:
  31.  *
  32.  * - add the item to the parent panel
  33.  * - set window_parent to the parent
  34.  * - NULL any extra child window pointers not created for this item
  35.  *   (e.g. label control that wasn't needed)
  36.  * - delete any extra child windows in the destructor (e.g. label control)
  37.  * - implement GetSize and SetSize
  38.  * - to find panel position if coordinates are (-1, -1), use GetPosition
  39.  * - call AdvanceCursor after creation, for panel layout mechanism.
  40.  *
  41.  */
  42.  
  43. /*
  44.  Motif notes
  45.  
  46.  A panel is a form.
  47.  Each item is created on a RowColumn or Form of its own, to allow a label to
  48.  be positioned. wxListBox and wxMultiText have forms, all the others have RowColumns.
  49.  This is to allow labels to be positioned to the top left (can't do it with a
  50.  RowColumn as far as I know).
  51.  AttachWidget positions widgets relative to one another (left->right, top->bottom)
  52.  unless the x, y coordinates are given (more than -1).
  53.  */
  54.  
  55.  
  56. #include <windows.h>
  57. #include <iostream.h>
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include "common.h"
  61. #include "wx_item.h"
  62. #include "wx_event.h"
  63. #include "wx_utils.h"
  64. #include "wx_main.h"
  65. #include "wx_frame.h"
  66. #include "wx_privt.h"
  67.  
  68. #ifdef wx_motif
  69. #include <X11/IntrinsicP.h>
  70. #include <Xm/Xm.h>
  71. #include <Xm/PushB.h>
  72. #include <Xm/Label.h>
  73. #include <Xm/Text.h>
  74. #include <Xm/RowColumn.h>
  75. #include <Xm/MainW.h>
  76. #include <Xm/DrawingA.h>
  77. #include <Xm/CascadeBG.h>
  78. #include <Xm/CascadeB.h>
  79. #include <Xm/SeparatoG.h>
  80. #include <Xm/PushBG.h>
  81. #include <Xm/ToggleB.h>
  82. #include <Xm/List.h>
  83. #include <Xm/ArrowB.h>
  84. #include <Xm/Scale.h>
  85. #include <string.h>
  86. void wxMenuItemCallback(Widget w, XtPointer clientData,
  87.                       XtPointer ptr);
  88. void wxMenuItemArmCallback(Widget w, XtPointer clientData,
  89.                       XtPointer ptr);
  90. void wxMenuItemDisarmCallback(Widget w, XtPointer clientData,
  91.                       XtPointer ptr);
  92. #endif
  93.  
  94. #ifdef wx_xview
  95. #include <xview/panel.h>
  96. #include <xview/openmenu.h>
  97. #include <xview/svrimage.h>
  98.  
  99. // General purpose item notifier proc
  100. void wxItemProc(Panel_item item, Event *event);
  101.  
  102. // Menu notifier proc
  103. void wxMenuProc(Menu x_menu, Menu_item menu_item);
  104. void wxMenuBarProc(Menu x_menu, Menu_item menu_item);
  105.  
  106. void wxCheckBoxProc(Panel_item item, int value, Event *x_event);
  107.  
  108. void wxChoiceProc(Panel_item item, int value, Event *event);
  109.  
  110. int wxListProc(Panel_item item, char *string, Xv_opaque client_data,
  111.                 Panel_list_op op, Event *event, int row);
  112.  
  113. Panel_setting wxTextProc(Panel_item item, Event *x_event);
  114.  
  115. void wxSliderProc(Panel_item item, int value, Event *event);
  116. #endif
  117.  
  118. #ifdef wx_msw
  119. // Find maximum size of window/rectangle
  120. void wxFindMaxSize(HWND hwnd, RECT *rect);
  121. wxList wxScrollBarList(wxKEY_INTEGER);
  122. #endif
  123.  
  124. // Item members
  125. wxItem::wxItem(void)
  126. {
  127. #ifdef wx_motif
  128.   formWidget = 0;
  129.   labelWidget = 0;
  130.   itemOrientation = wxHORIZONTAL;
  131. #endif
  132. }
  133.  
  134. wxItem::~wxItem(void)
  135. {
  136. #ifdef wx_motif
  137.   if (labelWidget)
  138.     XtDestroyWidget(labelWidget);
  139.  
  140.   if (formWidget)
  141.   {
  142.     wxWidgetHashTable->Delete((long)formWidget);
  143.     if (formWidget)
  144.       XtDestroyWidget(formWidget);
  145.   }
  146. #endif
  147. }
  148.  
  149. void wxItem::GetSize(int *width, int *height)
  150. {
  151. #ifdef wx_motif
  152.   Dimension xx, yy;
  153.   XtVaGetValues(formWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
  154.   *width = xx; *height = yy;
  155. #endif
  156. #ifdef wx_xview
  157.   Panel_item item = (Panel_item)handle;
  158.   Rect *rect = (Rect *)xv_get(item, XV_RECT);
  159.  
  160.   *height = rect->r_height;
  161.   *width = rect->r_width;
  162. #endif
  163. #ifdef wx_msw
  164.   HWND wnd = (HWND)ms_handle;
  165.   RECT rect;
  166.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  167.  
  168.   wxFindMaxSize(wnd, &rect);
  169.  
  170.   *width = rect.right - rect.left;
  171.   *height = rect.bottom - rect.top;
  172. #endif
  173. }
  174.  
  175. void wxItem::GetPosition(int *x, int *y)
  176. {
  177. #ifdef wx_motif
  178.   Dimension xx, yy;
  179.   XtVaGetValues(formWidget, XmNx, &xx, XmNy, &yy, NULL);
  180.   *x = xx; *y = yy;
  181. #endif
  182. #ifdef wx_xview
  183.   Xv_opaque x_win = (Xv_opaque)handle;
  184.  
  185.   *x = (int)xv_get(x_win, XV_X);
  186.   *y = (int)xv_get(x_win, XV_Y);
  187. #endif
  188. #ifdef wx_msw
  189.   HWND wnd = (HWND)ms_handle;
  190.   wxWindow *parent = GetParent();
  191.   RECT rect;
  192.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  193.  
  194.   wxFindMaxSize(wnd, &rect);
  195.  
  196.   // Since we now have the absolute screen coords,
  197.   // if there's a parent we must subtract its top left corner
  198.   POINT point;
  199.   point.x = rect.left;
  200.   point.y = rect.top;
  201.   if (parent)
  202.   {
  203.     wxWnd *cparent = (wxWnd *)(parent->handle);
  204.     ScreenToClient(cparent->handle, &point);
  205.   }
  206.  
  207.   *x = point.x;
  208.   *y = point.y;
  209. #endif
  210. }
  211.  
  212. void wxItem::SetSize(int x, int y, int width, int height)
  213. {
  214. #ifdef wx_motif
  215.   if (x > -1)
  216.     XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF,
  217.                    XmNx, x,
  218.                    NULL);
  219.   if (y > -1)
  220.     XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF,
  221.                    XmNy, y,
  222.                    NULL);
  223.   if (width > -1)
  224.     XtVaSetValues(formWidget, XmNwidth, width,
  225.                    NULL);
  226.   if (height > -1)
  227.     XtVaSetValues(formWidget, XmNheight, height,
  228.                    NULL);
  229.   OnSize(width, height);
  230. #endif
  231. }
  232.  
  233. void wxItem::SetClientSize(int width, int height)
  234. {
  235.   SetSize(-1, -1, width, height);
  236. }
  237.  
  238. void wxItem::SetLabel(char *label)
  239. {
  240. #ifdef wx_motif
  241.   XmString text = XmStringCreateSimple(label);
  242.   XtVaSetValues(labelWidget,
  243.                   XmNlabelString, text,
  244.                   NULL);
  245.   XmStringFree(text);
  246. #endif
  247. #ifdef wx_xview
  248.   Panel_item item = (Panel_item)handle;
  249.   xv_set(item, PANEL_LABEL_STRING, label, NULL);
  250. #endif
  251. #ifdef wx_msw
  252.   SetWindowText((HWND)ms_handle, label);
  253. #endif
  254. }
  255.  
  256. char *wxItem::GetLabel(void)
  257. {
  258. #ifdef wx_motif
  259.   XmString text;
  260.   char *s;
  261.   XtVaGetValues(labelWidget,
  262.                   XmNlabelString, &text,
  263.                   NULL);
  264.  
  265.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  266.   {
  267. //    XmStringFree(text);
  268.     char *val = copystring(s);
  269.     XtFree(s);
  270.     return val;
  271.   }
  272.   else
  273.   {
  274. //    XmStringFree(text);
  275.     return NULL;
  276.   }
  277. #endif
  278. #ifdef wx_xview
  279.   Panel_item item = (Panel_item)handle;
  280.   return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
  281. #endif
  282. #ifdef wx_msw
  283.   char buf[300];
  284.   GetWindowText((HWND)ms_handle, buf, 300);
  285.   return copystring(buf);
  286. #endif
  287. }
  288.  
  289. void wxItem::SetDefault(void)
  290. {
  291. #ifdef wx_motif
  292. #endif
  293. #ifdef wx_xview
  294.   wxPanel *panel = (wxPanel *)GetParent();
  295.   if (panel)
  296.   {
  297.     Panel p = (Panel)panel->handle;
  298.     xv_set(p, PANEL_DEFAULT_ITEM, (Panel_item)handle, 0);
  299.   }
  300. #endif
  301. }
  302.  
  303. void wxItem::SetFocus(void)
  304. {
  305. #ifdef wx_motif
  306.   wxWindow::SetFocus();
  307. #endif
  308. #ifdef wx_xview
  309. #endif
  310. #ifdef wx_msw
  311.   wxWindow::SetFocus();
  312. #endif
  313. }
  314.  
  315. int wxItem::GetLabelPosition(void)
  316. {
  317.   return labelPosition;
  318. }
  319.  
  320. void wxItem::SetLabelPosition(int pos)
  321. {
  322.   labelPosition = pos;
  323. }
  324.  
  325. void wxItem::Show(Bool show)
  326. {
  327. #ifdef wx_motif
  328. #endif
  329. #ifdef wx_xview
  330.   Xv_opaque window = (Xv_opaque)handle;
  331.   xv_set(window, XV_SHOW, show, NULL);
  332. #endif
  333. #ifdef wx_msw
  334.   HWND wnd = (HWND)ms_handle;
  335.   int cshow;
  336.   if (show)
  337.     cshow = SW_SHOW;
  338.   else
  339.     cshow = SW_HIDE;
  340.   ShowWindow(wnd, cshow);
  341.   if (show)
  342.     BringWindowToTop(wnd);
  343. #endif
  344. }
  345.  
  346. float wxItem::GetTextHeight(void)
  347. {
  348. #ifdef wx_motif
  349.   return 0.0;
  350. #endif
  351. #ifdef wx_xview
  352.   Xv_Font the_font;
  353.  
  354.   if (!(font && font->x_font))
  355.   {
  356.     Xv_opaque thing = (Xv_opaque)(GetParent()->handle);
  357.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  358.   }
  359.   else the_font = font->x_font;
  360.  
  361.   return (float)xv_get(the_font, FONT_DEFAULT_CHAR_HEIGHT);
  362. #endif
  363. #ifdef wx_msw
  364.   TEXTMETRIC lpTextMetric;
  365.   HWND wnd = (HWND)ms_handle;
  366.   HDC dc = GetDC(wnd);
  367.  
  368.   GetTextMetrics(dc, &lpTextMetric);
  369.   ReleaseDC(wnd, dc);
  370.  
  371.   return (float)lpTextMetric.tmHeight;
  372. #endif
  373. }
  374.  
  375. float wxItem::GetTextWidth(void)
  376. {
  377. #ifdef wx_motif
  378.   return 0.0;
  379. #endif
  380. #ifdef wx_xview
  381.   Xv_Font the_font;
  382.  
  383.   if (!(font && font->x_font))
  384.   {
  385.     Xv_opaque thing = (Xv_opaque)(GetParent()->handle);
  386.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  387.   }
  388.   else the_font = font->x_font;
  389.  
  390.   return (float)xv_get(the_font, FONT_DEFAULT_CHAR_WIDTH);
  391. #endif
  392. #ifdef wx_msw
  393.   TEXTMETRIC lpTextMetric;
  394.   HWND wnd = (HWND)ms_handle;
  395.   HDC dc = GetDC(wnd);
  396.  
  397.   GetTextMetrics(dc, &lpTextMetric);
  398.   ReleaseDC(wnd, dc);
  399.  
  400.   return (float)lpTextMetric.tmAveCharWidth;
  401. #endif
  402. }
  403.  
  404. void wxItem::GetTextExtent(char *string, float *x, float *y)
  405. {
  406. #ifdef wx_motif
  407.   *x = 0.0; *y = 0.0;
  408. #endif
  409. #ifdef wx_xview
  410.   Xv_Font the_font;
  411.  
  412.   if (!(font && font->x_font))
  413.   {
  414.     Xv_opaque thing = (Xv_opaque)(GetParent()->handle);
  415.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  416.   }
  417.   else the_font = font->x_font;
  418.  
  419.   Font_string_dims dims;
  420.  
  421.   (void)xv_get(the_font, FONT_STRING_DIMS, string, &dims);
  422.   *x = (float)dims.width;
  423.   *y = (float)dims.height;
  424. #endif
  425. #ifdef wx_msw
  426.   HWND wnd = (HWND)ms_handle;
  427.   HDC dc = GetDC(wnd);
  428.  
  429.   SIZE sizeRect;
  430.   GetTextExtentPoint(dc, string, strlen(string), &sizeRect);
  431.  
  432.   ReleaseDC(wnd, dc);
  433.  
  434.   *x = (float)sizeRect.cx;
  435.   *y = (float)sizeRect.cy;
  436.  
  437. #endif
  438. }
  439.  
  440. void wxItem::Centre(int direction)
  441. {
  442.   int x, y, width, height, panel_width, panel_height, new_x, new_y;
  443.  
  444.   wxPanel *panel = (wxPanel *)GetParent();
  445.   if (!panel)
  446.     return;
  447.  
  448.   panel->GetClientSize(&panel_width, &panel_height);
  449.   GetSize(&width, &height);
  450.   GetPosition(&x, &y);
  451.  
  452.   new_x = x;
  453.   new_y = y;
  454.  
  455.   if (direction == wxHORIZONTAL || direction == wxBOTH)
  456.     new_x = (int)((panel_width - width)/2);
  457.  
  458.   if (direction == wxVERTICAL || direction == wxBOTH)
  459.     new_y = (int)((panel_height - height)/2);
  460.  
  461.   SetSize(new_x, new_y, width, height);
  462. }
  463.  
  464. /*
  465.  * Attach new widget to last widget, or below previous widget of
  466.  * previous row if we've had a new line
  467.  */
  468.  
  469. #ifdef wx_motif
  470. void wxItem::AttachWidget(wxPanel *panel, Widget formWidget,
  471.                           int x, int y, int width, int height)
  472. {
  473.   itemOrientation = panel->label_position;
  474.  
  475.   wxWidgetHashTable->Put((long)formWidget, this);
  476.   XtOverrideTranslations(formWidget,
  477.               XtParseTranslationTable("<Configure>: resize()"));
  478.  
  479.   XtVaSetValues(formWidget,
  480.     XmNleftOffset, panel->hSpacing,
  481.     NULL);
  482.  
  483.   if (panel->new_line)
  484.   {
  485.     if ((x == -1) && (y == -1))
  486.       XtVaSetValues(formWidget,
  487.                     XmNtopAttachment,  panel->firstRowWidget ? XmATTACH_WIDGET: XmATTACH_FORM,
  488.                     XmNtopWidget,      panel->firstRowWidget,
  489.                     XmNtopOffset,      panel->vSpacing,
  490.                     XmNleftAttachment, XmATTACH_FORM,
  491.                     NULL);
  492.     panel->lastWidget = formWidget;
  493.     panel->firstRowWidget = formWidget;
  494.     panel->new_line = FALSE;
  495.   }
  496.   else
  497.   {
  498.     if ((x == -1) && (y == -1))
  499.       XtVaSetValues(formWidget,
  500.                     XmNleftAttachment, panel->lastWidget ? XmATTACH_WIDGET: XmATTACH_FORM,
  501.                     XmNleftWidget,     panel->lastWidget,
  502.                     XmNtopAttachment,  panel->lastWidget ? XmATTACH_OPPOSITE_WIDGET: XmATTACH_FORM,
  503.                     XmNtopWidget,      panel->lastWidget,
  504.                     XmNtopOffset,      panel->lastWidget ? 0: panel->vSpacing,
  505.                     NULL);
  506.     panel->lastWidget = formWidget;
  507.   }
  508.  
  509.   SetSize(x, y, width, height);
  510.  
  511.   if (!panel->firstRowWidget)
  512.     panel->firstRowWidget = formWidget;
  513.   else
  514.   {
  515.     Dimension hh1, hh2;
  516.     XtVaGetValues(formWidget, XmNheight, &hh1, NULL);
  517.     XtVaGetValues(panel->firstRowWidget, XmNheight, &hh2, NULL);
  518.  
  519.     if (hh1 > hh2)
  520.       panel->firstRowWidget = formWidget;
  521.   }
  522. }
  523. #endif
  524.  
  525. #ifdef wx_msw
  526.  
  527. // Call this repeatedly for several wnds to find the overall size
  528. // of the widget.
  529. // Call it initially with -1 for all values in rect.
  530. // Keep calling for other widgets, and rect will be modified
  531. // to calculate largest bounding rectangle.
  532. void wxFindMaxSize(HWND wnd, RECT *rect)
  533. {
  534.   int left = rect->left;
  535.   int right = rect->right;
  536.   int top = rect->top;
  537.   int bottom = rect->bottom;
  538.  
  539.   GetWindowRect(wnd, rect);
  540.  
  541.   if (left < 0)
  542.     return;
  543.  
  544.   if (left < rect->left)
  545.     rect->left = left;
  546.  
  547.   if (right > rect->right)
  548.     rect->right = right;
  549.  
  550.   if (top < rect->top)
  551.     rect->top = top;
  552.  
  553.   if (bottom > rect->bottom)
  554.     rect->bottom = bottom;
  555.  
  556. }
  557.  
  558. // General Windows item code
  559. // wxWnd (wx_win.cc) catches commands from child items, finds the child
  560. // and sends a Command message to the child.
  561.  
  562. // Buttons
  563.  
  564. BOOL wxButton::Command(UINT param)
  565. {
  566.   wxFunction fun = callback;
  567.   if (fun)
  568.   {
  569.     wxEvent event;
  570.     (void)(*(fun))(*this, event);
  571.     return TRUE;
  572.   }
  573.   else return FALSE;
  574. }
  575.  
  576. BOOL wxCheckBox::Command(UINT param)
  577. {
  578.   wxFunction fun = callback;
  579.   if (fun)
  580.   {
  581.     wxEvent event;
  582.     (void)(*(fun))(*this, event);
  583.     return TRUE;
  584.   }
  585.   else return FALSE;
  586. }
  587.  
  588. BOOL wxText::Command(UINT param)
  589. {
  590.   wxFunction fun = callback;
  591.   if (fun)
  592.   {
  593.     wxEvent event;
  594.     (void)(*(fun))(*this, event);
  595.     return TRUE;
  596.   }
  597.   else return FALSE;
  598. }
  599.  
  600. #endif
  601.  
  602. #ifdef wx_motif
  603. void wxButtonCallback(Widget w, XtPointer clientData,
  604.                       XtPointer ptr)
  605. {
  606.   wxItem *item = (wxItem *)clientData;
  607.   wxFunction fun = item->callback;
  608.   if (fun)
  609.   {
  610.     wxEvent event;
  611.     (void)(*(fun))(*item, event);
  612.   }
  613. }
  614. #endif
  615.  
  616. wxButton::wxButton(wxPanel *panel, wxFunction Function, char *label,
  617.            int x, int y, int width, int height)
  618. {
  619.   if (panel) panel->AddChild(this);
  620.   window_parent = panel;
  621.  
  622.   Callback(Function);
  623.   labelPosition = wxHORIZONTAL;
  624.  
  625. #ifdef wx_motif
  626.   Widget panelForm = panel->panelWidget;
  627.   XmString text = XmStringCreateSimple(label);
  628.  
  629.   formWidget = XtVaCreateManagedWidget("rowcol",
  630.                   xmRowColumnWidgetClass, panelForm,
  631.                   XmNorientation, XmHORIZONTAL,
  632.                   XmNmarginHeight, 0,
  633.                   XmNmarginWidth, 0,
  634.                   NULL);
  635.  
  636.   Widget buttonWidget;
  637.  
  638.   buttonWidget = XtVaCreateManagedWidget("button",
  639.                   xmPushButtonWidgetClass, formWidget,
  640.                   XmNlabelString,      text,
  641. //                XmNdefaultButtonShadowThickness, 1, // See comment for wxButton::SetDefault
  642.                   NULL);
  643.  
  644.   handle = (char *)buttonWidget;
  645.  
  646.   XmStringFree(text);
  647.  
  648.   XtAddCallback(buttonWidget, XmNactivateCallback, wxButtonCallback,
  649.                   this);
  650.  
  651.   AttachWidget(panel, formWidget, x, y, width, height);
  652. #endif
  653. #ifdef wx_xview
  654.   Panel x_panel = (Panel)(panel->GetHandle());
  655.   Panel_item x_button;
  656.  
  657.   if (panel->new_line)
  658.   {
  659.     x_button = (Panel_item) xv_create(x_panel, PANEL_BUTTON, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_NEXT_ROW, -1, NULL);
  660.     panel->new_line = FALSE;
  661.   }
  662.   else
  663.     x_button = (Panel_item) xv_create(x_panel, PANEL_BUTTON, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
  664.  
  665.   xv_set(x_button,
  666.                               PANEL_LABEL_STRING, label,
  667.                               PANEL_NOTIFY_PROC, wxItemProc,
  668.                   PANEL_CLIENT_DATA, (char *)this,
  669.                               NULL);
  670.   if (x > -1 && y > -1)
  671.     (void)xv_set(x_button, XV_X, x, XV_Y, y, NULL);
  672.  
  673.   if (width > 0)
  674.     { xv_set(x_button, PANEL_LABEL_WIDTH, (int) width, NULL); };
  675.                 
  676.   handle = (char *)x_button;
  677. #endif
  678. #ifdef wx_msw
  679.   wxWinType = wxTYPE_HWND;
  680.  
  681.   wxWnd *cparent = NULL;
  682.   if (panel)
  683.     cparent = (wxWnd *)(panel->handle);
  684.  
  685.   panel->GetValidPosition(&x, &y);
  686.  
  687.   RECT rect;
  688.   rect.left = 0; rect.top = 0; rect.right = 0; rect.bottom = 0;
  689.  
  690.   windows_id = (int)NewId();
  691.  
  692.   HWND wx_button =
  693.     CreateWindowEx(0, "BUTTON", label, BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD,
  694.                     0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  695.                     wxhInstance, NULL);
  696.  
  697.   ms_handle = (HANDLE)wx_button;
  698.  
  699.   SetSize(x, y, width, height);
  700.   ShowWindow(wx_button, SW_SHOW);
  701.  
  702.   panel->AdvanceCursor(this);
  703. #endif
  704.  
  705. }
  706.  
  707. wxButton::~wxButton(void)
  708. {
  709. }
  710.  
  711. // Button item notifier
  712.  
  713. #ifdef wx_xview
  714. void wxItemProc(Panel_item x_item, Event *x_event)
  715. {
  716.   wxItem *item = (wxItem *)xv_get(x_item, PANEL_CLIENT_DATA);
  717.  
  718.   wxEvent event(x_event);
  719.   if (item->callback)
  720.     {
  721.       (void)(*(item->callback))(*item, event);
  722.     }
  723.  
  724. }
  725. #endif
  726.  
  727. void wxButton::SetLabel(char *label)
  728. {
  729. #ifdef wx_motif
  730.   Widget widget = (Widget)handle;
  731.   XmString text = XmStringCreateSimple(label);
  732.   XtVaSetValues(widget,
  733.                   XmNlabelString, text,
  734.                   NULL);
  735.   XmStringFree(text);
  736. #endif
  737. #ifdef wx_xview
  738.   Panel_item item = (Panel_item)handle;
  739.   xv_set(item, PANEL_LABEL_STRING, label, NULL);
  740. #endif
  741. #ifdef wx_msw
  742.   SetWindowText((HWND)ms_handle, label);
  743. #endif
  744. }
  745.  
  746. char *wxButton::GetLabel(void)
  747. {
  748. #ifdef wx_motif
  749.   Widget widget = (Widget)handle;
  750.   XmString text;
  751.   char *s;
  752.   XtVaGetValues(widget,
  753.                   XmNlabelString, &text,
  754.                   NULL);
  755.  
  756.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  757.   {
  758. //    XmStringFree(text);
  759.     char *val = copystring(s);
  760.     XtFree(s);
  761.     return val;
  762.   }
  763.   else
  764.   {
  765. //    XmStringFree(text);
  766.     return NULL;
  767.   }
  768. #endif
  769. #ifdef wx_xview
  770.   Panel_item item = (Panel_item)handle;
  771.   return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
  772. #endif
  773. #ifdef wx_msw
  774.   char buf[300];
  775.   GetWindowText((HWND)ms_handle, buf, 300);
  776.   return copystring(buf);
  777. #endif
  778. }
  779.  
  780. void wxButton::SetSize(int x, int y, int width, int height)
  781. {
  782. #ifdef wx_motif
  783.   wxItem::SetSize(x, y, width, height);
  784.   OnSize(width, height);
  785. #endif
  786. #ifdef wx_xview
  787.   Xv_opaque x_win = (Xv_opaque)handle;
  788.  
  789.   if (x > -1)
  790.     (void)xv_set(x_win, XV_X, x, NULL);
  791.  
  792.   if (y > -1)
  793.     (void)xv_set(x_win, XV_Y, y, NULL);
  794.  
  795.   if (width > 0)
  796.     (void)xv_set(x_win, XV_WIDTH, width, NULL);
  797.  
  798.   if (height > 0)
  799.     (void)xv_set(x_win, XV_HEIGHT, height, NULL);
  800.   OnSize(width, height);
  801. #endif
  802. #ifdef wx_msw
  803.   int currentX, currentY;
  804.   GetPosition(¤tX, ¤tY);
  805.   if (x == -1)
  806.     x = currentX;
  807.   if (y == -1)
  808.     y = currentY;
  809.  
  810.   char buf[300];
  811.  
  812.   float current_width;
  813.  
  814.   int cx;
  815.   int cy;
  816.   float cyf;
  817.  
  818.   HWND button = (HWND)ms_handle;
  819.   wxGetCharSize(button, &cx, &cy);
  820.  
  821.   if (width < 0)
  822.   {
  823.     GetWindowText(button, buf, 300);
  824.     GetTextExtent(buf, ¤t_width, &cyf);
  825.     MoveWindow(button, x, y, (int)(current_width + 3*cx), (int)(cyf*7/4), TRUE);
  826.   }
  827.   else
  828.     MoveWindow(button, x, y, width, height, TRUE);
  829.   OnSize(width, height);
  830. #endif
  831. }
  832.  
  833. void wxButton::SetFocus(void)
  834. {
  835. #ifdef wx_msw
  836.   wxPanel *panel = (wxPanel *)GetParent();
  837.   if (panel)
  838.   {
  839.     wxWnd *wnd = (wxWnd *)panel->handle;
  840.     SendMessage(wnd->handle, DM_SETDEFID, windows_id, 0L);
  841.   }
  842. #endif
  843.   wxItem::SetFocus();
  844. }
  845.  
  846. void wxButton::SetDefault(void)
  847. {
  848. #ifdef wx_motif
  849.   // Seems to mess up tab traversal; AND if shadow thickness
  850.   // isn't set, resizes the button - not wanted.
  851.   // Setting shadow thickness on creation makes a BIG button. Also
  852.   // undesirable.
  853.   // Can't decide what to do here.
  854. //  XtVaSetValues((Widget)handle, XmNshowAsDefault, 1, NULL);
  855. #endif
  856. #ifdef wx_xview
  857.   wxPanel *panel = (wxPanel *)GetParent();
  858.   if (panel)
  859.   {
  860.     Panel p = (Panel)panel->handle;
  861.     xv_set(p, PANEL_DEFAULT_ITEM, (Panel_item)handle, 0);
  862.   }
  863. #endif
  864. #ifdef wx_msw
  865.   wxPanel *panel = (wxPanel *)GetParent();
  866.   if (panel)
  867.   {
  868.     wxWnd *wnd = (wxWnd *)panel->handle;
  869.     SendMessage(wnd->handle, DM_SETDEFID, windows_id, 0L);
  870.   }
  871. #endif
  872. }
  873.  
  874. // Menus
  875.  
  876. // Construct a menu with optional title (then use append)
  877. wxMenu::wxMenu(char *Title, wxFunction func)
  878. {
  879.   no_items = 0;
  880.   menu_bar = NULL;
  881.   title = NULL;
  882. #ifdef wx_motif
  883.   buttonWidget = NULL;
  884.   handle = NULL;
  885.   menuId = 0;
  886.   menuItems.DeleteContents(TRUE);
  887. #endif
  888. #ifdef wx_xview
  889.   Menu x_menu = (Menu) xv_create((Xv_opaque)NULL, MENU, MENU_CLIENT_DATA, (char *)this, NULL);
  890.   if (Title)
  891.   {
  892.     title = copystring(Title);
  893.     xv_set(x_menu, MENU_TITLE_ITEM, title, NULL);
  894.   }
  895.   handle = (char *)x_menu;
  896.   Callback(func);
  897.   top_level_menu = this;
  898. #endif // wx_xview
  899. #ifdef wx_msw
  900.   wxWinType = wxTYPE_HMENU;
  901.   ms_handle = (HANDLE)CreatePopupMenu();
  902. #endif
  903. }
  904.  
  905. // The wxWindow destructor will take care of deleting the submenus.
  906. wxMenu::~wxMenu(void)
  907. {
  908. #ifdef wx_motif
  909.   wxNode *node = menuItems.First();
  910.   while (node)
  911.   {
  912.     wxMenuItem *item = (wxMenuItem *)node->Data();
  913.     item->menuBar = NULL;
  914.  
  915.     if (item->itemName && (!item->subMenu))
  916.     {
  917.       XtRemoveCallback(item->buttonWidget, XmNactivateCallback, wxMenuItemCallback, (XtPointer)item);
  918.       XtRemoveCallback(item->buttonWidget, XmNarmCallback, wxMenuItemArmCallback, (XtPointer)item);
  919.       XtRemoveCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
  920.     }
  921.     else if (item->itemId == -1)
  922.     {
  923.     }
  924.     else if (item->subMenu)
  925.     {
  926.       XtRemoveCallback(item->buttonWidget, XmNcascadingCallback, wxMenuItemArmCallback, (XtPointer)item);
  927. //      XtRemoveCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
  928.     }
  929.     delete item;
  930.     node = node->Next();
  931.   }
  932. #endif
  933. #ifdef wx_xview
  934.   if (title)
  935.     delete title;
  936. #endif
  937. #ifdef wx_msw
  938.   DestroyMenu((HMENU)ms_handle);
  939.   ms_handle = NULL;
  940. #endif
  941. }
  942.  
  943. // Ordinary menu item
  944. void wxMenu::Append(int Id, char *Label)
  945. {
  946. #ifdef wx_motif
  947.   wxMenuItem *item = new wxMenuItem;
  948.   item->itemId = Id;
  949.   item->buttonWidget = NULL;
  950.   item->itemName = copystring(Label);
  951.   item->subMenu = NULL;
  952.   menuItems.Append(item);
  953. #endif
  954. #ifdef wx_xview
  955.   Menu menu = (Menu)handle;
  956.   wxStripMenuCodes(Label, wxBuffer);
  957.   char *p = strcpy(malloc(strlen(wxBuffer) + 1), wxBuffer);
  958.   Menu_item mi = (Menu_item)xv_create((Xv_opaque)NULL, MENUITEM,
  959.                        MENU_RELEASE,
  960.                        MENU_STRING, p,
  961.                        MENU_NOTIFY_PROC, wxMenuProc,
  962.                        MENU_CLIENT_DATA, (char *)Id,
  963.                        NULL);
  964.  
  965.   if (mi)
  966.     xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
  967. #endif // wx_xview
  968. #ifdef wx_msw
  969.   AppendMenu((HMENU)ms_handle, MF_STRING, Id, Label);
  970. #endif
  971.   no_items ++;
  972. }
  973.  
  974. void wxMenu::AppendSeparator(void)
  975. {
  976. #ifdef wx_motif
  977.   wxMenuItem *item = new wxMenuItem;
  978.   item->itemId = -1;
  979.   item->buttonWidget = NULL;
  980.   menuItems.Append(item);
  981. #endif
  982. #ifdef wx_xview
  983. /* HOW DO WE GET A SEPARATOR IN XVIEW?!
  984.  * This makes far too much space.
  985.  */
  986.  
  987.   Menu menu = (Menu)handle;
  988.   Menu_item mi = (Menu_item)xv_create((Xv_opaque)NULL,
  989.                        MENUITEM_SPACE,
  990.                        NULL);
  991.  
  992.   if (mi)
  993.     xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
  994. #endif
  995. #ifdef wx_msw
  996.   AppendMenu((HMENU)ms_handle, MF_SEPARATOR, NULL, NULL);
  997. #endif
  998. }
  999.  
  1000. // Pullright item
  1001. void wxMenu::Append(int Id, char *Label, wxMenu *SubMenu)
  1002. {
  1003.   SubMenu->top_level_menu = top_level_menu;
  1004.   SubMenu->window_parent = this;
  1005.   children->Append(SubMenu);               // Store submenu for later deletion
  1006.  
  1007. #ifdef wx_motif
  1008.   wxMenuItem *item = new wxMenuItem;
  1009.   item->itemId = Id;
  1010.   item->itemName = copystring(Label);
  1011.   item->buttonWidget = NULL;
  1012.   item->subMenu = SubMenu;
  1013.   menuItems.Append(item);
  1014. #endif
  1015. #ifdef wx_xview
  1016.   Menu menu = (Menu)handle;
  1017.   wxStripMenuCodes(Label, wxBuffer);
  1018.  
  1019.   Menu x_submenu = (Menu)(SubMenu->GetHandle());
  1020.   char *p = strcpy(malloc(strlen(wxBuffer) + 1), wxBuffer);
  1021.   Menu_item mi = (Menu_item)xv_create((Xv_opaque)NULL, MENUITEM,
  1022.                        MENU_RELEASE,
  1023.                        MENU_STRING, p,
  1024.                        MENU_NOTIFY_PROC, wxMenuProc,
  1025.                        MENU_PULLRIGHT, x_submenu,
  1026.                        MENU_CLIENT_DATA, (char *)Id,
  1027.                        NULL);
  1028.   if (mi)
  1029.     xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
  1030.  
  1031. #endif // wx_xview
  1032. #ifdef wx_msw
  1033.   HMENU menu = (HMENU)ms_handle;
  1034.   HMENU child = (HMENU)SubMenu->ms_handle;
  1035.   SubMenu->ms_handle = NULL;
  1036.   AppendMenu(menu, MF_POPUP | MF_STRING, child, Label);
  1037. #endif
  1038.   no_items ++;
  1039. }
  1040.  
  1041. void wxMenu::Enable(int Id, Bool Flag)
  1042. {
  1043. #ifdef wx_motif
  1044.   Widget w = FindMenuItem(Id);
  1045.   if (w)
  1046.   {
  1047.     XtSetSensitive(w, Flag);
  1048.     return;
  1049.   }
  1050. #endif
  1051. #ifdef wx_xview
  1052.   Menu menu = (Menu)handle;
  1053.   int n = (int)xv_get(menu, MENU_NITEMS);
  1054.   for (int i = 1; i <= n; i++)
  1055.   {
  1056.     Menu_item item = FindMenuItem(Id);
  1057.     if (item)
  1058.     {
  1059.       xv_set(item, MENU_INACTIVE, !Flag, NULL);
  1060.       return;
  1061.     }
  1062.   }
  1063. #endif
  1064. #ifdef wx_msw
  1065.   int ms_flag;
  1066.   if (Flag)
  1067.     ms_flag = MF_ENABLED;
  1068.   else
  1069.     ms_flag = MF_GRAYED;
  1070.   EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
  1071. #endif
  1072. }
  1073.  
  1074. void wxMenu::Check(int Id, Bool Flag)
  1075. {
  1076. #ifdef wx_motif
  1077. #endif
  1078. #ifdef wx_xview
  1079. // No checking in XView; perhaps could simulate it
  1080. // with a bitmap?
  1081. #endif
  1082. #ifdef wx_msw
  1083.   int ms_flag;
  1084.   if (Flag)
  1085.     ms_flag = MF_CHECKED;
  1086.   else
  1087.     ms_flag = MF_UNCHECKED;
  1088.   EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
  1089. #endif
  1090. }
  1091.  
  1092. #ifdef wx_xview
  1093. Menu_item wxMenu::FindMenuItem(int Id)
  1094. {
  1095.   Menu x_menu = (Menu)handle;
  1096.  
  1097.   int num = (int)xv_get(x_menu, MENU_NITEMS);
  1098.  
  1099.   for (int i = 1; i <= num; i++)
  1100.   {
  1101.     Menu_item item = (Menu_item)xv_get(x_menu, MENU_NTH_ITEM, i);
  1102.     int id = (int)xv_get(item, MENU_CLIENT_DATA);
  1103.     if (Id == id)
  1104.       return item;
  1105.   }
  1106.  
  1107.   wxNode *node = children->First();
  1108.   while (node)
  1109.   {
  1110.     wxMenu *child = (wxMenu *)node->Data();
  1111.     Menu_item item = child->FindMenuItem(Id);
  1112.     if (item)
  1113.       return item;
  1114.     node = node->Next();
  1115.   }
  1116.   return 0;
  1117. }
  1118. #endif
  1119.  
  1120. #ifdef wx_motif
  1121. Widget wxMenu::FindMenuItem(int Id)
  1122. {
  1123.   if (Id == menuId)
  1124.   {
  1125.     return buttonWidget;
  1126.   }
  1127.  
  1128.   wxNode *node = menuItems.First();
  1129.   while (node)
  1130.   {
  1131.     wxMenuItem *item = (wxMenuItem *)node->Data();
  1132.     if (item->itemId == Id)
  1133.       return item->buttonWidget;
  1134.  
  1135.     if (item->subMenu)
  1136.     {
  1137.       Widget w = item->subMenu->FindMenuItem(Id);
  1138.       if (w)
  1139.         return w;
  1140.     }
  1141.     node = node->Next();
  1142.   }
  1143.   return NULL;
  1144. }
  1145. #endif
  1146.  
  1147.  
  1148. #ifdef wx_xview
  1149. void wxMenuProc(Menu x_menu, Menu_item menu_item)
  1150. {
  1151.  
  1152.   wxMenu *item = (wxMenu *)xv_get(x_menu, MENU_CLIENT_DATA);
  1153.   char *label = (char *)xv_get(menu_item, MENU_STRING);
  1154.   int index = (int)xv_get(menu_item, MENU_CLIENT_DATA);
  1155.  
  1156.   // Should find top-level menu and use ITS callback
  1157.   wxMenu *top_level_menu = item->top_level_menu;
  1158.  
  1159.   wxFrame *frame = NULL;
  1160.  
  1161.   // If a menu bar, send a message to the frame
  1162.   if (top_level_menu && top_level_menu->menu_bar)
  1163.   {
  1164.     frame = top_level_menu->menu_bar->menu_bar_frame;
  1165.     frame->OnMenuCommand(index);
  1166.   }
  1167.   else if (top_level_menu && top_level_menu->callback)
  1168.     {
  1169.       wxEvent event(NULL);
  1170.  
  1171.       event.string = label;
  1172.       event.index = index;
  1173.  
  1174.       (void)(*(top_level_menu->callback))(*item, event);
  1175.     }
  1176. }
  1177.  
  1178. #endif
  1179.  
  1180. // Menu Bar
  1181.  
  1182. wxMenuBar::wxMenuBar(void)
  1183. {
  1184. #ifdef wx_msw
  1185.   wxWinType = wxTYPE_HMENU;
  1186. #endif
  1187.   n = 0;
  1188.   menus = NULL;
  1189.   titles = NULL;
  1190.   menu_bar_frame = NULL;
  1191. }
  1192.  
  1193. wxMenuBar::wxMenuBar(int N, wxMenu *Menus[], char *Titles[])
  1194. {
  1195. #ifdef wx_msw
  1196.   wxWinType = wxTYPE_HMENU;
  1197. #endif
  1198.   n = N;
  1199.   menus = Menus;
  1200.   titles = Titles;
  1201.   menu_bar_frame = NULL;
  1202. }
  1203.  
  1204. wxMenuBar::~wxMenuBar(void)
  1205. {
  1206. #ifdef wx_motif
  1207. #endif
  1208. #ifdef wx_xview
  1209.   wxFrame *frame = menu_bar_frame;
  1210.   if (frame)
  1211.   {
  1212.     frame->wx_menu_bar = 0;
  1213.     delete frame->menu_bar_panel;
  1214.     frame->y_offset = 0;
  1215.   }
  1216. #endif
  1217. #ifdef wx_msw
  1218.   HMENU menu = (HMENU)ms_handle;
  1219.  
  1220.   if (menu_bar_frame)
  1221.   {
  1222.     wxWnd *cframe = (wxWnd *)menu_bar_frame->handle;
  1223.     switch (menu_bar_frame->frame_type)
  1224.     {
  1225.       case wxMDI_PARENT:
  1226.       case wxMDI_CHILD:
  1227.       {
  1228.         int N = GetMenuItemCount(menu);
  1229.         int i;
  1230.         for (i = 0; i < N; i++)
  1231.         {
  1232.           char buf[100];
  1233.           int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
  1234.           if ((chars > 0) && (strcmp(buf, "&Window") == 0))
  1235.           {
  1236.             RemoveMenu(menu, i, MF_BYPOSITION);
  1237.           }
  1238.         }
  1239.         break;
  1240.       }
  1241.       default:
  1242.       case wxSDI:
  1243.         break;
  1244.     }
  1245.   }
  1246.  
  1247.   DestroyMenu(menu);
  1248.   ms_handle = NULL;
  1249. #endif
  1250.  
  1251.   int i;
  1252.   for (i = 0; i < n; i++)
  1253.   {
  1254.     delete menus[i];
  1255.     delete titles[i];
  1256.   }
  1257.   delete menus;
  1258.   delete titles;
  1259. }
  1260.  
  1261. void wxMenuBar::Append(wxMenu *menu, char *title)
  1262. {
  1263.   n ++;
  1264.   wxMenu **new_menus = new wxMenu *[n];
  1265.   char **new_titles = new char *[n];
  1266.  
  1267.   int i;
  1268.   for (i = 0; i < n - 1; i++)
  1269.     {
  1270.       new_menus[i] = menus[i];
  1271.       menus[i] = NULL;
  1272.       new_titles[i] = titles[i];
  1273.       titles[i] = NULL;
  1274.     }
  1275.   if (menus)
  1276.    {
  1277.      delete menus;
  1278.      delete titles;
  1279.    }
  1280.   menus = new_menus;
  1281.   titles = new_titles;
  1282.  
  1283.   menus[n-1] = menu;
  1284.   titles[n-1] = copystring(title);
  1285.  
  1286.   menu->menu_bar = this;
  1287. }
  1288.  
  1289. // Must only be used AFTER menu has been attached to frame,
  1290. // otherwise use individual menus to enable/disable items
  1291. void wxMenuBar::Enable(int Id, Bool Flag)
  1292. {
  1293. #ifdef wx_motif
  1294.   for (int j = 0; j < n; j++)
  1295.   {
  1296.     Widget w = menus[j]->FindMenuItem(Id);
  1297.     if (w)
  1298.     {
  1299.       XtSetSensitive(w, Flag);
  1300.       return;
  1301.     }
  1302.   }
  1303. #endif
  1304. #ifdef wx_xview
  1305.   for (int j = 0; j < n; j++)
  1306.   {
  1307.     Menu_item item = menus[j]->FindMenuItem(Id);
  1308.     if (item)
  1309.     {
  1310.       xv_set(item, MENU_INACTIVE, !Flag, NULL);
  1311.       return;
  1312.     }
  1313.   }
  1314. #endif
  1315. #ifdef wx_msw
  1316.   int ms_flag;
  1317.   if (Flag)
  1318.     ms_flag = MF_ENABLED;
  1319.   else
  1320.     ms_flag = MF_GRAYED;
  1321.   EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
  1322. #endif
  1323. }
  1324.  
  1325. // Must only be used AFTER menu has been attached to frame,
  1326. // otherwise use individual menus
  1327. void wxMenuBar::Check(int Id, Bool Flag)
  1328. {
  1329. #ifdef wx_motif
  1330. #endif
  1331. #ifdef wx_xview
  1332. #endif
  1333. #ifdef wx_msw
  1334.   int ms_flag;
  1335.   if (Flag)
  1336.     ms_flag = MF_CHECKED;
  1337.   else
  1338.     ms_flag = MF_UNCHECKED;
  1339.   EnableMenuItem((HMENU)ms_handle, Id, MF_BYCOMMAND | ms_flag);
  1340. #endif
  1341. }
  1342.  
  1343. #ifdef wx_motif
  1344. void wxMenuItemCallback(Widget w, XtPointer clientData,
  1345.                       XtPointer ptr)
  1346. {
  1347.   wxMenuItem *item = (wxMenuItem *)clientData;
  1348.   if (item)
  1349.   {
  1350.      if (item->menuBar && item->menuBar->menu_bar_frame)
  1351.      {
  1352. //       cout << "Id = " << item->itemId << "\n";
  1353.        item->menuBar->menu_bar_frame->OnMenuCommand(item->itemId);
  1354.      }
  1355.   }
  1356. }
  1357.  
  1358. void wxMenuItemArmCallback(Widget w, XtPointer clientData,
  1359.                       XtPointer ptr)
  1360. {
  1361.   wxMenuItem *item = (wxMenuItem *)clientData;
  1362.   if (item)
  1363.   {
  1364.      if (item->menuBar && item->menuBar->menu_bar_frame)
  1365.      {
  1366.        item->menuBar->menu_bar_frame->OnMenuSelect(item->itemId);
  1367.      }
  1368.   }
  1369. }
  1370.  
  1371. void wxMenuItemDisarmCallback(Widget w, XtPointer clientData,
  1372.                       XtPointer ptr)
  1373. {
  1374.   wxMenuItem *item = (wxMenuItem *)clientData;
  1375.   if (item)
  1376.   {
  1377.      if (item->menuBar && item->menuBar->menu_bar_frame)
  1378.      {
  1379.        item->menuBar->menu_bar_frame->OnMenuSelect(-1);
  1380.      }
  1381.   }
  1382. }
  1383.  
  1384. Widget wxMenu::CreateMenu(wxMenuBar *menu_bar, Widget parent, char *title)
  1385. {
  1386.   char mnem = wxFindMnemonic(title);
  1387.   wxStripMenuCodes(title, wxBuffer);
  1388.  
  1389.   Widget PullDown = XmCreatePulldownMenu(parent, "PullDown", NULL, 0);
  1390.  
  1391.   XmString label_str = XmStringCreateSimple(wxBuffer);
  1392.   Widget menuButton = XtVaCreateManagedWidget(wxBuffer, 
  1393.     xmCascadeButtonWidgetClass, parent,
  1394.     XmNlabelString,  label_str,
  1395.     XmNsubMenuId,    PullDown,
  1396.     NULL);
  1397.   /*
  1398.    * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
  1399.    */
  1400.   if (strcmp(wxBuffer, "Help") == 0)
  1401.     XtVaSetValues((Widget)menu_bar->handle, XmNmenuHelpWidget, menuButton, NULL);
  1402.  
  1403.   if (mnem != 0)
  1404.     XtVaSetValues(menuButton, XmNmnemonic, mnem, NULL);
  1405.  
  1406.   XmStringFree(label_str);
  1407.  
  1408.   wxNode *node = menuItems.First();
  1409.   while (node)
  1410.   {
  1411.     wxMenuItem *item = (wxMenuItem *)node->Data();
  1412.     item->menuBar = menu_bar;
  1413.  
  1414.     if (item->itemName && (!item->subMenu))
  1415.     {
  1416.       wxStripMenuCodes(item->itemName, wxBuffer);
  1417.       item->buttonWidget = XtVaCreateManagedWidget(wxBuffer,
  1418.        xmPushButtonGadgetClass, PullDown, NULL);
  1419.  
  1420.       mnem = wxFindMnemonic(item->itemName);  
  1421.       if (mnem != 0)
  1422.         XtVaSetValues(item->buttonWidget, XmNmnemonic, mnem, NULL);
  1423.  
  1424.       XtAddCallback(item->buttonWidget, XmNactivateCallback, wxMenuItemCallback, (XtPointer)item);
  1425.       XtAddCallback(item->buttonWidget, XmNarmCallback, wxMenuItemArmCallback, (XtPointer)item);
  1426.       XtAddCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
  1427.     }
  1428.     else if (item->itemId == -1)
  1429.     {
  1430.       item->buttonWidget = XtVaCreateManagedWidget("separator",
  1431.     xmSeparatorGadgetClass, PullDown, NULL);
  1432.     }
  1433.     else if (item->subMenu)
  1434.     {
  1435.       item->buttonWidget = item->subMenu->CreateMenu(menu_bar, PullDown, item->itemName);
  1436.       XtAddCallback(item->buttonWidget, XmNcascadingCallback, wxMenuItemArmCallback, (XtPointer)item);
  1437. //      XtAddCallback(item->buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer)item);
  1438.     }
  1439.     node = node->Next();
  1440.   }
  1441.   handle = (char *)PullDown;
  1442.   return menuButton;
  1443. }
  1444. #endif
  1445.  
  1446. #ifdef wx_motif
  1447. Widget wxFrame::GetMenuBarWidget(void)
  1448. {
  1449.   return (Widget)wx_menu_bar->handle;
  1450. }
  1451. #endif
  1452.  
  1453. void wxFrame::SetMenuBar(wxMenuBar *menu_bar)
  1454. {
  1455. #ifdef wx_motif
  1456.   Widget MenuBar = XmCreateMenuBar(frameWidget, "MenuBar", NULL, 0); 
  1457.   menu_bar->handle = (char *)MenuBar;
  1458.  
  1459.   for (int i = 0; i < menu_bar->n; i ++)
  1460.   {
  1461.     wxMenu *menu = menu_bar->menus[i];
  1462.     menu->buttonWidget = menu->CreateMenu(menu_bar, MenuBar, menu_bar->titles[i]);
  1463.   }
  1464.  
  1465.   XtRealizeWidget(MenuBar);
  1466.   XtManageChild(MenuBar);
  1467. #endif
  1468. #ifdef wx_xview
  1469.   y_offset = 0;
  1470.   menu_bar_panel = new wxPanel(this, 0, 0, -1, MENU_BAR_PANEL_HEIGHT-1);
  1471.   children->DeleteObject(menu_bar_panel);
  1472.   y_offset = MENU_BAR_PANEL_HEIGHT;
  1473.  
  1474.   int i;
  1475.   for (i = 0; i < menu_bar->n; i ++)
  1476.   {
  1477.     wxStripMenuCodes(menu_bar->titles[i], wxBuffer);
  1478.     Menu x_menu = (Menu)(menu_bar->menus[i]->handle);
  1479.     (void) xv_create((Panel)(menu_bar_panel->handle), PANEL_BUTTON,
  1480.                               PANEL_LABEL_STRING, wxBuffer,
  1481.                               PANEL_ITEM_MENU, x_menu,
  1482.                               NULL);
  1483.   }
  1484. #endif
  1485. #ifdef wx_msw
  1486.   int i;
  1487.   HMENU menu = CreateMenu();
  1488.  
  1489.   for (i = 0; i < menu_bar->n; i ++)
  1490.   {
  1491.     HMENU popup = (HMENU)menu_bar->menus[i]->ms_handle;
  1492.     menu_bar->menus[i]->ms_handle = NULL;
  1493.     AppendMenu(menu, MF_POPUP | MF_STRING, popup, menu_bar->titles[i]);
  1494.   }
  1495.  
  1496.   menu_bar->ms_handle = (HANDLE)menu;
  1497.   if (wx_menu_bar)
  1498.     delete wx_menu_bar;
  1499.  
  1500.   wxWnd *cframe = (wxWnd *)handle;
  1501.   switch (frame_type)
  1502.   {
  1503.     case wxMDI_PARENT:
  1504.     {
  1505.       wxMDIFrame *mdi_frame = (wxMDIFrame *)cframe;
  1506.  
  1507.       // Try to insert Window menu in front of Help, otherwise append it.
  1508.       int N = GetMenuItemCount(menu);
  1509.       Bool success = FALSE;
  1510.       for (i = 0; i < N; i++)
  1511.       {
  1512.         char buf[100];
  1513.         int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
  1514.         if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
  1515.                             strcmp(buf, "Help") == 0))
  1516.         {
  1517.            success = TRUE;
  1518.            InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
  1519.                       GetSubMenu(mdi_frame->window_menu, 0), "&Window");
  1520.            break;
  1521.         }
  1522.       }
  1523.       if (!success)
  1524.         AppendMenu(menu, MF_POPUP,
  1525.                          GetSubMenu(mdi_frame->window_menu, 0),
  1526.                          "&Window");
  1527.       mdi_frame->parent_frame_active = TRUE;
  1528. #ifdef WIN32
  1529.       SendMessage(mdi_frame->client_hwnd, WM_MDISETMENU, menu,
  1530.                   GetSubMenu(mdi_frame->window_menu, 0));
  1531. #else
  1532.       SendMessage(mdi_frame->client_hwnd, WM_MDISETMENU, 0,
  1533.                   MAKELPARAM(menu, GetSubMenu(mdi_frame->window_menu, 0)));
  1534. #endif
  1535.       DrawMenuBar(mdi_frame->handle);
  1536.       break;
  1537.     }
  1538.     case wxMDI_CHILD:
  1539.     {
  1540.       wxMDIFrame *parent = (wxMDIFrame *)GetParent()->handle;
  1541.       parent->parent_frame_active = FALSE;
  1542.  
  1543.       // Try to insert Window menu in front of Help, otherwise append it.
  1544.       int N = GetMenuItemCount(menu);
  1545.       Bool success = FALSE;
  1546.       for (i = 0; i < N; i++)
  1547.       {
  1548.         char buf[100];
  1549.         int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
  1550.         if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
  1551.                             strcmp(buf, "Help") == 0))
  1552.         {
  1553.            success = TRUE;
  1554.            InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
  1555.                       GetSubMenu(parent->window_menu, 0), "&Window");
  1556.            break;
  1557.         }
  1558.       }
  1559.       if (!success)
  1560.         AppendMenu(menu, MF_POPUP,
  1561.                          GetSubMenu(parent->window_menu, 0),
  1562.                          "&Window");
  1563. #ifdef WIN32
  1564.       SendMessage(parent->client_hwnd, WM_MDISETMENU, menu,
  1565.                   GetSubMenu(parent->window_menu, 0));
  1566. #else
  1567.       SendMessage(parent->client_hwnd, WM_MDISETMENU, 0,
  1568.                   MAKELPARAM(menu, GetSubMenu(parent->window_menu, 0)));
  1569. #endif
  1570.  
  1571.       DrawMenuBar(parent->handle);
  1572.       break;
  1573.     }
  1574.     default:
  1575.     case wxSDI:
  1576.     {
  1577.       SetMenu(cframe->handle, menu);
  1578.       break;
  1579.     }
  1580.   }
  1581. #endif
  1582.   wx_menu_bar = menu_bar;
  1583.   menu_bar->menu_bar_frame = this;
  1584. }
  1585.  
  1586. #ifdef wx_motif
  1587. void wxCheckBoxCallback(Widget w, XtPointer clientData,
  1588.                       XtPointer ptr)
  1589. {
  1590.   wxItem *item = (wxItem *)clientData;
  1591.   wxFunction fun = item->callback;
  1592.   if (fun)
  1593.   {
  1594.     wxEvent event;
  1595.     (void)(*(fun))(*item, event);
  1596.   }
  1597. }
  1598. #endif
  1599.  
  1600.  
  1601. // Single check box item
  1602. wxCheckBox::wxCheckBox(wxPanel *panel, wxFunction func, char *Title,
  1603.                        int x, int y, int width, int height)
  1604. {
  1605.   window_parent = panel;
  1606.   labelPosition = panel->label_position;
  1607. #ifdef wx_motif
  1608.   Widget panelForm = panel->panelWidget;
  1609.   XmString text = XmStringCreateSimple(Title);
  1610.  
  1611.   formWidget = XtVaCreateManagedWidget("rowcol",
  1612.                   xmRowColumnWidgetClass, panelForm,
  1613.                   XmNorientation, XmHORIZONTAL,
  1614.                   NULL);
  1615.  
  1616.   Widget buttonWidget;
  1617.  
  1618.   buttonWidget = XtVaCreateManagedWidget("toggle",
  1619.                   xmToggleButtonWidgetClass, formWidget,
  1620.                   XmNlabelString,      text,
  1621.                   NULL);
  1622.  
  1623.   handle = (char *)buttonWidget;
  1624.  
  1625.   XmStringFree(text);
  1626.  
  1627.   XtAddCallback(buttonWidget, XmNvalueChangedCallback, wxCheckBoxCallback,
  1628.                   this);
  1629.  
  1630.   AttachWidget(panel, formWidget, x, y, width, height);
  1631.  
  1632.   XmToggleButtonSetState(buttonWidget, FALSE, TRUE);
  1633. #endif
  1634. #ifdef wx_xview
  1635.   Panel x_panel = (Panel)panel->GetHandle();
  1636.   Panel_item x_choice;
  1637.  
  1638.   int label_position;
  1639.  
  1640.   if (panel->label_position == wxVERTICAL)
  1641.     label_position = PANEL_VERTICAL;
  1642.   else
  1643.     label_position = PANEL_HORIZONTAL;
  1644.  
  1645.   if (panel->new_line)
  1646.   {
  1647.     x_choice = (Panel_item) xv_create(x_panel, PANEL_CHECK_BOX, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
  1648.     panel->new_line = FALSE;
  1649.   }
  1650.   else
  1651.     x_choice = (Panel_item) xv_create(x_panel, PANEL_CHECK_BOX, PANEL_LAYOUT, label_position, NULL);
  1652.  
  1653.   xv_set(x_choice,
  1654. //                          PANEL_LABEL_STRING, Title,
  1655.                           PANEL_NOTIFY_PROC, wxCheckBoxProc,
  1656.                           PANEL_CLIENT_DATA, (char *)this,
  1657.                           PANEL_VALUE, 0,
  1658.                           PANEL_CHOICE_STRING, 0, Title,
  1659.                           NULL);
  1660.   if (x > -1 && y > -1)
  1661.     (void)xv_set(x_choice, XV_X, x, XV_Y, y, NULL);
  1662.  
  1663.   handle = (char *)x_choice;
  1664. #endif
  1665. #ifdef wx_msw
  1666.   wxWinType = wxTYPE_HWND;
  1667.   wxWnd *cparent = NULL;
  1668.   if (panel)
  1669.     cparent = (wxWnd *)panel->handle;
  1670.  
  1671.   panel->GetValidPosition(&x, &y);
  1672.  
  1673.   windows_id = (int)NewId();
  1674.  
  1675.   HWND wx_button = CreateWindowEx(0, "BUTTON", Title,
  1676.                     BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD,
  1677.                     0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  1678.                     wxhInstance, NULL);
  1679.  
  1680.   ms_handle = (HANDLE)wx_button;
  1681.   SetSize(x, y, width, height);
  1682.  
  1683.   panel->AdvanceCursor(this);
  1684.   ShowWindow(wx_button, SW_SHOW);
  1685. #endif
  1686.  
  1687.   if (panel) panel->AddChild(this);
  1688.   Callback(func);
  1689. }
  1690.  
  1691. wxCheckBox::~wxCheckBox(void)
  1692. {
  1693. }
  1694.  
  1695. void wxCheckBox::SetSize(int x, int y, int width, int height)
  1696. {
  1697. #ifdef wx_motif
  1698.  wxItem::SetSize(x, y, width, height);
  1699. #endif
  1700. #ifdef wx_xview
  1701.   Xv_opaque x_win = (Xv_opaque)handle;
  1702.  
  1703.   if (x > -1)
  1704.     (void)xv_set(x_win, XV_X, x, NULL);
  1705.  
  1706.   if (y > -1)
  1707.     (void)xv_set(x_win, XV_Y, y, NULL);
  1708.  
  1709.   if (width > 0)
  1710.     (void)xv_set(x_win, XV_WIDTH, width, NULL);
  1711.  
  1712.   if (height > 0)
  1713.     (void)xv_set(x_win, XV_HEIGHT, height, NULL);
  1714.   OnSize(width, height);
  1715. #endif
  1716. #ifdef wx_msw
  1717.   int currentX, currentY;
  1718.   GetPosition(¤tX, ¤tY);
  1719.   if (x == -1)
  1720.     x = currentX;
  1721.   if (y == -1)
  1722.     y = currentY;
  1723.  
  1724.   char buf[300];
  1725.  
  1726.   float current_width;
  1727.  
  1728.   int cx;
  1729.   int cy;
  1730.   float cyf;
  1731.  
  1732.   HWND button = (HWND)ms_handle;
  1733.   wxGetCharSize(button, &cx, &cy);
  1734.  
  1735.   if (width < 0)
  1736.   {
  1737.     GetWindowText(button, buf, 300);
  1738.     GetTextExtent(buf, ¤t_width, &cyf);
  1739.     MoveWindow(button, x, y, (int)(current_width + 3*cx), (int)cyf, TRUE);
  1740.   }
  1741.   else
  1742.     MoveWindow(button, x, y, width, height, TRUE);
  1743.   OnSize(width, height);
  1744. #endif
  1745. }
  1746.  
  1747.  
  1748. void wxCheckBox::SetValue(Bool val)
  1749. {
  1750. #ifdef wx_motif
  1751.   Widget buttonWidget = (Widget)handle;
  1752.   XmToggleButtonSetState(buttonWidget, val, TRUE);
  1753. #endif
  1754. #ifdef wx_xview
  1755.   Panel_item item = (Panel_item)handle;
  1756.   int the_val = 0;
  1757.   if (val)
  1758.     the_val = 1;
  1759.  
  1760.   xv_set(item, PANEL_VALUE, the_val, NULL);
  1761. #endif
  1762. #ifdef wx_msw
  1763.   SendMessage((HWND)ms_handle, BM_SETCHECK, val, 0);
  1764. #endif
  1765. }
  1766.  
  1767. Bool wxCheckBox::GetValue(void)
  1768. {
  1769. #ifdef wx_motif
  1770.   Widget buttonWidget = (Widget)handle;
  1771.   return XmToggleButtonGetState(buttonWidget);
  1772. #endif
  1773. #ifdef wx_xview
  1774.   Panel_item item = (Panel_item)handle;
  1775.   return (Bool)xv_get(item, PANEL_VALUE);
  1776. #endif
  1777. #ifdef wx_msw
  1778.   return (Bool)(0x003 & SendMessage((HWND)ms_handle, BM_GETSTATE, 0, 0));
  1779. #endif
  1780. }
  1781.  
  1782. #ifdef wx_xview
  1783. void wxCheckBoxProc(Panel_item item, int value, Event *x_event)
  1784. {
  1785.   wxCheckBox *choice = (wxCheckBox *)xv_get(item, PANEL_CLIENT_DATA);
  1786.   char *label = (char *) xv_get(item, PANEL_LABEL_STRING);
  1787.  
  1788.   wxEvent event(x_event);
  1789.  
  1790.   event.string = label;
  1791.   event.index = value;
  1792.  
  1793.   if (choice->callback)
  1794.     {
  1795.       (void)(*(choice->callback))(*choice, event);
  1796.     }
  1797. }
  1798. #endif
  1799.  
  1800. #ifdef wx_motif
  1801. void wxChoiceButtonCallback(Widget menu_item, XtPointer clientData, XButtonPressedEvent *event)
  1802. {
  1803.   if (event->button != 1)
  1804.     return;
  1805.  
  1806.   wxChoice *item = (wxChoice *)clientData;
  1807.   XmMenuPosition(item->menuWidget, event);
  1808.   XtManageChild(item->menuWidget);
  1809. }
  1810.  
  1811. void wxChoiceCallback(Widget w, XtPointer clientData,
  1812.                       XtPointer ptr)
  1813. {
  1814.   wxChoice *item = (wxChoice *)clientData;
  1815.   if (item)
  1816.   {
  1817.     XtUnmanageChild(item->menuWidget);
  1818.     char *s = NULL;
  1819.     XtVaGetValues(w, XmNuserData, &s, NULL);
  1820.     if (s)
  1821.     {
  1822.       XmString text = XmStringCreateSimple(s);
  1823.       XtVaSetValues(item->messageWidget,
  1824.                       XmNlabelString, text,
  1825.                       NULL);
  1826.       XmStringFree(text);
  1827.     }
  1828.   }
  1829. }
  1830.  
  1831. #endif
  1832.  
  1833. wxChoice::wxChoice(wxPanel *panel, wxFunction func, char *Title,
  1834.                    int x, int y, int width, int height, int N, char **Choices)
  1835. {
  1836.   window_parent = panel;
  1837.   labelPosition = panel->label_position;
  1838.   no_strings = N;
  1839. #ifdef wx_motif
  1840. //  char mnem = wxFindMnemonic(Title);
  1841.   wxStripMenuCodes(Title, wxBuffer);
  1842.  
  1843.   Widget panelForm = panel->panelWidget;
  1844.   formWidget = XtVaCreateManagedWidget("rowcol",
  1845.                   xmRowColumnWidgetClass, panelForm,
  1846.                   XmNorientation, panel->label_position == wxHORIZONTAL ? XmHORIZONTAL: XmVERTICAL,
  1847.                   NULL);
  1848.   XmString text = XmStringCreateSimple(Title);
  1849.  
  1850.   /*
  1851.    * Create the label
  1852.    *
  1853.    */
  1854.  
  1855.   labelWidget = XtVaCreateManagedWidget("choice",
  1856.                   xmLabelWidgetClass,  formWidget,
  1857.                   XmNlabelString,      text,
  1858.                   NULL);
  1859.  
  1860.   /*
  1861.    * Create row widget for selection and button
  1862.    *
  1863.    */
  1864.  
  1865.   rowWidget = XtVaCreateManagedWidget("rowcol", 
  1866.                   xmRowColumnWidgetClass, formWidget,
  1867.                   XmNorientation, XmHORIZONTAL,
  1868.                   NULL);
  1869.  
  1870.   /*
  1871.    * Create label widget for the selection
  1872.    */
  1873.  
  1874.   messageWidget = XtVaCreateManagedWidget("selection", xmLabelWidgetClass, rowWidget, NULL);
  1875.   XtManageChild(messageWidget);
  1876.  
  1877.   /*
  1878.    * Create button
  1879.    */
  1880.  
  1881.   buttonWidget = XtVaCreateManagedWidget("button",
  1882.                   xmArrowButtonWidgetClass, rowWidget,
  1883.                   XmNarrowDirection, XmARROW_RIGHT,
  1884.                   XmNwidth, 20,
  1885.                   XmNheight, 20,
  1886.                   NULL);
  1887.  
  1888.   handle = (char *)buttonWidget;
  1889.  
  1890.   XtAddEventHandler(buttonWidget, ButtonPressMask, False, wxChoiceButtonCallback, this);
  1891.  
  1892.   XtManageChild(buttonWidget);
  1893.  
  1894.   /*
  1895.    * Create the popup menu
  1896.    */
  1897.   menuWidget = XmCreatePopupMenu(panelForm, "popup", NULL, 0);
  1898.  
  1899.  
  1900.   XmStringFree(text);
  1901.  
  1902.   XtManageChild(rowWidget);
  1903.  
  1904.   AttachWidget(panel, formWidget, x, y, width, height);
  1905.  
  1906.   no_strings = 0;
  1907.   if (N > 0)
  1908.     for (int i = 0; i < N; i++)
  1909.       Append(Choices[i]);
  1910. #endif
  1911. #ifdef wx_xview
  1912.   char *title = NULL;
  1913.   if (Title)
  1914.     title = Title;
  1915.  
  1916.   Panel x_panel = (Panel)panel->GetHandle();
  1917.   Panel_item x_choice;
  1918.  
  1919.   int label_position;
  1920.   if (panel->label_position == wxVERTICAL)
  1921.     label_position = PANEL_VERTICAL;
  1922.   else
  1923.     label_position = PANEL_HORIZONTAL;
  1924.  
  1925.   if (panel->new_line)
  1926.   {
  1927.     x_choice = (Panel_item) xv_create(x_panel, PANEL_CHOICE_STACK, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
  1928.     panel->new_line = FALSE;
  1929.   }
  1930.   else
  1931.     x_choice = (Panel_item) xv_create(x_panel, PANEL_CHOICE_STACK, PANEL_LAYOUT, label_position,NULL);
  1932.  
  1933.   xv_set(x_choice,
  1934.                           PANEL_LABEL_STRING, title,
  1935.                           PANEL_NOTIFY_PROC, wxChoiceProc,
  1936.                           PANEL_CLIENT_DATA, (char *)this,
  1937.                           NULL);
  1938.   if (x > -1 && y > -1)
  1939.     (void)xv_set(x_choice, XV_X, x, XV_Y, y, NULL);
  1940.  
  1941.   for (int i = 0; i < N; i ++)
  1942.     { char *label = Choices[i];
  1943.       xv_set(x_choice, PANEL_CHOICE_STRING, i, label, NULL);
  1944.     }
  1945.   handle = (char *)x_choice;
  1946.  
  1947. #endif
  1948. #ifdef wx_msw
  1949.   wxWinType = wxTYPE_HWND;
  1950.  
  1951.   wxWnd *cparent = NULL;
  1952.   if (panel)
  1953.     cparent = (wxWnd *)(panel->handle);
  1954.  
  1955.   panel->GetValidPosition(&x, &y);
  1956.  
  1957.   if (Title)
  1958.   {
  1959.     static_label = CreateWindowEx(0, "STATIC", Title,
  1960.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  1961.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  1962.                          wxhInstance, NULL);
  1963.  
  1964.   }
  1965.   else
  1966.     static_label = NULL;
  1967.  
  1968.   windows_id = (int)NewId();
  1969.  
  1970.   HWND wx_combo = CreateWindowEx(0, "COMBOBOX", NULL,
  1971.                    WS_CHILD | CBS_DROPDOWNLIST | WS_HSCROLL | WS_VSCROLL
  1972.                    | WS_BORDER | WS_TABSTOP | WS_VISIBLE,
  1973.                          0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  1974.                          wxhInstance, NULL);
  1975.  
  1976.   for (int i = 0; i < N; i++)
  1977.     SendMessage(wx_combo, CB_INSERTSTRING, i, (LONG)Choices[i]);
  1978.   SendMessage(wx_combo, CB_SETCURSEL, i, 0);
  1979.  
  1980.   ms_handle = (HANDLE)wx_combo;
  1981.  
  1982.   SetSize(x, y, width, height);
  1983.   panel->AdvanceCursor(this);
  1984. #endif
  1985.  
  1986.   if (panel) panel->AddChild(this);
  1987.   Callback(func);
  1988.  
  1989. }
  1990.  
  1991. wxChoice::~wxChoice(void)
  1992. {
  1993. #ifdef wx_motif
  1994.   XtDestroyWidget(menuWidget);
  1995.   XtDestroyWidget(rowWidget);
  1996.   XtDestroyWidget(messageWidget);
  1997. #endif
  1998. #ifdef wx_msw
  1999.   if (static_label)
  2000.     DestroyWindow(static_label);
  2001.   static_label = NULL;
  2002. #endif
  2003. }
  2004.  
  2005.  
  2006. void wxChoice::Append(char *Item)
  2007. {
  2008. #ifdef wx_motif
  2009.   wxStripMenuCodes(Item, wxBuffer);
  2010.   Widget w = XtVaCreateManagedWidget(wxBuffer,
  2011.     xmPushButtonWidgetClass, menuWidget, NULL);
  2012.  
  2013.   char mnem = wxFindMnemonic(Item);  
  2014.   if (mnem != 0)
  2015.     XtVaSetValues(w, XmNmnemonic, mnem, NULL);
  2016.  
  2017.   XtAddCallback(w, XmNactivateCallback, wxChoiceCallback, (XtPointer)this);
  2018.  
  2019.   if (no_strings == 0)
  2020.   {
  2021.     XmString text = XmStringCreateSimple(Item);
  2022.     XtVaSetValues(messageWidget,
  2023.                     XmNlabelString, text,
  2024.                     NULL);
  2025.     XmStringFree(text);
  2026.   }
  2027.   wxNode *node = stringList.Add(Item);
  2028.   XtVaSetValues(w, XmNuserData, node->Data(), NULL);
  2029. #endif
  2030. #ifdef wx_xview
  2031.   Panel_item choice_item = (Panel_item)handle;
  2032.  
  2033.   xv_set(choice_item, PANEL_CHOICE_STRING, no_strings, Item,  NULL);
  2034. #endif
  2035. #ifdef wx_msw
  2036.   SendMessage((HWND)ms_handle, CB_ADDSTRING, 0, (LONG)Item);
  2037. #endif
  2038.   no_strings ++;
  2039. }
  2040.  
  2041. // Unfortunately, under XView it doesn't redisplay until user resizes
  2042. // window. Any suggestions folks?
  2043. void wxChoice::Clear(void)
  2044. {
  2045. #ifdef wx_motif
  2046.   stringList.Clear();
  2047.  
  2048.   XmString text = XmStringCreateSimple("");
  2049.   XtVaSetValues(messageWidget,
  2050.                   XmNlabelString, text,
  2051.                   NULL);
  2052.   XmStringFree(text);
  2053.  
  2054.   XtDestroyWidget(menuWidget);
  2055.  
  2056.   wxPanel *panel = (wxPanel *)GetParent();
  2057.   Widget panelForm = panel->panelWidget;
  2058.   menuWidget = XmCreatePopupMenu(panelForm, "popup", NULL, 0);
  2059. #endif
  2060. #ifdef wx_xview
  2061.   Panel_item choice_item = (Panel_item)handle;
  2062.   Rect *rect = (Rect *)xv_get(choice_item, XV_RECT);
  2063.  
  2064.   int height = rect->r_height;
  2065.   int width = rect->r_width;
  2066.   int x = (int)xv_get(choice_item, XV_X);
  2067.   int y = (int)xv_get(choice_item, XV_Y);
  2068.   char *label = GetLabel();
  2069.  
  2070.   xv_destroy_safe(choice_item);
  2071.   Panel panel = (Panel)GetParent()->handle;
  2072.   choice_item = (Panel_item) xv_create(panel, PANEL_CHOICE_STACK,
  2073.                           PANEL_LABEL_STRING, label,
  2074.                           PANEL_NOTIFY_PROC, wxChoiceProc,
  2075.                           PANEL_CLIENT_DATA, (char *)this,
  2076.                           XV_X, x, XV_Y, y, XV_WIDTH, width, XV_HEIGHT, height,
  2077.                           XV_SHOW, TRUE,
  2078.                           NULL);
  2079.  
  2080.   handle = (char *)choice_item;
  2081. #endif
  2082. #ifdef wx_msw
  2083.   SendMessage((HWND)ms_handle, CB_RESETCONTENT, 0, 0);
  2084. #endif
  2085.   no_strings = 0;
  2086. }
  2087.  
  2088.  
  2089. int wxChoice::GetSelection(void)
  2090. {
  2091. #ifdef wx_motif
  2092.   XmString text;
  2093.   char *s;
  2094.   XtVaGetValues(messageWidget,
  2095.                   XmNlabelString, &text,
  2096.                   NULL);
  2097.  
  2098.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  2099.   {
  2100.     int i = 0;
  2101.     wxNode *node = stringList.First();
  2102.     while (node)
  2103.     {
  2104.       char *s1 = (char *)node->Data();
  2105.       if (strcmp(s1, s) == 0)
  2106.       {
  2107.         XtFree(s);
  2108.     return i;
  2109.       }
  2110.       else
  2111.       {
  2112.         i ++;
  2113.         node = node->Next();
  2114.       }
  2115.     }
  2116.  
  2117.     XtFree(s);
  2118.     return -1;
  2119.   }
  2120.   else
  2121.   {
  2122.     return -1;
  2123.   }
  2124. #endif
  2125. #ifdef wx_xview
  2126.   Panel_item x_choice = (Panel_item)handle;
  2127.   
  2128.   return xv_get(x_choice, PANEL_VALUE);
  2129. #endif
  2130. #ifdef wx_msw
  2131.   return (int)SendMessage((HWND)ms_handle, CB_GETCURSEL, 0, 0);
  2132. #endif
  2133. }
  2134.  
  2135. void wxChoice::SetSelection(int n)
  2136. {
  2137. #ifdef wx_motif
  2138.   wxNode *node = stringList.Nth(n);
  2139.   if (node)
  2140.   {
  2141.     char *s = (char *)node->Data();
  2142.     XmString text = XmStringCreateSimple(s);
  2143.     XtVaSetValues(messageWidget,
  2144.                     XmNlabelString, text,
  2145.                     NULL);
  2146.     XmStringFree(text);
  2147.   }
  2148. #endif
  2149. #ifdef wx_xview
  2150.   Panel_item x_choice = (Panel_item)handle;
  2151.   
  2152.   (void)xv_set(x_choice, PANEL_VALUE, n, NULL);
  2153. #endif
  2154. #ifdef wx_msw
  2155.   SendMessage((HWND)ms_handle, CB_SETCURSEL, n, 0);
  2156. #endif
  2157. }
  2158.  
  2159. char *wxChoice::GetStringSelection(void)
  2160. {
  2161.   int sel = GetSelection();
  2162.   if (sel > -1)
  2163.     return this->String(sel);
  2164.   else
  2165.     return NULL;
  2166. }
  2167.  
  2168. Bool wxChoice::SetStringSelection(char *s)
  2169. {
  2170.   int sel = FindString(s);
  2171.   if (sel > -1)
  2172.   {
  2173.     SetSelection(sel);
  2174.     return TRUE;
  2175.   }
  2176.   else return FALSE;
  2177. }
  2178.  
  2179. int wxChoice::FindString(char *s)
  2180. {
  2181. #ifdef wx_motif
  2182.   int i = 0;
  2183.   wxNode *node = stringList.First();
  2184.   while (node)
  2185.   {
  2186.     char *s1 = (char *)node->Data();
  2187.     if (strcmp(s1, s) == 0)
  2188.     {
  2189.       return i;
  2190.     }
  2191.     else
  2192.     {
  2193.       i ++;
  2194.       node = node->Next();
  2195.     }
  2196.   }
  2197.   return -1;
  2198. #endif
  2199. #ifdef wx_xview
  2200.   Panel_item choice = (Panel_item)handle;
  2201.  
  2202.   int max1 = no_strings;
  2203.  
  2204.   int i = 0;
  2205.   int found = -1;
  2206.   while (found == -1 && i < max1)
  2207.     {
  2208.       char *label = (char *)xv_get(choice, PANEL_CHOICE_STRING, i);
  2209.       if (label && strcmp(label, s) == 0)
  2210.         found = i;
  2211.       else i ++;
  2212.     }
  2213.   return found;
  2214. #endif
  2215. #ifdef wx_msw
  2216.  int pos = (int)SendMessage((HWND)ms_handle, CB_FINDSTRING, -1, (LONG)s);
  2217.  if (pos == LB_ERR)
  2218.    return -1;
  2219.  else
  2220.    return pos;
  2221. #endif
  2222. }
  2223.  
  2224. char *wxChoice::String(int n)
  2225. {
  2226. #ifdef wx_motif
  2227.   wxNode *node = stringList.Nth(n);
  2228.   if (node)
  2229.     return (char *)node->Data();
  2230.   else return NULL;
  2231. #endif
  2232. #ifdef wx_xview
  2233.   Panel_item item = (Panel_item)handle;
  2234.   return (char *)xv_get(item, PANEL_CHOICE_STRING, n);
  2235. #endif
  2236. #ifdef wx_msw
  2237.   int len = (int)SendMessage((HWND)ms_handle, CB_GETLBTEXT, n, (long)wxBuffer);
  2238.   wxBuffer[len] = 0;
  2239.   return wxBuffer;
  2240. #endif
  2241. }
  2242.  
  2243. void wxChoice::SetSize(int x, int y, int width, int height)
  2244. {
  2245. #ifdef wx_motif
  2246.  wxItem::SetSize(x, y, width, height);
  2247. #endif
  2248. #ifdef wx_xview
  2249.   Panel_item list_item = (Panel_item)handle;
  2250.  
  2251.   if (x > -1)
  2252.     xv_set(list_item, XV_X, x, NULL);
  2253.  
  2254.   if (y > -1)
  2255.     xv_set(list_item, XV_Y, y, NULL);
  2256.  
  2257.   if (width > 0)
  2258.     xv_set(list_item, XV_WIDTH, width, NULL);
  2259.   if (height > 0)
  2260.     xv_set(list_item, XV_HEIGHT, height, NULL);
  2261.   OnSize(width, height);
  2262. #endif
  2263. #ifdef wx_msw
  2264.   int currentX, currentY;
  2265.   GetPosition(¤tX, ¤tY);
  2266.   if (x == -1)
  2267.     x = currentX;
  2268.   if (y == -1)
  2269.     y = currentY;
  2270.  
  2271.   char buf[300];
  2272.  
  2273.   int y_offset = y;
  2274.   int x_offset = x;
  2275.   float current_width;
  2276.  
  2277.   int cx;
  2278.   int cy;
  2279.   float cyf;
  2280.  
  2281.   HWND wnd = (HWND)ms_handle;
  2282.   wxGetCharSize(wnd, &cx, &cy);
  2283.  
  2284.   if (static_label)
  2285.   {
  2286.     GetWindowText(static_label, buf, 300);
  2287.     GetTextExtent(buf, ¤t_width, &cyf);
  2288.  
  2289.     MoveWindow(static_label, x_offset, y_offset, (int)(current_width + cx), (int)cyf,
  2290.                TRUE);
  2291.  
  2292.     if (labelPosition == wxVERTICAL)
  2293.       y_offset += cy;
  2294.     else
  2295.       x_offset += (int)(current_width + cx);
  2296.   }
  2297.  
  2298.   if (width <= 0)
  2299.   {
  2300.     // Find the longest string
  2301.     if (no_strings == 0)
  2302.       width = 100;
  2303.     else
  2304.     {
  2305.       float len, ht;
  2306.       float longest = 0.0;
  2307.       int i;
  2308.       for (i = 0; i < no_strings; i++)
  2309.       {
  2310.         char *s = String(i);
  2311.         GetTextExtent(s, &len, &ht);
  2312.         if ( len > longest) longest = len;
  2313.       }
  2314.  
  2315.       width = (int)(longest + cx*5);
  2316.     }
  2317.   }
  2318.   // Choice drop-down list depends on number of items (limited to 10)
  2319.   if (height <= 0)
  2320.   {
  2321.     if (no_strings == 0)
  2322.       height = cy*10;
  2323.     else height = (int)(cy*(min(10, no_strings) + 2));
  2324.   }
  2325.  
  2326.   MoveWindow(wnd, x_offset, y_offset, width, height, TRUE);
  2327.   OnSize(width, height);
  2328. #endif
  2329. }
  2330.  
  2331. void wxChoice::GetSize(int *width, int *height)
  2332. {
  2333. #ifdef wx_motif
  2334.   wxItem::GetSize(width, height);
  2335. #endif
  2336. #ifdef wx_xview
  2337.   Panel_item item = (Panel_item)handle;
  2338.   Rect *rect = (Rect *)xv_get(item, XV_RECT);
  2339.  
  2340.   *height = rect->r_height;
  2341.   *width = rect->r_width;
  2342. #endif
  2343. #ifdef wx_msw
  2344.   RECT rect;
  2345.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  2346.  
  2347.   wxFindMaxSize((HWND)ms_handle, &rect);
  2348.  
  2349.   if (static_label)
  2350.   {
  2351.     wxFindMaxSize(static_label, &rect);
  2352.   }
  2353.  
  2354.   *width = rect.right - rect.left;
  2355.   *height = rect.bottom - rect.top;
  2356. #endif
  2357. }
  2358.  
  2359. void wxChoice::GetPosition(int *x, int *y)
  2360. {
  2361. #ifdef wx_motif
  2362.   wxItem::GetPosition(x, y);
  2363. #endif
  2364. #ifdef wx_xview
  2365.   Xv_opaque x_win = (Xv_opaque)handle;
  2366.  
  2367.   *x = (int)xv_get(x_win, XV_X);
  2368.   *y = (int)xv_get(x_win, XV_Y);
  2369. #endif
  2370. #ifdef wx_msw
  2371.   HWND wnd = (HWND)ms_handle;
  2372.   wxWindow *parent = GetParent();
  2373.   RECT rect;
  2374.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  2375.  
  2376.   wxFindMaxSize(wnd, &rect);
  2377.   if (static_label)
  2378.     wxFindMaxSize(static_label, &rect);
  2379.  
  2380.   // Since we now have the absolute screen coords,
  2381.   // if there's a parent we must subtract its top left corner
  2382.   POINT point;
  2383.   point.x = rect.left;
  2384.   point.y = rect.top;
  2385.   if (parent)
  2386.   {
  2387.     wxWnd *cparent = (wxWnd *)(parent->handle);
  2388.     ScreenToClient(cparent->handle, &point);
  2389.   }
  2390.  
  2391.   *x = point.x;
  2392.   *y = point.y;
  2393. #endif
  2394. }
  2395.  
  2396. char *wxChoice::GetLabel(void)
  2397. {
  2398. #ifdef wx_motif
  2399.   XmString text;
  2400.   char *s;
  2401.   XtVaGetValues(labelWidget,
  2402.                   XmNlabelString, &text,
  2403.                   NULL);
  2404.  
  2405.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  2406.   {
  2407. //    XmStringFree(text);
  2408.     char *val = copystring(s);
  2409.     XtFree(s);
  2410.     return val;
  2411.   }
  2412.   else
  2413.   {
  2414. //    XmStringFree(text);
  2415.     return NULL;
  2416.   }
  2417. #endif
  2418. #ifdef wx_xview
  2419.   Panel_item item = (Panel_item)handle;
  2420.   return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
  2421. #endif
  2422. #ifdef wx_msw
  2423.   char buf[300];
  2424.   if (static_label)
  2425.   {
  2426.     GetWindowText(static_label, buf, 300);
  2427.     return copystring(buf);
  2428.   }
  2429.   else return NULL;
  2430. #endif
  2431. }
  2432.  
  2433. void wxChoice::SetLabel(char *label)
  2434. {
  2435. #ifdef wx_motif
  2436.   Widget widget = (Widget)handle;
  2437.   XmString text = XmStringCreateSimple(label);
  2438.   XtVaSetValues(widget,
  2439.                   XmNlabelString, text,
  2440.                   NULL);
  2441.   XmStringFree(text);
  2442. #endif
  2443. #ifdef wx_xview
  2444.   Panel_item item = (Panel_item)handle;
  2445.   xv_set(item, PANEL_LABEL_STRING, label, NULL);
  2446. #endif
  2447. #ifdef wx_msw
  2448.   if (static_label)
  2449.   {
  2450.     float w, h;
  2451.     RECT rect;
  2452.  
  2453.     wxWindow *parent = GetParent();
  2454.     GetWindowRect(static_label, &rect);
  2455.  
  2456.     // Since we now have the absolute screen coords,
  2457.     // if there's a parent we must subtract its top left corner
  2458.     POINT point;
  2459.     point.x = rect.left;
  2460.     point.y = rect.top;
  2461.     if (parent)
  2462.     {
  2463.       wxWnd *cparent = (wxWnd *)(parent->handle);
  2464.       ScreenToClient(cparent->handle, &point);
  2465.     }
  2466.  
  2467.     GetTextExtent(label, &w, &h);
  2468.     MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
  2469.                TRUE);
  2470.     SetWindowText(static_label, label);
  2471.   }
  2472. #endif
  2473. }
  2474.  
  2475.  
  2476. #ifdef wx_msw
  2477. BOOL wxChoice::Command(UINT param)
  2478. {
  2479.   wxFunction fun = callback;
  2480.   if (fun && (param == CBN_SELCHANGE))
  2481.   {
  2482.     wxEvent event;
  2483.     event.string = String(GetSelection());
  2484.     (void)(*(fun))(*this, event);
  2485.     return TRUE;
  2486.   }
  2487.   else return FALSE;
  2488. }
  2489. #endif
  2490.  
  2491. #ifdef wx_xview
  2492. void wxChoiceProc(Panel_item item, int value, Event *x_event)
  2493. {
  2494.   wxChoice *choice = (wxChoice *)xv_get(item, PANEL_CLIENT_DATA);
  2495.   char *label = (char *) xv_get(item, PANEL_CHOICE_STRING, value);
  2496.  
  2497.   wxEvent event(x_event);
  2498.  
  2499.   event.string = label;
  2500.   event.index = value;
  2501.  
  2502.   if (choice->callback)
  2503.     {
  2504.       (void)(*(choice->callback))(*choice, event);
  2505.     }
  2506. }
  2507. #endif
  2508.  
  2509. #ifdef wx_motif
  2510. void wxListBoxCallback(Widget w, XtPointer clientData,
  2511.                       XmListCallbackStruct *cbs)
  2512. {
  2513. /*
  2514.   if (cbs->reason == XmCR_EXTENDED_SELECT)
  2515.     cout << "*** Extend select\n";
  2516.   else if (cbs->reason == XmCR_SINGLE_SELECT)
  2517.     cout << "*** Single select\n";
  2518.   else if (cbs->reason == XmCR_MULTIPLE_SELECT)
  2519.     cout << "*** Multiple select\n";
  2520.   else if (cbs->reason == XmCR_BROWSE_SELECT)
  2521.     cout << "*** Browse select\n";
  2522.  
  2523.   if (cbs->selection_type == XmMODIFICATION)
  2524.     cout << "*** Modification\n";
  2525.   else if (cbs->selection_type == XmINITIAL)
  2526.     cout << "*** Initial\n";
  2527.   else if (cbs->selection_type == XmADDITION)
  2528.     cout << "*** Addition\n";
  2529. */
  2530.  
  2531.   int n;
  2532.   XtVaGetValues(w, XmNselectedItemCount, &n, NULL);
  2533.  
  2534.   if (n == 0)
  2535.     return;
  2536.  
  2537.   wxListBox *item = (wxListBox *)clientData;
  2538.   wxFunction fun = item->callback;
  2539.   if (fun)
  2540.   {
  2541.     wxEvent event;
  2542.     event.client_data = item->GetClientData(cbs->item_position - 1);
  2543.  
  2544.     if (!item->multiple)
  2545.       event.string = item->GetStringSelection();
  2546.     (void)(*(fun))(*item, event);
  2547.   }
  2548. }
  2549. #endif
  2550.  
  2551. // Listbox item
  2552. wxListBox::wxListBox(wxPanel *panel, wxFunction func,
  2553.                        char *Title, Bool Multiple,
  2554.                        int x, int y, int width, int height,
  2555.                        int N, char **Choices)
  2556. #ifdef wx_motif
  2557.  :clientDataList(wxKEY_INTEGER)
  2558. #endif
  2559. {
  2560.   selected = -1;
  2561.   selections = 0;
  2562.   multiple = Multiple;
  2563.   window_parent = panel;
  2564.   no_items = 0;
  2565.   labelPosition = panel->label_position;
  2566. #ifdef wx_motif
  2567.   Widget panelForm = panel->panelWidget;
  2568.   formWidget = XtVaCreateManagedWidget("form",
  2569.                   xmFormWidgetClass, panelForm,
  2570.                   NULL);
  2571.  
  2572.   XmString text = XmStringCreateSimple(Title);
  2573.  
  2574.   Widget listWidget;
  2575.   Arg args[2];
  2576.   XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
  2577.   if (Multiple)
  2578.     XtSetArg(args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
  2579.   else XtSetArg(args[1], XmNselectionPolicy, XmSINGLE_SELECT);
  2580.  
  2581.   labelWidget = XtVaCreateManagedWidget(Title,
  2582.                   xmLabelWidgetClass,  formWidget,
  2583.                   XmNlabelString,      text,
  2584.                   NULL);
  2585.  
  2586.   listWidget = XmCreateScrolledList(formWidget, "list", args, 2);
  2587.  
  2588.   handle = (char *)listWidget;
  2589.  
  2590.   if (panel->label_position == wxHORIZONTAL)
  2591.   {
  2592.     XtVaSetValues(labelWidget,
  2593.                   XmNtopAttachment,    XmATTACH_FORM,
  2594.                   XmNleftAttachment,   XmATTACH_FORM,
  2595.                   XmNalignment,        XmALIGNMENT_BEGINNING,
  2596.                   NULL);
  2597.     XtVaSetValues(XtParent(listWidget),
  2598.                   XmNleftOffset,       4,
  2599.                   XmNtopAttachment,    XmATTACH_FORM,
  2600.                   XmNbottomAttachment, XmATTACH_FORM,
  2601.                   XmNleftAttachment,   XmATTACH_WIDGET,
  2602.                   XmNleftWidget,       labelWidget,
  2603.                   NULL);
  2604.   }
  2605.   else
  2606.   {
  2607.     XtVaSetValues(labelWidget,
  2608.                   XmNtopAttachment,    XmATTACH_FORM,
  2609.                   XmNleftAttachment,   XmATTACH_FORM,
  2610.                   XmNalignment,        XmALIGNMENT_BEGINNING,
  2611.                   NULL);
  2612.  
  2613.     XtVaSetValues(XtParent(listWidget),
  2614.                   XmNtopAttachment,    XmATTACH_WIDGET,
  2615.                   XmNtopWidget,        labelWidget,
  2616.                   XmNbottomAttachment, XmATTACH_FORM,
  2617.                   XmNleftAttachment,   XmATTACH_FORM,
  2618.                   NULL);
  2619.   }
  2620.  
  2621.   XmStringFree(text);
  2622.  
  2623.   XtManageChild(listWidget);
  2624.  
  2625.   if (width == -1)
  2626.     width = 150;
  2627.   if (height == -1)
  2628.     height = 80;
  2629.  
  2630.   XtAddCallback(listWidget, XmNsingleSelectionCallback, wxListBoxCallback,
  2631.                   this);
  2632.   XtAddCallback(listWidget, XmNextendedSelectionCallback, wxListBoxCallback,
  2633.                   this);
  2634.   AttachWidget(panel, formWidget, x, y, width, height);
  2635.  
  2636.   if (N > 0)
  2637.     for (int i = 0; i < N; i++)
  2638.       Append(Choices[i]);
  2639.  
  2640. #endif
  2641. #ifdef wx_xview
  2642.   char *title = NULL;
  2643.  
  2644.   int choose_one = !Multiple;
  2645.   Panel x_panel = (Panel)panel->GetHandle();
  2646.   Panel_item x_list;
  2647.  
  2648.   int label_position;
  2649.   if (panel->label_position == wxVERTICAL)
  2650.     label_position = PANEL_VERTICAL;
  2651.   else
  2652.     label_position = PANEL_HORIZONTAL;
  2653.  
  2654.   if (panel->new_line)
  2655.   {
  2656.     x_list = (Panel_item) xv_create(x_panel, PANEL_LIST, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
  2657.     panel->new_line = FALSE;
  2658.   }
  2659.   else
  2660.     x_list = (Panel_item) xv_create(x_panel, PANEL_LIST, PANEL_LAYOUT, label_position, NULL);
  2661.  
  2662.   xv_set(x_list,
  2663.                           PANEL_CHOOSE_ONE, choose_one,
  2664.                           PANEL_NOTIFY_PROC, wxListProc,
  2665.                           PANEL_CLIENT_DATA, (char *)this,
  2666.                           PANEL_ITEM_MENU, NULL,
  2667.                           NULL);
  2668.   if (x > -1 && y > -1)
  2669.     (void)xv_set(x_list, XV_X, x, XV_Y, y, NULL);
  2670.  
  2671.   handle = (char *)x_list;
  2672.  
  2673.   SetSize(x, y, width, height);
  2674.  
  2675.   if (Title)
  2676.     { title = Title;
  2677.       xv_set(x_list, PANEL_LABEL_STRING, title, NULL);
  2678.     }
  2679.  
  2680.   if (N > 0)
  2681.     Set(N, Choices);
  2682.  
  2683. #endif
  2684. #ifdef wx_msw
  2685.   wxWinType = wxTYPE_HWND;
  2686.   wxWnd *cparent = NULL;
  2687.   if (panel)
  2688.     cparent = (wxWnd *)(panel->handle);
  2689.  
  2690.   panel->GetValidPosition(&x, &y);
  2691.  
  2692.   // If label exists, create a static control for it.
  2693.   if (Title)
  2694.   {
  2695.     static_label = CreateWindowEx(0, "STATIC", Title,
  2696.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  2697.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  2698.                          wxhInstance, NULL);
  2699.   }
  2700.   else
  2701.     static_label = NULL;
  2702.  
  2703.  
  2704.   DWORD style;
  2705.   if (Multiple == wxMULTIPLE)
  2706.     style = WS_VSCROLL | WS_BORDER | LBS_MULTIPLESEL | LBS_NOTIFY | WS_TABSTOP;
  2707.   else
  2708.     style = WS_VSCROLL | WS_BORDER | LBS_NOTIFY | WS_TABSTOP;
  2709.  
  2710.   windows_id = (int)NewId();
  2711.  
  2712.   HWND wx_list = CreateWindowEx(0, "LISTBOX", NULL,
  2713.                          style | WS_CHILD,
  2714.                          0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  2715.                          wxhInstance, NULL);
  2716.  
  2717.   for (int i = 0; i < N; i++)
  2718.     SendMessage(wx_list, LB_ADDSTRING, 0, (LONG)Choices[i]);
  2719.   if (!Multiple)
  2720.     SendMessage(wx_list, LB_SETCURSEL, 0, 0);
  2721.  
  2722.   ShowWindow(wx_list, SW_SHOW);
  2723.   no_items = N;
  2724.  
  2725.   ms_handle = (HANDLE)wx_list;
  2726.  
  2727.   SetSize(x, y, width, height);
  2728.   panel->AdvanceCursor(this);
  2729. #endif
  2730.   if (panel) panel->AddChild(this);
  2731.  
  2732.   Callback(func);
  2733. }
  2734.  
  2735. wxListBox::~wxListBox(void)
  2736. {
  2737.   if (selections)
  2738.     delete selections;
  2739. #ifdef wx_msw
  2740.   if (static_label)
  2741.     DestroyWindow(static_label);
  2742.   static_label = NULL;
  2743. #endif
  2744. }
  2745.  
  2746. #ifdef wx_msw
  2747. BOOL wxListBox::Command(UINT param)
  2748. {
  2749.   wxFunction fun = callback;
  2750.  
  2751.   if (fun && (param == LBN_SELCHANGE))
  2752.   {
  2753.     HWND listbox = (HWND)ms_handle;
  2754.     wxEvent event;
  2755.  
  2756.     if (multiple == wxSINGLE)
  2757.     {
  2758.       int sel = (int)SendMessage(listbox, LB_GETCURSEL, 0, 0);
  2759.       int len = (int)SendMessage(listbox, LB_GETTEXT, sel, (LONG)wxBuffer);
  2760.       wxBuffer[len] = 0;
  2761.       event.string = wxBuffer;
  2762.       event.index = sel;
  2763.       event.client_data = (char *)SendMessage(listbox, LB_GETITEMDATA, 0, 0);
  2764.     }
  2765.     else event.string = NULL;
  2766.  
  2767.     (void)(*(fun))(*this, event);
  2768.     return TRUE;
  2769.   }
  2770.   else return FALSE;
  2771. }
  2772. #endif
  2773.  
  2774. int wxListBox::Number(void)
  2775. {
  2776.   return no_items;
  2777. }
  2778.  
  2779. void wxListBox::Delete(int N)
  2780. {
  2781. #ifdef wx_motif
  2782.   XmListDeletePos((Widget)handle, N + 1);
  2783. #endif
  2784. #ifdef wx_xview
  2785.   Panel_item list_item = (Panel_item)handle;
  2786.  
  2787.   xv_set(list_item, PANEL_LIST_DELETE, N, NULL);
  2788. #endif
  2789. #ifdef wx_msw
  2790.   SendMessage((HWND)ms_handle, LB_DELETESTRING, N, 0);
  2791. #endif
  2792.   no_items --;
  2793. }
  2794.  
  2795. void wxListBox::Append(char *Item)
  2796. {
  2797. #ifdef wx_motif
  2798.   Widget listBox = (Widget)handle;
  2799.   int n;
  2800.   XtVaGetValues(listBox, XmNitemCount, &n, NULL);
  2801.   XmString text = XmStringCreateSimple(Item);
  2802.   XmListAddItem(listBox, text, n + 1);
  2803.   XmStringFree(text);
  2804. #endif
  2805. #ifdef wx_xview
  2806.   char *label = Item;
  2807.   Panel_item list_item = (Panel_item)handle;
  2808.  
  2809.   int n = (int)xv_get(list_item, PANEL_LIST_NROWS);
  2810.  
  2811.   xv_set(list_item, PANEL_LIST_INSERT, n, 
  2812.                     PANEL_LIST_STRING, n, label, 
  2813.                     PANEL_LIST_CLIENT_DATA, n, n,
  2814.                     NULL);
  2815.  
  2816. #endif
  2817. #ifdef wx_msw
  2818.   SendMessage((HWND)ms_handle, LB_ADDSTRING, 0, (LONG)Item);
  2819. #endif
  2820.   no_items ++;
  2821. }
  2822.  
  2823. void wxListBox::Append(char *Item, char *Client_data)
  2824. {
  2825. #ifdef wx_motif
  2826.   Widget listBox = (Widget)handle;
  2827.   int n;
  2828.   XtVaGetValues(listBox, XmNitemCount, &n, NULL);
  2829.   XmString text = XmStringCreateSimple(Item);
  2830.   XmListAddItem(listBox, text, n + 1);
  2831.   XmStringFree(text);
  2832.  
  2833.   clientDataList.Append((long)n, (wxObject *)Client_data);
  2834. #endif
  2835. #ifdef wx_xview
  2836.   char *label = Item;
  2837.   Panel_item list_item = (Panel_item)handle;
  2838.  
  2839.   int n = (int)xv_get(list_item, PANEL_LIST_NROWS);
  2840.  
  2841.   xv_set(list_item, PANEL_LIST_INSERT, n, 
  2842.                     PANEL_LIST_STRING, n, label, 
  2843.                     PANEL_LIST_CLIENT_DATA, n, Client_data,
  2844.                     NULL);
  2845.  
  2846. #endif
  2847. #ifdef wx_msw
  2848.   int index = (int)SendMessage((HWND)ms_handle, LB_ADDSTRING, 0, (LONG)Item);
  2849.   SendMessage((HWND)ms_handle, LB_SETITEMDATA, index, (LONG)Client_data);
  2850. #endif
  2851.   no_items ++;
  2852. }
  2853.  
  2854. void wxListBox::Set(int n, char *choices[])
  2855. {
  2856. #ifdef wx_motif
  2857.   for (int i = 0; i < n; i++)
  2858.     Append(choices[i]);
  2859. #endif
  2860. #ifdef wx_xview
  2861.   Panel_item list = (Panel_item)handle;
  2862.   if (selections)
  2863.     { delete selections; selections = NULL; }
  2864.  
  2865.   int max1 = (int)xv_get(list, PANEL_LIST_NROWS);
  2866.   xv_set(list, PANEL_LIST_DELETE_ROWS, 0, max1, NULL);
  2867.  
  2868.   int i;
  2869.   for (i = 0; i < n; i++)
  2870.     {
  2871.       char *label = choices[i];
  2872.       xv_set(list, PANEL_LIST_INSERT, i, 
  2873.                    PANEL_LIST_STRING, i, label,
  2874.                    PANEL_LIST_CLIENT_DATA, i, i, 
  2875.                    NULL);
  2876.     }
  2877. #endif
  2878. #ifdef wx_msw
  2879.   ShowWindow((HWND)ms_handle, SW_HIDE);
  2880.   for (int i = 0; i < n; i++)
  2881.     SendMessage((HWND)ms_handle, LB_ADDSTRING, 0, (LONG)choices[i]);
  2882.   ShowWindow((HWND)ms_handle, SW_SHOW);
  2883. #endif
  2884.   no_items = n;
  2885. }
  2886.  
  2887. int wxListBox::FindString(char *s)
  2888. {
  2889. #ifdef wx_motif
  2890.   XmString str = XmStringCreateSimple(s);
  2891.   int *positions;
  2892.   int no_positions;
  2893.   XmListGetMatchPos((Widget)handle, str, &positions, &no_positions);
  2894.   XmStringFree(str);
  2895.   if (no_positions == 0)
  2896.     return -1;
  2897.   else
  2898.     return positions[0] - 1;
  2899. #endif
  2900. #ifdef wx_xview
  2901.   Panel_item list = (Panel_item)handle;
  2902.  
  2903.   int max1 = (int)xv_get(list, PANEL_LIST_NROWS);
  2904.  
  2905.   int i = 0;
  2906.   int found = -1;
  2907.   while (found == -1 && i < max1)
  2908.     {
  2909.       char *label = (char *)xv_get(list, PANEL_LIST_STRING, i);
  2910.       if (label && strcmp(label, s) == 0)
  2911.         found = i;
  2912.       else i ++;
  2913.     }
  2914.   return found;
  2915. #endif
  2916. #ifdef wx_msw
  2917.  int pos = (int)SendMessage((HWND)ms_handle, LB_FINDSTRING, -1, (LONG)s);
  2918.  if (pos == LB_ERR)
  2919.    return -1;
  2920.  else
  2921.    return pos;
  2922. #endif
  2923. }
  2924.  
  2925. void wxListBox::Clear(void)
  2926. {
  2927. #ifdef wx_motif
  2928.   XmListDeleteAllItems((Widget)handle);
  2929.   clientDataList.Clear();
  2930. #endif
  2931. #ifdef wx_xview
  2932.   Panel_item list_item = (Panel_item)handle;
  2933.   xv_set(list_item, PANEL_LIST_DELETE_ROWS, 0, no_items, NULL);
  2934. #endif
  2935. #ifdef wx_msw
  2936.   SendMessage((HWND)ms_handle, LB_RESETCONTENT, 0, 0);
  2937. #endif
  2938.   no_items = 0;
  2939. }
  2940.  
  2941. void wxListBox::SetSelection(int N)
  2942. {
  2943. #ifdef wx_motif
  2944.   XmListSelectPos((Widget)handle, N + 1, TRUE);
  2945. #endif
  2946. #ifdef wx_xview
  2947.   Panel_item list_item = (Panel_item)handle;
  2948.   xv_set(list_item, PANEL_LIST_SELECT, N, TRUE, NULL);
  2949. #endif
  2950. #ifdef wx_msw
  2951.   if (multiple == wxMULTIPLE)
  2952.     SendMessage((HWND)ms_handle, LB_SETSEL, TRUE, N);
  2953.   else
  2954.     SendMessage((HWND)ms_handle, LB_SETCURSEL, N, 0);
  2955. #endif
  2956.  
  2957. }
  2958.  
  2959. void wxListBox::Deselect(int N)
  2960. {
  2961. #ifdef wx_motif
  2962.   XmListDeselectPos((Widget)handle, N + 1);
  2963. #endif
  2964. #ifdef wx_xview
  2965.   Panel_item list_item = (Panel_item)handle;
  2966.   xv_set(list_item, PANEL_LIST_SELECT, N, FALSE, NULL);
  2967. #endif
  2968. #ifdef wx_msw
  2969.   if (multiple == wxMULTIPLE)
  2970.     SendMessage((HWND)ms_handle, LB_SETSEL, FALSE, N);
  2971.   else
  2972.     SendMessage((HWND)ms_handle, LB_SETCURSEL, -N, 0);
  2973. #endif
  2974. }
  2975.  
  2976. char *wxListBox::GetClientData(int N)
  2977. {
  2978. #ifdef wx_motif
  2979.   wxNode *node = clientDataList.Find((long)N);
  2980.   if (node)
  2981.     return (char *)node->Data();
  2982.   else return NULL;
  2983. #endif
  2984. #ifdef wx_xview
  2985.   Panel_item list_item = (Panel_item)handle;
  2986.   char *data = (char *)xv_get(list_item, PANEL_LIST_CLIENT_DATA, N);
  2987.   return data;
  2988. #endif
  2989. #ifdef wx_msw
  2990.   return (char *)SendMessage((HWND)ms_handle, LB_GETITEMDATA, N, 0);
  2991. #endif
  2992. }
  2993.  
  2994. // Return number of selections and an array of selected integers
  2995. // Use selections field to store data, which will be cleaned up
  2996. // by destructor if necessary.
  2997. int wxListBox::GetSelections(int **list_selections)
  2998. {
  2999. #ifdef wx_motif
  3000.   Widget listBox = (Widget)handle;
  3001.   int *posList;
  3002.   int posCnt;
  3003.   Bool flag = XmListGetSelectedPos(listBox, &posList, &posCnt);
  3004.   if (flag)
  3005.   {
  3006.     if (posCnt > 0)
  3007.     {
  3008.       if (selections)
  3009.         delete selections;
  3010.       selections = new int[posCnt];
  3011.       for (int i = 0; i < posCnt; i++)
  3012.         selections[i] = posList[i] - 1;
  3013.  
  3014.       XtFree(posList);
  3015.       return posCnt;
  3016.     }
  3017.     else return FALSE;
  3018.   }
  3019.   else return FALSE;
  3020. #endif
  3021. #ifdef wx_xview
  3022.   Panel_item x_list = (Panel_item)handle;
  3023.  
  3024.   int i = 0;
  3025.   int j = 0;
  3026.  
  3027.   if (selections)
  3028.     { delete selections; selections = NULL; }
  3029.  
  3030.   for (j = 0 ; j < no_items; j++)
  3031.     if (xv_get(x_list, PANEL_LIST_SELECTED, j))
  3032.       { i ++; }
  3033.   if (i > 0)
  3034.     {
  3035.       selections = new int[i];
  3036.       int k = 0;
  3037.       for (j = 0; j < no_items; j++)
  3038.         if (xv_get(x_list, PANEL_LIST_SELECTED, j))
  3039.           { selections[k] = j; k ++; }
  3040.     }
  3041.  
  3042.   *list_selections = selections;
  3043.   return i;
  3044. #endif
  3045.  
  3046. #ifdef wx_msw
  3047.   HWND listbox = (HWND)ms_handle;
  3048.   if (selections)
  3049.     { delete selections; selections = NULL; };
  3050.   if (multiple == wxSINGLE)
  3051.   {
  3052.     int sel = (int)SendMessage(listbox, LB_GETCURSEL, 0, 0);
  3053.     if (sel == LB_ERR)
  3054.       return 0;
  3055.     selections = new int[1];
  3056.     selections[0] = sel;
  3057.     *list_selections = selections;
  3058.     return 1;
  3059.   }
  3060.   else
  3061.   {
  3062.     int no_sel = (int)SendMessage(listbox, LB_GETSELCOUNT, 0, 0);
  3063.     if (no_sel == 0)
  3064.       return 0;
  3065.     selections = new int[no_sel];
  3066.     SendMessage(listbox, LB_GETSELITEMS, no_sel, (LONG)selections);
  3067.     *list_selections = selections;
  3068.     return no_sel;
  3069.   }
  3070. #endif
  3071. }
  3072.  
  3073. // Get single selection, for single choice list items
  3074. int wxListBox::GetSelection(void)
  3075. {
  3076. #ifdef wx_motif
  3077.   Widget listBox = (Widget)handle;
  3078.   int *posList;
  3079.   int posCnt;
  3080.   Bool flag = XmListGetSelectedPos(listBox, &posList, &posCnt);
  3081.   if (flag)
  3082.   {
  3083.     int id = -1;
  3084.     if (posCnt > 0)
  3085.       id = posList[0] - 1;
  3086.     XtFree(posList);
  3087.     return id;
  3088.   }
  3089.   else return -1;
  3090. #endif
  3091. #ifdef wx_xview
  3092.   Panel_item x_list = (Panel_item)handle;
  3093.  
  3094.   int i = 0;
  3095.   if (selections)
  3096.     { delete selections; selections = NULL; }
  3097.  
  3098.   int found = -1;
  3099.   while (found == -1 && i < no_items)
  3100.   {
  3101.     if (xv_get(x_list, PANEL_LIST_SELECTED, i))
  3102.       found = i;
  3103.     else
  3104.       i ++;
  3105.   }
  3106.  
  3107.   return found;
  3108. #endif
  3109.  
  3110. #ifdef wx_msw
  3111.   HWND listbox = (HWND)ms_handle;
  3112.   if (selections)
  3113.     { delete selections; selections = NULL; };
  3114.   if (multiple == wxSINGLE)
  3115.   {
  3116.     int sel = (int)SendMessage(listbox, LB_GETCURSEL, 0, 0);
  3117.     if (sel == LB_ERR)
  3118.       return -1;
  3119.     else
  3120.     {
  3121.       return sel;
  3122.     }
  3123.   }
  3124.   else return -1;
  3125. #endif
  3126. }
  3127.  
  3128. // Find string for position
  3129. char *wxListBox::String(int N)
  3130. {
  3131. #ifdef wx_motif
  3132.   Widget listBox = (Widget)handle;
  3133.   XmString *strlist;
  3134.   int n;
  3135.   XtVaGetValues(listBox, XmNitemCount, &n, XmNitems, &strlist, NULL);
  3136.   if (N <= n)
  3137.   {
  3138.     char *txt;
  3139.     if (XmStringGetLtoR(strlist[N], "", &txt))
  3140.     {
  3141.       strcpy(wxBuffer, txt);
  3142.       XtFree(txt);
  3143.       return wxBuffer;
  3144.     }
  3145.     else return NULL;
  3146.   }
  3147.   else return NULL;
  3148.  
  3149. #endif
  3150. #ifdef wx_xview
  3151.   Panel_item x_list = (Panel_item)handle;
  3152.   return (char *)xv_get(x_list, PANEL_LIST_STRING, N);
  3153. #endif
  3154.  
  3155. #ifdef wx_msw
  3156.   int len = (int)SendMessage((HWND)ms_handle, LB_GETTEXT, N, (LONG)wxBuffer);
  3157.   wxBuffer[len] = 0;
  3158.   return wxBuffer;
  3159. #endif
  3160. }
  3161.  
  3162. // For single selection items only
  3163. char *wxListBox::GetStringSelection(void)
  3164. {
  3165.   int sel = GetSelection();
  3166.   if (sel > -1)
  3167.     return this->String(sel);
  3168.   else
  3169.     return NULL;
  3170. }
  3171.  
  3172. Bool wxListBox::SetStringSelection(char *s)
  3173. {
  3174.   int sel = FindString(s);
  3175.   if (sel > -1)
  3176.   {
  3177.     SetSelection(sel);
  3178.     return TRUE;
  3179.   }
  3180.   else return FALSE;
  3181. }
  3182.  
  3183. void wxListBox::SetSize(int x, int y, int width, int height)
  3184. {
  3185. #ifdef wx_motif
  3186.   Widget widget = (Widget)handle;
  3187.  
  3188.   if (x > -1)
  3189.     XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF,
  3190.                    XmNx, x, NULL);
  3191.   if (y > -1)
  3192.     XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF,
  3193.                    XmNy, y, NULL);
  3194.  
  3195.   // Must set the actual listbox to be desired size MINUS label size
  3196.   Dimension labelWidth, labelHeight, actualWidth, actualHeight;
  3197.   XtVaGetValues(labelWidget, XmNwidth, &labelWidth, XmNheight, &labelHeight, NULL);
  3198.   if (itemOrientation == wxHORIZONTAL)
  3199.   {
  3200.     actualWidth = width - labelWidth;
  3201.     actualHeight = height;
  3202.   }
  3203.   else
  3204.   {
  3205.     actualWidth = width;
  3206.     actualHeight = height - labelHeight;
  3207.   }
  3208.  
  3209.   if (width > -1)
  3210.   {
  3211.     XtVaSetValues(XtParent(widget), XmNwidth, actualWidth, NULL);
  3212.   }
  3213.   if (height > -1)
  3214.   {
  3215.     XtVaSetValues(XtParent(widget), XmNheight, actualHeight, NULL);
  3216.   }
  3217.   OnSize(width, height);
  3218. #endif
  3219. #ifdef wx_xview
  3220.   Panel_item list_item = (Panel_item)handle;
  3221.  
  3222.   int row_height = (int)xv_get(list_item, PANEL_LIST_ROW_HEIGHT);
  3223.  
  3224.   if (x > -1)
  3225.     xv_set(list_item, XV_X, x, NULL);
  3226.  
  3227.   if (y > -1)
  3228.     xv_set(list_item, XV_Y, y, NULL);
  3229.  
  3230.   if (width > -1)
  3231.     xv_set(list_item,
  3232.                     PANEL_LIST_WIDTH, width, NULL);
  3233.   else
  3234.     xv_set(list_item,
  3235.                     PANEL_LIST_WIDTH, 0, NULL);
  3236.  
  3237.   if (height > -1)
  3238.     xv_set(list_item,
  3239.                     PANEL_LIST_DISPLAY_ROWS, (int)((height/row_height)-2),
  3240.                     NULL);
  3241.   else
  3242.     xv_set(list_item,
  3243.                     PANEL_LIST_DISPLAY_ROWS, 5,
  3244.                     NULL);
  3245.   OnSize(width, height);
  3246. #endif
  3247. #ifdef wx_msw
  3248.   int currentX, currentY;
  3249.   GetPosition(¤tX, ¤tY);
  3250.   if (x == -1)
  3251.     x = currentX;
  3252.   if (y == -1)
  3253.     y = currentY;
  3254.  
  3255.   char buf[300];
  3256.  
  3257.   int y_offset = y;
  3258.   int x_offset = x;
  3259.   float current_width;
  3260.  
  3261.   int cx;
  3262.   int cy;
  3263.   float cyf;
  3264.   HWND wnd = (HWND)ms_handle;
  3265.   wxGetCharSize(wnd, &cx, &cy);
  3266.  
  3267.   if (static_label)
  3268.   {
  3269.     GetWindowText(static_label, buf, 300);
  3270.     GetTextExtent(buf, ¤t_width, &cyf);
  3271.     MoveWindow(static_label, x, y_offset, (int)(current_width + cx), (int)cyf,
  3272.                TRUE);
  3273.     if (labelPosition == wxVERTICAL)
  3274.       y_offset += cy;
  3275.     else
  3276.       x_offset += (int)(current_width + cx);
  3277.   }
  3278.  
  3279.   if (width < 0)
  3280.     width = 150;
  3281.   if (height < 0)
  3282.     height = 80;
  3283.  
  3284.   height -= cy;
  3285.  
  3286.   MoveWindow((HWND)ms_handle, x_offset, y_offset, width, height, TRUE);
  3287.   OnSize(width, height);
  3288. #endif
  3289. }
  3290.  
  3291. void wxListBox::GetSize(int *width, int *height)
  3292. {
  3293. #ifdef wx_motif
  3294.   Widget widget = (Widget)handle;
  3295.   Dimension xx, yy;
  3296.   XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
  3297.   *width = xx; *height = yy;
  3298. #endif
  3299. #ifdef wx_xview
  3300.   Panel_item item = (Panel_item)handle;
  3301.   Rect *rect = (Rect *)xv_get(item, XV_RECT);
  3302.  
  3303.   *height = rect->r_height;
  3304.   *width = rect->r_width;
  3305. #endif
  3306. #ifdef wx_msw
  3307.   RECT rect;
  3308.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  3309.  
  3310.   wxFindMaxSize((HWND)ms_handle, &rect);
  3311.  
  3312.   if (static_label)
  3313.   {
  3314.     wxFindMaxSize(static_label, &rect);
  3315.   }
  3316.  
  3317.   *width = rect.right - rect.left;
  3318.   *height = rect.bottom - rect.top;
  3319. #endif
  3320. }
  3321.  
  3322. void wxListBox::GetPosition(int *x, int *y)
  3323. {
  3324. #ifdef wx_motif
  3325.   Dimension xx, yy;
  3326.   XtVaGetValues(formWidget, XmNx, &xx, XmNy, &yy, NULL);
  3327.   *x = xx; *y = yy;
  3328. #endif
  3329. #ifdef wx_xview
  3330.   Xv_opaque x_win = (Xv_opaque)handle;
  3331.  
  3332.   *x = (int)xv_get(x_win, XV_X);
  3333.   *y = (int)xv_get(x_win, XV_Y);
  3334. #endif
  3335. #ifdef wx_msw
  3336.   wxWindow *parent = GetParent();
  3337.   RECT rect;
  3338.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  3339.  
  3340.   wxFindMaxSize((HWND)ms_handle, &rect);
  3341.   if (static_label)
  3342.     wxFindMaxSize(static_label, &rect);
  3343.  
  3344.   // Since we now have the absolute screen coords,
  3345.   // if there's a parent we must subtract its top left corner
  3346.   POINT point;
  3347.   point.x = rect.left;
  3348.   point.y = rect.top;
  3349.   if (parent)
  3350.   {
  3351.     wxWnd *cparent = (wxWnd *)(parent->handle);
  3352.     ScreenToClient(cparent->handle, &point);
  3353.   }
  3354.  
  3355.   *x = point.x;
  3356.   *y = point.y;
  3357. #endif
  3358. }
  3359.  
  3360. char *wxListBox::GetLabel(void)
  3361. {
  3362. #ifdef wx_motif
  3363.   XmString text;
  3364.   char *s;
  3365.   XtVaGetValues(labelWidget,
  3366.                   XmNlabelString, &text,
  3367.                   NULL);
  3368.  
  3369.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  3370.   {
  3371. //    XmStringFree(text);
  3372.     char *val = copystring(s);
  3373.     XtFree(s);
  3374.     return val;
  3375.   }
  3376.   else
  3377.   {
  3378. //    XmStringFree(text);
  3379.     return NULL;
  3380.   }
  3381. #endif
  3382. #ifdef wx_xview
  3383.   Panel_item item = (Panel_item)handle;
  3384.   return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
  3385. #endif
  3386. #ifdef wx_msw
  3387.   char buf[300];
  3388.   if (static_label)
  3389.   {
  3390.     GetWindowText(static_label, buf, 300);
  3391.     return copystring(buf);
  3392.   }
  3393.   else return NULL;
  3394. #endif
  3395. }
  3396.  
  3397. void wxListBox::SetLabel(char *label)
  3398. {
  3399. #ifdef wx_motif
  3400.   Widget widget = (Widget)handle;
  3401.   XmString text = XmStringCreateSimple(label);
  3402.   XtVaSetValues(widget,
  3403.                   XmNlabelString, text,
  3404.                   NULL);
  3405.   XmStringFree(text);
  3406. #endif
  3407. #ifdef wx_xview
  3408.   Panel_item item = (Panel_item)handle;
  3409.   xv_set(item, PANEL_LABEL_STRING, label, NULL);
  3410. #endif
  3411. #ifdef wx_msw
  3412.   if (static_label)
  3413.   {
  3414.     float w, h;
  3415.     RECT rect;
  3416.  
  3417.     wxWindow *parent = GetParent();
  3418.     GetWindowRect(static_label, &rect);
  3419.  
  3420.     // Since we now have the absolute screen coords,
  3421.     // if there's a parent we must subtract its top left corner
  3422.     POINT point;
  3423.     point.x = rect.left;
  3424.     point.y = rect.top;
  3425.     if (parent)
  3426.     {
  3427.       wxWnd *cparent = (wxWnd *)(parent->handle);
  3428.       ScreenToClient(cparent->handle, &point);
  3429.     }
  3430.  
  3431.     GetTextExtent((LPSTR)label, &w, &h);
  3432.     MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
  3433.                TRUE);
  3434.     SetWindowText(static_label, label);
  3435.   }
  3436. #endif
  3437. }
  3438.  
  3439. #ifdef wx_xview
  3440. int wxListProc(Panel_item item, char *string, Xv_opaque client_data,
  3441.                 Panel_list_op op, Event *x_event, int row)
  3442. {
  3443. //  if (op == PANEL_LIST_OP_SELECT || op == PANEL_LIST_OP_DESELECT)
  3444.   if (op == PANEL_LIST_OP_SELECT)
  3445.     {
  3446.       wxListBox *list = (wxListBox *)xv_get(item, PANEL_CLIENT_DATA);
  3447.       wxEvent event(x_event);
  3448.       event.string = string;
  3449.       event.index = row;
  3450.       event.client_data = (char *)client_data;
  3451.  
  3452.       if (list->callback)
  3453.       {
  3454.         (void)(*(list->callback))(*list, event);
  3455.       }
  3456.     }
  3457.   return XV_OK;
  3458.  
  3459. }
  3460. #endif
  3461.  
  3462. // Message
  3463. wxMessage::wxMessage(wxPanel *panel, char *label, int x, int y)
  3464. {
  3465.   window_parent = panel;
  3466.   labelPosition = panel->label_position;
  3467. #ifdef wx_motif
  3468.   Widget panelForm = panel->panelWidget;
  3469.   XmString text = XmStringCreateSimple(label);
  3470.  
  3471.   formWidget = XtVaCreateManagedWidget("rowcol",
  3472.                   xmRowColumnWidgetClass, panelForm,
  3473.                   NULL);
  3474.  
  3475.   labelWidget = NULL;
  3476.   Widget LabelWidget = XtVaCreateManagedWidget("message",
  3477.                   xmLabelWidgetClass,  formWidget,
  3478.                   XmNlabelString,      text,
  3479.                   XmNalignment,        XmALIGNMENT_BEGINNING,
  3480.                   NULL);
  3481.  
  3482.   handle = (char *)LabelWidget;
  3483.  
  3484.   XmStringFree(text);
  3485.  
  3486.   AttachWidget(panel, formWidget, x, y, -1, -1);
  3487. #endif
  3488. #ifdef wx_xview
  3489.   Panel x_panel = (Panel)(panel->GetHandle());
  3490.   Panel_item x_message;
  3491.  
  3492.   if (panel->new_line)
  3493.   {
  3494.     x_message = (Panel_item) xv_create(x_panel, PANEL_MESSAGE, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_NEXT_ROW, -1, NULL);
  3495.     panel->new_line = FALSE;
  3496.   }
  3497.   else
  3498.     x_message = (Panel_item) xv_create(x_panel, PANEL_MESSAGE, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
  3499.  
  3500.   xv_set(x_message,
  3501.                               PANEL_LABEL_STRING, label,
  3502.                   PANEL_CLIENT_DATA, (char *)this,
  3503.                               NULL);
  3504.   if (x > -1 && y > -1)
  3505.     (void)xv_set(x_message, XV_X, x, XV_Y, y, NULL);
  3506.  
  3507.   handle = (char *)x_message;
  3508. #endif
  3509. #ifdef wx_msw
  3510.   wxWinType = wxTYPE_HWND;
  3511.   wxWnd *cparent = NULL;
  3512.   if (panel)
  3513.     cparent = (wxWnd *)(panel->handle);
  3514.  
  3515.   HWND static_item = CreateWindowEx(0, "STATIC", label,
  3516.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  3517.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  3518.                          wxhInstance, NULL);
  3519.  
  3520.   ms_handle = (HANDLE)static_item;
  3521.  
  3522.   panel->GetValidPosition(&x, &y);
  3523.  
  3524.   SetSize(x, y, -1, -1);
  3525.   panel->AdvanceCursor(this);
  3526. #endif
  3527.   if (panel) panel->AddChild(this);
  3528. }
  3529.  
  3530. wxMessage::~wxMessage(void)
  3531. {
  3532. }
  3533.  
  3534. void wxMessage::SetSize(int x, int y, int width, int height)
  3535. {
  3536. #ifdef wx_motif
  3537.   wxItem::SetSize(x, y, width, height);
  3538. #endif
  3539. #ifdef wx_xview
  3540.   Xv_opaque x_win = (Xv_opaque)handle;
  3541.  
  3542.   if (x > -1)
  3543.     (void)xv_set(x_win, XV_X, x, NULL);
  3544.  
  3545.   if (y > -1)
  3546.     (void)xv_set(x_win, XV_Y, y, NULL);
  3547.  
  3548.   if (width > 0)
  3549.     (void)xv_set(x_win, XV_WIDTH, width, NULL);
  3550.  
  3551.   if (height > 0)
  3552.     (void)xv_set(x_win, XV_HEIGHT, height, NULL);
  3553.   OnSize(width, height);
  3554. #endif
  3555. #ifdef wx_msw
  3556.   int currentX, currentY;
  3557.   GetPosition(¤tX, ¤tY);
  3558.   if (x == -1)
  3559.     x = currentX;
  3560.   if (y == -1)
  3561.     y = currentY;
  3562.  
  3563.   char buf[300];
  3564.  
  3565.   float current_width;
  3566.  
  3567.   int cx;
  3568.   int cy;
  3569.   float cyf;
  3570.  
  3571.   wxGetCharSize((HWND)ms_handle, &cx, &cy);
  3572.  
  3573.   if (width < 0)
  3574.   {
  3575.     GetWindowText((HWND)ms_handle, buf, 300);
  3576.     GetTextExtent(buf, ¤t_width, &cyf);
  3577.     MoveWindow((HWND)ms_handle, x, y, (int)(current_width + cx), (int)(cyf), TRUE);
  3578.   }
  3579.   else
  3580.     MoveWindow((HWND)ms_handle, x, y, width, height, TRUE);
  3581.   OnSize(width, height);
  3582. #endif
  3583. }
  3584.  
  3585. #ifdef wx_xview
  3586. Panel_setting wxTextProc(Panel_item item, Event *x_event)
  3587. {
  3588.   wxText *text = (wxText *)xv_get(item, PANEL_CLIENT_DATA);
  3589.   wxEvent event(x_event);
  3590.   event.string = (char *)xv_get(item, PANEL_VALUE);
  3591.  
  3592.   if (text->callback)
  3593.   {
  3594.     (void)(*(text->callback))(*text, event);
  3595.   }
  3596.  
  3597.   return PANEL_NONE;
  3598. }
  3599. #endif
  3600.  
  3601. #ifdef wx_motif
  3602. void wxTextCallback(Widget w, XtPointer clientData,
  3603.                       XtPointer ptr)
  3604. {
  3605.   wxItem *item = (wxItem *)clientData;
  3606.   wxFunction fun = item->callback;
  3607.   if (fun)
  3608.   {
  3609.     wxEvent event;
  3610.     (void)(*(fun))(*item, event);
  3611.   }
  3612. }
  3613. #endif
  3614.  
  3615.  
  3616.  
  3617. // Text item
  3618. wxText::wxText(void)
  3619. {
  3620. }
  3621.  
  3622. wxText::wxText(wxPanel *panel, wxFunction Function, char *label, char *value,
  3623.                int x, int y, int width, int height)
  3624. {
  3625.   window_parent = panel;
  3626.   labelPosition = panel->label_position;
  3627. #ifdef wx_motif
  3628.   Widget panelForm = panel->panelWidget;
  3629.   formWidget = XtVaCreateManagedWidget("rowcol",
  3630.                   xmRowColumnWidgetClass, panelForm,
  3631.                   XmNorientation, panel->label_position == wxHORIZONTAL ? XmHORIZONTAL: XmVERTICAL,
  3632.                   NULL);
  3633.   XmString text = XmStringCreateSimple(label);
  3634.  
  3635.   Widget textWidget;
  3636.  
  3637.   labelWidget = XtVaCreateManagedWidget(label,
  3638.                   xmLabelWidgetClass,  formWidget,
  3639.                   XmNlabelString,      text,
  3640.                   NULL);
  3641.  
  3642.   textWidget = XtVaCreateManagedWidget("text",
  3643.                   xmTextWidgetClass,   formWidget,
  3644.                   NULL);
  3645.  
  3646.   handle = (char *)textWidget;
  3647.  
  3648.   XmStringFree(text);
  3649.  
  3650.   XtAddCallback(textWidget, XmNactivateCallback, wxTextCallback,
  3651.                   this);
  3652.  
  3653.   AttachWidget(panel, formWidget, x, y, width, height);
  3654.  
  3655.   if (value)
  3656.     XmTextSetString(textWidget, value);
  3657.  
  3658. #endif
  3659. #ifdef wx_xview
  3660.   Panel x_panel = (Panel)(panel->GetHandle());
  3661.   Panel_item x_text;
  3662.  
  3663.   int label_position;
  3664.   if (panel->label_position == wxVERTICAL)
  3665.     label_position = PANEL_VERTICAL;
  3666.   else
  3667.     label_position = PANEL_HORIZONTAL;
  3668.  
  3669.   if (panel->new_line)
  3670.   {
  3671.     x_text = (Panel_item) xv_create(x_panel, PANEL_TEXT,
  3672.                                PANEL_VALUE_DISPLAY_WIDTH, 30,
  3673.                                PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
  3674.     panel->new_line = FALSE;
  3675.   }
  3676.   else
  3677.     x_text = (Panel_item) xv_create(x_panel, PANEL_TEXT,
  3678.                                PANEL_VALUE_DISPLAY_WIDTH, 30,
  3679.                                PANEL_LAYOUT, label_position, NULL);
  3680.  
  3681.   xv_set(x_text,
  3682.                               PANEL_NOTIFY_PROC, wxTextProc,
  3683.                   PANEL_CLIENT_DATA, (char *)this,
  3684.                               NULL);
  3685.  
  3686.   if (x > -1 && y > -1)
  3687.     (void)xv_set(x_text, XV_X, x, XV_Y, y, NULL);
  3688.  
  3689.  
  3690.   if (width <= 0)
  3691.     width = 80;
  3692.  
  3693.   xv_set(x_text, PANEL_VALUE_DISPLAY_WIDTH, (int) width, NULL);
  3694.  
  3695.   if (label)
  3696.     { xv_set(x_text, PANEL_LABEL_STRING, label, NULL); };
  3697.  
  3698.   if (value)
  3699.     { xv_set(x_text, PANEL_VALUE, value, NULL); };
  3700.  
  3701.   handle = (char *)x_text;
  3702. #endif
  3703. #ifdef wx_msw
  3704.   wxWinType = wxTYPE_HWND;
  3705.   wxWnd *cparent = NULL;
  3706.   if (panel)
  3707.     cparent = (wxWnd *)(panel->handle);
  3708.  
  3709.   panel->GetValidPosition(&x, &y);
  3710.  
  3711.   // If label exists, create a static control for it.
  3712.   if (label)
  3713.   {
  3714.     static_label = CreateWindowEx(0, "STATIC", label,
  3715.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  3716.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  3717.                          wxhInstance, NULL);
  3718.   }
  3719.   else
  3720.     static_label = NULL;
  3721.  
  3722.   windows_id = (int)NewId();
  3723.   HWND edit = CreateWindowEx(0, "EDIT", NULL,
  3724.                         ES_AUTOHSCROLL | ES_LEFT | WS_BORDER |
  3725.                         WS_VISIBLE | WS_CHILD | WS_TABSTOP,
  3726.                         0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  3727.                         wxhInstance, NULL);
  3728.   ms_handle = (HANDLE)edit;
  3729.  
  3730.   SetSize(x, y, width, height);
  3731.  
  3732.   if (value)
  3733.     SetWindowText(edit, value);
  3734.  
  3735.   panel->AdvanceCursor(this);
  3736. #endif
  3737.   if (panel) panel->AddChild(this);
  3738.   Callback(Function);
  3739. }
  3740.  
  3741. wxText::~wxText(void)
  3742. {
  3743. #ifdef wx_msw
  3744.   if (static_label)
  3745.     DestroyWindow(static_label);
  3746. #endif
  3747. }
  3748.  
  3749.  
  3750. char *wxText::GetLabel(void)
  3751. {
  3752. #ifdef wx_motif
  3753.   XmString text;
  3754.   char *s;
  3755.   XtVaGetValues(labelWidget,
  3756.                   XmNlabelString, &text,
  3757.                   NULL);
  3758.  
  3759.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  3760.   {
  3761. //    XmStringFree(text);
  3762.     char *val = copystring(s);
  3763.     XtFree(s);
  3764.     return val;
  3765.   }
  3766.   else
  3767.   {
  3768. //    XmStringFree(text);
  3769.     return NULL;
  3770.   }
  3771. #endif
  3772. #ifdef wx_xview
  3773.   Panel_item item = (Panel_item)handle;
  3774.   return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
  3775. #endif
  3776. #ifdef wx_msw
  3777.   char buf[300];
  3778.   if (static_label)
  3779.   {
  3780.     GetWindowText(static_label, buf, 300);
  3781.     return copystring(buf);
  3782.   }
  3783.   else return NULL;
  3784. #endif
  3785. }
  3786.  
  3787. void wxText::SetLabel(char *label)
  3788. {
  3789. #ifdef wx_motif
  3790.   XmString text = XmStringCreateSimple(label);
  3791.   XtVaSetValues(labelWidget,
  3792.                   XmNlabelString, text,
  3793.                   NULL);
  3794.   XmStringFree(text);
  3795. #endif
  3796. #ifdef wx_xview
  3797.   Panel_item item = (Panel_item)handle;
  3798.   xv_set(item, PANEL_LABEL_STRING, label, NULL);
  3799. #endif
  3800. #ifdef wx_msw
  3801.   if (static_label)
  3802.   {
  3803.     float w, h;
  3804.     RECT rect;
  3805.  
  3806.     wxWindow *parent = GetParent();
  3807.     GetWindowRect(static_label, &rect);
  3808.  
  3809.     // Since we now have the absolute screen coords,
  3810.     // if there's a parent we must subtract its top left corner
  3811.     POINT point;
  3812.     point.x = rect.left;
  3813.     point.y = rect.top;
  3814.     if (parent)
  3815.     {
  3816.       wxWnd *cparent = (wxWnd *)(parent->handle);
  3817.       ScreenToClient(cparent->handle, &point);
  3818.     }
  3819.  
  3820.     GetTextExtent(label, &w, &h);
  3821.     MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
  3822.                TRUE);
  3823.     SetWindowText(static_label, label);
  3824.   }
  3825. #endif
  3826. }
  3827.  
  3828. char *wxText::GetValue(void)
  3829. {
  3830. #ifdef wx_motif
  3831.   char *s = XmTextGetString((Widget)handle);
  3832.   if (s)
  3833.   {
  3834.     strcpy(wxBuffer, s);
  3835.     XtFree(s);
  3836.     return copystring(wxBuffer);
  3837.   }
  3838.   else return NULL;
  3839. #endif
  3840. #ifdef wx_xview
  3841.   Panel_item item = (Panel_item)handle;
  3842.   return copystring((char *)xv_get(item, PANEL_VALUE));
  3843. #endif
  3844.  
  3845. #ifdef wx_msw
  3846.   *(LPINT)wxBuffer = 500;
  3847.   int n = (int)SendMessage((HWND)ms_handle, EM_GETLINE, 0, (LONG)wxBuffer);
  3848.   wxBuffer[n] = 0;
  3849.   return copystring(wxBuffer);
  3850. #endif
  3851. }
  3852.  
  3853. void wxText::SetValue(char *value)
  3854. {
  3855. #ifdef wx_motif
  3856.   if (value)
  3857.     XmTextSetString((Widget)handle, value);
  3858. #endif
  3859. #ifdef wx_xview
  3860.   Panel_item item = (Panel_item)handle;
  3861.   xv_set(item, PANEL_VALUE, value, NULL);
  3862. #endif
  3863. #ifdef wx_msw
  3864.   SetWindowText((HWND)ms_handle, value);
  3865. #endif
  3866. }
  3867.  
  3868.  
  3869. void wxText::GetSize(int *width, int *height)
  3870. {
  3871. #ifdef wx_motif
  3872.   wxItem::GetSize(width, height);
  3873. #endif
  3874. #ifdef wx_xview
  3875.   Panel_item item = (Panel_item)handle;
  3876.   Rect *rect = (Rect *)xv_get(item, XV_RECT);
  3877.  
  3878.   *height = rect->r_height;
  3879.   *width = rect->r_width;
  3880. #endif
  3881. #ifdef wx_msw
  3882.   RECT rect;
  3883.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  3884.  
  3885.   wxFindMaxSize((HWND)ms_handle, &rect);
  3886.  
  3887.   if (static_label)
  3888.   {
  3889.     wxFindMaxSize(static_label, &rect);
  3890.   }
  3891.  
  3892.   *width = rect.right - rect.left;
  3893.   *height = rect.bottom - rect.top;
  3894. #endif
  3895. }
  3896.  
  3897. void wxText::GetPosition(int *x, int *y)
  3898. {
  3899. #ifdef wx_motif
  3900.   wxItem::GetPosition(x, y);
  3901. #endif
  3902. #ifdef wx_xview
  3903.   Xv_opaque x_win = (Xv_opaque)handle;
  3904.  
  3905.   *x = (int)xv_get(x_win, XV_X);
  3906.   *y = (int)xv_get(x_win, XV_Y);
  3907. #endif
  3908. #ifdef wx_msw
  3909.   wxWindow *parent = GetParent();
  3910.   RECT rect;
  3911.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  3912.  
  3913.   wxFindMaxSize((HWND)ms_handle, &rect);
  3914.   if (static_label)
  3915.     wxFindMaxSize(static_label, &rect);
  3916.  
  3917.   // Since we now have the absolute screen coords,
  3918.   // if there's a parent we must subtract its top left corner
  3919.   POINT point;
  3920.   point.x = rect.left;
  3921.   point.y = rect.top;
  3922.   if (parent)
  3923.   {
  3924.     wxWnd *cparent = (wxWnd *)(parent->handle);
  3925.     ScreenToClient(cparent->handle, &point);
  3926.   }
  3927.  
  3928.   *x = point.x;
  3929.   *y = point.y;
  3930. #endif
  3931. }
  3932.  
  3933.  
  3934. void wxText::SetSize(int x, int y, int width, int height)
  3935. {
  3936. #ifdef wx_motif
  3937.   if (x > -1)
  3938.     XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF,
  3939.                    XmNx, x,
  3940.                    NULL);
  3941.   if (y > -1)
  3942.     XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF,
  3943.                    XmNy, y,
  3944.                    NULL);
  3945.  
  3946.   Dimension labelWidth, labelHeight;
  3947.   int actualWidth, actualHeight;
  3948.   XtVaGetValues(labelWidget, XmNwidth, &labelWidth, XmNheight, &labelHeight, NULL);
  3949.   if (itemOrientation == wxHORIZONTAL)
  3950.   {
  3951.     actualWidth = width - labelWidth;
  3952.     actualHeight = height;
  3953.   }
  3954.   else
  3955.   {
  3956.     actualWidth = width;
  3957.     actualHeight = height - labelHeight;
  3958.   }
  3959.  
  3960.   if (width > -1)
  3961.     XtVaSetValues((Widget)handle, XmNwidth, width,
  3962.                    NULL);
  3963.   if (height > -1)
  3964.     XtVaSetValues((Widget)handle, XmNheight, height,
  3965.                    NULL);
  3966.   OnSize(width, height);
  3967. #endif
  3968. #ifdef wx_xview
  3969.   Xv_opaque x_win = (Xv_opaque)handle;
  3970.  
  3971.   if (x > -1)
  3972.     (void)xv_set(x_win, XV_X, x, NULL);
  3973.  
  3974.   if (y > -1)
  3975.     (void)xv_set(x_win, XV_Y, y, NULL);
  3976.  
  3977.   if (width <= 0)
  3978.     width = 80;
  3979.  
  3980.   (void)xv_set(x_win, PANEL_VALUE_DISPLAY_WIDTH, width, NULL);
  3981.   OnSize(width, height);
  3982. #endif
  3983. #ifdef wx_msw
  3984.   int currentX, currentY;
  3985.   GetPosition(¤tX, ¤tY);
  3986.   if (x == -1)
  3987.     x = currentX;
  3988.   if (y == -1)
  3989.     y = currentY;
  3990.  
  3991.   char buf[300];
  3992.  
  3993.   int x_offset = x;
  3994.   int y_offset = y;
  3995.   float current_width;
  3996.  
  3997.   int cx;
  3998.   int cy;
  3999.   float cyf;
  4000.   wxGetCharSize((HWND)ms_handle, &cx, &cy);
  4001.  
  4002.   if (static_label)
  4003.   {
  4004.     GetWindowText(static_label, buf, 300);
  4005.     GetTextExtent(buf, ¤t_width, &cyf);
  4006.     MoveWindow(static_label, x_offset, y, (int)(current_width + cx), (int)cyf, TRUE);
  4007.     if (labelPosition == wxVERTICAL)
  4008.       y_offset += cy;
  4009.     else
  4010.       x_offset += (int)(current_width + cx);
  4011.   }
  4012.  
  4013.   int text_length = (int)(width - (x_offset - x));
  4014.  
  4015.   // Text must have a minimum/default length
  4016.   if (text_length < 0)
  4017.     text_length = 80;
  4018.  
  4019.   MoveWindow((HWND)ms_handle, x_offset, y_offset, text_length, (int)(cy*7/4), TRUE);
  4020.   OnSize(width, height);
  4021. #endif
  4022. }
  4023.  
  4024. void wxText::SetFocus(void)
  4025. {
  4026. #ifdef wx_motif
  4027. #endif
  4028. #ifdef wx_xview
  4029.   wxPanel *panel = (wxPanel *)GetParent();
  4030.   if (panel)
  4031.   {
  4032.     Panel p = (Panel)panel->handle;
  4033.     xv_set(p, PANEL_CARET_ITEM, (Panel_item)handle, 0);
  4034.   }
  4035. #endif
  4036. #ifdef wx_msw
  4037.   wxItem::SetFocus();
  4038. #endif
  4039. }
  4040.  
  4041. // Multi-line Text item
  4042. wxMultiText::wxMultiText(wxPanel *panel, wxFunction Function, char *label, char *value,
  4043.                int x, int y, int width, int height)
  4044. {
  4045.   window_parent = panel;
  4046.   labelPosition = panel->label_position;
  4047. #ifdef wx_motif
  4048.   Widget panelForm = panel->panelWidget;
  4049.   formWidget = XtVaCreateManagedWidget("form",
  4050.                   xmFormWidgetClass, panelForm,
  4051.                   NULL);
  4052.  
  4053.   XmString text = XmStringCreateSimple(label);
  4054.  
  4055.   Widget textWidget;
  4056.  
  4057.   labelWidget = XtVaCreateManagedWidget(label,
  4058.                 xmLabelWidgetClass,  formWidget,
  4059.                 XmNlabelString,      text,
  4060.                 NULL);
  4061.  
  4062.   textWidget = XmCreateScrolledText(formWidget, "multi_text", NULL, 0);
  4063.  
  4064.   handle = (char *)textWidget;
  4065.  
  4066.   XtVaSetValues(textWidget,
  4067.                 XmNeditMode, XmMULTI_LINE_EDIT,
  4068.                 NULL);
  4069.   XtManageChild(textWidget);
  4070.  
  4071.   if (panel->label_position == wxHORIZONTAL)
  4072.   {
  4073.     XtVaSetValues(labelWidget,
  4074.                   XmNtopAttachment,    XmATTACH_FORM,
  4075.                   XmNleftAttachment,   XmATTACH_FORM,
  4076.                   XmNalignment,        XmALIGNMENT_BEGINNING,
  4077.                   NULL);
  4078.     XtVaSetValues(XtParent(textWidget),
  4079.                   XmNleftOffset,       4,
  4080.                   XmNtopAttachment,    XmATTACH_FORM,
  4081.                   XmNbottomAttachment, XmATTACH_FORM,
  4082.                   XmNleftAttachment,   XmATTACH_WIDGET,
  4083.                   XmNleftWidget,       labelWidget,
  4084.                   NULL);
  4085.   }
  4086.   else
  4087.   {
  4088.     XtVaSetValues(labelWidget,
  4089.                   XmNtopAttachment,    XmATTACH_FORM,
  4090.                   XmNleftAttachment,   XmATTACH_FORM,
  4091.                   XmNalignment,        XmALIGNMENT_BEGINNING,
  4092.                   NULL);
  4093.  
  4094.     XtVaSetValues(XtParent(textWidget),
  4095.                   XmNtopAttachment,    XmATTACH_WIDGET,
  4096.                   XmNtopWidget,        labelWidget,
  4097.                   XmNbottomAttachment, XmATTACH_FORM,
  4098.                   XmNleftAttachment,   XmATTACH_FORM,
  4099.                   XmNalignment,        XmALIGNMENT_BEGINNING,
  4100.                   NULL);
  4101.   }
  4102.  
  4103.   XmStringFree(text);
  4104.  
  4105.   XtAddCallback(textWidget, XmNactivateCallback, wxTextCallback,
  4106.                   this);
  4107.  
  4108.   AttachWidget(panel, formWidget, x, y, width, height);
  4109.  
  4110.   if (value)
  4111.     XmTextSetString(textWidget, value);
  4112. #endif
  4113. #ifdef wx_xview
  4114.   Panel x_panel = (Panel)(panel->GetHandle());
  4115.   Panel_item x_text;
  4116.  
  4117.   int label_position;
  4118.   if (panel->label_position == wxVERTICAL)
  4119.     label_position = PANEL_VERTICAL;
  4120.   else
  4121.     label_position = PANEL_HORIZONTAL;
  4122.  
  4123.   if (panel->new_line)
  4124.   {
  4125.     x_text = (Panel_item) xv_create(x_panel, PANEL_MULTILINE_TEXT,
  4126.                                PANEL_VALUE_DISPLAY_WIDTH, 120,
  4127.                                PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1, NULL);
  4128.     panel->new_line = FALSE;
  4129.   }
  4130.   else
  4131.     x_text = (Panel_item) xv_create(x_panel, PANEL_MULTILINE_TEXT,
  4132.                                PANEL_VALUE_DISPLAY_WIDTH, 120,
  4133.                                PANEL_LAYOUT, label_position, NULL);
  4134.  
  4135.   xv_set(x_text,
  4136.                               PANEL_NOTIFY_PROC, wxTextProc,
  4137.                   PANEL_CLIENT_DATA, (char *)this,
  4138.                               NULL);
  4139.  
  4140.   if (x > -1 && y > -1)
  4141.     (void)xv_set(x_text, XV_X, x, XV_Y, y, NULL);
  4142.  
  4143.   if (width > 0)
  4144.     { xv_set(x_text, PANEL_VALUE_DISPLAY_WIDTH, (int) width, NULL); };
  4145.  
  4146.   Xv_Font font = (Xv_Font)xv_get(x_panel, XV_FONT);
  4147.   int pixel_height = (int)xv_get(font, FONT_DEFAULT_CHAR_HEIGHT);
  4148.  
  4149.   if (height > -1)
  4150.     (void)xv_set(x_text, PANEL_DISPLAY_ROWS, (int)(height/pixel_height), NULL);
  4151.  
  4152.   if (label)
  4153.     { xv_set(x_text, PANEL_LABEL_STRING, label, NULL); };
  4154.  
  4155.   if (value)
  4156.     { xv_set(x_text, PANEL_VALUE, value, NULL); };
  4157.  
  4158.   handle = (char *)x_text;
  4159. #endif
  4160. #ifdef wx_msw
  4161.   wxWinType = wxTYPE_HWND;
  4162.   wxWnd *cparent = NULL;
  4163.   if (panel)
  4164.     cparent = (wxWnd *)(panel->handle);
  4165.  
  4166.   panel->GetValidPosition(&x, &y);
  4167.  
  4168.   int x_offset = x;
  4169.  
  4170.   // If label exists, create a static control for it.
  4171.   if (label)
  4172.   {
  4173.     static_label = CreateWindowEx(0, "STATIC", label,
  4174.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  4175.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  4176.                          wxhInstance, NULL);
  4177.   }
  4178.   else
  4179.     static_label = NULL;
  4180.  
  4181.   windows_id = (int)NewId();
  4182.   HWND edit = CreateWindowEx(0, "EDIT", label,
  4183.                ES_MULTILINE | ES_AUTOHSCROLL | ES_LEFT | ES_WANTRETURN |
  4184.                WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP |
  4185.                WS_HSCROLL | WS_VSCROLL,
  4186.                0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  4187.                wxhInstance, NULL);
  4188.  
  4189.   ms_handle = (HANDLE)edit;
  4190.  
  4191.   SetSize(x, y, width, height);
  4192.  
  4193.   if (value)
  4194.     SetWindowText(edit, value);
  4195.  
  4196.   panel->AdvanceCursor(this);
  4197. #endif
  4198.   if (panel) panel->AddChild(this);
  4199.   Callback(Function);
  4200. }
  4201.  
  4202. char *wxMultiText::GetValue(void)
  4203. {
  4204. #ifdef wx_motif
  4205.   return wxText::GetValue();
  4206. #endif
  4207. #ifdef wx_xview
  4208.   Panel_item item = (Panel_item)handle;
  4209.   return copystring((char *)xv_get(item, PANEL_VALUE));
  4210. #endif
  4211.  
  4212. #ifdef wx_msw
  4213.   int buf_len = 1000;
  4214.   int no_chars = 0;
  4215.   int no_lines = (int)SendMessage((HWND)ms_handle, EM_GETLINECOUNT, 0, 0L);
  4216.   for (int i = 0; i < no_lines; i++)
  4217.   {
  4218.     *(LPINT)(wxBuffer+no_chars) = buf_len;
  4219.     int n = (int)SendMessage((HWND)ms_handle, EM_GETLINE, i,
  4220.                          (LONG)(wxBuffer+no_chars));
  4221.     no_chars += n;
  4222.     buf_len -= (n + 2);
  4223.     if (i < (no_lines - 1))
  4224.     {
  4225.       wxBuffer[no_chars] = 13;
  4226.       no_chars ++;
  4227.       wxBuffer[no_chars] = 10;
  4228.       no_chars ++;
  4229.     }
  4230.   }
  4231.   wxBuffer[no_chars] = 0;
  4232.   return copystring(wxBuffer);
  4233. #endif
  4234. }
  4235.  
  4236. void wxMultiText::GetValue(char *buffer, int maxSize)
  4237. {
  4238.   buffer[0] = 0;
  4239. #ifdef wx_motif
  4240.   char *s = XmTextGetString((Widget)handle);
  4241.   if (s)
  4242.   {
  4243.     if (strlen(s) > (maxSize - 1))
  4244.     {
  4245.       strncpy(buffer, s, maxSize - 1);
  4246.       buffer[maxSize-1] = 0;
  4247.     }
  4248.     else
  4249.       strcpy(buffer, s);
  4250.     XtFree(s);
  4251.   }
  4252.   else buffer[0] = 0;
  4253. #endif
  4254. #ifdef wx_xview
  4255.   Panel_item item = (Panel_item)handle;
  4256.   char *s = (char *)xv_get(item, PANEL_VALUE);
  4257.   strncpy(buffer, s, strlen(s));
  4258. #endif
  4259.  
  4260. #ifdef wx_msw
  4261.   int no_chars = 0;
  4262.   int no_lines = (int)SendMessage((HWND)ms_handle, EM_GETLINECOUNT, 0, 0L);
  4263.   for (int i = 0; i < no_lines; i++)
  4264.   {
  4265.     *(LPINT)(buffer+no_chars) = maxSize;
  4266.     int n = (int)SendMessage((HWND)ms_handle, EM_GETLINE, i,
  4267.                          (LONG)(buffer+no_chars));
  4268.     no_chars += n;
  4269.     maxSize -= (n + 2);
  4270.     if (i < (no_lines - 1))
  4271.     {
  4272.       buffer[no_chars] = 13;
  4273.       no_chars ++;
  4274.       buffer[no_chars] = 10;
  4275.       no_chars ++;
  4276.     }
  4277.   }
  4278.   buffer[no_chars] = 0;
  4279. #endif
  4280. }
  4281.  
  4282. void wxMultiText::SetSize(int x, int y, int width, int height)
  4283. {
  4284. #ifdef wx_motif
  4285.   wxText::SetSize(x, y, width, height);
  4286. #endif
  4287. #ifdef wx_xview
  4288.   Xv_opaque x_win = (Xv_opaque)handle;
  4289.  
  4290.   if (x > -1)
  4291.     (void)xv_set(x_win, XV_X, x, NULL);
  4292.  
  4293.   if (y > -1)
  4294.     (void)xv_set(x_win, XV_Y, y, NULL);
  4295.  
  4296.   if (width <= 0)
  4297.     width = 120;
  4298.  
  4299.   (void)xv_set(x_win, PANEL_VALUE_DISPLAY_WIDTH, width, NULL);
  4300.  
  4301.   Panel panel = (Panel)(GetParent()->handle);
  4302.   Xv_Font font = (Xv_Font)xv_get(panel, XV_FONT);
  4303.   int pixel_height = (int)xv_get(font, FONT_DEFAULT_CHAR_HEIGHT);
  4304.  
  4305.   if (height > -1)
  4306.     (void)xv_set(x_win, PANEL_DISPLAY_ROWS, (int)(height/pixel_height), NULL);
  4307.   OnSize(width, height);
  4308. #endif
  4309. #ifdef wx_msw
  4310.   int currentX, currentY;
  4311.   GetPosition(¤tX, ¤tY);
  4312.   if (x == -1)
  4313.     x = currentX;
  4314.   if (y == -1)
  4315.     y = currentY;
  4316.  
  4317.   char buf[300];
  4318.  
  4319.   int x_offset = x;
  4320.   int y_offset = y;
  4321.   float current_width;
  4322.  
  4323.   int cx;
  4324.   int cy;
  4325.   float cyf;
  4326.   wxGetCharSize((HWND)ms_handle, &cx, &cy);
  4327.  
  4328.   if (static_label)
  4329.   {
  4330.     GetWindowText(static_label, buf, 300);
  4331.     GetTextExtent(buf, ¤t_width, &cyf);
  4332.     MoveWindow(static_label, x_offset, y, (int)(current_width + cx), (int)cyf, TRUE);
  4333.     if (labelPosition == wxVERTICAL)
  4334.       y_offset += cy;
  4335.     else
  4336.       x_offset += (int)(current_width + cx);
  4337.   }
  4338.  
  4339.   int text_length = (int)(width - (x_offset - x));
  4340.  
  4341.   int text_height = (int)height;
  4342.   if (text_height <= 0)
  4343.     text_height = (int)(cy*14/4);
  4344.  
  4345.   // Text must have a minimum/default length
  4346.   if (text_length < 0)
  4347.     text_length = 80;
  4348.  
  4349.   MoveWindow((HWND)ms_handle, x_offset, y_offset, text_length, text_height, TRUE);
  4350.   OnSize(width, height);
  4351. #endif
  4352. }
  4353.  
  4354.  
  4355. // Slider
  4356.  
  4357. #ifdef wx_xview
  4358. void wxSliderProc(Panel_item item, int value, Event *x_event)
  4359. {
  4360.   wxSlider *slider = (wxSlider *)xv_get(item, PANEL_CLIENT_DATA);
  4361.   wxEvent event(x_event);
  4362.   event.index = value;
  4363.  
  4364.   if (slider->callback)
  4365.   {
  4366.     (void)(*(slider->callback))(*slider, event);
  4367.   }
  4368. }
  4369. #endif
  4370.  
  4371. #ifdef wx_motif
  4372. void wxSliderCallback(Widget widget, XtPointer clientData, XmScaleCallbackStruct *cbs)
  4373. {
  4374.   wxSlider *slider = (wxSlider *)clientData;
  4375.   wxEvent event;
  4376.   XtVaGetValues(widget, XmNvalue, &event.index, NULL);
  4377.  
  4378.   if (slider->callback)
  4379.   {
  4380.     (void)(*(slider->callback))(*slider, event);
  4381.   }
  4382. }
  4383. #endif
  4384.  
  4385.  
  4386. wxSlider::wxSlider(wxPanel *panel, wxFunction func, char *label, int value,
  4387.            int min_value, int max_value, int width, int x, int y)
  4388. {
  4389.   window_parent = panel;
  4390.   labelPosition = panel->label_position;
  4391. #ifdef wx_motif
  4392.   Widget panelForm = panel->panelWidget;
  4393.   XmString text = XmStringCreateSimple(label);
  4394.  
  4395.   formWidget = XtVaCreateManagedWidget("rowcol",
  4396.                   xmRowColumnWidgetClass, panelForm,
  4397.                   XmNorientation, XmHORIZONTAL,
  4398.                   NULL);
  4399.  
  4400.   labelWidget = XtVaCreateManagedWidget(label,
  4401.                   xmLabelWidgetClass,  formWidget,
  4402.                   XmNlabelString,      text,
  4403.                   NULL);
  4404.  
  4405.   Widget sliderWidget;
  4406.  
  4407.   sliderWidget = XtVaCreateManagedWidget("slider",
  4408.                   xmScaleWidgetClass, formWidget,
  4409.                   XmNorientation,      XmHORIZONTAL,
  4410.                   XmNprocessingDirection, XmMAX_ON_RIGHT,
  4411.                   XmNmaximum,          max_value,
  4412.                   XmNminimum,          min_value,
  4413.                   XmNvalue,            value,
  4414.                   XmNshowValue,        True,
  4415.                   NULL);
  4416.  
  4417.   handle = (char *)sliderWidget;
  4418.  
  4419.   XtAddCallback(sliderWidget, XmNvalueChangedCallback, wxSliderCallback, this);
  4420.  
  4421.   XmStringFree(text);
  4422.  
  4423.   AttachWidget(panel, formWidget, x, y, width, -1);
  4424. #endif
  4425. #ifdef wx_xview
  4426.   Panel x_panel = (Panel)(panel->GetHandle());
  4427.   Panel_item x_slider;
  4428.  
  4429.   int label_position;
  4430.   if (panel->label_position == wxVERTICAL)
  4431.     label_position = PANEL_VERTICAL;
  4432.   else
  4433.     label_position = PANEL_HORIZONTAL;
  4434.  
  4435.   if (x > -1 && y > -1)
  4436.   {
  4437.     if (panel->new_line)
  4438.     {
  4439.       x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, label_position, PANEL_NEXT_ROW, -1,
  4440.               XV_X, x, XV_Y, y, NULL);
  4441.       panel->new_line = FALSE;
  4442.     }
  4443.     else
  4444.       x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, label_position, XV_X, x, XV_Y, y, NULL);
  4445.  
  4446.   }
  4447.   else
  4448.   {
  4449.     if (panel->new_line)
  4450.     {
  4451.       x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_NEXT_ROW, -1,
  4452.               NULL);
  4453.       panel->new_line = FALSE;
  4454.     }
  4455.     else
  4456.       x_slider = (Panel_item) xv_create(x_panel, PANEL_SLIDER, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
  4457.   }
  4458.  
  4459.   xv_set(x_slider,
  4460.                               PANEL_MIN_VALUE, min_value,
  4461.                               PANEL_MAX_VALUE, max_value,
  4462.                               PANEL_NOTIFY_PROC, wxSliderProc,
  4463.                   PANEL_CLIENT_DATA, (char *)this,
  4464.                               PANEL_VALUE, value,
  4465.                               NULL);
  4466.  
  4467.   if (width > 0)
  4468.     { xv_set(x_slider, PANEL_SLIDER_WIDTH, (int) width, NULL); };
  4469.  
  4470.   if (label)
  4471.     { xv_set(x_slider, PANEL_LABEL_STRING, label, NULL); };
  4472.  
  4473.   handle = (char *)x_slider;
  4474.   Callback(func);
  4475. #endif
  4476. #ifdef wx_msw
  4477.   wxWinType = wxTYPE_HWND;
  4478.   wxWnd *cparent = NULL;
  4479.   if (panel)
  4480.     cparent = (wxWnd *)(panel->handle);
  4481.  
  4482.   panel->GetValidPosition(&x, &y);
  4483.  
  4484.   int cx;
  4485.   int cy;
  4486.   wxGetCharSize(cparent->handle, &cx, &cy);
  4487.  
  4488.   // If label exists, create a static control for it.
  4489.   if (label)
  4490.   {
  4491.     static_label = CreateWindowEx(0, "STATIC", label,
  4492.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  4493.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  4494.                          wxhInstance, NULL);
  4495.   }
  4496.   else
  4497.     static_label = NULL;
  4498.  
  4499.   edit_value = CreateWindowEx(0, "EDIT", NULL,
  4500.                          ES_AUTOHSCROLL | ES_LEFT | WS_VISIBLE | WS_CHILD |
  4501.                          WS_TABSTOP,
  4502.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  4503.                          wxhInstance, NULL);
  4504.  
  4505.   // Now create min static control
  4506.   sprintf(wxBuffer, "%d", min_value);
  4507.   static_min = CreateWindowEx(0, "STATIC", wxBuffer,
  4508.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  4509.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  4510.                          wxhInstance, NULL);
  4511.  
  4512.   // Now create slider
  4513.   windows_id = (int)NewId();
  4514.   HWND scroll_bar = CreateWindowEx(0, "SCROLLBAR", wxBuffer,
  4515.                          SBS_HORZ | WS_CHILD | WS_VISIBLE,
  4516.                          0, 0, 0, 0, cparent->handle, (HMENU)windows_id,
  4517.                          wxhInstance, NULL);
  4518.  
  4519.   wxScrollBarList.Append((long)scroll_bar, this);
  4520.  
  4521.   page_size = (int)((max_value-min_value)/10);
  4522.   s_max = max_value;
  4523.   s_min = min_value;
  4524.  
  4525.   SetScrollRange(scroll_bar, SB_CTL, min_value, max_value, FALSE);
  4526.   SetScrollPos(scroll_bar, SB_CTL, value, FALSE);
  4527.   ShowWindow(scroll_bar, SW_SHOW);
  4528.  
  4529.   ms_handle = (HANDLE)scroll_bar;
  4530.  
  4531.   // Finally, create max value static item
  4532.   sprintf(wxBuffer, "%d", max_value);
  4533.   static_max = CreateWindowEx(0, "STATIC", wxBuffer,
  4534.                          SS_LEFT | WS_CHILD | WS_VISIBLE,
  4535.                          0, 0, 0, 0, cparent->handle, (HMENU)NewId(),
  4536.                          wxhInstance, NULL);
  4537.  
  4538.  
  4539.   SetSize(x, y, width, -1);
  4540.   SetValue(value);
  4541.   panel->AdvanceCursor(this);
  4542. #endif
  4543.   if (panel) panel->AddChild(this);
  4544.  
  4545.   Callback(func);
  4546. }
  4547.  
  4548. #ifdef wx_msw
  4549.  
  4550. // Called from wx_win.cc: wxWnd::OnHScroll
  4551. void wxSliderEvent(HWND bar, WORD wParam, WORD pos)
  4552. {
  4553.     wxNode *node = (wxNode *)wxScrollBarList.Find((long)bar);
  4554.     if (!node)
  4555.       return;
  4556.  
  4557.     wxSlider *slider = (wxSlider *)node->Data();
  4558.     int position = GetScrollPos(bar, SB_CTL);
  4559.  
  4560.     int nScrollInc;
  4561.     switch ( wParam )
  4562.     {
  4563.             case SB_LINEUP:
  4564.                     nScrollInc = -1;
  4565.                     break;
  4566.  
  4567.             case SB_LINEDOWN:
  4568.                     nScrollInc = 1;
  4569.                     break;
  4570.  
  4571.             case SB_PAGEUP:
  4572.                     nScrollInc = -slider->page_size;
  4573.                     break;
  4574.  
  4575.             case SB_PAGEDOWN:
  4576.                     nScrollInc = slider->page_size;;
  4577.                     break;
  4578.  
  4579.             case SB_THUMBTRACK:
  4580.                     nScrollInc = pos - position;
  4581.                     break;
  4582.  
  4583.             default:
  4584.                     nScrollInc = 0;
  4585.     }
  4586.  
  4587.     if (nScrollInc != 0)
  4588.     {
  4589.       int new_pos = position + nScrollInc;
  4590.       if (!(new_pos < slider->s_min || new_pos > slider->s_max))
  4591.         slider->SetValue(new_pos);
  4592.     }
  4593. }
  4594.  
  4595. #endif
  4596.  
  4597. wxSlider::~wxSlider(void)
  4598. {
  4599. #ifdef wx_msw
  4600.     if (static_min)
  4601.     {
  4602.       DestroyWindow(static_min);
  4603.     }
  4604.     if (static_max)
  4605.     {
  4606.       DestroyWindow(static_max);
  4607.     }
  4608.     if (edit_value)
  4609.     {
  4610.       DestroyWindow(edit_value);
  4611.     }
  4612.     if (static_label)
  4613.     {
  4614.       DestroyWindow(static_label);
  4615.     }
  4616.     wxScrollBarList.DeleteObject(this);
  4617. #endif
  4618. }
  4619.  
  4620. int wxSlider::GetValue(void)
  4621. {
  4622. #ifdef wx_motif
  4623.   int val;
  4624.   XtVaGetValues((Widget)handle, XmNvalue, &val, NULL);
  4625.   return val;
  4626. #endif
  4627. #ifdef wx_xview
  4628.   Panel_item item = (Panel_item)handle;
  4629.   return (int)xv_get(item, PANEL_VALUE);
  4630. #endif
  4631. #ifdef wx_msw
  4632.   return GetScrollPos((HWND)ms_handle, SB_CTL);
  4633. #endif
  4634. }
  4635.  
  4636. char *wxSlider::GetLabel(void)
  4637. {
  4638. #ifdef wx_motif
  4639.   XmString text;
  4640.   char *s;
  4641.   XtVaGetValues(labelWidget,
  4642.                   XmNlabelString, &text,
  4643.                   NULL);
  4644.  
  4645.   if (XmStringGetLtoR(text, XmSTRING_DEFAULT_CHARSET, &s))
  4646.   {
  4647. //    XmStringFree(text);
  4648.     char *val = copystring(s);
  4649.     XtFree(s);
  4650.     return val;
  4651.   }
  4652.   else
  4653.   {
  4654. //    XmStringFree(text);
  4655.     return NULL;
  4656.   }
  4657. #endif
  4658. #ifdef wx_xview
  4659.   Panel_item item = (Panel_item)handle;
  4660.   return copystring((char *)xv_get(item, PANEL_LABEL_STRING));
  4661. #endif
  4662. #ifdef wx_msw
  4663.   char buf[300];
  4664.   if (static_label)
  4665.   {
  4666.     GetWindowText(static_label, buf, 300);
  4667.     return copystring(buf);
  4668.   }
  4669.   else return NULL;
  4670. #endif
  4671. }
  4672.  
  4673. void wxSlider::SetValue(int value)
  4674. {
  4675. #ifdef wx_motif
  4676.   XtVaSetValues((Widget)handle, XmNvalue, value, NULL);
  4677. #endif
  4678. #ifdef wx_xview
  4679.   Panel_item item = (Panel_item)handle;
  4680.   xv_set(item, PANEL_VALUE, value, NULL);
  4681. #endif
  4682. #ifdef wx_msw
  4683.   SetScrollPos((HWND)ms_handle, SB_CTL, value, TRUE);
  4684.  
  4685.   sprintf(wxBuffer, "%d", value);
  4686.   SetWindowText(edit_value, wxBuffer);
  4687.  
  4688.   wxEvent event;
  4689.   event.index = value;
  4690.  
  4691.   if (callback)
  4692.     (void)(*callback)(*this, event);
  4693. #endif
  4694. }
  4695.  
  4696. void wxSlider::SetLabel(char *label)
  4697. {
  4698. #ifdef wx_motif
  4699.   XmString text = XmStringCreateSimple(label);
  4700.   XtVaSetValues(labelWidget,
  4701.                   XmNlabelString, text,
  4702.                   NULL);
  4703.   XmStringFree(text);
  4704. #endif
  4705. #ifdef wx_xview
  4706.   Panel_item item = (Panel_item)handle;
  4707.   xv_set(item, PANEL_LABEL_STRING, label, NULL);
  4708. #endif
  4709. #ifdef wx_msw
  4710.   if (static_label)
  4711.   {
  4712.     float w, h;
  4713.     RECT rect;
  4714.  
  4715.     wxWindow *parent = GetParent();
  4716.     GetWindowRect(static_label, &rect);
  4717.  
  4718.     // Since we now have the absolute screen coords,
  4719.     // if there's a parent we must subtract its top left corner
  4720.     POINT point;
  4721.     point.x = rect.left;
  4722.     point.y = rect.top;
  4723.     if (parent)
  4724.     {
  4725.       wxWnd *cparent = (wxWnd *)(parent->handle);
  4726.       ScreenToClient(cparent->handle, &point);
  4727.     }
  4728.  
  4729.     GetTextExtent(label, &w, &h);
  4730.     MoveWindow(static_label, point.x, point.y, (int)(w + 10), (int)h,
  4731.                TRUE);
  4732.     SetWindowText(static_label, label);
  4733.   }
  4734. #endif
  4735. }
  4736.  
  4737. void wxSlider::GetSize(int *width, int *height)
  4738. {
  4739. #ifdef wx_motif
  4740.   Widget sliderWidget = (Widget)handle;
  4741.   Dimension x, y;
  4742.   XtVaGetValues(sliderWidget, XmNscaleWidth, &x, XmNscaleHeight, &y, NULL);
  4743.   *width = x;
  4744.   *height = y;
  4745. #endif
  4746. #ifdef wx_xview
  4747.   Panel_item item = (Panel_item)handle;
  4748.   Rect *rect = (Rect *)xv_get(item, XV_RECT);
  4749.  
  4750.   *height = rect->r_height;
  4751.   *width = rect->r_width;
  4752. #endif
  4753. #ifdef wx_msw
  4754.   RECT rect;
  4755.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  4756.  
  4757.   wxFindMaxSize((HWND)ms_handle, &rect);
  4758.  
  4759.   if (static_label)
  4760.   {
  4761.     wxFindMaxSize(static_label, &rect);
  4762.   }
  4763.   if (static_min)
  4764.   {
  4765.     wxFindMaxSize(static_min, &rect);
  4766.   }
  4767.   if (static_max)
  4768.   {
  4769.     wxFindMaxSize(static_max, &rect);
  4770.   }
  4771.   if (edit_value)
  4772.   {
  4773.     wxFindMaxSize(edit_value, &rect);
  4774.   }
  4775.  
  4776.   *width = rect.right - rect.left;
  4777.   *height = rect.bottom - rect.top;
  4778. #endif
  4779. }
  4780.  
  4781. void wxSlider::GetPosition(int *x, int *y)
  4782. {
  4783. #ifdef wx_motif
  4784.   wxItem::GetPosition(x, y);
  4785. #endif
  4786. #ifdef wx_xview
  4787.   Xv_opaque x_win = (Xv_opaque)handle;
  4788.  
  4789.   *x = (int)xv_get(x_win, XV_X);
  4790.   *y = (int)xv_get(x_win, XV_Y);
  4791. #endif
  4792. #ifdef wx_msw
  4793.   wxWindow *parent = GetParent();
  4794.   RECT rect;
  4795.   rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
  4796.  
  4797.   wxFindMaxSize((HWND)ms_handle, &rect);
  4798.  
  4799.   if (static_label)
  4800.   {
  4801.     wxFindMaxSize(static_label, &rect);
  4802.   }
  4803.   if (static_min)
  4804.   {
  4805.     wxFindMaxSize(static_min, &rect);
  4806.   }
  4807.   if (static_max)
  4808.   {
  4809.     wxFindMaxSize(static_max, &rect);
  4810.   }
  4811.   if (edit_value)
  4812.   {
  4813.     wxFindMaxSize(edit_value, &rect);
  4814.   }
  4815.  
  4816.   // Since we now have the absolute screen coords,
  4817.   // if there's a parent we must subtract its top left corner
  4818.   POINT point;
  4819.   point.x = rect.left;
  4820.   point.y = rect.top;
  4821.   if (parent)
  4822.   {
  4823.     wxWnd *cparent = (wxWnd *)(parent->handle);
  4824.     ScreenToClient(cparent->handle, &point);
  4825.   }
  4826.  
  4827.   *x = point.x;
  4828.   *y = point.y;
  4829. #endif
  4830. }
  4831.  
  4832. void wxSlider::SetSize(int x, int y, int width, int height)
  4833. {
  4834. #ifdef wx_motif
  4835.   Widget sliderWidget = (Widget)handle;
  4836.  
  4837.   if (width > -1)
  4838.   {
  4839.     Dimension labelWidth;
  4840.     XtVaGetValues(labelWidget, XmNwidth, &labelWidth, NULL);
  4841.  
  4842.     XtVaSetValues(sliderWidget, XmNscaleWidth, max(width-labelWidth, 10), NULL);
  4843.   }
  4844.  
  4845.   if (x > -1)
  4846.     XtVaSetValues(formWidget, XmNleftAttachment, XmATTACH_SELF, XmNx, x, NULL);
  4847.   if (y > -1)
  4848.     XtVaSetValues(formWidget, XmNtopAttachment, XmATTACH_SELF, XmNy, y, NULL);
  4849.   OnSize(width, height);
  4850. #endif
  4851. #ifdef wx_xview
  4852.   Xv_opaque x_win = (Xv_opaque)handle;
  4853.  
  4854.   if (x > -1)
  4855.     (void)xv_set(x_win, XV_X, x, NULL);
  4856.  
  4857.   if (y > -1)
  4858.     (void)xv_set(x_win, XV_Y, y, NULL);
  4859.  
  4860.   if (width > 0)
  4861.     (void)xv_set(x_win, XV_WIDTH, width, NULL);
  4862.  
  4863.   if (height > 0)
  4864.     (void)xv_set(x_win, XV_HEIGHT, height, NULL);
  4865.   OnSize(width, height);
  4866. #endif
  4867. #ifdef wx_msw
  4868.   int currentX, currentY;
  4869.   GetPosition(¤tX, ¤tY);
  4870.   if (x == -1)
  4871.     x = currentX;
  4872.   if (y == -1)
  4873.     y = currentY;
  4874.  
  4875.   char buf[300];
  4876.  
  4877.   int x_offset = x;
  4878.   float current_width;
  4879.  
  4880.   int cx;
  4881.   int cy;
  4882.   float cyf;
  4883.   wxGetCharSize((HWND)ms_handle, &cx, &cy);
  4884.  
  4885.   if (static_label)
  4886.   {
  4887.     GetWindowText(static_label, buf, 300);
  4888.     GetTextExtent(buf, ¤t_width, &cyf);
  4889.     MoveWindow(static_label, x_offset, y, (int)(current_width + 2*cx), (int)cyf,
  4890.                TRUE);
  4891.     x_offset += (int)(current_width + 2*cx + cx);
  4892.   }
  4893.  
  4894.   float min_len;
  4895.   GetWindowText(static_min, buf, 300);
  4896.   GetTextExtent(buf, &min_len, &cyf);
  4897.  
  4898.   float max_len;
  4899.   GetWindowText(static_max, buf, 300);
  4900.   GetTextExtent(buf, &max_len, &cyf);
  4901.  
  4902.   if (edit_value)
  4903.   {
  4904.     int new_width = (int)(max(min_len, max_len));
  4905.     MoveWindow(edit_value, x_offset, y, new_width, (int)cyf, TRUE);
  4906.     x_offset += new_width + cx;
  4907.   }
  4908.  
  4909.   MoveWindow(static_min, x_offset, y, (int)min_len, cy, TRUE);
  4910.   x_offset += (int)(min_len + cx);
  4911.  
  4912.   int slider_length = (int)(width - x_offset - max_len - cx);
  4913.  
  4914.   // Slider must have a minimum/default length
  4915.   if (slider_length < 0)
  4916.     slider_length = 100;
  4917.  
  4918.   MoveWindow((HWND)ms_handle, x_offset, y, slider_length, cy, TRUE);
  4919.   x_offset += slider_length + cx;
  4920.  
  4921.   MoveWindow(static_max, x_offset, y, (int)max_len, cy, TRUE);
  4922.   OnSize(width, height);
  4923. #endif
  4924. }
  4925.  
  4926. // Yeuch! Have to put this here since 'delete menu_bar' is not allowed before
  4927. // wxMenuBar has been defined!
  4928. #ifdef wx_msw
  4929. extern wxList wxModelessWindows;
  4930. #endif
  4931.  
  4932. wxFrame::~wxFrame(void)
  4933. {
  4934.   if (handle)
  4935.     Show(FALSE);
  4936.  
  4937.   if (wx_menu_bar)
  4938.     delete wx_menu_bar;
  4939.   if (icon)
  4940.     delete icon;
  4941.  
  4942. #ifdef wx_motif
  4943.   XtDestroyWidget(workArea);
  4944.   XtDestroyWidget(frameWidget);
  4945.   XtDestroyWidget(frameShell);
  4946.  
  4947.   if (statusTextWidget)
  4948.     XtDestroyWidget(statusTextWidget);
  4949.  
  4950.   if (statusLineWidget)
  4951.     XtDestroyWidget(statusLineWidget);
  4952.  
  4953.   if (this == wxTheApp->wx_frame)
  4954.     exit(0);
  4955. #endif
  4956.  
  4957. #ifdef wx_msw
  4958.   if (status_window)
  4959.   {
  4960.     status_window->DestroyWindow();
  4961.     delete status_window;
  4962.   }
  4963.  
  4964.   if (wxWinType == wxTYPE_MDICHILD)
  4965.   {
  4966.     wxMDIChild *child = (wxMDIChild *)handle;
  4967.     child->DestroyWindow();
  4968.     delete child;
  4969.     handle = NULL;
  4970.   }
  4971.  
  4972.   if (this == wxTheApp->wx_frame)
  4973.   {
  4974.      wxTheApp->wx_frame = NULL;
  4975.      PostQuitMessage(0);
  4976.   }
  4977.  
  4978.   wxModelessWindows.DeleteObject(this);
  4979. #endif
  4980. }
  4981.  
  4982. #ifdef wx_msw
  4983. HMENU wxFrame::GetWinMenu(void)
  4984. {
  4985.   if (wx_menu_bar)
  4986.     return (HMENU)wx_menu_bar->ms_handle;
  4987.   else return 0;
  4988. }
  4989. #endif
  4990.  
  4991. /*
  4992. #ifdef wx_msw
  4993. // Not currently used
  4994. void wxConvertDialogToPixels(wxWindow *control, int *x, int *y)
  4995. {
  4996.   if (control->window_parent && control->window_parent->is_dialog)
  4997.   {
  4998.     DWORD word = GetDialogBaseUnits();
  4999.     int xs = LOWORD(word);
  5000.     int ys = HIWORD(word);
  5001.     *x = (int)(*x * xs/4);
  5002.     *y = (int)(*y * ys/8);
  5003.   }
  5004.   else
  5005.   {
  5006.     *x = *x;
  5007.     *y = *y;
  5008.   }
  5009. }
  5010. #endif
  5011. */
  5012.  
  5013. #ifdef wx_x
  5014. void wxStripMenuCodes(char *in, char *out)
  5015. {
  5016.   int len = strlen(in);
  5017.   int j = 0;
  5018.   for (int i = 0; i < len; i++)
  5019.   {
  5020.     if (in[i] == '&')
  5021.     {}
  5022.     else if (in[i] == '\\' && (i + 1) <= len && in[i+1] == 't')
  5023.     {
  5024.       i ++;
  5025.       out[j] = ' ';
  5026.       j ++;
  5027.     }
  5028.     else
  5029.     {
  5030.       out[j] = in[i];
  5031.       j ++;
  5032.     }
  5033.   }
  5034.   out[j] = 0;
  5035. }
  5036.  
  5037. // Find the letter corresponding to the mnemonic, for Motif
  5038. char wxFindMnemonic(char *s)
  5039. {
  5040.   char mnem = 0;
  5041.   int len = strlen(s);
  5042.   for (int i = 0; i < len; i++)
  5043.   {
  5044.     if (s[i] == '&')
  5045.     {
  5046.       mnem = s[i+1];
  5047.       break;
  5048.     }
  5049.   }
  5050.   return mnem;
  5051. }
  5052. #endif
  5053.  
  5054. #ifdef wx_xview
  5055. void wxPanelEventProc(Panel x_panel, Event *x_event)
  5056. {
  5057.   wxPanel *panel = (wxPanel *)xv_get(x_panel, WIN_CLIENT_DATA);
  5058.   if (panel)
  5059.   {
  5060.     if (event_id(x_event) == KBD_USE)
  5061.       panel->OnSetFocus();
  5062.     else if (event_id(x_event) == KBD_DONE)
  5063.       panel->OnKillFocus();
  5064.     else if (event_is_ascii(x_event))
  5065.     {
  5066.       if (x_event->ie_code == 13)
  5067.       {
  5068.         // Find the default item, if any, and execute its callback
  5069.         Panel_item item = (Panel_item)xv_get(x_panel, PANEL_DEFAULT_ITEM);
  5070.         if (item)
  5071.         {
  5072.           wxItem *wx_item = (wxItem *)xv_get(item, PANEL_CLIENT_DATA);
  5073.           if (wx_item)
  5074.           {
  5075.             wxFunction fun = wx_item->callback;
  5076.             if (fun)
  5077.             {
  5078.               wxEvent event;
  5079.               (void)(*(fun))(*wx_item, event);
  5080.             }
  5081.           }
  5082.         } else panel->OnChar(x_event->ie_code);
  5083.       }
  5084.       else panel->OnChar(x_event->ie_code);
  5085.     }
  5086.     else
  5087.     {
  5088.       wxEvent event(x_event);
  5089.       event.x = event_x(x_event);
  5090.       event.y = event_y(x_event);
  5091.  
  5092.       panel->OnEvent(event);
  5093.     }
  5094.   }
  5095. }
  5096. #endif
  5097.  
  5098.