⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cwindow.cpp

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************  CWindow.cpp  The Window and Form classes  (c) 2000-2003 Beno� Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __CWINDOW_CPP#include <qnamespace.h>#include <qapplication.h>#include <qmenubar.h>#include <qframe.h>#include <qabstractlayout.h>#include <qsizepolicy.h>#include <qtoolbar.h>#include <qworkspace.h>#include <qkeycode.h>#include <qpixmap.h>#include <qbitmap.h>#if QT_VERSION >= 0x030100  #include <qeventloop.h>#endif#include "gambas.h"#include "main.h"#include "CWidget.h"#include "CMenu.h"#include "CWindow.h"#include <X11/Xlib.h>#include <X11/Xatom.h>#include <X11/extensions/shape.h>//#define DEBUG_STATEDECLARE_EVENT(EVENT_Open);DECLARE_EVENT(EVENT_Close);DECLARE_EVENT(EVENT_Activate);DECLARE_EVENT(EVENT_Deactivate);DECLARE_EVENT(EVENT_Move);DECLARE_EVENT(EVENT_Resize);DECLARE_EVENT(EVENT_Show);DECLARE_EVENT(EVENT_Hide);CWINDOW *CWINDOW_Main = NULL;CWINDOW *CWINDOW_Current = NULL;static GB_CLASS CLASS_Workspace = NULL;static GB_CLASS CLASS_Container = NULL;/***************************************************************************  Window manager specific code***************************************************************************/#define MAX_WINDOW_STATE 8static bool _atom_init = false;static Atom _atom_net_wm_state;static Atom _atom_net_wm_state_above;static Atom _atom_net_wm_state_stays_on_top;static Atom _atom_net_wm_state_skip_taskbar;static Atom _window_state[MAX_WINDOW_STATE];static int _window_state_count = 0;static void init_atoms(Display *dpy){  if (_atom_init)    return;  _atom_net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", True);  _atom_net_wm_state_above = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", True);  _atom_net_wm_state_stays_on_top = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_TOP", True);  _atom_net_wm_state_skip_taskbar = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", True);  _atom_init = true;}static void load_window_state(Display *dpy, WId wid){  Atom type;  int format;  unsigned long length, after;  unsigned char *data;  init_atoms(dpy);  _window_state_count = 0;  XGetWindowProperty(dpy, wid, _atom_net_wm_state, 0, 8,    False, AnyPropertyType, &type, &format,    &length, &after, &data);  if (length > 8)    length = 8;  _window_state_count = length;  memcpy(_window_state, data, _window_state_count * sizeof(Atom));  XFree(data);}static void save_window_state(Display *dpy, WId wid){  XChangeProperty(dpy, wid, _atom_net_wm_state, XA_ATOM, 32, PropModeReplace,      (unsigned char *)_window_state, _window_state_count);}static bool is_window_state(Atom state){  int i;  for (i = 0; i < _window_state_count; i++)  {    if (_window_state[i] == state)      return true;  }  return false;}static void set_window_state(Atom state){  if (is_window_state(state))    return;  if (_window_state_count == MAX_WINDOW_STATE)  {    qDebug("Too many properties in window");    return;  }  _window_state[_window_state_count++] = state;}static void clear_window_state(Atom state){  int i;  for (i = 0; i < _window_state_count; i++)  {    if (_window_state[i] == state)    {      _window_state_count--;      for (; i < _window_state_count; i++)        _window_state[i] = _window_state[i + 1];      return;    }  }}void CWINDOW_change_property(QWidget *w, Atom property, bool set){  XEvent e;  long mask = (SubstructureRedirectMask | SubstructureNotifyMask);  if (!w->isTopLevel())    return;  if (w->isVisible())  {    e.xclient.type = ClientMessage;    e.xclient.message_type = _atom_net_wm_state;    e.xclient.display = w->x11Display();    e.xclient.window = w->winId();    e.xclient.format = 32;    e.xclient.data.l[0] = set ? 1 : 0;    e.xclient.data.l[1] = property;    e.xclient.data.l[2] = 0;    e.xclient.data.l[3] = 0;    e.xclient.data.l[4] = 0;    XSendEvent(w->x11Display(), qt_xrootwin(), False, mask, &e);  }  else  {    load_window_state(w->x11Display(), w->winId());    if (set)      set_window_state(property);    else      clear_window_state(property);    save_window_state(w->x11Display(), w->winId());  }}/***************************************************************************  Window***************************************************************************/BEGIN_METHOD_VOID(CWINDOW_init)  CLASS_Workspace = GB.FindClass("Workspace");  CLASS_Container = GB.FindClass("Container");END_METHODBEGIN_METHOD(CWINDOW_new, GB_OBJECT parent)  //MyMainWindow *win = new MyMainWindow(window_main ? QMAINWINDOW(window_main) : NULL);  MyMainWindow *win = 0;  QFrame *frame = 0;  QWidget *container;  if (MISSING(parent))  {    //qDebug("CWINDOW_new: missing parent");    //qDebug("CWINDOW_Main = %p", CWINDOW_Main);    //qDebug("CWINDOW_new %p", THIS);    win = new MyMainWindow(CWINDOW_Main ? (MyMainWindow *)QWIDGET(CWINDOW_Main) : 0);    container = new MyContainer(win);    THIS->widget.widget = win;    THIS->embedded = false;    THIS->window = true;    CWIDGET_new(win, (void *)_object, NULL);  }  else if (GB.Is(VARG(parent), CLASS_Container))  {    frame = new MyEmbeddedWindow(CONTAINER(VARG(parent)));    container = frame;    THIS->widget.widget = frame;    THIS->embedded = true;    THIS->window = false;    CWIDGET_new(frame, (void *)_object, NULL);  }  else if (GB.Is(VARG(parent), CLASS_Workspace))  {    //qDebug(">> CWINDOW_new: workspace");    win = new MyMainWindow(QWIDGET(VARG(parent)));    container = new MyContainer(win);    THIS->widget.widget = win;    //frame = new MyEmbeddedWindow(QWIDGET(VARG(parent)));    //container = frame;    //FRAME = frame;    THIS->embedded = true;    THIS->window = true;    //CWIDGET_set_flag(THIS, WF_PARENT_GEOMETRY);    CWIDGET_new(win, (void *)_object, NULL);    //qDebug("<< CWINDOW_new: workspace");  }  else  {    GB.Error("The parent of a Window must be a Container or a Workspace");    return;  }  THIS->container = container;  container->setBackgroundOrigin(QWidget::WindowOrigin);  if (frame)  {    frame->installEventFilter(&CWindow::manager);  }  else  {    win->setCentralWidget(container);    win->setOpaqueMoving(true);    win->installEventFilter(&CWindow::manager);    if (!THIS->embedded)    {      /*if (CWindow::count >= 64)      {        GB.Error("Too many windows opened");        return;      }*/      CWindow::dict.insert(_object, OBJECT(const CWINDOW));      CWindow::count = CWindow::dict.count();      //qDebug("CWindow::count = %d (%p %s)", CWindow::count, _object, THIS->embedded ? "E" : "W");      if (CWINDOW_Main == 0)      {        //qDebug("CWINDOW_Main -> %p", THIS);        CWINDOW_Main = THIS;      }    }  }END_METHODBEGIN_METHOD_VOID(CFORM_new)  GB.Attach(_object, _object, "Form");  if (THIS->embedded && !THIS->window)    FRAME->show();END_METHODBEGIN_METHOD_VOID(CFORM_main)  CWINDOW *form;  form = (CWINDOW *)GB.AutoCreate(GB.GetClass(NULL), 0);  //GB.New((void **)&form, GB.GetClass(NULL), NULL, NULL);  ((MyMainWindow *)form->widget.widget)->showActivate();END_METHODBEGIN_METHOD(CFORM_load, GB_OBJECT parent)  if (!MISSING(parent))  {    GB.Push(1, GB_T_OBJECT, VARG(parent));    //qDebug("CFORM_load + parent");  }  GB.AutoCreate(GB.GetClass(NULL), MISSING(parent) ? 0 : 1);END_METHODBEGIN_METHOD_VOID(CWINDOW_free)  //qDebug("CWINDOW_free");  if (THIS->menu)    delete THIS->menu;  //PICTURE_set(&(window->icon), 0);  GB.StoreObject(NULL, (void **)&(THIS->icon));  GB.StoreObject(NULL, (void **)&(THIS->mask));  GB.Unref((void **)&THIS->focus);  /*CALL_METHOD_VOID(CWIDGET_delete);*/END_METHODBEGIN_METHOD_VOID(CWINDOW_next)  CWINDOW *next;  QPtrDictIterator<CWINDOW> *iter = ENUM(QPtrDictIterator<CWINDOW> *);  if (iter == NULL)  {    iter = new QPtrDictIterator<CWINDOW>(CWindow::dict);    ENUM(QPtrDictIterator<CWINDOW> *) = iter;  }  next = iter->current();  if (next == NULL)  {    delete iter;    //ENUM(QPtrDictIterator<CWINDOW>) = NULL;    GB.StopEnum();    return;  }  ++(*iter);  GB.ReturnObject(next);END_METHODBEGIN_PROPERTY(CWINDOW_count)  GB.ReturnInteger(CWindow::dict.count());END_PROPERTYBEGIN_METHOD(CWINDOW_get, GB_INTEGER id)  QWidget *wid = QWidget::find(VARG(id));  //qDebug("id = %d wid = %p", PARAM(id), wid);  if (wid != 0 && wid->isTopLevel())  {    //qDebug("-> %p", CWidget::getReal(wid));    GB.ReturnObject(CWidget::getReal(wid));  }  else  {    //qDebug("-> %p", 0);    GB.ReturnNull();  }END_METHODstatic bool do_close(CWINDOW *_object, long ret, bool destroyed = false){  bool closed;  if (CWIDGET_test_flag(THIS, WF_IN_CLOSE) || CWIDGET_test_flag(THIS, WF_CLOSED))    return false;  if (!THIS->window)  {    CWIDGET_set_flag(THIS, WF_IN_CLOSE);    closed = !GB.Raise(THIS, EVENT_Close, 0);    CWIDGET_clear_flag(THIS, WF_IN_CLOSE);    if (destroyed)    {      CWIDGET_set_flag(THIS, WF_CLOSED);    }    else if (closed)    {      CWIDGET_set_flag(THIS, WF_CLOSED);      WINDOW->hide();      if (!CWIDGET_test_flag(_object, WF_PERSISTENT))        CWIDGET_destroy((CWIDGET *)THIS);    }  }  else  {    if (WINDOW->isHidden())    {      QCloseEvent e;      QApplication::sendEvent(WINDOW, &e);      closed = e.isAccepted();    }    else      closed = WINDOW->close();  }  if (closed)    THIS->ret = ret;  //qDebug("CWINDOW_close: ret = %d", THIS->ret);  return (!closed);}BEGIN_METHOD(CWINDOW_close, GB_INTEGER ret)  long ret = VARGOPT(ret, 0);  GB.ReturnBoolean(do_close(THIS, ret));END_METHODBEGIN_METHOD_VOID(CWINDOW_raise)  if (!THIS->window)  {    if (!FRAME->isVisible())      FRAME->show();    FRAME->raise();  }  else  {    if (!WINDOW->isVisible())      WINDOW->showActivate();    else      WINDOW->raise();  }END_METHODBEGIN_METHOD_VOID(CWINDOW_show)  if (!THIS->window)  {    FRAME->raise();    FRAME->show();  }  else  {    //if (CWINDOW_Current)    //  GB.Error("A modal window is already displayed");    //else    if (CWINDOW_Current)      WINDOW->showModal();    else      WINDOW->showActivate();  }END_METHODBEGIN_METHOD_VOID(CWINDOW_show_modal)  THIS->ret = 0;  if (!THIS->embedded)    WINDOW->showModal();  //qDebug("CWINDOW_show_modal: ret = %d", THIS->ret);  GB.ReturnInteger(THIS->ret);END_METHODBEGIN_PROPERTY(CWINDOW_modal)  if (!THIS->embedded)    GB.ReturnBoolean(WINDOW->isModal());  else    GB.ReturnBoolean(false);END_PROPERTY/*BEGIN_METHOD_VOID(CWINDOW_dialog)  CWINDOW *win;  GB.New((void **)&win, GB.GetClass(NULL), NULL, NULL);  win->ret = 0;  ((MyMainWindow *)win->widget.widget)->showModal();  GB.ReturnInteger(win->ret);END_METHOD*/BEGIN_PROPERTY(CWINDOW_persistent)  /*  if (READ_PROPERTY)    GB.ReturnBoolean(WIDGET->isPersistent());  else    WIDGET->setPersistent(PROPERTY(char) != 0);  */  if (!THIS->window)  {    if (READ_PROPERTY)      GB.ReturnBoolean(true);  }  else  {    if (READ_PROPERTY)      GB.ReturnBoolean(CWIDGET_test_flag(THIS, WF_PERSISTENT));    else    {      if (VPROP(GB_BOOLEAN))        CWIDGET_set_flag(THIS, WF_PERSISTENT);      else        CWIDGET_clear_flag(THIS, WF_PERSISTENT);    }  }END_PROPERTYBEGIN_PROPERTY(CWINDOW_text)  if (!THIS->window)  {    if (READ_PROPERTY)      GB.ReturnNull();  }  else  {    if (READ_PROPERTY)      GB.ReturnNewZeroString(TO_UTF8(WINDOW->caption()));    else      WINDOW->setCaption(QSTRING_PROP());  }END_PROPERTYBEGIN_PROPERTY(CWINDOW_menu_count)  if (THIS->menu)    GB.ReturnInteger(THIS->menu->count());  else    GB.ReturnInteger(0);END_PROPERTYBEGIN_METHOD_VOID(CWINDOW_menu_next)  CWINDOW *window = OBJECT(CWINDOW);  unsigned int index;  if (window->menu == NULL)  {    GB.StopEnum();    return;  }  index = ENUM(int);  if (index >= window->menu->count())  {    GB.StopEnum();    return;  }  GB.ReturnObject(window->menu->at(index));  ENUM(int) = index + 1;END_PROPERTY/*BEGIN_METHOD(CWINDOW_toolbar_add, CTOOLBAR *toolbar)  QMainWindow *wid = WIDGET;  QToolBar *tb = QTOOLBAR(PARAM(toolbar));  qDebug("ToolBar H = %d", tb->height());  wid->addToolBar(tb);  qDebug("ToolBar H = %d", tb->height());END_METHODBEGIN_METHOD(CWINDOW_toolbar_remove, CTOOLBAR *toolbar)  QMainWindow *wid = WIDGET;  wid->removeToolBar(QTOOLBAR(PARAM(toolbar)));END_METHOD*/BEGIN_PROPERTY(CWINDOW_id)  if (!THIS->window)    GB.ReturnInteger(0);  else    GB.ReturnInteger((long)WINDOW->winId());END_PROPERTYBEGIN_PROPERTY(CWINDOW_border)  if (!THIS->window)  {    if (READ_PROPERTY)      GB.ReturnInteger(0);  }  else  {    if (READ_PROPERTY)      GB.ReturnInteger(WINDOW->getBorder());    else      WINDOW->setBorder(VPROP(GB_INTEGER));  }END_PROPERTYBEGIN_PROPERTY(CWINDOW_icon)  if (!THIS->window)  {    if (READ_PROPERTY)      GB.ReturnNull();  }  else  {    if (READ_PROPERTY)      GB.ReturnObject(THIS->icon);    else      SET_PIXMAP(WINDOW->setIcon, &(THIS->icon), PROP(GB_OBJECT));      //WIDGET->setIcon(PICTURE_set(&(THIS->icon), PROPERTY(CPICTURE *)));  }END_PROPERTYBEGIN_PROPERTY(CWINDOW_mask)  if (THIS->embedded)  {    if (READ_PROPERTY)      GB.ReturnNull();  }  else  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -