1. wxFrame restores focus better

2. fixed _2_ memory leaks in wxGrid::IsCellEditControlShown
3. modified wxGridCellEditor::StartingKey() to accept several more keys
4. fixed (but why is this needed?) bug in wxCalCtrl appearance
5. made it possible to close the log dialog with <Esc> under MSW


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7585 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-06-17 22:44:45 +00:00
parent afa7da4a16
commit ac82c949d0
8 changed files with 237 additions and 136 deletions

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
// Name: panelg.h
// Purpose: wxPanel: similar to wxWindows but is coloured as for a dialog
// Name: wx/generic/panelg.h
// Purpose: wxPanel: a container for child controls
// Author: Julian Smart
// Modified by:
// Created: 01/02/97
@@ -13,14 +13,23 @@
#define _WX_GENERIC_PANEL_H_
#ifdef __GNUG__
#pragma interface "panelg.h"
#pragma interface "panelg.h"
#endif
// ----------------------------------------------------------------------------
// headers and forward declarations
// ----------------------------------------------------------------------------
#include "wx/window.h"
#include "wx/button.h"
class WXDLLEXPORT wxButton;
WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
// ----------------------------------------------------------------------------
// wxPanel contains other controls and implements TAB traversal between them
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxPanel : public wxWindow
{
public:
@@ -106,5 +115,8 @@ private:
DECLARE_EVENT_TABLE()
};
// this function is for wxWindows use only
extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
#endif
// _WX_GENERIC_PANEL_H_

View File

@@ -149,6 +149,9 @@ protected:
static bool m_useNativeStatusBar;
#endif // wxUSE_STATUSBAR
// the last focused child: we restore focus to it on activation
wxWindow *m_winLastFocused;
// Data to save/restore when calling ShowFullScreen
long m_fsStyle; // Passed to ShowFullScreen
wxRect m_fsOldSize;

View File

