rootwindow.cpp

Go to the documentation of this file.
00001 /*
00002   libwt - Vassilis Virvilis Toolkit - a widget library
00003   Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm>
00004  
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009   
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014   
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the
00017   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018   Boston, MA  02111-1307, SA.
00019 */
00020 
00021 #include <wt/rootwindow.h>
00022 #include <wt/event.h>
00023 #include <wt/trace.h>
00024 
00025 namespace Wt {
00026 
00027 RootWindow::RootWindow(int w, int h, int depth, const std::string &name, int wflags)
00028         : Display(w, h, depth, wflags),
00029 Window(0, name, wflags) {
00030 
00031     // set the initial focus
00032     focusPolicy = StrongFocus;
00033     setFocus(FocusEvent::ActiveWindow);
00034     Window::resize(Display::size());
00035     trace("root") << "Root Window " << Window::rect() << std::endl;
00036 }
00037 
00038 void RootWindow::resize(int w, int h) {
00039     const Size& min_size = minimumSize();
00040     w = std::max(w, min_size.width());
00041     h = std::max(h, min_size.height());
00042     trace("resize") << "RootWindow size " << Size(w, h)
00043     << " sizeHint " << sizeHint() << " minimum Size " << min_size << std::endl;
00044     Display::resize(w, h);
00045     Window::resize(w, h);
00046 }
00047 
00048 /// blits the region from w to screen without traversing the widget tree
00049 void RootWindow::blit_region(const Widget *w, const Region& r) {
00050     if (w->isHidden())
00051         return;
00052     trace("paint") << "Non recursive paint for " << w << " region: " << r;
00053     const RectArray& ra = r.rects();
00054     const int n = ra.size();
00055     for (int i = 0; i < n; i++) {
00056         const Rect src(w->mapFromGlobal(ra[i].topLeft()), ra[i].size());
00057         trace("paint") << " local src " << ra[i] << std::endl;
00058         Display::blit(ra[i].x(), ra[i].y(), *w, src);
00059     }
00060 }
00061 
00062 /// blits the region from w to screen by traversing the widget tree recursively
00063 void RootWindow::blit_region_ex(const Widget *w, const Region& r) {
00064     if (w->isHidden())
00065         return;
00066     trace("paint") << "Region to paint from " << w << " region " << r;
00067     // first paint all the non client area region to parent
00068     // that is all the region that is not occupied or
00069     // occupied by transparent widgets
00070     Region non_client(r);
00071     for (Object::List::const_iterator child(w->children().begin()),
00072             end(w->children().end()); child != end; ++child) {
00073         const Widget* ww = dynamic_cast<Widget *>(*child);
00074         // it is possible to be a layout children. Don't crash
00075         // reduce non_client only for opaque widgets
00076         if (ww && ww->isOpaque() && ww->isShown()) {
00077             const Rect wr(ww->mapToGlobal(Point(0, 0)), ww->geometry().size());
00078             const Region rr(r & wr);
00079             if (!rr.isEmpty()) {
00080                 non_client -= rr;
00081             }
00082         }
00083         if (non_client.isEmpty())
00084             break;
00085     }
00086 
00087     // Now paint the parent area
00088     if (!non_client.isEmpty()) {
00089         trace("paint") << "Painting parent area for " << w << " region: " << non_client;
00090         blit_region(w, non_client);
00091     }
00092 
00093     // Now paint the client area (widgets)
00094     for (Object::List::const_iterator child(w->children().begin()),
00095             end(w->children().end()); child != end; ++child) {
00096         const Widget* ww = dynamic_cast<Widget *>(*child);
00097         // it is possible to be a layout children. Don't crash
00098         if (ww && ww->isShown()) {
00099             const Rect wr(ww->mapToGlobal(Point(0, 0)), ww->geometry().size());
00100             const Region rr(r & wr);
00101             trace("paint") << "blit from child " << ww << " wr " << wr << " rr " << rr;
00102             if (!rr.isEmpty()) {
00103                 blit_region_ex(ww, rr);
00104             }
00105         }
00106     }
00107 }
00108 
00109 void RootWindow::paintEvent(PaintEvent *e) {
00110     Widget::paintEvent(e);
00111 
00112     trace("paint") << "root paintEvent: " << this << " region: " << e->region() << std::endl;
00113     blit_region_ex(this, e->region());
00114     Display::update(e->region());
00115 }
00116 
00117 }

Generated Fri Jul 28 19:23:00 2006.
Copyright © 1998-2003 by the respective authors.

This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.