~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/generic/laywin.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/generic/laywin.cpp
 
3
// Purpose:     Implements a simple layout algorithm, plus
 
4
//              wxSashLayoutWindow which is an example of a window with
 
5
//              layout-awareness (via event handlers). This is suited to
 
6
//              IDE-style window layout.
 
7
// Author:      Julian Smart
 
8
// Modified by:
 
9
// Created:     04/01/98
 
10
// Copyright:   (c) Julian Smart
 
11
// Licence:     wxWindows licence
 
12
/////////////////////////////////////////////////////////////////////////////
 
13
 
 
14
// For compilers that support precompilation, includes "wx/wx.h".
 
15
#include "wx/wxprec.h"
 
16
 
 
17
#ifdef __BORLANDC__
 
18
#pragma hdrstop
 
19
#endif
 
20
 
 
21
#ifndef WX_PRECOMP
 
22
    #include "wx/frame.h"
 
23
#endif
 
24
 
 
25
#include "wx/laywin.h"
 
26
#include "wx/mdi.h"
 
27
 
 
28
 
 
29
IMPLEMENT_DYNAMIC_CLASS(wxQueryLayoutInfoEvent, wxEvent)
 
30
IMPLEMENT_DYNAMIC_CLASS(wxCalculateLayoutEvent, wxEvent)
 
31
 
 
32
wxDEFINE_EVENT( wxEVT_QUERY_LAYOUT_INFO, wxQueryLayoutInfoEvent );
 
33
wxDEFINE_EVENT( wxEVT_CALCULATE_LAYOUT, wxCalculateLayoutEvent );
 
34
 
 
35
 
 
36
// ----------------------------------------------------------------------------
 
37
// wxSashLayoutWindow
 
38
// ----------------------------------------------------------------------------
 
39
 
 
40
#if wxUSE_SASH
 
41
IMPLEMENT_CLASS(wxSashLayoutWindow, wxSashWindow)
 
42
BEGIN_EVENT_TABLE(wxSashLayoutWindow, wxSashWindow)
 
43
    EVT_CALCULATE_LAYOUT(wxSashLayoutWindow::OnCalculateLayout)
 
44
    EVT_QUERY_LAYOUT_INFO(wxSashLayoutWindow::OnQueryLayoutInfo)
 
45
END_EVENT_TABLE()
 
46
 
 
47
bool wxSashLayoutWindow::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,
 
48
        const wxSize& size, long style, const wxString& name)
 
49
{
 
50
    return wxSashWindow::Create(parent, id, pos, size, style, name);
 
51
}
 
52
 
 
53
void wxSashLayoutWindow::Init()
 
54
{
 
55
    m_orientation = wxLAYOUT_HORIZONTAL;
 
56
    m_alignment = wxLAYOUT_TOP;
 
57
#ifdef __WXMAC__
 
58
    MacSetClipChildren( true ) ;
 
59
#endif
 
60
}
 
61
 
 
62
// This is the function that wxLayoutAlgorithm calls to ascertain the window
 
63
// dimensions.
 
64
void wxSashLayoutWindow::OnQueryLayoutInfo(wxQueryLayoutInfoEvent& event)
 
65
{
 
66
  //    int flags = event.GetFlags();
 
67
    int requestedLength = event.GetRequestedLength();
 
68
 
 
69
    event.SetOrientation(m_orientation);
 
70
    event.SetAlignment(m_alignment);
 
71
 
 
72
    if (m_orientation == wxLAYOUT_HORIZONTAL)
 
73
        event.SetSize(wxSize(requestedLength, m_defaultSize.y));
 
74
    else
 
75
        event.SetSize(wxSize(m_defaultSize.x, requestedLength));
 
76
}
 
77
 
 
78
// Called by parent to allow window to take a bit out of the
 
79
// client rectangle, and size itself if not in wxLAYOUT_QUERY mode.
 
80
 
 
81
void wxSashLayoutWindow::OnCalculateLayout(wxCalculateLayoutEvent& event)
 
