ultimatepp/uppsrc/CtrlCore/GtkCreate.cpp
cxl 597466fea8 uppsrc: NAMESPACE_UPP / END_UPP_NAMESPACE removed
git-svn-id: svn://ultimatepp.org/upp/trunk@10186 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2016-08-26 17:15:30 +00:00

160 lines
3.9 KiB
C++

#include <CtrlCore/CtrlCore.h>
#ifdef GUI_GTK
namespace Upp {
#define LLOG(x) // DLOG(x)
void Ctrl::Create(Ctrl *owner, bool popup)
{
MemoryIgnoreLeaksBlock ___;
GuiLock __;
ASSERT_(IsMainThread(), "Only the main thread can open a window");
LLOG("Create " << Name() << " " << GetRect());
ASSERT(!IsChild() && !IsOpen());
LLOG("Ungrab1");
top = new Top;
top->window = gtk_window_new(popup && owner ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
top->owner = owner;
static int id;
top->id = ++id;
Win& w = wins.Add();
w.id = top->id;
w.ctrl = this;
w.gtk = top->window;
w.gdk = top->window->window;
TopWindow *tw = dynamic_cast<TopWindow *>(this);
if(popup && !owner) {
gtk_window_set_decorated(gtk(), FALSE);
gtk_window_set_has_frame(gtk(), FALSE);
gtk_window_set_type_hint(gtk(), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
}
else
gtk_window_set_type_hint(gtk(), popup ? GDK_WINDOW_TYPE_HINT_COMBO
: tw && tw->tool ? GDK_WINDOW_TYPE_HINT_UTILITY
: owner ? GDK_WINDOW_TYPE_HINT_DIALOG
: GDK_WINDOW_TYPE_HINT_NORMAL);
top->cursor_id = -1;
gtk_widget_set_events(top->window, 0xffffffff);
g_signal_connect(top->window, "event", G_CALLBACK(GtkEvent), (gpointer)(uintptr_t)top->id);
gtk_widget_realize(top->window);
Rect r = GetRect();
gtk_window_move(gtk(), r.left, r.top);
gtk_window_resize(gtk(), r.GetWidth(), r.GetHeight());
if(owner && owner->top)
gtk_window_set_transient_for(gtk(), owner->gtk());
gtk_widget_set_app_paintable(top->window, TRUE);
gtk_widget_set_can_focus(top->window, TRUE);
isopen = true;
top->im_context = gtk_im_multicontext_new();
gtk_im_context_set_client_window(top->im_context, gdk());
gtk_im_context_set_use_preedit(top->im_context, false);
g_signal_connect(top->im_context, "commit", G_CALLBACK(IMCommit), (gpointer)(uintptr_t)top->id);
WndShow(IsShown());
FocusSync();
if(!popup)
SetWndFocus();
SweepConfigure(true);
DndInit();
StateH(OPEN);
activeCtrl = this;
int mousex, mousey;
gdk_window_get_pointer(gdk(), &mousex, &mousey, NULL);
Point m(mousex, mousey);
r = GetWndScreenRect().GetSize();
if(r.Contains(m))
DispatchMouse(MOUSEMOVE, m);
RefreshLayoutDeep();
}
void Ctrl::WndDestroy()
{
GuiLock __;
LLOG("WndDestroy " << Name());
DndExit();
Ctrl *owner = GetOwner();
if(owner && owner->top) {
for(int i = 0; i < wins.GetCount(); i++)
if(wins[i].ctrl && wins[i].ctrl->GetOwner() == this && wins[i].gtk) {
LLOG("Changing owner");
gtk_window_set_transient_for((GtkWindow *)wins[i].gtk, owner->gtk());
}
if(HasFocusDeep())
activeCtrl = owner;
}
g_object_unref(top->im_context);
gtk_widget_destroy(top->window);
isopen = false;
popup = false;
delete top;
top = NULL;
int q = FindCtrl(this);
if(q >= 0)
wins.Remove(q);
if(owner)
owner->WndUpdate();
}
Vector< Ptr<Ctrl> > Ctrl::activePopup;
Vector< Ptr<Ctrl> > Ctrl::visiblePopup;
void Ctrl::GuiPlatformRemove()
{
for(int i = 0; i < visiblePopup.GetCount();)
if(visiblePopup[i] == this)
visiblePopup.Remove(i);
else
i++;
for(int i = 0; i < activePopup.GetCount();)
if(activePopup[i] == this) {
if(this == grabpopup && gdk_pointer_is_grabbed())
StopGrabPopup();
activePopup.Remove(i);
StartGrabPopup();
}
else
i++;
}
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool, bool)
{
GuiLock __;
LLOG("POPUP " << Name() << ", " << GetRect() << ", activate " << activate);
Create(owner ? owner->GetTopCtrl() : GetActiveCtrl(), true);
popup = true;
Ptr<Ctrl> _this = this;
if(activate) {
SetFocus();
if(_this) {
activePopup.Add(this);
StartGrabPopup();
CheckMouseCtrl();
}
}
if(_this)
visiblePopup.Add(this);
}
}
#endif