Added support for unstyled and frameless EffectFrames. Converted all
effects that display text or boxes to use the class. Minor speed increase in XRender mode for those effects and a massive increase in OpenGL mode (Double framerate in present windows in my case). svn path=/trunk/KDE/kdebase/workspace/; revision=929951
This commit is contained in:
parent
d31dc9eb9b
commit
1e91a66fd2
11 changed files with 324 additions and 153 deletions
|
@ -41,12 +41,16 @@ KWIN_EFFECT( boxswitch, BoxSwitchEffect )
|
|||
BoxSwitchEffect::BoxSwitchEffect()
|
||||
: mActivated( 0 )
|
||||
, mMode( 0 )
|
||||
, thumbnailFrame( true )
|
||||
, thumbnailFrame( EffectFrame::Styled )
|
||||
, selected_window( 0 )
|
||||
, painting_desktop( 0 )
|
||||
, animation( false )
|
||||
, highlight_is_set( false )
|
||||
{
|
||||
text_font.setBold( true );
|
||||
text_font.setPointSize( 12 );
|
||||
thumbnailFrame.setFont( text_font );
|
||||
thumbnailFrame.setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
|
||||
|
||||
highlight_margin = 10;
|
||||
reconfigure( ReconfigureAll );
|
||||
|
@ -147,7 +151,6 @@ void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
|
|||
paintWindowIcon( w );
|
||||
}
|
||||
}
|
||||
paintText( selected_window->caption() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -164,7 +167,6 @@ void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
|
|||
|
||||
paintDesktopThumbnail( painting_desktop );
|
||||
}
|
||||
paintText( effects->desktopName( selected_desktop ));
|
||||
painting_desktop = 0;
|
||||
}
|
||||
}
|
||||
|
@ -401,11 +403,12 @@ void BoxSwitchEffect::tabBoxUpdated()
|
|||
effects->addRepaint( text_area );
|
||||
original_windows = effects->currentTabBoxWindowList();
|
||||
}
|
||||
else
|
||||
else if( mMode != TabBoxWindowsMode )
|
||||
{ // DesktopMode
|
||||
if( desktops.contains( selected_desktop ))
|
||||
effects->addRepaint( desktops.value( selected_desktop )->area );
|
||||
selected_desktop = effects->currentTabBoxDesktop();
|
||||
thumbnailFrame.setText( effects->desktopName( selected_desktop ));
|
||||
if( desktops.contains( selected_desktop ))
|
||||
effects->addRepaint( desktops.value( selected_desktop )->area );
|
||||
effects->addRepaint( text_area );
|
||||
|
@ -438,6 +441,7 @@ void BoxSwitchEffect::setActive()
|
|||
{
|
||||
original_desktops = effects->currentTabBoxDesktopList();
|
||||
selected_desktop = effects->currentTabBoxDesktop();
|
||||
thumbnailFrame.setText( effects->desktopName( selected_desktop ));
|
||||
}
|
||||
calculateFrameSize();
|
||||
calculateItemSizes();
|
||||
|
@ -491,6 +495,7 @@ void BoxSwitchEffect::setSelectedWindow( EffectWindow* w )
|
|||
effects->setElevatedWindow( selected_window, false );
|
||||
}
|
||||
selected_window = w;
|
||||
thumbnailFrame.setText( selected_window->caption() );
|
||||
if( elevate_window && w )
|
||||
{
|
||||
effects->setElevatedWindow( selected_window, true );
|
||||
|
@ -528,8 +533,6 @@ void BoxSwitchEffect::calculateFrameSize()
|
|||
item_max_size.setHeight( 200 );
|
||||
}
|
||||
// How much height to reserve for a one-line text label
|
||||
text_font.setBold( true );
|
||||
text_font.setPointSize( 12 );
|
||||
text_area.setHeight( QFontMetrics( text_font ).height() * 1.2 );
|
||||
// Separator space between items and text
|
||||
const int separator_height = 6;
|
||||
|
@ -1053,10 +1056,4 @@ void BoxSwitchEffect::paintWindowIcon( EffectWindow* w )
|
|||
#endif
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintText( const QString& text )
|
||||
{
|
||||
int maxwidth = text_area.width();
|
||||
effects->paintText( text, text_area.center(), maxwidth, EffectFrame::textColor(), text_font );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -70,7 +70,6 @@ class BoxSwitchEffect
|
|||
void paintWindowThumbnail( EffectWindow* w );
|
||||
void paintDesktopThumbnail( int iDesktop );
|
||||
void paintWindowIcon( EffectWindow* w );
|
||||
void paintText( const QString& text );
|
||||
|
||||
bool mActivated;
|
||||
Window mInput;
|
||||
|
|
|
@ -52,8 +52,8 @@ CoverSwitchEffect::CoverSwitchEffect()
|
|||
, scaleFactor( 0.0 )
|
||||
, direction( Left )
|
||||
, selected_window( 0 )
|
||||
, captionFrame( true )
|
||||
, thumbnailFrame( true )
|
||||
, captionFrame( EffectFrame::Styled )
|
||||
, thumbnailFrame( EffectFrame::Styled )
|
||||
{
|
||||
reconfigure( ReconfigureAll );
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ CubeEffect::CubeEffect()
|
|||
, cubeOpacity( 1.0 )
|
||||
, opacityDesktopOnly( true )
|
||||
, displayDesktopName( false )
|
||||
, desktopNameFrame( true )
|
||||
, desktopNameFrame( EffectFrame::Styled )
|
||||
, reflection( true )
|
||||
, rotating( false )
|
||||
, desktopChangedWhileRotating( false )
|
||||
|
|
|
@ -135,12 +135,6 @@ void DesktopGridEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
|||
|
||||
if( desktopNameAlignment )
|
||||
{
|
||||
double progress = timeline.value();
|
||||
QColor textColor( 255, 255, 255, 255 * progress );
|
||||
QColor bgColor( 0, 0, 0, 178 * progress ); // 70%
|
||||
QFont f;
|
||||
f.setBold( true );
|
||||
f.setPointSize( 12 );
|
||||
for( int screen = 0; screen < effects->numScreens(); screen++ )
|
||||
{
|
||||
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
||||
|
@ -152,8 +146,21 @@ void DesktopGridEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
|||
QRect textArea( posTL.x(), posTL.y(), posBR.x() - posTL.x(), posBR.y() - posTL.y() );
|
||||
textArea.adjust( textArea.width() / 10, textArea.height() / 10,
|
||||
-textArea.width() / 10, -textArea.height() / 10 );
|
||||
effects->paintTextWithBackground( effects->desktopName( desktop ),
|
||||
textArea, textColor, bgColor, f, desktopNameAlignment );
|
||||
int x, y;
|
||||
if( desktopNameAlignment & Qt::AlignLeft )
|
||||
x = textArea.x();
|
||||
else if( desktopNameAlignment & Qt::AlignRight )
|
||||
x = textArea.right();
|
||||
else
|
||||
x = textArea.center().x();
|
||||
if( desktopNameAlignment & Qt::AlignTop )
|
||||
y = textArea.y();
|
||||
else if( desktopNameAlignment & Qt::AlignBottom )
|
||||
y = textArea.bottom();
|
||||
else
|
||||
y = textArea.center().y();
|
||||
desktopNames[desktop-1]->setPosition( QPoint( x, y ));
|
||||
desktopNames[desktop-1]->render( region, timeline.value(), 0.7 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -750,6 +757,22 @@ void DesktopGridEffect::setup()
|
|||
}
|
||||
hoverTimeline[effects->currentDesktop() - 1].setProgress( 1.0 );
|
||||
|
||||
// Create desktop name textures if enabled
|
||||
if( desktopNameAlignment )
|
||||
{
|
||||
desktopNames = new EffectFrame*[effects->numberOfDesktops()];
|
||||
QFont font;
|
||||
font.setBold( true );
|
||||
font.setPointSize( 12 );
|
||||
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
||||
{
|
||||
desktopNames[i] = new EffectFrame( EffectFrame::Unstyled, false );
|
||||
desktopNames[i]->setFont( font );
|
||||
desktopNames[i]->setText( effects->desktopName( i+1 ));
|
||||
desktopNames[i]->setAlignment( desktopNameAlignment );
|
||||
}
|
||||
}
|
||||
|
||||
// We need these variables for every paint so lets cache them
|
||||
int x, y;
|
||||
int numDesktops = effects->numberOfDesktops();
|
||||
|
@ -806,6 +829,13 @@ void DesktopGridEffect::setup()
|
|||
|
||||
void DesktopGridEffect::finish()
|
||||
{
|
||||
if( desktopNameAlignment )
|
||||
{
|
||||
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
||||
delete desktopNames[i];
|
||||
delete[] desktopNames;
|
||||
}
|
||||
|
||||
if( keyboardGrab )
|
||||
effects->ungrabKeyboard();
|
||||
keyboardGrab = false;
|
||||
|
|
|
@ -85,7 +85,9 @@ class DesktopGridEffect
|
|||
|
||||
// Soft highlighting
|
||||
QList<TimeLine> hoverTimeline;
|
||||
|
||||
|
||||
EffectFrame** desktopNames;
|
||||
|
||||
QSize gridSize;
|
||||
Qt::Orientation orientation;
|
||||
QPoint activeCell;
|
||||
|
|
|
@ -51,7 +51,7 @@ PresentWindowsEffect::PresentWindowsEffect()
|
|||
, m_hasKeyboardGrab( false )
|
||||
, m_tabBoxEnabled( false )
|
||||
, m_highlightedWindow( NULL )
|
||||
, m_filterFrame( false )
|
||||
, m_filterFrame( EffectFrame::Styled, false )
|
||||
{
|
||||
QFont font;
|
||||
font.setPointSize( font.pointSize() * 2 );
|
||||
|
@ -136,7 +136,16 @@ void PresentWindowsEffect::postPaintScreen()
|
|||
else if( !m_activated && m_motionManager.managingWindows() )
|
||||
{ // We have finished moving them back, stop processing
|
||||
m_motionManager.unmanageAll();
|
||||
|
||||
DataHash::iterator i = m_windowData.begin();
|
||||
while( i != m_windowData.end() )
|
||||
{
|
||||
delete i.value().textFrame;
|
||||
delete i.value().iconFrame;
|
||||
i++;
|
||||
}
|
||||
m_windowData.clear();
|
||||
|
||||
effects->setActiveFullScreenEffect( NULL );
|
||||
}
|
||||
|
||||
|
@ -211,23 +220,21 @@ void PresentWindowsEffect::paintWindow( EffectWindow *w, int mask, QRegion regio
|
|||
m_motionManager.apply( w, data );
|
||||
|
||||
effects->paintWindow( w, mask, region, data );
|
||||
|
||||
const WindowData &wData = m_windowData[w];
|
||||
|
||||
QRect rect = m_motionManager.transformedGeometry( w ).toRect();
|
||||
if( m_showIcons )
|
||||
paintWindowIcon( w, data );
|
||||
{
|
||||
QPoint point( rect.x() + rect.width() * 0.95,
|
||||
rect.y() + rect.height() * 0.95 );
|
||||
m_windowData[w].iconFrame->setPosition( point );
|
||||
m_windowData[w].iconFrame->render( region, 0.9 * data.opacity * m_decalOpacity, 0.75 );
|
||||
}
|
||||
if( m_showCaptions )
|
||||
{
|
||||
QString text = w->caption();
|
||||
QRect textArea( w->x() + data.xTranslate, w->y() + data.yTranslate,
|
||||
w->width() * data.xScale, w->height() * data.yScale );
|
||||
textArea.adjust( 10, 10, -10, -10 );
|
||||
double opacity = (0.7 + 0.2 * wData.highlight) * data.opacity * m_decalOpacity;
|
||||
QColor textcolor( 255, 255, 255, int( 255 * opacity ));
|
||||
QColor bgcolor( 0, 0, 0, int( 255 * opacity ));
|
||||
QFont f;
|
||||
f.setBold( true );
|
||||
f.setPointSize( 12 );
|
||||
effects->paintTextWithBackground( text, textArea, textcolor, bgcolor, f );
|
||||
QPoint point( rect.x() + rect.width() / 2,
|
||||
rect.y() + rect.height() / 2 );
|
||||
m_windowData[w].textFrame->setPosition( point );
|
||||
m_windowData[w].textFrame->render( region, 0.9 * data.opacity * m_decalOpacity, 0.75 );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -245,6 +252,14 @@ void PresentWindowsEffect::windowAdded( EffectWindow *w )
|
|||
m_windowData[w].visible = isVisibleWindow( w );
|
||||
m_windowData[w].opacity = 0.0;
|
||||
m_windowData[w].highlight = 0.0;
|
||||
m_windowData[w].textFrame = new EffectFrame( EffectFrame::Unstyled, false );
|
||||
QFont font;
|
||||
font.setBold( true );
|
||||
font.setPointSize( 12 );
|
||||
m_windowData[w].textFrame->setFont( font );
|
||||
m_windowData[w].iconFrame = new EffectFrame( EffectFrame::Unstyled, false );
|
||||
m_windowData[w].iconFrame->setAlignment( Qt::AlignRight | Qt::AlignBottom );
|
||||
m_windowData[w].iconFrame->setIcon( w->icon() );
|
||||
if( isSelectableWindow( w ))
|
||||
{
|
||||
m_motionManager.manage( w );
|
||||
|
@ -262,6 +277,8 @@ void PresentWindowsEffect::windowClosed( EffectWindow *w )
|
|||
|
||||
void PresentWindowsEffect::windowDeleted( EffectWindow *w )
|
||||
{
|
||||
delete m_windowData[w].textFrame;
|
||||
delete m_windowData[w].iconFrame;
|
||||
m_windowData.remove( w );
|
||||
m_motionManager.unmanage( w );
|
||||
}
|
||||
|
@ -511,6 +528,19 @@ void PresentWindowsEffect::rearrangeWindows()
|
|||
else
|
||||
calculateWindowTransformationsNatural( windows, screen );
|
||||
}
|
||||
|
||||
// Resize text frames if required
|
||||
QFontMetrics* metrics = NULL; // All fonts are the same
|
||||
foreach( EffectWindow *w, m_motionManager.managedWindows() )
|
||||
{
|
||||
if( !metrics )
|
||||
metrics = new QFontMetrics( m_windowData[w].textFrame->font() );
|
||||
QRect geom = m_motionManager.targetGeometry( w ).toRect();
|
||||
QString string = metrics->elidedText( w->caption(), Qt::ElideRight, geom.width() * 0.9 );
|
||||
if( string != m_windowData[w].textFrame->text() )
|
||||
m_windowData[w].textFrame->setText( string );
|
||||
}
|
||||
delete metrics;
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::calculateWindowTransformationsClosest( EffectWindowList windowlist, int screen )
|
||||
|
@ -1110,6 +1140,14 @@ void PresentWindowsEffect::setActive( bool active, bool closingTab )
|
|||
if( w->isOnCurrentDesktop() && !w->isMinimized() )
|
||||
m_windowData[w].opacity = 1.0;
|
||||
m_windowData[w].highlight = 1.0;
|
||||
m_windowData[w].textFrame = new EffectFrame( EffectFrame::Unstyled, false );
|
||||
QFont font;
|
||||
font.setBold( true );
|
||||
font.setPointSize( 12 );
|
||||
m_windowData[w].textFrame->setFont( font );
|
||||
m_windowData[w].iconFrame = new EffectFrame( EffectFrame::Unstyled, false );
|
||||
m_windowData[w].iconFrame->setAlignment( Qt::AlignRight | Qt::AlignBottom );
|
||||
m_windowData[w].iconFrame->setIcon( w->icon() );
|
||||
}
|
||||
|
||||
if( m_tabBoxEnabled )
|
||||
|
@ -1135,7 +1173,16 @@ void PresentWindowsEffect::setActive( bool active, bool closingTab )
|
|||
(( m_motionManager.managedWindows().count() == 1 ) && m_motionManager.managedWindows().first()->isOnCurrentDesktop() ))
|
||||
{ // No point triggering if there is nothing to do
|
||||
m_activated = false;
|
||||
|
||||
DataHash::iterator i = m_windowData.begin();
|
||||
while( i != m_windowData.end() )
|
||||
{
|
||||
delete i.value().textFrame;
|
||||
delete i.value().iconFrame;
|
||||
i++;
|
||||
}
|
||||
m_windowData.clear();
|
||||
|
||||
m_motionManager.unmanageAll();
|
||||
return;
|
||||
}
|
||||
|
@ -1417,63 +1464,6 @@ EffectWindow* PresentWindowsEffect::findFirstWindow() const
|
|||
return topLeft;
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::paintWindowIcon( EffectWindow *w, WindowPaintData &data )
|
||||
{
|
||||
// Don't bother if we don't even have an icon
|
||||
if( w->icon().isNull() )
|
||||
return;
|
||||
|
||||
WindowData &wData = m_windowData[w];
|
||||
if( wData.icon.cacheKey() != w->icon().cacheKey())
|
||||
{ // Make sure data.icon is the right QPixmap, and rebind
|
||||
wData.icon = w->icon();
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if( effects->compositingType() == OpenGLCompositing )
|
||||
{
|
||||
wData.iconTexture = new GLTexture( wData.icon );
|
||||
wData.iconTexture->setFilter( GL_LINEAR );
|
||||
}
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
if( effects->compositingType() == XRenderCompositing )
|
||||
wData.iconPicture = XRenderPicture( wData.icon );
|
||||
#endif
|
||||
}
|
||||
int icon_margin = 8;
|
||||
int width = wData.icon.width();
|
||||
int height = wData.icon.height();
|
||||
int x = w->x() + data.xTranslate + w->width() * data.xScale * 0.95 - width - icon_margin;
|
||||
int y = w->y() + data.yTranslate + w->height() * data.yScale * 0.95 - height - icon_margin;
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if( effects->compositingType() == OpenGLCompositing )
|
||||
{
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
// Render some background
|
||||
glColor4f( 0, 0, 0, 0.5 * wData.opacity * m_decalOpacity );
|
||||
renderRoundBox( QRect( x-3, y-3, width+6, height+6 ), 3 );
|
||||
// Render the icon
|
||||
glColor4f( 1, 1, 1, 1 * wData.opacity * m_decalOpacity );
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
wData.iconTexture->bind();
|
||||
wData.iconTexture->render( infiniteRegion(), QRect( x, y, width, height ));
|
||||
wData.iconTexture->unbind();
|
||||
glPopAttrib();
|
||||
}
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
if( effects->compositingType() == XRenderCompositing )
|
||||
{
|
||||
XRenderComposite( display(),
|
||||
wData.icon.depth() == 32 ? PictOpOver : PictOpSrc,
|
||||
wData.iconPicture, None,
|
||||
effects->xrenderBufferPicture(),
|
||||
0, 0, 0, 0, x, y, width, height );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "presentwindows.moc"
|
||||
|
|
|
@ -24,10 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include "presentwindows_proxy.h"
|
||||
|
||||
// Include with base class for effects.
|
||||
#include <kwineffects.h>
|
||||
#include <kwinglutils.h>
|
||||
#include <kwinxrenderutils.h>
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
|
@ -52,12 +49,8 @@ class PresentWindowsEffect
|
|||
int slot;
|
||||
int slot_distance;
|
||||
QPixmap icon;
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
KSharedPtr< GLTexture > iconTexture;
|
||||
#endif
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
XRenderPicture iconPicture;
|
||||
#endif
|
||||
EffectFrame* textFrame;
|
||||
EffectFrame* iconFrame;
|
||||
};
|
||||
typedef QHash<EffectWindow*, WindowData> DataHash;
|
||||
struct GridSize
|
||||
|
@ -129,7 +122,6 @@ class PresentWindowsEffect
|
|||
void setHighlightedWindow( EffectWindow *w );
|
||||
EffectWindow* relativeWindow( EffectWindow *w, int xdiff, int ydiff, bool wrap ) const;
|
||||
EffectWindow* findFirstWindow() const;
|
||||
void paintWindowIcon( EffectWindow *w, WindowPaintData &data ); // TODO: Do we need this?
|
||||
|
||||
private:
|
||||
PresentWindowsEffectProxy m_proxy;
|
||||
|
|
|
@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <kdebug.h>
|
||||
#include <ksharedconfig.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kconfiggroup.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -1297,6 +1298,18 @@ QRectF WindowMotionManager::transformedGeometry( EffectWindow *w ) const
|
|||
return geometry;
|
||||
}
|
||||
|
||||
QRectF WindowMotionManager::targetGeometry( EffectWindow *w ) const
|
||||
{
|
||||
QRectF geometry( w->geometry() );
|
||||
|
||||
// TODO: Take into account existing scale so that we can work with multiple managers (E.g. Present windows + grid)
|
||||
geometry.moveTo( m_managedWindows[ w ].translation.target() );
|
||||
geometry.setWidth( geometry.width() * m_managedWindows[ w ].scale.target().x() );
|
||||
geometry.setHeight( geometry.height() * m_managedWindows[ w ].scale.target().y() );
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
EffectWindow* WindowMotionManager::windowAtPoint( QPoint point, bool useStackingOrder ) const
|
||||
{
|
||||
// TODO: Stacking order uses EffectsHandler::stackingOrder() then filters by m_managedWindows
|
||||
|
@ -1313,8 +1326,11 @@ EffectWindow* WindowMotionManager::windowAtPoint( QPoint point, bool useStacking
|
|||
EffectFrame
|
||||
***************************************************************/
|
||||
|
||||
EffectFrame::EffectFrame( bool staticSize, QPoint position, Qt::Alignment alignment )
|
||||
GLTexture* EffectFrame::m_unstyledTexture = NULL;
|
||||
|
||||
EffectFrame::EffectFrame( Style style, bool staticSize, QPoint position, Qt::Alignment alignment )
|
||||
: QObject()
|
||||
, m_style( style )
|
||||
, m_static( staticSize )
|
||||
, m_point( position )
|
||||
, m_alignment( alignment )
|
||||
|
@ -1328,10 +1344,19 @@ EffectFrame::EffectFrame( bool staticSize, QPoint position, Qt::Alignment alignm
|
|||
m_textPicture = NULL;
|
||||
#endif
|
||||
|
||||
m_frame.setImagePath( "widgets/background" );
|
||||
m_frame.setCacheAllRenderedFrames( true );
|
||||
|
||||
connect( Plasma::Theme::defaultTheme(), SIGNAL( themeChanged() ), this, SLOT( plasmaThemeChanged() ));
|
||||
if( m_style == Unstyled )
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if( effects->compositingType() == OpenGLCompositing && !m_unstyledTexture )
|
||||
updateUnstyledTexture();
|
||||
#endif
|
||||
}
|
||||
else if( m_style == Styled )
|
||||
{
|
||||
m_frame.setImagePath( "widgets/background" );
|
||||
m_frame.setCacheAllRenderedFrames( true );
|
||||
connect( Plasma::Theme::defaultTheme(), SIGNAL( themeChanged() ), this, SLOT( plasmaThemeChanged() ));
|
||||
}
|
||||
}
|
||||
|
||||
EffectFrame::~EffectFrame()
|
||||
|
@ -1362,32 +1387,94 @@ void EffectFrame::free()
|
|||
#endif
|
||||
}
|
||||
|
||||
void EffectFrame::render( QRegion region, double opacity )
|
||||
void EffectFrame::render( QRegion region, double opacity, double frameOpacity )
|
||||
{
|
||||
if( m_geometry.isEmpty() )
|
||||
return; // Nothing to display
|
||||
|
||||
region = infiniteRegion(); // TODO: Old region doesn't seem to work with OpenGL
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if( effects->compositingType() == OpenGLCompositing )
|
||||
{
|
||||
if( !m_texture ) // Lazy creation
|
||||
updateTexture();
|
||||
if( !m_texture || m_geometry.isEmpty() )
|
||||
return;
|
||||
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity );
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
// Render the actual frame
|
||||
m_texture->bind();
|
||||
qreal left, top, right, bottom;
|
||||
m_frame.getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
|
||||
m_texture->render( region, m_geometry.adjusted( -left, -top, right, bottom ));
|
||||
m_texture->unbind();
|
||||
if( m_style == Unstyled )
|
||||
{
|
||||
const QRect& area = m_geometry.adjusted( -5, -5, 5, 5 );
|
||||
const int roundness = 5;
|
||||
QVector<float> verts, texCoords;
|
||||
verts.reserve( 80 );
|
||||
texCoords.reserve( 80 );
|
||||
|
||||
// Center
|
||||
addQuadVertices( verts, area.left() + roundness, area.top() + roundness,
|
||||
area.right() - roundness, area.bottom() - roundness );
|
||||
addQuadVertices( texCoords, 0.5, 0.5, 0.5, 0.5 );
|
||||
|
||||
// Left
|
||||
addQuadVertices( verts, area.left(), area.top() + roundness,
|
||||
area.left() + roundness, area.bottom() - roundness );
|
||||
addQuadVertices( texCoords, 0.0, 0.5, 0.5, 0.5 );
|
||||
// Top
|
||||
addQuadVertices( verts, area.left() + roundness, area.top(),
|
||||
area.right() - roundness, area.top() + roundness );
|
||||
addQuadVertices( texCoords, 0.5, 0.0, 0.5, 0.5 );
|
||||
// Right
|
||||
addQuadVertices( verts, area.right() - roundness, area.top() + roundness,
|
||||
area.right(), area.bottom() - roundness );
|
||||
addQuadVertices( texCoords, 0.5, 0.5, 1.0, 0.5 );
|
||||
// Bottom
|
||||
addQuadVertices( verts, area.left() + roundness, area.bottom() - roundness,
|
||||
area.right() - roundness, area.bottom() );
|
||||
addQuadVertices( texCoords, 0.5, 0.5, 0.5, 1.0 );
|
||||
|
||||
// Top-left
|
||||
addQuadVertices( verts, area.left(), area.top(),
|
||||
area.left() + roundness, area.top() + roundness );
|
||||
addQuadVertices( texCoords, 0.0, 0.0, 0.5, 0.5 );
|
||||
// Top-right
|
||||
addQuadVertices( verts, area.right() - roundness, area.top(),
|
||||
area.right(), area.top() + roundness );
|
||||
addQuadVertices( texCoords, 0.5, 0.0, 1.0, 0.5 );
|
||||
// Bottom-left
|
||||
addQuadVertices( verts, area.left(), area.bottom() - roundness,
|
||||
area.left() + roundness, area.bottom() );
|
||||
addQuadVertices( texCoords, 0.0, 0.5, 0.5, 1.0 );
|
||||
// Bottom-right
|
||||
addQuadVertices( verts, area.right() - roundness, area.bottom() - roundness,
|
||||
area.right(), area.bottom() );
|
||||
addQuadVertices( texCoords, 0.5, 0.5, 1.0, 1.0 );
|
||||
|
||||
glColor4f( 0.0, 0.0, 0.0, opacity * frameOpacity );
|
||||
|
||||
m_unstyledTexture->bind();
|
||||
m_unstyledTexture->enableNormalizedTexCoords();
|
||||
renderGLGeometry( verts.count() / 2, verts.data(), texCoords.data() );
|
||||
m_unstyledTexture->disableNormalizedTexCoords();
|
||||
m_unstyledTexture->unbind();
|
||||
}
|
||||
else if( m_style == Styled )
|
||||
{
|
||||
if( !m_texture ) // Lazy creation
|
||||
updateTexture();
|
||||
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity * frameOpacity );
|
||||
|
||||
m_texture->bind();
|
||||
qreal left, top, right, bottom;
|
||||
m_frame.getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
|
||||
m_texture->render( region, m_geometry.adjusted( -left, -top, right, bottom ));
|
||||
m_texture->unbind();
|
||||
}
|
||||
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity );
|
||||
|
||||
// Render icon
|
||||
if( !m_icon.isNull() && !m_iconSize.isEmpty() )
|
||||
|
@ -1418,19 +1505,23 @@ void EffectFrame::render( QRegion region, double opacity )
|
|||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
if( effects->compositingType() == XRenderCompositing )
|
||||
{
|
||||
if( !m_picture ) // Lazy creation
|
||||
updatePicture();
|
||||
if( !m_picture || m_geometry.isEmpty() )
|
||||
return;
|
||||
|
||||
// TODO: Opacity
|
||||
|
||||
// Render the actual frame
|
||||
qreal left, top, right, bottom;
|
||||
m_frame.getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
|
||||
QRect geom = m_geometry.adjusted( -left, -top, right, bottom );
|
||||
XRenderComposite( display(), PictOpOver, *m_picture, None, effects->xrenderBufferPicture(),
|
||||
0, 0, 0, 0, geom.x(), geom.y(), geom.width(), geom.height() );
|
||||
if( m_style == Unstyled )
|
||||
xRenderRoundBox( effects->xrenderBufferPicture(), m_geometry.adjusted( -5, -5, 5, 5 ),
|
||||
5, QColor( 0, 0, 0, int( opacity * frameOpacity * 255 )));
|
||||
else if( m_style == Styled )
|
||||
{
|
||||
if( !m_picture ) // Lazy creation
|
||||
updatePicture();
|
||||
qreal left, top, right, bottom;
|
||||
m_frame.getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
|
||||
QRect geom = m_geometry.adjusted( -left, -top, right, bottom );
|
||||
XRenderComposite( display(), PictOpOver, *m_picture, None, effects->xrenderBufferPicture(),
|
||||
0, 0, 0, 0, geom.x(), geom.y(), geom.width(), geom.height() );
|
||||
}
|
||||
|
||||
// Opacity, TODO: Can we further optimize this?
|
||||
XRenderPicture fill = xRenderFill( QColor( 255, 255, 255, int( opacity * 255 )));
|
||||
|
||||
// Render icon
|
||||
if( !m_icon.isNull() && !m_iconSize.isEmpty() )
|
||||
|
@ -1438,8 +1529,8 @@ void EffectFrame::render( QRegion region, double opacity )
|
|||
QPoint topLeft( m_geometry.x(), m_geometry.center().y() - m_iconSize.height() / 2 );
|
||||
|
||||
XRenderPicture* icon = new XRenderPicture( m_icon ); // TODO: Cache
|
||||
geom = QRect( topLeft, m_iconSize );
|
||||
XRenderComposite( display(), PictOpOver, *icon, None, effects->xrenderBufferPicture(),
|
||||
QRect geom = QRect( topLeft, m_iconSize );
|
||||
XRenderComposite( display(), PictOpOver, *icon, fill, effects->xrenderBufferPicture(),
|
||||
0, 0, 0, 0, geom.x(), geom.y(), geom.width(), geom.height() );
|
||||
delete icon;
|
||||
}
|
||||
|
@ -1449,7 +1540,7 @@ void EffectFrame::render( QRegion region, double opacity )
|
|||
{
|
||||
if( !m_textPicture ) // Lazy creation
|
||||
updateTextPicture();
|
||||
XRenderComposite( display(), PictOpOver, *m_textPicture, None, effects->xrenderBufferPicture(),
|
||||
XRenderComposite( display(), PictOpOver, *m_textPicture, fill, effects->xrenderBufferPicture(),
|
||||
0, 0, 0, 0, m_geometry.x(), m_geometry.y(), m_geometry.width(), m_geometry.height() );
|
||||
}
|
||||
}
|
||||
|
@ -1459,6 +1550,7 @@ void EffectFrame::render( QRegion region, double opacity )
|
|||
void EffectFrame::setPosition( const QPoint& point )
|
||||
{
|
||||
m_point = point;
|
||||
autoResize();
|
||||
}
|
||||
|
||||
void EffectFrame::setGeometry( const QRect& geometry, bool force )
|
||||
|
@ -1471,9 +1563,13 @@ void EffectFrame::setGeometry( const QRect& geometry, bool force )
|
|||
effects->addRepaint( m_geometry );
|
||||
if( !newSize && !force )
|
||||
return;
|
||||
qreal left, top, right, bottom;
|
||||
m_frame.getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
|
||||
m_frame.resizeFrame( m_geometry.adjusted( -left, -top, right, bottom ).size() );
|
||||
|
||||
if( m_style == Styled )
|
||||
{
|
||||
qreal left, top, right, bottom;
|
||||
m_frame.getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
|
||||
m_frame.resizeFrame( m_geometry.adjusted( -left, -top, right, bottom ).size() );
|
||||
}
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
if( effects->compositingType() == OpenGLCompositing )
|
||||
|
@ -1625,7 +1721,8 @@ void EffectFrame::updateTexture()
|
|||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
delete m_texture;
|
||||
m_texture = new GLTexture( m_frame.framePixmap() );
|
||||
if( m_style == Styled )
|
||||
m_texture = new GLTexture( m_frame.framePixmap() );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1656,7 +1753,7 @@ void EffectFrame::updateTextTexture()
|
|||
QPainter p( &pixmap );
|
||||
p.setFont( m_font );
|
||||
p.setPen( textColor() );
|
||||
p.drawText( rect, Qt::AlignCenter, text );
|
||||
p.drawText( rect, m_alignment, text );
|
||||
p.end();
|
||||
m_textTexture = new GLTexture( pixmap );
|
||||
#endif
|
||||
|
@ -1666,7 +1763,8 @@ void EffectFrame::updatePicture()
|
|||
{
|
||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||
delete m_picture;
|
||||
m_picture = new XRenderPicture( m_frame.framePixmap() );
|
||||
if( m_style == Styled )
|
||||
m_picture = new XRenderPicture( m_frame.framePixmap() );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1696,10 +1794,19 @@ void EffectFrame::updateTextPicture()
|
|||
QPainter p( &pixmap );
|
||||
p.setFont( m_font );
|
||||
p.setPen( textColor() );
|
||||
p.drawText( rect, Qt::AlignCenter, text );
|
||||
p.drawText( rect, m_alignment, text );
|
||||
p.end();
|
||||
m_textPicture = new XRenderPicture( pixmap );
|
||||
#endif
|
||||
}
|
||||
|
||||
void EffectFrame::updateUnstyledTexture()
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
delete m_unstyledTexture;
|
||||
QString filename = KGlobal::dirs()->findResource( "data", "kwin/circle.png" );
|
||||
m_unstyledTexture = new GLTexture( filename );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -714,6 +714,8 @@ class KWIN_EXPORT EffectsHandler
|
|||
virtual int shadowTextureList( ShadowType type ) const = 0;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see EffectFrame
|
||||
* Paints given text onto screen, possibly in elided form
|
||||
* @param text
|
||||
* @param center center point of the painted text
|
||||
|
@ -723,11 +725,23 @@ class KWIN_EXPORT EffectsHandler
|
|||
**/
|
||||
bool paintText( const QString& text, const QPoint& center, int maxwidth,
|
||||
const QColor& color, const QFont& font = QFont() );
|
||||
/**
|
||||
* @deprecated
|
||||
* @see EffectFrame
|
||||
*/
|
||||
bool paintText( const QString& text, const QRect& rect, const QColor& color,
|
||||
const QFont& font = QFont(), const Qt::Alignment& alignment = Qt::AlignCenter );
|
||||
/**
|
||||
* @deprecated
|
||||
* @see EffectFrame
|
||||
*/
|
||||
bool paintTextWithBackground( const QString& text, const QPoint& center, int maxwidth,
|
||||
const QColor& color, const QColor& bgcolor,
|
||||
const QFont& font = QFont() );
|
||||
/**
|
||||
* @deprecated
|
||||
* @see EffectFrame
|
||||
*/
|
||||
bool paintTextWithBackground( const QString& text, const QRect& rect, const QColor& color,
|
||||
const QColor& bgcolor, const QFont& font = QFont(),
|
||||
const Qt::Alignment& alignment = Qt::AlignCenter );
|
||||
|
@ -1551,6 +1565,11 @@ class KWIN_EXPORT WindowMotionManager
|
|||
* window.
|
||||
*/
|
||||
QRectF transformedGeometry( EffectWindow *w ) const;
|
||||
/**
|
||||
* Retrieve the current target geometry of a registered
|
||||
* window.
|
||||
*/
|
||||
QRectF targetGeometry( EffectWindow *w ) const;
|
||||
/**
|
||||
* Return the window that has it's transformed geometry under
|
||||
* the specified point. It is recommended to use the stacking
|
||||
|
@ -1592,22 +1611,32 @@ class KWIN_EXPORT WindowMotionManager
|
|||
};
|
||||
|
||||
/**
|
||||
* @short Helper class for painting themed boxes.
|
||||
* @short Helper class for displaying text and icons in frames.
|
||||
*
|
||||
* Paints a box using the default Plasma theme.
|
||||
* Paints text and/or and icon with an optional frame around them. The
|
||||
* available frames includes one that follows the default Plasma theme and
|
||||
* another that doesn't.
|
||||
* It is recommended to use this class whenever displaying text.
|
||||
*/
|
||||
class KWIN_EXPORT EffectFrame : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Style
|
||||
{
|
||||
None, ///< Displays no frame around the contents.
|
||||
Unstyled, ///< Displays a basic box around the contents.
|
||||
Styled ///< Displays a Plasma-styled frame around the contents.
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new frame object. If the frame does not have a static size
|
||||
* then it will be located at @a position with @a alignment. A
|
||||
* non-static frame will automatically adjust its size to fit the
|
||||
* contents.
|
||||
*/
|
||||
EffectFrame( bool staticSize = false, QPoint position = QPoint( -1, -1 ),
|
||||
EffectFrame( Style style, bool staticSize = true, QPoint position = QPoint( -1, -1 ),
|
||||
Qt::Alignment alignment = Qt::AlignCenter );
|
||||
~EffectFrame();
|
||||
|
||||
|
@ -1620,22 +1649,34 @@ class KWIN_EXPORT EffectFrame : public QObject
|
|||
/**
|
||||
* Render the frame.
|
||||
*/
|
||||
void render( QRegion region = infiniteRegion(), double opacity = 1.0 );
|
||||
void render( QRegion region = infiniteRegion(), double opacity = 1.0, double frameOpacity = 1.0 );
|
||||
|
||||
void setPosition( const QPoint& point );
|
||||
/**
|
||||
* Set the text alignment for static frames and the position alignment
|
||||
* for non-static.
|
||||
*/
|
||||
inline void setAlignment( Qt::Alignment alignment )
|
||||
{ m_alignment = alignment; }; // Doesn't change geometry
|
||||
void setGeometry( const QRect& geometry, bool force = false );
|
||||
QRect geometry() const // Inner/contents geometry
|
||||
inline QRect geometry() const // Inner/contents geometry
|
||||
{ return m_geometry; };
|
||||
|
||||
void setText( const QString& text );
|
||||
inline QString text() const
|
||||
{ return m_text; };
|
||||
void setFont( const QFont& font );
|
||||
inline QFont font() const
|
||||
{ return m_font; };
|
||||
/**
|
||||
* Set the icon that will appear on the left-hand size of the frame.
|
||||
*/
|
||||
void setIcon( const QPixmap& icon );
|
||||
inline QPixmap icon() const
|
||||
{ return m_icon; };
|
||||
void setIconSize( const QSize& size );
|
||||
inline QSize iconSize() const
|
||||
{ return m_iconSize; };
|
||||
|
||||
/**
|
||||
* The foreground text color as specified by the default Plasma theme.
|
||||
|
@ -1646,12 +1687,15 @@ class KWIN_EXPORT EffectFrame : public QObject
|
|||
void plasmaThemeChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY( EffectFrame ) // As we need to use Qt slots we cannot copy this class
|
||||
|
||||
void autoResize(); // Auto-resize if not a static size
|
||||
void updateTexture(); // Update OpenGL frame texture
|
||||
void updateTexture(); // Update OpenGL styled frame texture
|
||||
void updateTextTexture(); // Update OpenGL text texture
|
||||
void updatePicture(); // Update XRender frame picture
|
||||
void updatePicture(); // Update XRender styled frame picture
|
||||
void updateTextPicture(); // Update XRender text picture
|
||||
|
||||
Style m_style;
|
||||
Plasma::FrameSvg m_frame;
|
||||
GLTexture* m_texture;
|
||||
GLTexture* m_textTexture;
|
||||
|
@ -1669,6 +1713,9 @@ class KWIN_EXPORT EffectFrame : public QObject
|
|||
QFont m_font;
|
||||
QPixmap m_icon;
|
||||
QSize m_iconSize;
|
||||
|
||||
static GLTexture* m_unstyledTexture;
|
||||
static void updateUnstyledTexture(); // Update OpenGL unstyled frame texture
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -101,6 +101,13 @@ KWIN_EXPORT void renderGLGeometryImmediate( int count,
|
|||
int dim = 2, int stride = 0 );
|
||||
|
||||
|
||||
KWIN_EXPORT void addQuadVertices( QVector<float>& verts, float x1, float y1, float x2, float y2 );
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see EffectFrame
|
||||
*/
|
||||
KWIN_EXPORT void renderRoundBox( const QRect& area, float roundness = 10.0f, GLTexture* texture = 0 );
|
||||
/**
|
||||
* @deprecated
|
||||
|
|
Loading…
Reference in a new issue