82
{
 
83
    wxRect clientSize(event.GetRect());
 
84
 
 
85
    int flags = event.GetFlags();
 
86
 
 
87
    if (!IsShown())
 
88
        return;
 
89
 
 
90
    // Let's assume that all windows stretch the full extent of the window in
 
91
    // the direction of that window orientation. This will work for non-docking toolbars,
 
92
    // and the status bar. Note that the windows have to have been created in a certain
 
93
    // order to work, else you might get a left-aligned window going to the bottom
 
94
    // of the window, and the status bar appearing to the right of it. The
 
95
    // status bar would have to be created after or before the toolbar(s).
 
96
 
 
97
    wxRect thisRect;
 
98
 
 
99
    // Try to stretch
 
100
    int length = (GetOrientation() == wxLAYOUT_HORIZONTAL) ? clientSize.width : clientSize.height;
 
101
    wxLayoutOrientation orient = GetOrientation();
 
102
 
 
103
    // We assume that a window that says it's horizontal, wants to be stretched in that
 
104
    // direction. Is this distinction too fine? Do we assume that any horizontal
 
105
    // window needs to be stretched in that direction? Possibly.
 
106
    int whichDimension = (GetOrientation() == wxLAYOUT_HORIZONTAL) ? wxLAYOUT_LENGTH_X : wxLAYOUT_LENGTH_Y;
 
107
 
 
108
    wxQueryLayoutInfoEvent infoEvent(GetId());
 
109
    infoEvent.SetEventObject(this);
 
110
    infoEvent.SetRequestedLength(length);
 
111
    infoEvent.SetFlags(orient | whichDimension);
 
112
 
 
113
    if (!GetEventHandler()->ProcessEvent(infoEvent))
 
114
        return;
 
115
 
 
116
    wxSize sz = infoEvent.GetSize();
 
117
 
 
118
    if (sz.x == 0 && sz.y == 0) // Assume it's invisible
 
119
        return;
 
120
 
 
121
    // Now we know the size it wants to be. We wish to decide where to place it, i.e.
 
122
    // how it's aligned.
 
123
    switch (GetAlignment())
 
124
    {
 
125
        case wxLAYOUT_TOP:
 
126
        {
 
127
            thisRect.x = clientSize.x; thisRect.y = clientSize.y;
 
128
            thisRect.width = sz.x; thisRect.height = sz.y;
 
129
            clientSize.y += thisRect.height;
 
130
            clientSize.height -= thisRect.height;
 
131
            break;
 
132
        }
 
133
        case wxLAYOUT_LEFT:
 
134
        {
 
135
            thisRect.x = clientSize.x; thisRect.y = clientSize.y;
 
136
            thisRect.width = sz.x; thisRect.height = sz.y;
 
137
            clientSize.x += thisRect.width;
 
138
            clientSize.width -= thisRect.width;
 
139
            break;
 
140
        }
 
141
        case wxLAYOUT_RIGHT:
 
142
        {
 
143
            thisRect.x = clientSize.x + (clientSize.width - sz.x); thisRect.y = clientSize.y;
 
144
            thisRect.width = sz.x; thisRect.height = sz.y;
 
145
            clientSize.width -= thisRect.width;
 
146
            break;
 
147
        }
 
148
        case wxLAYOUT_BOTTOM:
 
149
        {
 
150
            thisRect.x = clientSize.x; thisRect.y = clientSize.y + (clientSize.height - sz.y);
 
151
            thisRect.width = sz.x; thisRect.height = sz.y;
 
152
            clientSize.height -= thisRect.height;
 
153
            break;
 
154
        }
 
155
        case wxLAYOUT_NONE:
 
156
        {
 
157
            break;
 
158
        }
 
159
 
 
160
    }
 
161
 
 
162
    if ((flags & wxLAYOUT_QUERY) == 0)
 
163
    {
 
164
        // If not in query mode, resize the window.
 
165
        // TODO: add wxRect& form to wxWindow::SetSize
 
166
        wxSize sz2 = GetSize();
 
167
        wxPoint pos = GetPosition();
 
168
        SetSize(thisRect.x, thisRect.y, thisRect.width, thisRect.height);
 
169
 
 
170
        // Make sure the sash is erased when the window is resized
 
171
        if ((pos.x != thisRect.x || pos.y != thisRect.y || sz2.x != thisRect.width || sz2.y != thisRect.height) &&
 
172
            (GetSashVisible(wxSASH_TOP) || GetSashVisible(wxSASH_RIGHT) || GetSashVisible(wxSASH_BOTTOM) || GetSashVisible(wxSASH_LEFT)))
 
173
            Refresh(true);
 
174
 
 
175
    }
 
176
 
 
177
    event.SetRect(clientSize);
 
178
}
 
