GtkTop.cpp

Zbigniew Rebacz, 03/03/2014 01:05 PM

Download (5.88 KB)

 
1
#include <CtrlCore/CtrlCore.h>
2

    
3
#ifdef GUI_GTK
4

    
5
NAMESPACE_UPP
6

    
7
#define LLOG(x)  // DLOG(x)
8

    
9
Rect Ctrl::frameMargins;
10

    
11
Rect Ctrl::GetFrameMargins()
12
{
13
        GuiLock __;
14
        return frameMargins != Rect(0, 0, 0, 0) ? frameMargins : Rect(8, 32, 8, 8);
15
}
16

    
17
void    TopWindow::SyncSizeHints()
18
{
19
        GuiLock __;
20
        if(!top)
21
                return;
22
        GdkGeometry m;
23
        Size sz0 = GetRect().GetSize();
24
        Size sz = sz0;
25
        if(sizeable)
26
                sz = GetMinSize();
27
        m.min_width = sz.cx;
28
        m.min_height = sz.cy;
29
        sz = sz0;
30
        if(sizeable)
31
                sz = GetMaxSize();
32
        m.max_width = sz.cx;
33
        m.max_height = sz.cy;
34
        gtk_window_set_resizable(gtk(), sizeable);
35
        gtk_window_set_geometry_hints(gtk(), top->window, &m,
36
                                      GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE));