@@ -564,7 +564,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
RecalcGeometry();
#if DEBUG_PAINT
printf("--- starting to paint, selection: %s, week %u\n",
wxLogDebug("--- starting to paint, selection: %s, week %u\n",
m_date.Format("%a %d-%m-%Y %H:%M:%S").c_str(),
GetWeek(m_date));
#endif
@@ -573,7 +573,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
if ( IsExposed(0, 0, 7*m_widthCol, m_heightRow) )
{
#if DEBUG_PAINT
puts("painting the header");
wxLogDebug("painting the header");
#endif
dc.SetBackgroundMode(wxTRANSPARENT);
@@ -603,7 +603,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
wxDateTime date = GetStartDate();
#if DEBUG_PAINT
printf("starting calendar from %s\n",
wxLogDebug("starting calendar from %s\n",
date.Format("%a %d-%m-%Y %H:%M:%S").c_str());
#endif
@@ -619,7 +619,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
}
#if DEBUG_PAINT
printf("painting week %d at y = %d\n", nWeek, y);
wxLogDebug("painting week %d at y = %d\n", nWeek, y);
#endif
for ( size_t wd = 0; wd < 7; wd++ )
@@ -732,7 +732,7 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
}
}
#if DEBUG_PAINT
puts("+++ finished painting");
wxLogDebug("+++ finished painting");
#endif
}
@@ -750,8 +750,17 @@ void wxCalendarCtrl::RefreshDate(const wxDateTime& date)
rect.width = 7*m_widthCol;
rect.height = m_heightRow;
#ifdef __WXMSW__
// VZ: for some reason, the selected date seems to occupy more space under
// MSW - this is probably some bug in the font size calculations, but I
// don't know where exactly. This fix is ugly and leads to more
// refreshes than really needed, but without it the selected days
// leaves even more ugly underscores on screen.
rect.Inflate(0, 1);
#endif // MSW
#if DEBUG_PAINT
printf("*** refreshing week %d at (%d, %d)-(%d, %d)\n",
wxLogDebug("*** refreshing week %d at (%d, %d)-(%d, %d)\n",
GetWeek(date),
rect.x, rect.y,
rect.x + rect.width, rect.y + rect.height);

View File

@@ -604,8 +604,50 @@ void wxGridCellTextEditor::StartingKey(wxKeyEvent& event)
if ( !event.AltDown() && !event.MetaDown() && !event.ControlDown() )
{
// insert the key in the control
wxChar ch;
int keycode = (int)event.KeyCode();
if ( isprint(keycode) && keycode < 256 && keycode >= 0 )
switch ( keycode )
{
case WXK_NUMPAD0:
case WXK_NUMPAD1:
case WXK_NUMPAD2:
case WXK_NUMPAD3:
case WXK_NUMPAD4:
case WXK_NUMPAD5:
case WXK_NUMPAD6:
case WXK_NUMPAD7:
case WXK_NUMPAD8:
case WXK_NUMPAD9:
ch = _T('0') + keycode - WXK_NUMPAD0;
break;
case WXK_MULTIPLY:
case WXK_NUMPAD_MULTIPLY:
ch = _T('*');
break;
case WXK_ADD:
case WXK_NUMPAD_ADD:
ch = _T('+');
break;
case WXK_SUBTRACT:
case WXK_NUMPAD_SUBTRACT:
ch = _T('-');
break;
case WXK_DECIMAL:
case WXK_NUMPAD_DECIMAL:
ch = _T('.');
break;
case WXK_DIVIDE:
case WXK_NUMPAD_DIVIDE:
ch = _T('/');
break;
default:
if ( keycode < 256 && keycode >= 0 && isprint(keycode) )
{
// FIXME this is not going to work for non letters...
if ( !event.ShiftDown() )
@@ -613,11 +655,21 @@ void wxGridCellTextEditor::StartingKey(wxKeyEvent& event)
keycode = tolower(keycode);
}
Text()->AppendText((wxChar)keycode);
return;
ch = (wxChar)keycode;
}
else
{
ch = _T('\0');
}
}
if ( ch )
{
Text()->AppendText(ch);
// skip event.Skip() below
return;
}
}
event.Skip();
@@ -5284,15 +5336,9 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
default:
// alphanumeric keys or F2 (special key just for this) enable
// the cell edit control
// On just Shift/Control I get values for event.KeyCode()
// that are outside the range where isalnum's behaviour is
// well defined, so do an additional sanity check.
if ( !(event.AltDown() ||
event.MetaDown() ||
event.ControlDown()) &&
((isalnum((int)event.KeyCode()) &&
(event.KeyCode() < 256 && event.KeyCode() >= 0)) ||
event.KeyCode() == WXK_F2 || event.KeyCode() == WXK_SPACE) &&
!IsCellEditControlEnabled() &&
CanEnableCellControl() )
{
@@ -6024,19 +6070,28 @@ bool wxGrid::IsCellEditControlEnabled() const
bool wxGrid::IsCellEditControlShown() const
{
if (m_cellEditCtrlEnabled)
bool isShown = FALSE;
if ( m_cellEditCtrlEnabled )
{
int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol();
wxGridCellAttr* attr = GetCellAttr(row, col);
wxGridCellEditor* editor = attr->GetEditor((wxGrid*) this, row, col);
if ( editor && editor->IsCreated() )
attr->DecRef();
if ( editor )
{
wxWindow *control = editor->GetControl();
return control->IsShown();
if ( editor->IsCreated() )
{
isShown = editor->GetControl()->IsShown();
}
editor->DecRef();
}
}
return FALSE;
return isShown;
}
void wxGrid::ShowCellEditControl()

View File

@@ -121,7 +121,7 @@ private:
};
BEGIN_EVENT_TABLE(wxLogDialog, wxDialog)
EVT_BUTTON(wxID_OK, wxLogDialog::OnOk)
EVT_BUTTON(wxID_CANCEL, wxLogDialog::OnOk)
EVT_BUTTON(wxID_MORE, wxLogDialog::OnDetails)
#if wxUSE_FILE
EVT_BUTTON(wxID_SAVE, wxLogDialog::OnSave)
@@ -727,7 +727,10 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
wxBoxSizer *sizerButtons = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizerAll = new wxBoxSizer(wxHORIZONTAL);
wxButton *btnOk = new wxButton(this, wxID_OK, _("OK"));
// this "Ok" button has wxID_CANCEL id - not very logical, but this allows
// to close the log dialog with <Esc> which wouldn't work otherwise (as it
// translates into click on cancel button)
wxButton *btnOk = new wxButton(this, wxID_CANCEL, _("OK"));
sizerButtons->Add(btnOk, 0, wxCENTRE|wxBOTTOM, MARGIN/2);
m_btnDetails = new wxButton(this, wxID_MORE, ms_details + _T(" >>"));
sizerButtons->Add(m_btnDetails, 0, wxCENTRE|wxTOP, MARGIN/2 - 1);

View File