179
#endif // wxUSE_SASH
 
180
 
 
181
 
 
182
// ----------------------------------------------------------------------------
 
183
// wxLayoutAlgorithm
 
184
// ----------------------------------------------------------------------------
 
185
 
 
186
#if wxUSE_MDI_ARCHITECTURE
 
187
 
 
188
// Lays out windows for an MDI frame. The MDI client area gets what's left
 
189
// over.
 
190
bool wxLayoutAlgorithm::LayoutMDIFrame(wxMDIParentFrame* frame, wxRect* r)
 
191
{
 
192
    int cw, ch;
 
193
    frame->GetClientSize(& cw, & ch);
 
194
 
 
195
    wxRect rect(0, 0, cw, ch);
 
196
    if (r)
 
197
        rect = * r;
 
198
 
 
199
    wxCalculateLayoutEvent event;
 
200
    event.SetRect(rect);
 
201
 
 
202
    wxWindowList::compatibility_iterator node = frame->GetChildren().GetFirst();
 
203
    while (node)
 
204
    {
 
205
        wxWindow* win = node->GetData();
 
206
 
 
207
        event.SetId(win->GetId());
 
208
        event.SetEventObject(win);
 
209
        event.SetFlags(0); // ??
 
210
 
 
211
        win->GetEventHandler()->ProcessEvent(event);
 
212
 
 
213
        node = node->GetNext();
 
214
    }
 
215
 
 
216
    wxWindow* clientWindow = frame->GetClientWindow();
 
217
 
 
218
    rect = event.GetRect();
 
219
 
 
220
    clientWindow->SetSize(rect.x, rect.y, rect.width, rect.height);
 
221
 
 
222
    return true;
 
223
}
 
224
 
 
225
#endif // wxUSE_MDI_ARCHITECTURE
 
226
 
 
227
bool wxLayoutAlgorithm::LayoutFrame(wxFrame* frame, wxWindow* mainWindow)
 
228
{
 
229
    return LayoutWindow(frame, mainWindow);
 
230
}
 
231
 
 
232
// Layout algorithm for any window. mainWindow gets what's left over.
 
233
bool wxLayoutAlgorithm::LayoutWindow(wxWindow* parent, wxWindow* mainWindow)
 
