/*************************************************************************** CDrawingArea.cpp (c) 2000-2007 Benoit Minisini 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 __CDRAWINGAREA_CPP #include #include #ifndef NO_X_WINDOW #include #endif #include "CDraw.h" #include "CDrawingArea.h" DECLARE_EVENT(EVENT_draw); /*************************************************************************** class MyDrawingArea ***************************************************************************/ MyDrawingArea::MyDrawingArea(QWidget *parent) : QFrame(parent) { drawn = 0; cache = 0; _background = 0; _frozen = false; _event_mask = 0; setMerge(false); setCached(false); setBackground(); setAllowFocus(false); setKeyCompression(false); } MyDrawingArea::~MyDrawingArea() { if (_background) delete _background; } void MyDrawingArea::setAllowFocus(bool f) { if (f) { setFocusPolicy(WheelFocus); setInputMethodEnabled(true); } else setFocusPolicy(NoFocus); } void MyDrawingArea::setMerge(bool m) { _merge = m; if (_frozen) return; if (_merge) clearWFlags(Qt::WPaintClever); else setWFlags(Qt::WPaintClever); } void MyDrawingArea::setFrozen(bool f) { XWindowAttributes attr; if (f == _frozen) return; #ifndef NO_X_WINDOW if (f) { //setBackgroundMode(Qt::NoBackground); XGetWindowAttributes(x11Display(), winId(), &attr); _event_mask = attr.your_event_mask; XSelectInput(x11Display(), winId(), ExposureMask); clearWFlags(Qt::WPaintClever); //qDebug("frozen"); } else { //setBackgroundMode(Qt::PaletteBackground); XSelectInput(x11Display(), winId(), _event_mask); setMerge(_merge); //qDebug("unfrozen"); } #endif _frozen = f; } #if 1 void MyDrawingArea::paintEvent(QPaintEvent *event) { //QFrame::paintEvent(event); if (_background) { QFrame::paintEvent(event); } else { QPainter paint( this ); QRect r; r = event->rect().intersect(frameRect()); if (r.isValid()) { QPainter *p; void *object = CWidget::get(this); bool frame = !contentsRect().contains(event->rect()); cache = new QPixmap(r.width(), r.height()); cache->fill(this, r.x(), r.y()); //qDebug("paint: %d %d %d %d", event->rect().x(), event->rect().y(), event->rect().width(), event->rect().height()); //status = DRAW_status(); //DRAW_begin(NULL, p, width(), height()); DRAW_begin(object); p = DRAW_get_current(); p->translate(-r.x(), -r.y()); p->setClipRect(r, QPainter::CoordPainter); //p->setClipRegion(event->region().intersect(contentsRect())); p->setBrushOrigin(-r.x(), -r.y()); if (frame) p->save(); //qDebug("MyDrawingArea::paintEvent %p", CWidget::get(this)); GB.Raise(object, EVENT_draw, 0); if (!contentsRect().contains(event->rect())) { p->restore(); //paint.setClipRegion( event->region().intersect(frameRect()) ); drawFrame(p); } //DRAW_restore(status); DRAW_end(); //delete p; //paint.setClipRegion( event->region().intersect( contentsRect() ) ); paint.drawPixmap(r.x(), r.y(), *cache); delete cache; cache = 0; } } } #endif #if 0 void MyDrawingArea::paintEvent(QPaintEvent *event) { QPainter paint( this ); if ( !contentsRect().contains( event->rect() ) ) { paint.save(); paint.setClipRegion( event->region().intersect(frameRect()) ); drawFrame( &paint ); paint.restore(); } if (!_frozen && !_background) { if (event->rect().intersects(contentsRect())) { void *object = CWidget::get(this); int status; QPainter *p = new QPainter(this); p->setClipRegion( event->region().intersect( contentsRect() ) ); //p->translate(-event->rect().x(), -event->rect().y()); //p->setClipRegion(event->region().intersect(contentsRect())); //p->setBrushOrigin(-event->rect().x(), -event->rect().y()); status = DRAW_status(); DRAW_begin(NULL, p); //qDebug("MyDrawingArea::paintEvent %p", CWidget::get(this)); GB.Raise(object, EVENT_draw, 0); DRAW_restore(status); //delete p; //paint.drawPixmap(event->rect().x(), event->rect().y(), cache); } } } #endif void MyDrawingArea::setBackground() { if (_background) { _background->detach(); #ifdef NO_X_WINDOW setErasePixmap(*_background); #else XSetWindowBackgroundPixmap(x11AppDisplay(), winId(), _background->handle()); #endif setWFlags(Qt::WNoAutoErase); setWFlags(Qt::WStaticContents); } else { #ifdef NO_X_WINDOW setBackgroundMode(Qt::NoBackground); #else XSetWindowBackgroundPixmap(x11AppDisplay(), winId(), None); #endif setWFlags(Qt::WNoAutoErase); clearWFlags(Qt::WStaticContents); } } void MyDrawingArea::refreshBackground() { //QPainter p; //p.begin(_background, this); //drawFrame(&p); //p.end(); #ifndef NO_X_WINDOW XClearWindow(x11AppDisplay(), winId()); #endif } void MyDrawingArea::clearBackground() { if (_background) { QPainter p(_background); p.fillRect(0, 0, _background->width(), _background->height(), paletteBackgroundColor()); p.end(); setBackground(); refreshBackground(); } else // widgets flags may have changed when called from CDRAWINGAREA_background() for example setBackground(); } bool MyDrawingArea::doResize(int w, int h) { int wb, hb; if (drawn) { GB.Error("DrawingArea is being drawn"); return true; } if (w == width() && h == height()) return false; if (_background) { w = QMAX(w, 1); h = QMAX(h, 1); QPixmap *p = new QPixmap(w, h); p->fill(paletteBackgroundColor()); wb = QMIN(w, _background->width()); hb = QMIN(h, _background->height()); bitBlt(p, 0, 0, _background, 0, 0, wb, hb, CopyROP); delete _background; _background = p; setBackground(); refreshBackground(); } return false; } void MyDrawingArea::resize(int w, int h) { if (doResize(w, h)) return; QFrame::resize(w, h); } void MyDrawingArea::setGeometry(int x, int y, int w, int h) { if (doResize(w, h)) return; QFrame::setGeometry(x, y, w, h); } void MyDrawingArea::setCached(bool c) { if (_background) delete _background; if (c) { _background = new QPixmap(width(), height()); _background->fill(paletteBackgroundColor()); clearWFlags(WRepaintNoErase | WResizeNoErase); } else { _background = 0; setWFlags(WRepaintNoErase | WResizeNoErase); } setBackground(); } void MyDrawingArea::setPalette(const QPalette &pal) { QFrame::setPalette(pal); repaint(); } /*************************************************************************** DrawingArea ***************************************************************************/ BEGIN_METHOD(CDRAWINGAREA_new, GB_OBJECT parent) MyDrawingArea *wid = new MyDrawingArea(QCONTAINER(VARG(parent))); //THIS->widget.background = QColorGroup::Base; THIS->container = wid; CWIDGET_new(wid, (void *)_object); END_METHOD BEGIN_PROPERTY(CDRAWINGAREA_cached) if (READ_PROPERTY) GB.ReturnBoolean(WIDGET->isCached()); else WIDGET->setCached(VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_PROPERTY(CDRAWINGAREA_track_mouse) if (READ_PROPERTY) GB.ReturnBoolean(WIDGET->hasMouseTracking()); else WIDGET->setMouseTracking(VPROP(GB_BOOLEAN)); END_PROPERTY DECLARE_METHOD(CCONTROL_background); BEGIN_METHOD_VOID(CDRAWINGAREA_clear) WIDGET->clearBackground(); END_METHOD BEGIN_PROPERTY(CDRAWINGAREA_background) CCONTROL_background(_object, _param); if (!READ_PROPERTY) WIDGET->clearBackground(); END_PROPERTY BEGIN_PROPERTY(CDRAWINGAREA_border) CWIDGET_border_full(_object, _param); if (!READ_PROPERTY) WIDGET->clearBackground(); END_PROPERTY BEGIN_PROPERTY(CDRAWINGAREA_enabled) CCONTROL_enabled(_object, _param); if (!READ_PROPERTY) WIDGET->setFrozen(!VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_PROPERTY(CDRAWINGAREA_merge) if (READ_PROPERTY) GB.ReturnBoolean(WIDGET->isMerge()); else WIDGET->setMerge(VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_PROPERTY(CDRAWINGAREA_focus) if (READ_PROPERTY) GB.ReturnBoolean(WIDGET->isAllowFocus()); else WIDGET->setAllowFocus(VPROP(GB_BOOLEAN)); END_PROPERTY GB_DESC CDrawingAreaDesc[] = { GB_DECLARE("DrawingArea", sizeof(CDRAWINGAREA)), GB_INHERITS("Container"), GB_METHOD("_new", NULL, CDRAWINGAREA_new, "(Parent)Container;"), GB_PROPERTY("Cached", "b", CDRAWINGAREA_cached), GB_PROPERTY("Merge", "b", CDRAWINGAREA_merge), GB_PROPERTY("Border", "i", CDRAWINGAREA_border), GB_PROPERTY("Background", "i", CDRAWINGAREA_background), GB_PROPERTY("BackColor", "i", CDRAWINGAREA_background), GB_PROPERTY("Tracking", "b", CDRAWINGAREA_track_mouse), GB_PROPERTY("Focus", "b", CDRAWINGAREA_focus), GB_PROPERTY("Enabled", "b", CDRAWINGAREA_enabled), GB_METHOD("Clear", NULL, CDRAWINGAREA_clear, NULL), GB_EVENT("Draw", NULL, NULL, &EVENT_draw), GB_INTERFACE("Draw", &DRAW_Interface), DRAWINGAREA_DESCRIPTION, GB_END_DECLARE };