wxSpinCtrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3923 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 1999-10-10 23:28:07 +00:00
parent 2083616e16
commit b782f2e0f6
9 changed files with 462 additions and 74 deletions

View File

@ -13,7 +13,7 @@
#define _WX_SPINBUTT_H_
#ifdef __GNUG__
#pragma interface "spinbutt.h"
#pragma interface "spinbutt.h"
#endif
#include "wx/control.h"
@ -21,15 +21,10 @@
#if defined(__WIN95__)
class WXDLLEXPORT wxSpinButton : public wxSpinButtonBase
{
DECLARE_DYNAMIC_CLASS(wxSpinButton)
public:
/*
* Public interface
*/
// construction
wxSpinButton() { }
wxSpinButton(wxWindow *parent,
@ -62,9 +57,15 @@ public:
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
virtual bool MSWOnScroll(int orientation, WXWORD wParam,
WXWORD pos, WXHWND control);
protected:
virtual wxSize DoGetBestSize();
private:
DECLARE_DYNAMIC_CLASS(wxSpinButton)
};
#endif
// _WX_WIN95__
// __WIN95__
#endif
// _WX_SPINBUTT_H_

61
include/wx/msw/spinctrl.h Normal file
View File

@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////
// Name: msw/spinctrl.h
// Purpose: wxSpinCtrl class declaration for Win32
// Author: Vadim Zeitlin
// Modified by:
// Created: 22.07.99
// RCS-ID: $Id$
// Copyright: (c) Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_SPINCTRL_H_
#define _WX_MSW_SPINCTRL_H_
#ifdef __GNUG__
#pragma interface "spinctrl.h"
#endif
#include "wx/spinbutt.h" // the base class
// ----------------------------------------------------------------------------
// Under Win32, wxSpinCtrl is a wxSpinButton with a buddy (as MSDN docs call
// it) text window whose contents is automatically updated when the spin
// control is clicked.
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxSpinCtrl : public wxSpinButton
{
public:
wxSpinCtrl() { }
wxSpinCtrl(wxWindow *parent,
wxWindowID id = -1,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxSP_ARROW_KEYS,
int min = 0, int max = 100, int initial = 0,
const wxString& name = _T("wxSpinCtrl"))
{
Create(parent, id, pos, size, style, min, max, initial, name);
}
bool Create(wxWindow *parent,
wxWindowID id = -1,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxSP_ARROW_KEYS,
int min = 0, int max = 100, int initial = 0,
const wxString& name = _T("wxSpinCtrl"));
protected:
void DoMoveWindow(int x, int y, int width, int height);
WXHWND m_hwndBuddy;
DECLARE_DYNAMIC_CLASS(wxSpinCtrl)
};
#endif // _WX_MSW_SPINCTRL_H_

View File

@ -49,6 +49,7 @@ enum
// ---------------------------------------------------------------------------
// wxWindow declaration for MSW
// ---------------------------------------------------------------------------
class WXDLLEXPORT wxWindow : public wxWindowBase
{
DECLARE_DYNAMIC_CLASS(wxWindow);
@ -404,6 +405,12 @@ protected:
// will be the width and height of the text
virtual wxSize DoGetBestSize();
// move the window to the specified location and resize it: this is called
// from both DoSetSize() and DoSetClientSize() and would usually just call
// ::MoveWindow() except for composite controls which will want to arrange
// themselves inside the given rectangle
virtual void DoMoveWindow(int x, int y, int width, int height);
#if wxUSE_TOOLTIPS
virtual void DoSetToolTip( wxToolTip *tip );
#endif // wxUSE_TOOLTIPS

60
include/wx/spinctrl.h Normal file
View File

@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////
// Name: spinctrl.h
// Purpose: wxSpinCtrlBase class
// Author: Vadim Zeitlin
// Modified by:
// Created: 22.07.99
// RCS-ID: $Id$
// Copyright: (c) Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_SPINCTRL_H_
#define _WX_SPINCTRL_H_
#include "wx/control.h"
#include "wx/event.h"
// ----------------------------------------------------------------------------
// a spin ctrl is a text control with a spin button which is usually used to
// prompt the user for a numeric input
// ----------------------------------------------------------------------------
/* there is no generic base class for this control because it's imlpemented
very differently under MSW and other platforms
class WXDLLEXPORT wxSpinCtrlBase : public wxControl
{
public:
wxSpinCtrlBase() { Init(); }
// accessors
virtual int GetValue() const = 0;
virtual int GetMin() const { return m_min; }
virtual int GetMax() const { return m_max; }
// operations
virtual void SetValue(int val) = 0;
virtual void SetRange(int minVal, int maxVal) = 0;
protected:
// initialize m_min/max with the default values
void Init() { m_min = 0; m_max = 100; }
int m_min;
int m_max;
};
*/
// ----------------------------------------------------------------------------
// include the platform-dependent class implementation
// ----------------------------------------------------------------------------
#if defined(__WXMSW__) && defined(__WIN32__)
#include "wx/msw/spinctrl.h"
#else // Win16 || !Win
#include "wx/generic/spinctrl.h"
#endif // platform
#endif // _WX_SPINCTRL_H_

View File

@ -51,10 +51,21 @@
// Win16 doesn't have them
#undef wxUSE_SPINBUTTON
#define wxUSE_SPINBUTTON 0
#else
#if !defined(wxUSE_SPINBUTTON)
#define wxUSE_SPINBUTTON 1
#endif
#endif // __WIN16__
#include "wx/progdlg.h"
// VZ: this is a temp. hack, will remove soon
#define wxUSE_SPINCTRL 1
#if wxUSE_SPINCTRL
#include "wx/spinctrl.h"
#endif // wxUSE_SPINCTRL
//----------------------------------------------------------------------
// class definitions
//----------------------------------------------------------------------
@ -85,7 +96,7 @@ public:
void OnPageChanged( wxNotebookEvent &event );
void OnPageChanging( wxNotebookEvent &event );
void OnSliderUpdate( wxCommandEvent &event );
#ifndef wxUSE_SPINBUTTON
#if wxUSE_SPINBUTTON
void OnSpinUp( wxSpinEvent &event );
void OnSpinDown( wxSpinEvent &event );
void OnSpinUpdate( wxSpinEvent &event );
@ -102,10 +113,15 @@ public:
wxButton *m_fontButton;
wxButton *m_lbSelectNum;
wxButton *m_lbSelectThis;
#ifndef wxUSE_SPINBUTTON
#if wxUSE_SPINBUTTON
wxSpinButton *m_spinbutton;
wxButton *m_btnProgress;
#endif
#endif // wxUSE_SPINBUTTON
#if wxUSE_SPINCTRL
wxSpinCtrl *m_spinctrl;
#endif // wxUSE_SPINCTRL
wxTextCtrl *m_spintext;
wxCheckBox *m_checkbox;
@ -281,7 +297,7 @@ EVT_BUTTON (ID_RADIOBOX_FONT, MyPanel::OnRadioButtons)
EVT_CHECKBOX (ID_RADIOBOX_ENABLE, MyPanel::OnRadioButtons)
EVT_BUTTON (ID_SET_FONT, MyPanel::OnSetFont)
EVT_SLIDER (ID_SLIDER, MyPanel::OnSliderUpdate)
#ifndef wxUSE_SPINBUTTON
#if wxUSE_SPINBUTTON
EVT_SPIN (ID_SPIN, MyPanel::OnSpinUpdate)
EVT_SPIN_UP (ID_SPIN, MyPanel::OnSpinUp)
EVT_SPIN_DOWN (ID_SPIN, MyPanel::OnSpinDown)
@ -467,26 +483,33 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
wxString s;
s << initialSpinValue;
m_spintext = new wxTextCtrl( panel, -1, s, wxPoint(20,160), wxSize(80,-1) );
#ifndef wxUSE_SPINBUTTON
m_spinbutton = new wxSpinButton( panel, ID_SPIN, wxPoint(103,159), wxSize(-1,-1) );
#if wxUSE_SPINBUTTON
m_spinbutton = new wxSpinButton( panel, ID_SPIN, wxPoint(103,159), wxSize(80, -1) );
m_spinbutton->SetRange(-10,30);
m_spinbutton->SetValue(initialSpinValue);
m_btnProgress = new wxButton( panel, ID_BTNPROGRESS, "Show progress dialog",
wxPoint(208, 159) );
#endif
wxPoint(408, 159) );
#endif // wxUSE_SPINBUTTON
#if wxUSE_SPINCTRL
m_spinctrl = new wxSpinCtrl( panel, -1, wxPoint(200, 159), wxSize(80, 20) );
m_spinctrl->SetRange(10,30);
m_spinctrl->SetValue(15);
#endif // wxUSE_SPINCTRL
m_notebook->AddPage(panel, "wxGauge", FALSE, Image_Gauge);
panel = new wxPanel(m_notebook);
#ifndef __WXMOTIF__ // wxStaticBitmap not working under Motif yet. MB
wxIcon icon = wxTheApp->GetStdIcon(wxICON_INFORMATION);
wxStaticBitmap *bmpStatic = new wxStaticBitmap(panel, -1, icon, wxPoint(10, 10));
bmpStatic = new wxStaticBitmap(panel, -1, wxNullIcon, wxPoint(50, 10));
bmpStatic->SetIcon(wxTheApp->GetStdIcon(wxICON_QUESTION));
#endif
#endif // !Motif
wxBitmap bitmap( 100, 100 );
wxMemoryDC dc;
dc.SelectObject( bitmap );
@ -766,7 +789,7 @@ void MyPanel::OnSliderUpdate( wxCommandEvent &WXUNUSED(event) )
m_gauge->SetValue( m_slider->GetValue() );
}
#ifndef wxUSE_SPINBUTTON
#if wxUSE_SPINBUTTON
void MyPanel::OnSpinUp( wxSpinEvent &event )
{
wxString value;

View File

@ -281,6 +281,9 @@ bool wxApp::Initialize()
// RegisterWindowClasses
// ---------------------------------------------------------------------------
// TODO we should only register classes really used by the app. For this it
// would be enough to just delay the class registration until an attempt
// to create a window of this class is made.
bool wxApp::RegisterWindowClasses()
{
WNDCLASS wndclass;
@ -301,8 +304,8 @@ bool wxApp::RegisterWindowClasses()
// Register the frame window class.
wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
wndclass.style = styleNormal;
wndclass.lpszClassName = wxFrameClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{
@ -324,7 +327,8 @@ bool wxApp::RegisterWindowClasses()
// Register the MDI frame window class.
wndclass.hbrBackground = (HBRUSH)NULL; // paint MDI frame ourselves
wndclass.lpszClassName = wxMDIFrameClassNameNoRedraw;
wndclass.lpszClassName = wxMDIFrameClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{
@ -334,7 +338,7 @@ bool wxApp::RegisterWindowClasses()
}
// "no redraw" MDI frame
wndclass.lpszClassName = wxMDIFrameClassName;
wndclass.lpszClassName = wxMDIFrameClassNameNoRedraw;
wndclass.style = styleNoRedraw;
if ( !RegisterClass(&wndclass) )
@ -347,6 +351,7 @@ bool wxApp::RegisterWindowClasses()
// Register the MDI child frame window class.
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszClassName = wxMDIChildFrameClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{
@ -369,6 +374,7 @@ bool wxApp::RegisterWindowClasses()
// Register the panel window class.
wndclass.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH );
wndclass.lpszClassName = wxPanelClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{

View File

@ -9,6 +9,14 @@
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "spinbutt.h"
#endif
@ -36,11 +44,23 @@
#include <commctrl.h>
#endif
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxSpinButton, wxControl)
IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxScrollEvent);
#endif
// ----------------------------------------------------------------------------
// wxSpinButton
// ----------------------------------------------------------------------------
bool wxSpinButton::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
@ -48,70 +68,108 @@ bool wxSpinButton::Create(wxWindow *parent,
long style,
const wxString& name)
{
wxSystemSettings settings;
m_backgroundColour = parent->GetBackgroundColour() ;
m_foregroundColour = parent->GetForegroundColour() ;
// basic initialization
InitBase();
SetName(name);
m_windowId = (id == -1) ? NewControlId() : id;
int x = pos.x;
int y = pos.y;
int width = size.x;
int height = size.y;
m_backgroundColour = parent->GetBackgroundColour() ;
m_foregroundColour = parent->GetForegroundColour() ;
m_windowStyle = style;
SetName(name);
SetParent(parent);
int x = pos.x;
int y = pos.y;
int width = size.x;
int height = size.y;
if (width <= 0)
width = 100;
if (height <= 0)
height = 30;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
m_windowStyle = style;
InitBase();
SetParent(parent);
m_windowId = (id == -1) ? NewControlId() : id;
// get the right size for the control
if ( width <= 0 || height <= 0 )
{
wxSize size = DoGetBestSize();
if ( width <= 0 )
width = size.x;
if ( height <= 0 )
height = size.y;
}
DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP;
if ( x < 0 )
x = 0;
if ( y < 0 )
y = 0;
if ( m_windowStyle & wxSP_HORIZONTAL )
wstyle |= UDS_HORZ;
if ( m_windowStyle & wxSP_ARROW_KEYS )
wstyle |= UDS_ARROWKEYS;
if ( m_windowStyle & wxSP_WRAP )
wstyle |= UDS_WRAP;
// translate the styles
DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
UDS_SETBUDDYINT; // it doesn't harm if we don't have buddy
// Create the ListView control.
HWND hWndListControl = CreateUpDownControl(wstyle,
x, y, width, height,
(HWND) parent->GetHWND(),
m_windowId,
wxGetInstance(),
0,
m_min, m_max, m_min);
if ( m_windowStyle & wxSP_HORIZONTAL )
wstyle |= UDS_HORZ;
if ( m_windowStyle & wxSP_ARROW_KEYS )
wstyle |= UDS_ARROWKEYS;
if ( m_windowStyle & wxSP_WRAP )
wstyle |= UDS_WRAP;
m_hWnd = (WXHWND) hWndListControl;
if (parent) parent->AddChild(this);
// create the UpDown control.
m_hWnd = (WXHWND)CreateUpDownControl
(
wstyle,
x, y, width, height,
GetHwndOf(parent),
m_windowId,
wxGetInstance(),
NULL, // no buddy
m_max, m_min,
m_min // initial position
);
// TODO: have this for all controls.
if ( !m_hWnd )
return FALSE;
if ( !m_hWnd )
{
wxLogLastError("CreateUpDownControl");
SubclassWin((WXHWND) m_hWnd);
return FALSE;
}
return TRUE;
if ( parent )
{
parent->AddChild(this);
}
SubclassWin(m_hWnd);
return TRUE;
}
wxSpinButton::~wxSpinButton()
{
}
// ----------------------------------------------------------------------------
// size calculation
// ----------------------------------------------------------------------------
wxSize wxSpinButton::DoGetBestSize()
{
if ( (GetWindowStyle() & wxSP_VERTICAL) != 0 )
{
// vertical control
return wxSize(GetSystemMetrics(SM_CXVSCROLL),
2*GetSystemMetrics(SM_CYVSCROLL));
}
else
{
// horizontal control
return wxSize(2*GetSystemMetrics(SM_CXHSCROLL),
GetSystemMetrics(SM_CYHSCROLL));
}
}
// ----------------------------------------------------------------------------
// Attributes
////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
int wxSpinButton::GetValue() const
{
@ -170,7 +228,7 @@ bool wxSpinButton::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
*result = event.IsAllowed() ? 0 : 1;
return processed;
#else
#else // GnuWin32
return FALSE;
#endif
}

167
src/msw/spinctrl.cpp Normal file
View File

@ -0,0 +1,167 @@
/////////////////////////////////////////////////////////////////////////////
// Name: msw/spinctrl.cpp
// Purpose: wxSpinCtrl class implementation for Win32
// Author: Vadim Zeitlin
// Modified by:
// Created: 22.07.99
// RCS-ID: $Id$
// Copyright: (c) Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
#ifdef __GNUG__
#pragma implementation "spinctrlbase.h"
#pragma implementation "spinctrl.h"
#endif
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if defined(__WIN95__)
#include "wx/spinctrl.h"
#include "wx/msw/private.h"
#include <commctrl.h>
// ----------------------------------------------------------------------------
// macros
// ----------------------------------------------------------------------------
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
#endif
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// the margin between the up-down control and its buddy
static const int MARGIN_BETWEEN = 5;
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// construction
// ----------------------------------------------------------------------------
bool wxSpinCtrl::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
int min, int max, int initial,
const wxString& name)
{
// before using DoGetBestSize(), have to set style to let the base class
// know whether this is a horizontal or vertical control (we're always
// vertical)
SetWindowStyle(style | wxSP_VERTICAL);
// calculate the sizes: the size given is the toal size for both controls
// and we need to fit them both in the given width (height is the same)
wxSize sizeText(size), sizeBtn(size);
sizeBtn.x = wxSpinButton::DoGetBestSize().x;
sizeText.x -= sizeBtn.x + MARGIN_BETWEEN;
if ( sizeText.x <= 0 )
{
wxLogDebug(_T("not enough space for wxSpinCtrl!"));
}
wxPoint posBtn(pos);
posBtn.x += sizeText.x + MARGIN_BETWEEN;
// create the spin button
if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) )
{
return FALSE;
}
SetRange(min, max);
SetValue(initial);
// create the text window
if ( sizeText.y <= 0 )
{
// make it the same height as the button then
int x, y;
wxSpinButton::DoGetSize(&x, &y);
sizeText.y = y;
}
m_hwndBuddy = (WXHWND)::CreateWindowEx
(
WS_EX_CLIENTEDGE, // sunken border
_T("EDIT"), // window class
NULL, // no window title
WS_CHILD | WS_VISIBLE | WS_BORDER, // style
pos.x, pos.y, // position
sizeText.x, sizeText.y, // size
GetHwndOf(parent), // parent
(HMENU)-1, // control id
wxGetInstance(), // app instance
NULL // unused client data
);
if ( !m_hwndBuddy )
{
wxLogLastError("CreateWindow(buddy text window)");
return FALSE;
}
// should have the same font as the other controls
WXHANDLE hFont = GetParent()->GetFont().GetResourceHandle();
::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE);
// associate the text window with the spin button
(void)SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0);
return TRUE;
}
// ----------------------------------------------------------------------------
// size calculations
// ----------------------------------------------------------------------------
void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
{
int widthBtn = DoGetBestSize().x;
int widthText = width - widthBtn - MARGIN_BETWEEN;
if ( widthText <= 0 )
{
wxLogDebug(_T("not enough space for wxSpinCtrl!"));
}
if ( !::MoveWindow((HWND)m_hwndBuddy, x, y, widthText, height, TRUE) )
{
wxLogLastError("MoveWindow(buddy)");
}
x += widthText + MARGIN_BETWEEN;
if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) )
{
wxLogLastError("MoveWindow");
}
}
#endif // __WIN95__

