<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:refactormycode.com,2007:users348</id>
  <link type="application/atom+xml" href="http://refactormycode.com/users/348" rel="self"/>
  <title>fenix</title>
  <updated>Sun Dec 09 15:03:47 +0000 2007</updated>
  <entry>
    <id>tag:refactormycode.com,2007:Code177</id>
    <published>2007-12-09T15:03:47+00:00</published>
    <updated>2007-12-09T15:03:47+00:00</updated>
    <title>[Java] Widget Mirror</title>
    <content type="html">&lt;p&gt;Hi at all, I try to reply a very cool widget maked by Matthias Kretz (&lt;a href="http://vir.homelinux.org/blog/index.php" target="_blank"&gt;http://vir.homelinux.org/blog/index.php&lt;/a&gt;?/archives/88-QWidgetrender.html), but it seem not work.
&lt;br /&gt;I believe that error is in a call at memset of alphaChannel.
&lt;br /&gt;Thanks a lot, predatelly.&lt;/p&gt;

&lt;p&gt;P.S. Excuse for my English! :-)&lt;/p&gt;

&lt;pre&gt;/**
 * ================================================================
 * Enterprise Managerial
 * ================================================================
 *
 * Project Info:  http://portus.sourceforge.net
 * Project Lead:  Francesco Portus (portusgraphics@gmail.com);
 *
 * (C) Copyright 2005, by Francesco Portus
 *
 * @author Francesco Portus
 * @version 0.1
 *
 * This library is free software; you can redistribute it and/or modify it underthe terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
package it.portus.view;

import java.util.ArrayList;
import java.util.Stack;
import java.util.Vector;

import com.trolltech.qt.core.QChildEvent;
import com.trolltech.qt.core.QCoreApplication;
import com.trolltech.qt.core.QEvent;
import com.trolltech.qt.core.QObject;
import com.trolltech.qt.core.QPoint;
import com.trolltech.qt.core.QRect;
import com.trolltech.qt.core.QSize;
import com.trolltech.qt.core.Qt;
import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QColor;
import com.trolltech.qt.gui.QGridLayout;
import com.trolltech.qt.gui.QImage;
import com.trolltech.qt.gui.QLineEdit;
import com.trolltech.qt.gui.QListWidget;
import com.trolltech.qt.gui.QPaintEvent;
import com.trolltech.qt.gui.QPainter;
import com.trolltech.qt.gui.QPushButton;
import com.trolltech.qt.gui.QRegion;
import com.trolltech.qt.gui.QVBoxLayout;
import com.trolltech.qt.gui.QWidget;


public class WidgetMirror extends QWidget {

    static final int MIRROR_HEIGHT = 38;
    private QWidget m_widget;
    
    private boolean m_inPaintEvent = false;

    public WidgetMirror(QWidget parent)
    {
        super(parent);
        m_widget = this;
        m_inPaintEvent = false;
    }

    void setMirroredWidget(QWidget w)
    {
        if (m_widget != null) {
            m_widget.removeEventFilter(this);
            Stack&amp;lt;QObject&amp;gt; parentStack = new Stack&amp;lt;QObject&amp;gt;();
            parentStack.push(m_widget);
            while (!parentStack.isEmpty()) {
                QObject parent = parentStack.pop();
                for (QObject child : parent.children()) {
                    child.removeEventFilter(this);
                    parentStack.push(child);
                }
            }
        }
        m_widget = w;
        if (m_widget != null) {
            m_widget.installEventFilter(this);
            setSizePolicy(m_widget.sizePolicy());

            Stack&amp;lt;QObject&amp;gt; parentStack = new Stack&amp;lt;QObject&amp;gt;();
            parentStack.push(m_widget);
            while (!parentStack.isEmpty()) {
                QObject parent = parentStack.pop();
                for (QObject child : parent.children()) {
                    if (child.isWidgetType()) {
                        child.installEventFilter(this);
                        parentStack.push(child);
                    }
                }
            }
        }
    }

    public boolean eventFilter(QObject obj, QEvent event) {
        if (event.type() == QEvent.Type.ChildPolished) {
            QChildEvent e = (QChildEvent)event;
            QObject child = e.child();
            if (child.isWidgetType()) {
                child.installEventFilter(this);
                Stack&amp;lt;QObject&amp;gt; parentStack = new Stack&amp;lt;QObject&amp;gt;();
                parentStack.push(child);
                while (!parentStack.isEmpty()) {
                    QObject parent = parentStack.pop();
                    for (QObject c : parent.children()) {
                        if (c.isWidgetType()) {
                            c.installEventFilter(this);
                            parentStack.push(c);
                        }
                    }
                }
            }
        } else if (!m_inPaintEvent &amp;amp;&amp;amp; obj.isWidgetType() &amp;amp;&amp;amp; event.type() == QEvent.Type.Paint) {
            QWidget w = (QWidget)obj;
            QPaintEvent pe = (QPaintEvent)event;
            QRect r = new QRect(pe.rect().topLeft(), pe.rect().bottomRight());
            final QPoint diff = w.mapTo(m_widget, new QPoint());
            r.translate(diff);
            int tmp = r.top();
            r.setTop(m_widget.height() - r.bottom() - 1);
            r.setBottom(m_widget.height() - tmp - 1);
            update(r);
        }
        return super.eventFilter(obj, event);
    }

    protected void paintEvent(QPaintEvent e) {
        if (m_widget == null) {
            return;
        }

        QRect dirty = new QRect(e.rect().topLeft(), e.rect().bottomRight());
        dirty.setHeight(Math.min(dirty.height(), MIRROR_HEIGHT));
        int tmp = dirty.top();
        dirty.setTop(m_widget.height() - dirty.bottom() - 1);
        dirty.setBottom(m_widget.height() - tmp - 1);

        m_inPaintEvent = true;

        QImage im = new QImage(e.rect().size(), QImage.Format.Format_ARGB32_Premultiplied);
        QRegion region = new QRegion(dirty);
        
        RenderFlags flags = new QWidget.RenderFlags(QWidget.RenderFlag.resolve(QWidget.RenderFlag.DrawWindowBackground.value() | QWidget.RenderFlag.DrawChildren.value()));
        m_widget.render(im, dirty.topLeft().multiply(-1), region, flags);// | QWidget::IgnoreMask);
        im = im.mirrored();
        

        QImage alphaChannel = new QImage(im.size(), QImage.Format.Format_Indexed8);

        Vector&amp;lt;Integer&amp;gt; s_colorTable = new Vector&amp;lt;Integer&amp;gt;();
        if (s_colorTable.isEmpty()) {
            //s_colorTable.setSize(256);
            for (int i = 0; i &amp;lt; 256; ++i) {
                System.out.println(i);
                s_colorTable.add(i, QColor.fromRgb(i, i, i).rgb());
            }
        }

        if (alphaChannel != null) {
            System.out.println(&amp;quot;colors&amp;quot;);
        }
        alphaChannel.setColorTable(s_colorTable);
        alphaChannel.fill(0);

        final int maxAlpha = 100;
        for (int line = 0; line &amp;lt; alphaChannel.height() &amp;amp;&amp;amp; line &amp;lt; MIRROR_HEIGHT - e.rect().top(); ++line) {
            final int x = line + e.rect().top();
            int value = 4 * (maxAlpha - x * maxAlpha / MIRROR_HEIGHT) / (x + 4); // ;
           // std::memset(alphaChannel.scanLine(line), value, alphaChannel.bytesPerLine());
        }
        im.setAlphaChannel(alphaChannel);

        QPainter p = new QPainter(this);
        p.drawImage(e.rect(), im);

        m_inPaintEvent = false;
    }

    public QSize sizeHint(){
        if (m_widget == null) {
            return new QSize();
        }
        QSize s = new QSize(m_widget.sizeHint().width(), m_widget.sizeHint().height());
        s.setHeight(Math.min(s.height(), MIRROR_HEIGHT));
        return s;
    }
    
    public static void main(String args[]) {
        QApplication.initialize(args);
        QCoreApplication.processEvents();
        
        QWidget topLevel = new QWidget();
        QWidget w = new QWidget(topLevel);
        WidgetMirror leMirror = new WidgetMirror(topLevel);
        leMirror.setMirroredWidget(w);
        QPushButton b = new QPushButton(&amp;quot;Button&amp;quot;, w);
        QLineEdit le = new QLineEdit(w);
        QListWidget lw = new QListWidget(w);
        lw.setMaximumHeight(64);
        ArrayList&amp;lt;String&amp;gt; items = new ArrayList&amp;lt;String&amp;gt;();
        items.add(&amp;quot;Item 1&amp;quot;);
        items.add(&amp;quot;Item 2&amp;quot;);
        items.add(&amp;quot;Item 3&amp;quot;);
        items.add(&amp;quot;Item 4&amp;quot;);
        items.add(&amp;quot;Item 5&amp;quot;);
        items.add(&amp;quot;Item 6&amp;quot;);
        items.add(&amp;quot;Item 7&amp;quot;);
        items.add(&amp;quot;Item 8&amp;quot;);
        lw.addItems(items);
        QGridLayout layout = new QGridLayout(w);
        layout.setMargin(0);
        layout.addWidget(b, 0, 0, Qt.AlignmentFlag.AlignBottom);
        layout.addWidget(le, 0, 1, Qt.AlignmentFlag.AlignBottom);
        layout.addWidget(lw, 0, 2, Qt.AlignmentFlag.AlignBottom);
        QVBoxLayout outerLayout = new QVBoxLayout(topLevel);
        outerLayout.setSpacing(0);
        outerLayout.addWidget(w);
        outerLayout.addWidget(leMirror);
        topLevel.show();
        
        QApplication.exec();
    }
}&lt;/pre&gt;</content>
    <author>
      <name>fenix</name>
      <email>portusgraphics@gmail.com</email>
    </author>
    <link type="text/html" href="http://refactormycode.com/codes/177-widget-mirror" rel="alternate"/>
  </entry>
</feed>
