void ButtonBuildStructure::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); if ( enabled() && m_Build.valid() ) { DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); // draw the eta to build this structure Font * pFont = windowStyle()->font(); if ( pFont != NULL ) { WideString eta; GameDocument * pDoc = (GameDocument *)document(); if ( pDoc != NULL ) { NounShip::Ref pShip = pDoc->ship(); if ( pShip.valid() ) { int buildTime = m_Build->buildTime()* pShip->calculateModifier(MT_BUILD_SPEED,true); eta.format( "%d:%2.2d", buildTime / 60, buildTime % 60); SizeInt etaSize( pFont->size( eta ) ); PointInt etaPos( window.right - etaSize.width, window.bottom - etaSize.height ); Font::push( context.display(), pFont, etaPos, eta, WHITE ); } } } } }
void WindowTree::onRenderItem( RenderContext & context, const RectInt & window, PointInt & pos, Item * pItem ) { WindowStyle * pStyle = windowStyle(); ASSERT( pStyle ); Font * pFont = windowStyle()->font(); ASSERT( pFont ); // get the depth of this item int depth = itemDepth( pItem ); // determine the X position based on it's depth pos.x = window.left + (depth * m_Indent); // get the size of the label text SizeInt labelSize( pFont->size( pItem->sLabel ) ); // determine the height of this item int height = (int)(labelSize.height + TREE_ITEM_BUFFER); RectInt itemRect( window.left, pos.y, window.right, pos.y + height ); // check if this item is highlighted or not if ( m_CursorInWindow && itemRect.inRect( m_LastCursorPosition ) ) onHighlight( pItem ); PrimitiveMaterial::push( context.display(), WHITE, PrimitiveMaterial::ALPHA ); if ( pItem->dwFlags & BUTTON ) { bool expanded = (pItem->dwFlags & EXPANDED) != 0; Color backColor( expanded ? pStyle->backColor() * TREE_SHADE_COLOR : pStyle->backColor() ); Color shadeColor( expanded ? pStyle->borderColor() * TREE_LIGHT_COLOR : pStyle->borderColor() * TREE_SHADE_COLOR ); Color lightColor( expanded ? pStyle->borderColor() * TREE_SHADE_COLOR : pStyle->borderColor() * TREE_LIGHT_COLOR ); // render the button pushBackground( context, itemRect, backColor, TREE_BUTTON_STYLE, TREE_BUTTON_BORDER ); pushBorder( context, itemRect, lightColor, shadeColor, TREE_BUTTON_STYLE, TREE_BUTTON_BORDER ); // draw glow around this object if the mouse is currently over this button if ( m_pCursorOver == pItem ) pushGlow( context, itemRect, TREE_GLOW_SIZE, TREE_GLOW_INNER, TREE_GLOW_OUTER, TREE_BUTTON_STYLE, TREE_BUTTON_BORDER ); // place the label in the center of the button PointInt labelPos( itemRect.center() - PointInt( labelSize.width / 2, labelSize.height / 2 ) ); // draw the label Font::push( context.display(), pFont, labelPos, pItem->sLabel, pItem->cColor ); } else { if ( m_pSelected == pItem ) pushBackground( context, itemRect, pStyle->highColor(), 0, 0 ); if ( m_pCursorOver == pItem ) pushGlow( context, itemRect, TREE_GLOW_SIZE, TREE_GLOW_INNER, TREE_GLOW_OUTER, 0, 0 ); PointInt labelPos( pos.x, (int)(pos.y + (TREE_ITEM_BUFFER / 2)) ); // render the label text` Font::push( context.display(), pFont, labelPos, pItem->sLabel, pItem->cColor ); } // move y down pos.y += (int)(height + WINDOW_TREE_SPACING); }
void ButtonUnit::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); if ( enabled() && m_Unit.valid() ) { GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); NounShip * pShip = pDoc->ship(); if (! pShip ) return; DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); // draw the gadget icon if ( m_Icon.valid() ) { RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 32, 16 ) ); RectFloat iconUV(0,0,1,1); Material::push( context, m_Icon ); PrimitiveWindow::push( pDisplay, iconBox, iconUV, pShip->isFriend( m_Unit ) ? GREEN : pShip->isEnemy( m_Unit ) ? RED : YELLOW ); } // draw the unit health on the button Font * pFont = windowStyle()->font(); ASSERT( pFont ); WideString sHealth; sHealth.format( STR("%d%%"), 100 - ((m_Unit->damage() * 100) / m_Unit->maxDamage()) ); SizeInt szHealth( pFont->size( sHealth ) ); PointInt ptHealth( window.right - szHealth.width, window.bottom - szHealth.height ); Font::push( context.display(), pFont, ptHealth, sHealth, WHITE ); // display damage bar if ( m_Unit->damage() > 0 ) { float damage = 1.0f - (m_Unit->damage() / m_Unit->maxDamage()); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); RectFloat barUV(0,0,1,1); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, barUV, barColor ); } // display blinking border if this unit is the current target if ( pDoc->target() == m_Unit && (pDoc->tick() % 10) < 6) renderGlow( context ); } }
void Material::createDevicePrimitives( RenderContext & context ) { DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); m_Material = NULL; // clear any previous primitive pDisplay->create( m_Material ); if ( context.alpha() < 1.0f ) { m_Material->setMaterial( Color( m_Diffuse.r, m_Diffuse.g, m_Diffuse.b, (u8)(context.alpha() * m_Diffuse.a) ), m_Ambient, m_Emissive, m_Specular, m_SpecularPower ); m_Material->setPass( DisplayDevice::SECONDARY ); if ( m_Blending == PrimitiveMaterial::NONE ) m_Material->setBlending( PrimitiveMaterial::ALPHA ); else m_Material->setBlending( m_Blending ); } else { m_Material->setMaterial( m_Diffuse, m_Ambient, m_Emissive, m_Specular, m_SpecularPower ); m_Material->setPass( m_nPass ); m_Material->setBlending( m_Blending ); } m_Material->setLightEnable( m_LightEnable ); m_Material->setDoubleSided( m_DoubleSided ); if ( m_sShader.length() > 0 ) m_Material->setShader( m_sShader ); if (! m_bSurfaceReady ) createDeviceSurfaces( context.display() ); // attach the surfaces to the material now if ( m_Surfaces.size() > 0 ) { Array< PrimitiveSurface::Ref > & surfaces = m_Surfaces[ 0 ]; ASSERT( surfaces.size() == m_Textures.size() ); for(int i=0;i<surfaces.size();++i) { Texture & texture = m_Textures[ i ]; m_Material->addSurface( surfaces[i], texture.m_eType, texture.m_nIndex, texture.m_nUV, texture.m_fParams ); } } m_nLastFrame = 0; m_fLastAlpha = context.alpha(); }
void WindowGadget::onRender( RenderContext & context, const RectInt & window ) { GameDocument * pDoc = (GameDocument *)document(); if ( pDoc != NULL && pDoc->gadgetTarget() != NULL ) { NounGadget * pTarget = pDoc->gadgetTarget(); // get the hull of the object float scale = 1.0f / pTarget->hull().radius(); // calculate the view direction from the players ship Vector3 view( cos(m_ActiveTime),-1,sin(m_ActiveTime) ); view.normalize(); Matrix33 cameraFrame( view ); cameraFrame = cameraFrame * pTarget->frame(); Vector3 cameraPosition( view * 4.0f ); // end previous scene context.endScene(); RenderContext::SaveState state( context ); // set up new render context context.setPosition( cameraPosition ); context.setFrame( cameraFrame ); context.setWindow( window ); context.setTime( pDoc->tick() * TICK_DURATION_S ); DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); // increase the ambient light so that the object is clearly visible pDisplay->setAmbient( WHITE ); // remove all lights from the render device pDisplay->clearLights(); // disable lights NodeLight::sm_bDisable = true; NodeSound::sm_bDisable = true; NounGadget::sm_bRenderGadgets = true; // render the target object pTarget->render( context, Matrix33::IDENTITY, Vector3::ZERO ); // enable lights NodeLight::sm_bDisable = false; NodeSound::sm_bDisable = false; NounGadget::sm_bRenderGadgets = false; context.endScene(); // restore the ambient light pDisplay->setAmbient( UNIVERSE_AMBIENT ); } }
void ViewEngineering::ButtonGadget::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); if ( enabled() ) { DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); Font * pFont = windowStyle()->font(); ASSERT( pFont ); // display damage percentage String status; status.format( "%d%%", int( m_rGadget->damageRatioInv() * 100) ); SizeInt stringSize( pFont->size( status ) ); PointInt stringPos( window.m_Right - stringSize.width, window.top ); Font::push( pDisplay, pFont, stringPos, status, YELLOW ); // display the damage bar if ( m_rGadget->damage() > 0 ) { if ( fmod( activeTime(), 1.0f ) < 0.5f ) // make the bar blink { float damage = m_rGadget->damageRatioInv(); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, DAMAGE_BAR_UV, barColor ); } } // display white blinking box around gadget currently at the top of the queue NounShip * pShip = WidgetCast<NounShip>( m_rGadget->parentBody() ); if ( pShip != NULL && pShip->repairCount() > 0 && pShip->repair( 0 ) == m_rGadget && fmod( activeTime(), 1.0f ) < 0.5f ) renderGlow( context ); } }
void ButtonCargo::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); if ( enabled() ) { Noun * pCargo = m_Cargo; ASSERT( pCargo ); // display white box around cargo if current target GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); if ( pDoc->target() == pCargo && (pDoc->tick() % 10) < 6 ) renderGlow( context ); if ( WidgetCast<CargoEnhancement>( pCargo ) ) { // show the durability if an enhancement.. CargoEnhancement * pCargoEnh = (CargoEnhancement *)pCargo; Font * pFont = windowStyle()->font(); ASSERT( pFont ); NounEnhancement * pEnhancement = pCargoEnh->enhancement(); if ( pEnhancement != NULL ) { int nMaxDamage = pEnhancement->maxDamage(); if ( nMaxDamage > 0 ) { WideString sQuantity; sQuantity.format( "%d/%d", nMaxDamage - pCargoEnh->damage(), nMaxDamage ); SizeInt stringSize( pFont->size( sQuantity ) ); PointInt stringPos( window.m_Right - stringSize.width, window.top ); Font::push( context.display(), pFont, stringPos, sQuantity, WHITE ); } } if ( ((CargoEnhancement *)pCargo)->quantity() <= 0 ) destroy(); } else if ( WidgetCast<NounCargo>( pCargo ) ) { // draw the quantity if cargo Font * pFont = windowStyle()->font(); ASSERT( pFont ); WideString sQuantity; sQuantity.format( "%d", ((NounCargo *)pCargo)->quantity() ); SizeInt stringSize( pFont->size( sQuantity ) ); PointInt stringPos( window.m_Right - stringSize.width, window.top ); Font::push( context.display(), pFont, stringPos, sQuantity, WHITE ); if ( ((NounCargo *)pCargo)->quantity() <= 0 ) destroy(); } else if ( WidgetCast<NounUnit>( pCargo ) ) { NounUnit * pUnit = (NounUnit *)pCargo; // draw the unit health on the button Font * pFont = windowStyle()->font(); ASSERT( pFont ); WideString sHealth; sHealth.format( "%d%%", 100 - ((pUnit->damage() * 100) / pUnit->maxDamage()) ); PointInt ptHealth( window.right - pFont->size( sHealth ).width, window.top ); Font::push( context.display(), pFont, ptHealth, sHealth, WHITE ); // display damage bar if ( pUnit->damage() > 0 ) { float damage = 1.0f - (pUnit->damage() / pUnit->maxDamage()); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); RectFloat barUV(0,0,1,1); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( context.display(), PrimitiveMaterial::NONE ); PrimitiveWindow::push( context.display(), bar, barUV, barColor ); } } } }
void WindowEdit::onRender( RenderContext & context, const RectInt & window ) { if (! windowStyle() ) return; DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); Font * pFont = windowStyle()->font(); ASSERT( pFont ); // calculate the total text size SizeInt textSize( pFont->size( WideString( m_Text ) ) ); // get the text color Color textColor( windowStyle()->color() ); textColor.m_A = m_Editing ? ACTIVE_ALPHA : INACTIVE_ALPHA; SizeInt windowSize( window.size() ); // check the size of the window compared to the text size m_EditBegin = 0; m_EditEnd = m_Text.length() - 1; while ( textSize.m_Width > windowSize.m_Width ) { if ( m_EditBegin < m_Cursor ) { textSize.m_Width -= pFont->characterWidth( m_Text[ m_EditBegin ] ); m_EditBegin++; } else if ( m_EditEnd > m_Cursor ) { textSize.m_Width -= pFont->characterWidth( m_Text[ m_EditEnd ] ); m_EditEnd--; } else // not enough room, the font is probably too large so just return return; } // extract the displayable part of the text WideString display( m_Text ); display.mid( m_EditBegin, (m_EditEnd - m_EditBegin) + 1 ); // draw text left justified and centered vertically PointInt ptText( window.m_Left, window.m_Top + ((windowSize.m_Height / 2) - (textSize.m_Height / 2)) ); // draw the text, construct another PointInt on the stack because Font::push will modify the point PointInt ptText2 = ptText; Font::push( pDisplay, pFont, ptText2, display, textColor ); // display cursor if editing if ( m_Editing ) { // draw cursor for(int i=m_EditBegin;i<m_Cursor;i++) ptText.m_X += pFont->characterWidth( m_Text[i] ); Color cursorColor( textColor ); cursorColor.m_A = (u8)(fmod( m_ActiveTime, CURSOR_BLINK_RATE ) * 255); RectInt cursorRect( ptText, SizeInt( CURSOR_WIDTH, textSize.height ) ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::ADDITIVE ); PrimitiveWindow::push( pDisplay, cursorRect , RectFloat(0,0,0,0), cursorColor ); } }
void WindowButton::onRender( RenderContext & context, const RectInt & window ) { int baseAlpha = m_Alpha * 255; int alpha = Clamp( baseAlpha + (enabled() ? (m_ButtonDown ? DOWN_ALPHA : m_CursorOver ? OVER_ALPHA : 0) : DISABLED_ALPHA) , 0, 255 ); // update the image frame if ( m_Button.valid() ) { static RectFloat buttonUV( 0, 0, 1, 1 ); // get the button color //Color buttonColor( m_ButtonDown ? windowStyle()->highColor() : windowStyle()->color() ); Color buttonColor( m_ButtonDown ? m_Color * 2.0f : m_Color ); buttonColor.m_A = alpha; if ( m_bGreyed ) buttonColor.greyscale(BUTTON_GREYED_SCALE); // if the button has multiple frames, set the time to display the correct frame if ( m_Button->frames() > 1 ) { ASSERT( m_Button->fps() > 0 ); int frame = 0; if ( m_Button->frames() == 2 ) frame = m_ButtonDown ? 1 : 0; else frame = m_ButtonDown ? 1 : m_CursorOver ? 2 : 0; m_Time = (1.0f / m_Button->fps()) * frame; } RectInt buttonRect( window ); if ( (m_Style & LOCK_ICON_SIZE) != 0 ) { int nDiffuse = m_Button->findTexture( PrimitiveSurface::DIFFUSE ); if ( nDiffuse >= 0 ) { SizeInt buttonSize( m_Button->texture( nDiffuse ).m_pImage->size() ); // keep button original size buttonRect.setWidth( buttonSize.width ); buttonRect.setHeight( buttonSize.height ); } } // flush the button material, so we can have different frames for each button m_Button->flushMaterial(); // save then change the context time float fContextTime = context.time(); context.setTime( m_Time ); // push the button material Material::push( context, m_Button ); // draw the button PrimitiveWindow::push( context.display(), buttonRect, buttonUV, buttonColor ); // restore the context time context.setTime( fContextTime ); } // display the label if ( m_Label.length() > 0 ) { String sLabel = m_Label; Font * pFont = windowStyle()->font(); ASSERT( pFont ); Color cLabel = labelColor(); if ( m_Style & EFFECT_FADEIN && visibleTime() < BUTTON_FADE_IN_TIME ) cLabel.a = (visibleTime() / BUTTON_FADE_IN_TIME) * 255; else cLabel.a = 255; SizeInt labelSize( pFont->size( sLabel ) ); PointInt labelPos( window.m_Left + ((window.width() / 2) - (labelSize.width / 2)), window.m_Top + ((window.height() / 2) - (labelSize.height / 2)) ); Font::push( context.display(), pFont, labelPos, sLabel, cLabel ); } // display hotkey in lower right corner if ( (m_Style & SHOW_HOTKEY) != 0 && m_HotKey != 0 ) { Font * pFont = windowStyle()->font(); ASSERT( pFont ); Color color( ((m_CursorOver || m_ButtonDown) && enabled()) ? windowStyle()->highColor() : windowStyle()->color() ); if ( m_Style & EFFECT_FADEIN && visibleTime() < BUTTON_FADE_IN_TIME ) color.a = (visibleTime() / BUTTON_FADE_IN_TIME) * 255; else color.a = 255; if ( m_bGreyed ) color.greyscale(BUTTON_GREYED_SCALE); String sKey( Keyboard::keyShortText( Keyboard::unmap( m_HotKey ) ) ); SizeInt textSize( pFont->size( sKey ) ); PointInt textPos( window.m_Right - textSize.width, window.m_Bottom - textSize.height ); Font::push( context.display(), pFont, textPos, sKey, color ); } }
void ButtonContact::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); NounShip * pShip = pDoc->ship(); if (! pShip ) return; WindowStyle * pStyle = windowStyle(); ASSERT( pStyle ); Font * pFont = pStyle->font(); ASSERT( pFont ); // get a pointer to our gadget Noun * pContact = m_Noun; if (! pContact ) return; RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 16, 16 ) ); Color iconColor( YELLOW ); if ( pShip->isFriend( pContact ) ) iconColor = GREEN; else if ( pShip->isEnemy( pContact ) ) iconColor = RED; // draw the gadget icon Material::push( context, m_Icon ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, iconColor ); if ( WidgetCast<NounShip>( pContact ) && ((NounShip *)pContact)->canOrder( pShip ) ) { Material::push( context, WidgetCast<Material>( resource("team") ) ); iconBox += PointInt( 16, 0 ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, WHITE ); } else if ( m_IsObjective ) { Material::push( context, WidgetCast<Material>( resource("objective") ) ); iconBox += PointInt( 16, 0 ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, WHITE ); } // display status text CharString sStatus = pContact->displayName( false ); if ( m_HotKey != 0 ) sStatus = CharString().format("%c:%s", m_HotKey, sStatus ); if ( sStatus.length() > 0 ) { SizeInt stringSize( pFont->size( sStatus ) ); // make sure the text fits on the label while( stringSize.width > (BUTTON_WIDTH - 5 ) ) { // remove the right most character and check the width again sStatus.left( sStatus.length() - 1 ); stringSize = pFont->size( sStatus ); } PointInt stringPos( window.m_Right - stringSize.width, window.m_Bottom - stringSize.height ); Font::push( pDisplay, pFont, stringPos, sStatus, m_bGroupLeader ? YELLOW : (m_bGroupPending ? GREY : WHITE) ); } // display the damage bar if ( WidgetCast<NounShip>( pContact ) ) { if ( ((NounShip *)pContact)->damage() > 0 ) { float damage = ((NounShip *)pContact)->damageRatioInv(); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, barColor ); } } // render additional border if this contact is our current target if ( pDoc->rootTarget() == m_Noun && (pDoc->tick() % 10) < 6 ) renderGlow( context ); }
void ButtonGadget::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); // get a pointer to our gadget NounGadget * pGadget = m_Gadget; if ( pGadget != NULL ) { DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); WindowStyle * pStyle = windowStyle(); ASSERT( pStyle ); Font * pFont = pStyle->font(); ASSERT( pFont ); // display bar if gadget has delay before usabled int delay = pGadget->usableWhen(); if ( delay > 0 ) { if ( (pDoc->tick() % 10) < 6 ) // make the bar blink { RectInt bar( window.left, window.top, window.right - ((window.width() * delay) / 100), window.top + 16 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::ADDITIVE ); PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, Color(0,0,255,255) ); } } // draw the gadget icon Material * pIcon = pGadget->icon(); if ( pIcon != NULL ) { RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 32, 16 ) ); Material::push( context, pIcon ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, m_IconColor ); } // display any gadget status text WideString sStatus( pGadget->status() ); if ( sStatus.length() > 0 ) { SizeInt stringSize( pFont->size( sStatus ) ); Font::push( pDisplay, pFont, PointInt( window.m_Right - stringSize.width, window.top ), sStatus, YELLOW ); } // display hotkey in lower-left corner of button CharString sHotKey; if ( pGadget->hotkey() != 0 && pGadget->hotkey() != HK_SPACE ) sHotKey += keyText( Keyboard::unmap( pGadget->hotkey() ) ); if ( m_Gadget->group() != 0 ) sHotKey += CharString().format(" %c", m_Gadget->group() ); if ( WidgetCast<GadgetBeamWeapon>( pGadget ) && ((GadgetBeamWeapon *)pGadget)->pointDefense() ) sHotKey += " PD"; if ( sHotKey.length() > 0 ) { WideString sWide = sHotKey; SizeInt stringSize( pFont->size( sWide ) ); Font::push( pDisplay, pFont, PointInt( window.m_Right - stringSize.width, window.m_Bottom - stringSize.height ), sWide, YELLOW ); } // display the damage bar if ( pGadget->damage() > 0 ) { if ( (pDoc->tick() % 10) < 6 ) // make the bar blink { float damage = pGadget->damageRatioInv(); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, barColor ); } } // blink a white border if this is the current target if ( pDoc->target() == m_Gadget && (pDoc->tick() % 10) < 6 ) renderGlow( context ); } }