Example #1
0
void QDirectFbBlitter::drawPixmapOpacity(const QRectF &rect, const QPixmap &pixmap, const QRectF &subrect, QPainter::CompositionMode cmode, qreal opacity)
{
    QRect sQRect = subrect.toRect();
    QRect dQRect = rect.toRect();
    DFBRectangle sRect(sQRect.x(), sQRect.y(), sQRect.width(), sQRect.height());
    DFBRectangle dRect(dQRect.x(), dQRect.y(), dQRect.width(), dQRect.height());
    DFBResult result;

    // skip if dst too small
    if ((dRect.w <= 0) || (dRect.h <= 0)) return;

    // correct roundings if needed
    if (sRect.w <= 0) sRect.w = 1;
    if (sRect.h <= 0) sRect.h = 1;

    QDirectFbBlitterPlatformPixmap *blitPm = static_cast<QDirectFbBlitterPlatformPixmap *>(pixmap.handle());
    QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable());
    dfbBlitter->unlock();

    IDirectFBSurface *s = dfbBlitter->m_surface.data();

    DFBSurfaceBlittingFlags blittingFlags = DFBSurfaceBlittingFlags(DSBLIT_BLEND_ALPHACHANNEL);
    DFBSurfacePorterDuffRule porterDuff = (cmode == QPainter::CompositionMode_SourceOver) ? DSPD_SRC_OVER : DSPD_SRC;

    if (opacity != 1.0)
    {
        blittingFlags = DFBSurfaceBlittingFlags(blittingFlags | DSBLIT_BLEND_COLORALPHA | (m_premult ? DSBLIT_SRC_PREMULTCOLOR : 0));
        m_surface->SetColor(m_surface.data(), 0xff, 0xff, 0xff, (u8) (opacity * 255.0));
    }

    m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(blittingFlags));
    m_surface->SetPorterDuff(m_surface.data(), porterDuff);

    if (cmode == QPainter::CompositionMode_SourceOver)
        m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA);

    if ((sRect.w == dRect.w) && (sRect.h == dRect.h)) {
        result = m_surface->Blit(m_surface.data(), s, &sRect, dRect.x, dRect.y);
        if (result != DFB_OK)
            DirectFBError("QDirectFBBlitter::drawPixmapOpacity()", result);
        if (m_debugPaint)
            drawDebugRect(QRect(dRect.x, dRect.y, sRect.w, sRect.h), QColor(Qt::green));
    } else {
        result = m_surface->StretchBlit(m_surface.data(), s, &sRect, &dRect);
        if (result != DFB_OK)
            DirectFBError("QDirectFBBlitter::drawPixmapOpacity()", result);
        if (m_debugPaint)
            drawDebugRect(QRect(dRect.x, dRect.y, dRect.w, dRect.h), QColor(Qt::red));
    }
}
void LLJoystickCameraRotate::draw()
{
	LLGLSUIDefault gls_ui;

	getImageUnselected()->draw( 0, 0 );

	if( mInTop )
	{
		drawRotatedImage( getImageSelected()->getImage(), 0 );
	}

	if( mInRight )
	{
		drawRotatedImage( getImageSelected()->getImage(), 1 );
	}

	if( mInBottom )
	{
		drawRotatedImage( getImageSelected()->getImage(), 2 );
	}

	if( mInLeft )
	{
		drawRotatedImage( getImageSelected()->getImage(), 3 );
	}

	if (sDebugRects)
	{
		drawDebugRect();
	}
}
Example #3
0
void LLTextBox::draw()
{
	if (mBorderVisible)
	{
		gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
	}

	if( mBorderDropShadowVisible )
	{
		static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow");
		static S32 drop_shadow_tooltip = LLUI::sConfigGroup->getS32("DropShadowTooltip");
		gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
			color_drop_shadow, drop_shadow_tooltip);
	}

	if (mBackgroundVisible)
	{
		LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
		gl_rect_2d( r, mBackgroundColor );
	}

	S32 text_x = 0;
	switch( mHAlign )
	{
	case LLFontGL::LEFT:	
		text_x = mHPad;						
		break;
	case LLFontGL::HCENTER:
		text_x = getRect().getWidth() / 2;
		break;
	case LLFontGL::RIGHT:
		text_x = getRect().getWidth() - mHPad;
		break;
	}

	S32 text_y = getRect().getHeight() - mVPad;

	if ( getEnabled() )
	{
		if(mHasHover)
		{
			drawText( text_x, text_y, mHoverColor );
		}
		else
		{
			drawText( text_x, text_y, mTextColor );
		}				
	}
	else
	{
		drawText( text_x, text_y, mDisabledColor );
	}

	if (sDebugRects)
	{
		drawDebugRect();
	}

	mHasHover = FALSE; // This is reset every frame.
}
void LLJoystickCameraZoom::draw()
{
	if( mInTop )
	{
		mPlusInImage->draw(0,0);
	}
	else
	if( mInBottom )
	{
		mMinusInImage->draw(0,0);
	}
	else
	{
		getImageUnselected()->draw( 0, 0 );
	}

	if (sDebugRects)
	{
		drawDebugRect();
	}
}
Example #5
0
void QDirectFbBlitter::alphaFillRect(const QRectF &rect, const QColor &color, QPainter::CompositionMode cmode)
{
    int x, y, w, h;
    DFBResult result;

    // check parameters
    rect.toRect().getRect(&x, &y ,&w, &h);
    if ((w <= 0) || (h <= 0)) return;

    if ((cmode == QPainter::CompositionMode_Source) || (color.alpha() == 255)) {
        // CompositionMode_Source case or CompositionMode_SourceOver with opaque color

        m_surface->SetDrawingFlags(m_surface.data(),
            DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_NOFX | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_NOFX));
        m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC);

    } else {
        // CompositionMode_SourceOver case

        // check if operation is useless
        if (color.alpha() == 0)
            return;

        m_surface->SetDrawingFlags(m_surface.data(),
            DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_BLEND));
        m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC_OVER);
    }

    // set color
    m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha());

    // perform fill
    result = m_surface->FillRectangle(m_surface.data(), x, y, w, h);
    if (result != DFB_OK)
        DirectFBError("QDirectFBBlitter::alphaFillRect()", result);
    if (m_debugPaint)
        drawDebugRect(QRect(x, y, w, h), QColor(Qt::blue));
}
Example #6
0
// virtual
void LLButton::draw()
{
	BOOL flash = FALSE;
	if( mFlashing )
	{
		F32 elapsed = mFlashingTimer.getElapsedTimeF32();
		S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f);
		// flash on or off?
		flash = (flash_count % 2 == 0) || flash_count > S32((F32)LLUI::sConfigGroup->getS32("ButtonFlashCount") * 2.f);
	}

	BOOL pressed_by_keyboard = FALSE;
	if (hasFocus())
	{
		pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
	}

	// Unselected image assignments
	S32 local_mouse_x;
	S32 local_mouse_y;
	LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);

	BOOL pressed = pressed_by_keyboard 
					|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) 
					|| mToggleState;
	
	BOOL use_glow_effect = FALSE;
	LLColor4 glow_color = LLColor4::white;
	LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
	if ( mNeedsHighlight )
	{
		if (pressed)
		{
			if (mImageHoverSelected)
			{
				mImagep = mImageHoverSelected;
			}
			else
			{
				mImagep = mImageSelected;
				use_glow_effect = TRUE;
			}
		}
		else
		{
			if (mImageHoverUnselected)
			{
				mImagep = mImageHoverUnselected;
			}
			else
			{
				mImagep = mImageUnselected;
				use_glow_effect = TRUE;
			}
		}
	}
	else if ( pressed )
	{
		mImagep = mImageSelected;
	}
	else
	{
		mImagep = mImageUnselected;
	}

	if (mFlashing)
	{
		use_glow_effect = TRUE;
		glow_type = LLRender::BT_ALPHA; // blend the glow
		if (mNeedsHighlight) // highlighted AND flashing
			glow_color = (glow_color*0.5f + mFlashBgColor*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
		else
			glow_color = mFlashBgColor;
	}

	// Override if more data is available
	// HACK: Use gray checked state to mean either:
	//   enabled and tentative
	// or
	//   disabled but checked
	if (!mImageDisabledSelected.isNull() 
		&& 
			( (getEnabled() && getTentative()) 
			|| (!getEnabled() && pressed ) ) )
	{
		mImagep = mImageDisabledSelected;
	}
	else if (!mImageDisabled.isNull() 
		&& !getEnabled() 
		&& !pressed)
	{
		mImagep = mImageDisabled;
	}

	if (mNeedsHighlight && !mImagep)
	{
		use_glow_effect = TRUE;
	}

	// Figure out appropriate color for the text
	LLColor4 label_color;

	// label changes when button state changes, not when pressed
	if ( getEnabled() )
	{
		if ( mToggleState )
		{
			label_color = mSelectedLabelColor;
		}
		else
		{
			label_color = mUnselectedLabelColor;
		}
	}
	else
	{
		if ( mToggleState )
		{
			label_color = mDisabledSelectedLabelColor;
		}
		else
		{
			label_color = mDisabledLabelColor;
		}
	}

	// Unselected label assignments
	LLWString label;

	if( mToggleState )
	{
		if( getEnabled() || mDisabledSelectedLabel.empty() )
		{
			label = mSelectedLabel;
		}
		else
		{
			label = mDisabledSelectedLabel;
		}
	}
	else
	{
		if( getEnabled() || mDisabledLabel.empty() )
		{
			label = mUnselectedLabel;
		}
		else
		{
			label = mDisabledLabel;
		}
	}

	// overlay with keyboard focus border
	if (hasFocus())
	{
		F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
		drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
	}
	
	if (use_glow_effect)
	{
		mCurGlowStrength = lerp(mCurGlowStrength,
					mFlashing ? (flash? 1.0 : 0.0)
					: mHoverGlowStrength,
					LLCriticalDamp::getInterpolant(0.05f));
	}
	else
	{
		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
	}

	// Draw button image, if available.
	// Otherwise draw basic rectangular button.
	if (mImagep.notNull())
	{
		if ( mScaleImage)
		{
			mImagep->draw(getLocalRect(), getEnabled() ? mImageColor : mDisabledImageColor  );
			if (mCurGlowStrength > 0.01f)
			{
				gGL.setSceneBlendType(glow_type);
				mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % mCurGlowStrength);
				gGL.setSceneBlendType(LLRender::BT_ALPHA);
			}
		}
		else
		{
			mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor );
			if (mCurGlowStrength > 0.01f)
			{
				gGL.setSceneBlendType(glow_type);
				mImagep->drawSolid(0, 0, glow_color % mCurGlowStrength);
				gGL.setSceneBlendType(LLRender::BT_ALPHA);
			}
		}
	}
	else
	{
		// no image
		llwarns << "No image for button " << getName() << llendl;
		// draw it in pink so we can find it
		gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE);
	}

	// let overlay image and text play well together
	S32 text_left = mLeftHPad;
	S32 text_right = getRect().getWidth() - mRightHPad;
	S32 text_width = getRect().getWidth() - mLeftHPad - mRightHPad;
	S32 text_middle = text_left + text_width/2;

	// draw overlay image
	if (mImageOverlay.notNull() && mImageOverlay->getWidth() > 1)
	{
		// get max width and height (discard level 0)
		S32 overlay_width = mImageOverlay->getWidth();
		S32 overlay_height = mImageOverlay->getHeight();

		F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
		overlay_width = llround((F32)overlay_width * scale_factor);
		overlay_height = llround((F32)overlay_height * scale_factor);

		S32 center_x = getLocalRect().getCenterX();
		S32 center_y = getLocalRect().getCenterY();

		//FUGLY HACK FOR "DEPRESSED" BUTTONS
		if (pressed)
		{
			center_y--;
			center_x++;
		}

		// fade out overlay images on disabled buttons
		LLColor4 overlay_color = mImageOverlayColor;
		if (!getEnabled())
		{
			overlay_color.mV[VALPHA] = 0.5f;
		}

		switch(mImageOverlayAlignment)
		{
		case LLFontGL::LEFT:
			text_left += overlay_width + 1;
			text_width -= overlay_width + 1;
			text_middle += (overlay_width+1)/4;
			mImageOverlay->draw(
				mLeftHPad, 
				center_y - (overlay_height / 2), 
				overlay_width, 
				overlay_height, 
				overlay_color);
			break;
		case LLFontGL::HCENTER:
			mImageOverlay->draw(
				center_x - (overlay_width / 2), 
				center_y - (overlay_height / 2), 
				overlay_width, 
				overlay_height, 
				overlay_color);
			break;
		case LLFontGL::RIGHT:
			text_right -= overlay_width + 1;				
			text_width -= overlay_width + 1;
			text_middle += (overlay_width+1)/4;
			mImageOverlay->draw(
				getRect().getWidth() - mRightHPad - overlay_width, 
				center_y - (overlay_height / 2), 
				overlay_width, 
				overlay_height, 
				overlay_color);
			break;
		default:
			// draw nothing
			break;
		}
	}

	// Draw label
	if( !label.empty() )
	{
		LLWStringUtil::trim(label);

		S32 x;
		switch( mHAlign )
		{
		case LLFontGL::RIGHT:
			x = text_right;
			break;
		case LLFontGL::HCENTER:
			{
				S32 actual_width = mGLFont->getWidth(label.c_str());
				x = llmax(text_middle, text_left + actual_width/2);
			}
			break;
		case LLFontGL::LEFT:
		default:
			x = text_left;
			break;
		}

		S32 y_offset = 2 + (getRect().getHeight() - 20)/2;
	
		if (pressed)
		{
			y_offset--;
			x++;
		}


		mGLFont->render(label, 0, 
			(F32)x, 
			(F32)(LLBUTTON_V_PAD + y_offset), 
			label_color,
			mHAlign, LLFontGL::BOTTOM,
			LLFontGL::NORMAL,
			mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,
			U32_MAX, text_width,
			NULL, FALSE, FALSE);
	}

	if (sDebugRects	
		|| (LLView::sEditingUI && this == LLView::sEditingUIView))
	{
		drawDebugRect();
	}

	// reset hover status for next frame
	mNeedsHighlight = FALSE;
}
Example #7
0
bool QDirectFbBlitter::drawCachedGlyphs(const QPaintEngineState *state, QFontEngine::GlyphFormat glyphFormat, int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine)
{
    void *cacheKey = QDirectFbConvenience::dfbInterface();

    QDirectFbTextureGlyphCache *cache =
            static_cast<QDirectFbTextureGlyphCache *>(fontEngine->glyphCache(cacheKey, glyphFormat, state->transform()));
    if (!cache) {
        cache = new QDirectFbTextureGlyphCache(glyphFormat, state->transform());
        fontEngine->setGlyphCache(cacheKey, cache);
    }

    cache->populate(fontEngine, numGlyphs, glyphs, positions);
    cache->fillInPendingGlyphs();

    if (cache->image().width() == 0 || cache->image().height() == 0)
        return false;

    const int margin = fontEngine->glyphMargin(glyphFormat);

    QVarLengthArray<DFBRectangle, 64> sourceRects(numGlyphs);
    QVarLengthArray<DFBPoint, 64> destPoints(numGlyphs);
    int nGlyphs = 0;

    for (int i=0; i<numGlyphs; ++i) {

        QFixed subPixelPosition = fontEngine->subPixelPositionForX(positions[i].x);
        QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
        const QTextureGlyphCache::Coord &c = cache->coords[glyph];
        if (c.isNull())
            continue;

        int x = qFloor(positions[i].x) + c.baseLineX - margin;
        int y = qRound(positions[i].y) - c.baseLineY - margin;

        // printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
        //        c.x, c.y,
        //        c.w, c.h,
        //        c.baseLineX, c.baseLineY,
        //        glyphs[i],
        //        x, y,
        //        positions[i].x.toInt(), positions[i].y.toInt());

        sourceRects[nGlyphs].x = c.x;
        sourceRects[nGlyphs].y = c.y;
        sourceRects[nGlyphs].w = c.w;
        sourceRects[nGlyphs].h = c.h;
        destPoints[nGlyphs].x = x;
        destPoints[nGlyphs].y = y;
        ++nGlyphs;
    }

    const QColor color = state->pen().color();
    m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha());

    m_surface->SetSrcBlendFunction(m_surface.data(), DSBF_SRCALPHA);
    m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA);

    int flags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE;
    if (color.alpha() != 0xff)
        flags |= DSBLIT_BLEND_COLORALPHA;
    m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(flags));

    const QRasterPaintEngineState *rs = static_cast<const QRasterPaintEngineState*>(state);
    if (rs->clip && rs->clip->enabled) {
        Q_ASSERT(rs->clip->hasRectClip);
        DFBRegion dfbClip;
        dfbClip.x1 = rs->clip->clipRect.x();
        dfbClip.y1 = rs->clip->clipRect.y();
        dfbClip.x2 = rs->clip->clipRect.right();
        dfbClip.y2 = rs->clip->clipRect.bottom();
        m_surface->SetClip(m_surface.data(), &dfbClip);
    }

    m_surface->BatchBlit(m_surface.data(), cache->sourceSurface(), sourceRects.constData(), destPoints.constData(), nGlyphs);

    if (m_debugPaint) {
        for (int i = 0; i < nGlyphs; ++i) {
            drawDebugRect(QRect(destPoints[i].x, destPoints[i].y, sourceRects[i].w, sourceRects[i].h), QColor(Qt::yellow));
        }
    }

    if (rs->clip && rs->clip->enabled)
        m_surface->SetClip(m_surface.data(), 0);
    return true;
}
Example #8
0
// virtual
void LLButton::draw()
{
	if( getVisible() ) 
	{
		BOOL flash = FALSE;
		if( mFlashing )
		{
			F32 elapsed = mFlashingTimer.getElapsedTimeF32();
			S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f);
			// flash on or off?
			flash = (flash_count % 2 == 0) || flash_count > (F32)LLUI::sConfigGroup->getS32("ButtonFlashCount");
		}

		BOOL pressed_by_keyboard = FALSE;
		if (hasFocus())
		{
			pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
		}

		// Unselected image assignments
		S32 local_mouse_x;
		S32 local_mouse_y;
		LLCoordWindow cursor_pos_window;
		getWindow()->getCursorPosition(&cursor_pos_window);
		LLCoordGL cursor_pos_gl;
		getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
		cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
		cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
		screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);

		BOOL pressed = pressed_by_keyboard 
						|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) 
						|| mToggleState;
		
		BOOL use_glow_effect = FALSE;
		if ( mNeedsHighlight || flash )
		{
			if (pressed)
			{
				if (mImageHoverSelected)
				{
					mImagep = mImageHoverSelected;
				}
				else
				{
					mImagep = mImageSelected;
					use_glow_effect = TRUE;
				}
			}
			else
			{
				if (mImageHoverUnselected)
				{
					mImagep = mImageHoverUnselected;
				}
				else
				{
					mImagep = mImageUnselected;
					use_glow_effect = TRUE;
				}
			}
		}
		else if ( pressed )
		{
			mImagep = mImageSelected;
		}
		else
		{
			mImagep = mImageUnselected;
		}

		// Override if more data is available
		// HACK: Use gray checked state to mean either:
		//   enabled and tentative
		// or
		//   disabled but checked
		if (!mImageDisabledSelected.isNull() && ( (mEnabled && mTentative) || (!mEnabled && pressed ) ) )
		{
			mImagep = mImageDisabledSelected;
		}
		else if (!mImageDisabled.isNull() && !mEnabled && !pressed)
		{
			mImagep = mImageDisabled;
		}

		if (mNeedsHighlight && !mImagep)
		{
			use_glow_effect = TRUE;
		}

		// Figure out appropriate color for the text
		LLColor4 label_color;

		// label changes when button state changes, not when pressed
		if ( mEnabled )
		{
			if ( mToggleState )
			{
				label_color = mSelectedLabelColor;
			}
			else
			{
				label_color = mUnselectedLabelColor;
			}
		}
		else
		{
			if ( mToggleState )
			{
				label_color = mDisabledSelectedLabelColor;
			}
			else
			{
				label_color = mDisabledLabelColor;
			}
		}

		// Unselected label assignments
		LLWString label;

		if( mToggleState )
		{
			if( mEnabled || mDisabledSelectedLabel.empty() )
			{
				label = mSelectedLabel;
			}
			else
			{
				label = mDisabledSelectedLabel;
			}
		}
		else
		{
			if( mEnabled || mDisabledLabel.empty() )
			{
				label = mUnselectedLabel;
			}
			else
			{
				label = mDisabledLabel;
			}
		}
		
		// draw default button border
		if (mEnabled && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel
		{
			drawBorder(LLUI::sColorsGroup->getColor( "ButtonBorderColor" ), BORDER_SIZE);
		}

		// overlay with keyboard focus border
		if (hasFocus())
		{
			F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
			drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
		}
		
		if (use_glow_effect)
		{
			mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
		}
		else
		{
			mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
		}

		// Draw button image, if available.
		// Otherwise draw basic rectangular button.
		if( mImagep.notNull() && !mScaleImage)
		{
			mImagep->draw(0, 0, mEnabled ? mImageColor : mDisabledImageColor );
			if (mCurGlowStrength > 0.01f)
			{
				glBlendFunc(GL_SRC_ALPHA, GL_ONE);
				mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			}
		}
		else
		if ( mImagep.notNull() && mScaleImage)
		{
			mImagep->draw(0, 0, mRect.getWidth(), mRect.getHeight(), mEnabled ? mImageColor : mDisabledImageColor  );
			if (mCurGlowStrength > 0.01f)
			{
				glBlendFunc(GL_SRC_ALPHA, GL_ONE);
				mImagep->drawSolid(0, 0, mRect.getWidth(), mRect.getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			}
		}
		else
		{
			// no image
			llwarns << "No image for button " << mName << llendl;
			// draw it in pink so we can find it
			gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE);
		}

		// let overlay image and text play well together
		S32 text_left = mLeftHPad;
		S32 text_right = mRect.getWidth() - mRightHPad;
		S32 text_width = mRect.getWidth() - mLeftHPad - mRightHPad;

		// draw overlay image
		if (mImageOverlay.notNull())
		{
			// get max width and height (discard level 0)
			S32 overlay_width = mImageOverlay->getWidth();
			S32 overlay_height = mImageOverlay->getHeight();

			F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f);
			overlay_width = llround((F32)overlay_width * scale_factor);
			overlay_height = llround((F32)overlay_height * scale_factor);

			S32 center_x = getLocalRect().getCenterX();
			S32 center_y = getLocalRect().getCenterY();

			//FUGLY HACK FOR "DEPRESSED" BUTTONS
			if (pressed)
			{
				center_y--;
				center_x++;
			}

			// fade out overlay images on disabled buttons
			LLColor4 overlay_color = mImageOverlayColor;
			if (!getEnabled())
			{
				overlay_color.mV[VALPHA] = 0.5f;
			}

			switch(mImageOverlayAlignment)
			{
			case LLFontGL::LEFT:
				text_left += overlay_width + 1;
				text_width -= overlay_width + 1;
				mImageOverlay->draw(
					mLeftHPad, 
					center_y - (overlay_height / 2), 
					overlay_width, 
					overlay_height, 
					overlay_color);
				break;
			case LLFontGL::HCENTER:
				mImageOverlay->draw(
					center_x - (overlay_width / 2), 
					center_y - (overlay_height / 2), 
					overlay_width, 
					overlay_height, 
					overlay_color);
				break;
			case LLFontGL::RIGHT:
				text_right -= overlay_width + 1;				
				text_width -= overlay_width + 1;
				mImageOverlay->draw(
					mRect.getWidth() - mRightHPad - overlay_width, 
					center_y - (overlay_height / 2), 
					overlay_width, 
					overlay_height, 
					overlay_color);
				break;
			default:
				// draw nothing
				break;
			}
		}

		// Draw label
		if( !label.empty() )
		{
			LLWString::trim(label);

			S32 x;
			switch( mHAlign )
			{
			case LLFontGL::RIGHT:
				x = text_right;
				break;
			case LLFontGL::HCENTER:
				x = mRect.getWidth() / 2;
				break;
			case LLFontGL::LEFT:
			default:
				x = text_left;
				break;
			}

			S32 y_offset = 2 + (mRect.getHeight() - 20)/2;
		
			if (pressed)
			{
				y_offset--;
				x++;
			}

			mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset), 
				label_color,
				mHAlign, LLFontGL::BOTTOM,
				mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL,
				U32_MAX, text_width,
				NULL, FALSE, FALSE);
		}

		if (sDebugRects	
			|| (LLView::sEditingUI && this == LLView::sEditingUIView))
		{
			drawDebugRect();
		}
	}
	// reset hover status for next frame
	mNeedsHighlight = FALSE;
}
void LLScrollableContainerView::draw()
{
	if (mAutoScrolling)
	{
		// add acceleration to autoscroll
		mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE);
	}
	else
	{
		// reset to minimum
		mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
	}
	// clear this flag to be set on next call to handleDragAndDrop
	mAutoScrolling = FALSE;

	// auto-focus when scrollbar active
	// this allows us to capture user intent (i.e. stop automatically scrolling the view/etc)
	if (!gFocusMgr.childHasKeyboardFocus(this) && 
		(mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
	{
		focusFirstItem();
	}

	// Draw background
	if( mIsOpaque )
	{
		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
		gGL.color4fv( mBackgroundColor.mV );
		gl_rect_2d( mInnerRect );
	}
	
	// Draw mScrolledViews and update scroll bars.
	// get a scissor region ready, and draw the scrolling view. The
	// scissor region ensures that we don't draw outside of the bounds
	// of the rectangle.
	if( mScrolledView )
	{
		updateScroll();

		// Draw the scrolled area.
		{
			S32 visible_width = 0;
			S32 visible_height = 0;
			BOOL show_v_scrollbar = FALSE;
			BOOL show_h_scrollbar = FALSE;
			calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );

			LLLocalClipRect clip(LLRect(mInnerRect.mLeft, 
					mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
					visible_width,
					mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
					));
			drawChild(mScrolledView);
		}
	}

	// Highlight border if a child of this container has keyboard focus
	if( mBorder->getVisible() )
	{
		mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
	}

	// Draw all children except mScrolledView
	// Note: scrollbars have been adjusted by above drawing code
	for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
		 child_iter != getChildList()->rend(); ++child_iter)
	{
		LLView *viewp = *child_iter;
		if( sDebugRects )
		{
			sDepth++;
		}
		if( (viewp != mScrolledView) && viewp->getVisible() )
		{
			drawChild(viewp);
		}
		if( sDebugRects )
		{
			sDepth--;
		}
	}

	if (sDebugRects)
	{
		drawDebugRect();
	}

} // end draw