37
}
38

    
39
void TopWindow::SyncTitle()
40
{
41
        GuiLock __;
42
        if(top)
43
                gtk_window_set_title(gtk(), FromUnicode(title, CHARSET_UTF8));
44
}
45

    
46
void TopWindow::SyncCaption()
47
{
48
        GuiLock __;
49
        SyncTitle();
50
        if(top) {
51
                GList *icons = NULL;
52
                if(gdk_icon.Set(icon))
53
                        icons = g_list_append(icons, gdk_icon);
54
                if(gdk_largeicon.Set(largeicon))
55
                        icons = g_list_append(icons, gdk_largeicon);
56
                if(icons != NULL) {
57
                        gtk_window_set_icon_list(gtk(), icons);
58
                        g_list_free(icons);
59
                }
60
                gtk_window_set_decorated(gtk(), !frameless);
61
                gtk_window_set_urgency_hint(gtk(), urgent);
62
        }
63
}
64

    
65
void TopWindow::CenterRect(Ctrl *owner)
66
{
67
        GuiLock __;
68
        SetupRect();
69
        if(owner && center == 1 || center == 2) {
70
                Size sz = GetRect().Size();
71
                Rect r, wr;
72
                wr = Ctrl::GetWorkArea();
73
                Rect fm = GetFrameMargins();
74
                if(center == 1)
75
                        r = owner->GetRect();
76
                else
77
                        r = wr;
78
                Point p = r.CenterPos(sz);
79
                r = RectC(p.x, p.y, sz.cx, sz.cy);
80
                wr.left += fm.left;
81
                wr.right -= fm.right;
82
                wr.top += fm.top;
83
                wr.bottom -= fm.bottom;
84
                if(r.top < wr.top) {
85
                        r.bottom += wr.top - r.top;
86
                        r.top = wr.top;
87
                }
88
                if(r.bottom > wr.bottom)
89
                        r.bottom = wr.bottom;
90
                minsize.cx = min(minsize.cx, r.GetWidth());
91
                minsize.cy = min(minsize.cy, r.GetHeight());
92
                SetRect(r);
93
        }
94
}
95

    
96
gboolean TopWindow::StateEvent(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
97
{
98
        TopWindow *w = (TopWindow *)user_data;
99
        dword h = event->new_window_state;
100
        if(h & GDK_WINDOW_STATE_FULLSCREEN)
101
                w->state = FULLSCREEN;
102
        else
103
        if(h & GDK_WINDOW_STATE_ICONIFIED)
104
                w->state = MINIMIZED;
105
        else
106
        if(h & GDK_WINDOW_STATE_MAXIMIZED)
107
                w->state = MAXIMIZED;
108
        else
109
                w->state = OVERLAPPED;
110
        w->topmost = h & GDK_WINDOW_STATE_ABOVE;
111
        return FALSE;
112
}
113

    
114
void TopWindow::Open(Ctrl *owner)
115
{
116
        GuiLock __;
117
        LLOG("OPEN " << Name() << " owner: " << UPP::Name(owner));
118
        if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
119
                DistributeAccessKeys();
120
        if(fullscreen)
121
                SetRect(GetPrimaryScreenArea());
122
        else
123
                CenterRect(owner);
124
        IgnoreMouseUp();
125
        Create(owner, false);
126
        g_signal_connect(top->window, "window-state-event", G_CALLBACK(StateEvent), this);
127
        SyncSizeHints();
128
        SyncCaption();
129
        PlaceFocus();
130
        int q = state;
131
        state = OVERLAPPED;
132
        SetMode(q);
133
        SyncTopMost();
134
        GdkRectangle fr;
135
        gdk_window_get_frame_extents(gdk(), &fr);
136
        Rect r = GetRect();
137
        frameMargins.left = max(frameMargins.left, minmax(r.left - fr.x, 0, 32));
138
        frameMargins.right = max(frameMargins.right, minmax(fr.x + fr.width - r.right, 0, 32));
139
        frameMargins.top = max(frameMargins.top, minmax(r.top - fr.y, 0, 64));
140
        frameMargins.bottom = max(frameMargins.bottom, minmax(fr.y + fr.height - r.bottom, 0, 48));
141
}
142

    
143
void TopWindow::Open()
144
{
145
        Open(GetActiveWindow());
146
}
147

    
148
void TopWindow::OpenMain()
149
{
150
        Open(NULL);
151
}
152

    
153
void TopWindow::SyncTopMost()
154
{
155
        GuiLock __;
156
        if(top)
157
                gtk_window_set_keep_above(gtk(), topmost);
158
}
159

    
160
void TopWindow::SetMode(int mode)
161
{
162
        GuiLock __;
163
        GtkWindow *w = gtk();
164
        if(w)
165
                switch(state) {
166
                case MINIMIZED:
167
                        gtk_window_deiconify(w);
168
                        break;
169
                case MAXIMIZED:
170
                        gtk_window_unmaximize(w);
171
                        break;
172
                case FULLSCREEN:
173
                        gtk_window_unfullscreen(w);
174
                        break;
175
                }
176
        state = mode;
177
        if(w)
178
                switch(state) {
179
                case MINIMIZED:
180
                        gtk_window_iconify(w);
181
                        break;
182
                case MAXIMIZED:
183
                        gtk_window_maximize(w);
184
                        break;
185
                case FULLSCREEN:
186
                        gtk_window_fullscreen(w);
187
                        break;
188
                }
189
}
190

    
191
void TopWindow::Minimize(bool effect)
192
{
193
        SetMode(MINIMIZED);
194
}
195

    
196
TopWindow& TopWindow::FullScreen(bool b)
197
{
198
        SetMode(FULLSCREEN);
199
        return *this;
200
}
201

    
202
void TopWindow::Maximize(bool effect)
203
{
204
        SetMode(MAXIMIZED);
205
}
206

    
207
void TopWindow::Overlap(bool effect)
208
{
209
        SetMode(OVERLAPPED);
210
}
211

    
212
TopWindow& TopWindow::TopMost(bool b, bool)
213
{
214
        GuiLock __; 
215
        topmost = b;
216
        SyncTopMost();
217
        return *this;
218
}
219

    
220
bool TopWindow::IsTopMost() const
221
{
222
        GuiLock __; 
223
        return topmost;
224
}
225

    
226
void TopWindow::GuiPlatformConstruct()
227
{
228
        topmost = false;
229
}
230

    
231
void TopWindow::GuiPlatformDestruct()
232
{
233
}
234

    
235
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
236
{
237
        GuiLock __;
238
        int version = 0;
239
        s / version;
240
        Rect rect = GetRect();
241
        s % overlapped % rect;
242
        bool mn = state == MINIMIZED;
243
        bool mx = state == MAXIMIZED;
244
        s.Pack(mn, mx);
245
        LLOG("TopWindow::SerializePlacement / " << (s.IsStoring() ? "write" : "read"));
246
        LLOG("minimized = " << mn << ", maximized = " << mx);
247
        LLOG("rect = " << rect << ", overlapped = " << overlapped);
248
        if(s.IsLoading()) {
249
                if(mn) rect = overlapped;
250
                Rect limit = GetVirtualWorkArea();
251
                Rect fm = GetFrameMargins();
252
                limit.left += fm.left;
253
                limit.right -= fm.right;
254
                limit.top += fm.top;
255
                limit.bottom -= fm.bottom;
256
                Size sz = min(rect.Size(), limit.Size());
257
                rect = RectC(
258
                        minmax(rect.left, limit.left, limit.right - sz.cx),
259
                        minmax(rect.top,  limit.top,  limit.bottom - sz.cy),
260
                        sz.cx, sz.cy);
261
                state = OVERLAPPED;
262
                if(mn && reminimize)
263
                        state = MINIMIZED;
264
                if(mx)
265
                        state = MAXIMIZED;
266
                if(state == OVERLAPPED)
267
                        SetRect(rect);
268
                if(IsOpen()) {
269
                        if(state == MINIMIZED)
270
                                Minimize(false);
271
                        if(state == MAXIMIZED)
272
                                Maximize(false);
273
                }
274
        }
275
}
276

    
277
END_UPP_NAMESPACE
278

    
279
#endif