View File

@ -1174,6 +1174,14 @@ void wxWindow::DoGetClientSize(int *x, int *y) const
*y = rect.bottom;
}
void wxWindow::DoMoveWindow(int x, int y, int width, int height)
{
if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
{
wxLogLastError("MoveWindow");
}
}
// set the size of the window: if the dimensions are positive, just use them,
// but if any of them is equal to -1, it means that we must find the value for
// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
@ -1225,7 +1233,7 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
if ( size.x == -1 )
{
size= DoGetBestSize();
size = DoGetBestSize();
}
//else: already called DoGetBestSize() above
@ -1238,10 +1246,7 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
}
}
if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
{
wxLogLastError("MoveWindow");
}
DoMoveWindow(x, y, width, height);
}
// for a generic window there is no natural best size - just use the current one
@ -1281,7 +1286,7 @@ void wxWindow::DoSetClientSize(int width, int height)
::ScreenToClient(hParentWnd, &point);
}
MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
DoMoveWindow(point.x, point.y, actual_width, actual_height);
wxSizeEvent event(wxSize(width, height), m_windowId);
event.SetEventObject(this);
@ -2291,7 +2296,7 @@ bool wxWindow::MSWCreate(int id,
}
m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
wclass,
className,
title ? title : wxT(""),
style,
x1, y1,