234
{
 
235
    // Test if the parent is a sash window, and if so,
 
236
    // reduce the available space to allow space for any active edges.
 
237
 
 
238
    int leftMargin = 0, rightMargin = 0, topMargin = 0, bottomMargin = 0;
 
239
#if wxUSE_SASH
 
240
    if (wxDynamicCast(parent, wxSashWindow))
 
241
    {
 
242
        wxSashWindow* sashWindow = (wxSashWindow*) parent;
 
243
 
 
244
        leftMargin = sashWindow->GetExtraBorderSize();
 
245
        rightMargin = sashWindow->GetExtraBorderSize();
 
246
        topMargin = sashWindow->GetExtraBorderSize();
 
247
        bottomMargin = sashWindow->GetExtraBorderSize();
 
248
 
 
249
        if (sashWindow->GetSashVisible(wxSASH_LEFT))
 
250
            leftMargin += sashWindow->GetDefaultBorderSize();
 
251
        if (sashWindow->GetSashVisible(wxSASH_RIGHT))
 
252
            rightMargin += sashWindow->GetDefaultBorderSize();
 
253
        if (sashWindow->GetSashVisible(wxSASH_TOP))
 
254
            topMargin += sashWindow->GetDefaultBorderSize();
 
255
        if (sashWindow->GetSashVisible(wxSASH_BOTTOM))
 
256
            bottomMargin += sashWindow->GetDefaultBorderSize();
 
257
    }
 
258
#endif // wxUSE_SASH
 
259
 
 
260
    int cw, ch;
 
261
    parent->GetClientSize(& cw, & ch);
 
262
 
 
263
    wxRect rect(leftMargin, topMargin, cw - leftMargin - rightMargin, ch - topMargin - bottomMargin);
 
264
 
 
265
    wxCalculateLayoutEvent event;
 
266
    event.SetRect(rect);
 
267
 
 
268
    // Find the last layout-aware window, so we can make it fill all remaining
 
269
    // space.
 
270
    wxWindow *lastAwareWindow = NULL;
 
271
    wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
 
272
 
 
273
    while (node)
 
274
    {
 
275
        wxWindow* win = node->GetData();
 
276
 
 
277
        if (win->IsShown())
 
278
        {
 
279
            wxCalculateLayoutEvent tempEvent(win->GetId());
 
280
            tempEvent.SetEventObject(win);
 
281
            tempEvent.SetFlags(wxLAYOUT_QUERY);
 
282
            tempEvent.SetRect(event.GetRect());
 
283
            if (win->GetEventHandler()->ProcessEvent(tempEvent))
 
284
                lastAwareWindow = win;
 
285
        }
 
286
 
 
287
        node = node->GetNext();
 
288
    }
 
289
 
 
290
    // Now do a dummy run to see if we have any space left for the final window (fail if not)
 
291
    node = parent->GetChildren().GetFirst();
 
292
    while (node)
 
293
    {
 
294
        wxWindow* win = node->GetData();
 
295
 
 
296
        // If mainWindow is NULL and we're at the last window,
 
297
        // skip this, because we'll simply make it fit the remaining space.
 
298
        if (win->IsShown() && (win != mainWindow) && (mainWindow != NULL || win != lastAwareWindow))
 
299
        {
 
300
            event.SetId(win->GetId());
 
301
            event.SetEventObject(win);
 
302
            event.SetFlags(wxLAYOUT_QUERY);
 
303
 
 
304
            win->GetEventHandler()->ProcessEvent(event);
 
305
        }
 
306
 
 
307
        node = node->GetNext();
 
308
    }
 
309
 
 
310
    if (event.GetRect().GetWidth() < 0 || event.GetRect().GetHeight() < 0)
 
311
        return false;
 
312
 
 
313
    event.SetRect(rect);
 
314
 
 
315
    node = parent->GetChildren().GetFirst();
 
316
    while (node)
 
317
    {
 
318
        wxWindow* win = node->GetData();
 
319
 
 
320
        // If mainWindow is NULL and we're at the last window,
 
321
        // skip this, because we'll simply make it fit the remaining space.
 
322
        if (win->IsShown() && (win != mainWindow) && (mainWindow != NULL || win != lastAwareWindow))
 
323
        {
 
324
            event.SetId(win->GetId());
 
325
            event.SetEventObject(win);
 
326
            event.SetFlags(0); // ??
 
327
 
 
328
            win->GetEventHandler()->ProcessEvent(event);
 
329
        }
 
330
 
 
331
        node = node->GetNext();
 
332
    }
 
333
 
 
334
    rect = event.GetRect();
 
335
 
 
336
    if (mainWindow)
 
337
        mainWindow->SetSize(rect.x, rect.y, wxMax(0, rect.width), wxMax(0, rect.height));
 
338
    else if (lastAwareWindow)
 
339
    {
 
340
        // Fit the remaining space
 
341
        lastAwareWindow->SetSize(rect.x, rect.y, wxMax(0, rect.width), wxMax(0, rect.height));
 
342
    }
 
343
 
 
344
    return true;
 
345
}
 
346