@@ -340,39 +340,58 @@ void wxPanel::OnFocus(wxFocusEvent& event)
bool wxPanel::SetFocusToChild()
{
if ( m_winLastFocused )
return wxSetFocusToChild(this, &m_winLastFocused);
}
// ----------------------------------------------------------------------------
// SetFocusToChild(): this function is used by wxPanel but also by wxFrame in
// wxMSW, this is why it is outside of wxPanel class
// ----------------------------------------------------------------------------
bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
{
if ( *childLastFocused )
{
// It might happen that the window got reparented or no longer accepts
// the focus.
if ( (m_winLastFocused->GetParent() == this) &&
m_winLastFocused->AcceptsFocus() )
if ( (*childLastFocused)->GetParent() == win &&
(*childLastFocused)->AcceptsFocus() )
{
wxLogTrace(_T("focus"),
_T("SetFocusToChild() => last child (0x%08x)."),
m_winLastFocused->GetHandle());
(*childLastFocused)->GetHandle());
m_winLastFocused->SetFocus();
(*childLastFocused)->SetFocus();
return TRUE;
}
else
{
// it doesn't count as such any more
m_winLastFocused = (wxWindow *)NULL;
*childLastFocused = (wxWindow *)NULL;
}
}
// set the focus to the first child who wants it
wxWindowList::Node *node = GetChildren().GetFirst();
wxWindowList::Node *node = win->GetChildren().GetFirst();
while ( node )
{
wxWindow *child = node->GetData();
if ( child->AcceptsFocus() )
if ( child->AcceptsFocus()
&& !child->IsTopLevel()
#if wxUSE_TOOLBAR
&& !wxDynamicCast(child, wxToolBar)
#endif // wxUSE_TOOLBAR
#if wxUSE_STATUSBAR
&& !wxDynamicCast(child, wxStatusBar)
#endif // wxUSE_STATUSBAR
)
{
wxLogTrace(_T("focus"),
_T("SetFocusToChild() => first child (0x%08x)."),
child->GetHandle());
m_winLastFocused = child; // should be redundant, but it is not
*childLastFocused = child; // should be redundant, but it is not
child->SetFocus();
return TRUE;
}

View File

@@ -38,6 +38,7 @@
#include "wx/settings.h"
#include "wx/dcclient.h"
#include "wx/mdi.h"
#include "wx/panel.h"
#endif // WX_PRECOMP
#include "wx/msw/private.h"
@@ -110,6 +111,8 @@ void wxFrame::Init()
m_fsIsMaximized = FALSE;
m_fsIsShowing = FALSE;
m_winLastFocused = (wxWindow *)NULL;
// unlike (almost?) all other windows, frames are created hidden
m_isShown = FALSE;
}
@@ -703,37 +706,32 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow
// subwindow found.
void wxFrame::OnActivate(wxActivateEvent& event)
{
if ( !event.GetActive() )
if ( event.GetActive() )
{
event.Skip();
return;
}
// restore focus to the child which was last focused
wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd);
for ( wxWindowList::Node *node = GetChildren().GetFirst();
node;
node = node->GetNext() )
{
// FIXME all this is totally bogus - we need to do the same as wxPanel,
// but how to do it without duplicating the code?
// restore focus
wxWindow *child = node->GetData();
if ( !child->IsTopLevel()
#if wxUSE_TOOLBAR
&& !wxDynamicCast(child, wxToolBar)
#endif // wxUSE_TOOLBAR
#if wxUSE_STATUSBAR
&& !wxDynamicCast(child, wxStatusBar)
#endif // wxUSE_STATUSBAR
)
{
child->SetFocus();
break;
wxSetFocusToChild(this, &m_winLastFocused);
}
else
{
// remember the last focused child
m_winLastFocused = FindFocus();
while ( m_winLastFocused )
{
if ( GetChildren().Find(m_winLastFocused) )
break;
m_winLastFocused = m_winLastFocused->GetParent();
}
wxLogTrace(_T("focus"),
_T("wxFrame %08x deactivated, last focused: %08x."),
m_hWnd,
m_winLastFocused ? GetHwndOf(m_winLastFocused)
: NULL);
event.Skip();
}
}

View File

@@ -3543,7 +3543,7 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font)
// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
int wxCharCodeMSWToWX(int keySym)
{
int id = 0;
int id;
switch (keySym)
{
case VK_CANCEL: id = WXK_CANCEL; break;
@@ -3582,8 +3582,11 @@ int wxCharCodeMSWToWX(int keySym)
case VK_NUMPAD8: id = WXK_NUMPAD8; break;
case VK_NUMPAD9: id = WXK_NUMPAD9; break;
case VK_MULTIPLY: id = WXK_MULTIPLY; break;
case 0xBB: // VK_OEM_PLUS
case VK_ADD: id = WXK_ADD; break;
case 0xBD: // VK_OEM_MINUS
case VK_SUBTRACT: id = WXK_SUBTRACT; break;
case 0xBE: // VK_OEM_PERIOD
case VK_DECIMAL: id = WXK_DECIMAL; break;
case VK_DIVIDE: id = WXK_DIVIDE; break;
case VK_F1: id = WXK_F1; break;
@@ -3613,10 +3616,9 @@ int wxCharCodeMSWToWX(int keySym)
case VK_NUMLOCK: id = WXK_NUMLOCK; break;
case VK_SCROLL: id = WXK_SCROLL; break;
default:
{
return 0;
}
id = 0;
}
return id;
}