Пример #1
0
	SizeInt Viewer::calculateCappedImageSize( const SizeInt& imageSize, const SizeInt &windowEdges ) {
		wxDisplay display(DisplayFromPointFallback(PositionScreen()));
		auto rtDesktop = wxToRect(display.GetClientArea());

		return SizeInt(
			std::max<int>(MinWindowWidth,  std::min<int>(rtDesktop.Width(), imageSize.Width + windowEdges.Width)),
			std::max<int>(MinWindowHeight,	std::min<int>(rtDesktop.Height(),imageSize.Height + windowEdges.Height)));
	}
Пример #2
0
	SizeInt Viewer::calculateImageSize( ResizeBehaviour mode, float xratio, float yratio, const SizeInt &imageSize, const SizeInt &windowEdges ) {
		wxDisplay display(DisplayFromPointFallback(PositionScreen()));
		auto rtDesktop = wxToRect(display.GetClientArea());

		// The image is larger than the desktop. The image is not supposed
		// to be downscaled so fill the screen.
		if ((mode == ResizeEnlargeOnly) && (xratio < 1.0) && (yratio < 1.0))
			return rtDesktop.Dimensions();
		// The image is smaller than the desktop. It must not be made
		// smaller needlessly so size the window after the image.
		else if ((mode == ResizeReduceOnly) && (xratio > 1.0) && (yratio > 1.0))
			return SizeInt(
				std::max<int>(MinWindowWidth, imageSize.Width + windowEdges.Width),
				std::max<int>(MinWindowHeight,imageSize.Height + windowEdges.Height));

		return Maximum(SizeInt(MinWindowWidth, MinWindowHeight), Minimum(RoundCast(imageSize * std::min(xratio, yratio)) + windowEdges, rtDesktop.Dimensions()));
	}
Пример #3
0
ButtonUnit::ButtonUnit()
{
	m_Flags |= NOCLIP;
	m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL;
	m_Alpha = 0.75f;

	setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) );
	setEnable( false );
}
Пример #4
0
ViewEngineering::ButtonGadget::ButtonGadget() 
{
	m_Flags |= NOCLIP;
	m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL | LOCK_ICON_SIZE;
	m_Alpha = 0.75f;

	setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) );
	setEnable( false );
}
Пример #5
0
ButtonBuildStructure::ButtonBuildStructure()
{
	m_Flags |= NOCLIP;
	m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL | LOCK_ICON_SIZE;
	m_Alpha = 0.75f;

	setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) );
	setEnable( false );
}
Пример #6
0
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 );
	}
}
Пример #7
0
ButtonGadget::ButtonGadget() : 
	m_bCursorOver( false )
{
	m_Flags |= NOCLIP;
	m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL;
	m_Alpha = 0.75f;
	m_IconColor = GREEN;

	setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) );
	setEnable( false );
}
Пример #8
0
ButtonContact::ButtonContact() : 
	m_IsObjective( false ),
	m_bGroupLeader( false ),
	m_bGroupPending( false )

{
	m_Flags |= NOCLIP;
	m_Style = HAS_BACK | EFFECT_HIGHLIGHT | SMOOTH_LL | EFFECT_FADEIN;
	m_Alpha = 0.75f;

	setWindow( RectInt( PointInt(0,0), SizeInt( BUTTON_WIDTH, BUTTON_HEIGHT ) ) );
}
Пример #9
0
ButtonContact::ButtonContact( NodeWindow * pParent, Noun * pNoun ) : 
	m_IsObjective( false ),
	m_bGroupLeader( false ),
	m_bGroupPending( false )
{
	m_Flags |= NOCLIP;
	m_Style = HAS_BACK | EFFECT_HIGHLIGHT | SMOOTH_LL | EFFECT_FADEIN;
	m_Alpha = 0.75f;

	setWindow( RectInt( PointInt(0,0), SizeInt( BUTTON_WIDTH, BUTTON_HEIGHT ) ) );

	// attach this button to the parent
	pParent->attachNode( this );
	// set this button
	setButton( pNoun );
}
Пример #10
0
	void Viewer::PanHorizontal(int length) {
		m_viewPort.Pan(SizeInt(length, 0));
	}
Пример #11
0
	void Viewer::PanVertical(int length) {
		m_viewPort.Pan(SizeInt(0, length));
	}
Пример #12
0
PrimitiveSurface * Material::getSurface( DisplayDevice * pDisplay, Image::Link pImage, int nFrame, bool bMipMap )
{
	// generate a unique key from the components
	WidgetKey nKey = pImage.key() + nFrame;
	if ( bMipMap )
		nKey += MIPMAP_KEY;

	AutoLock lock( &sm_SurfaceHashLock );
	SurfaceHash::Iterator it = sm_SurfaceHash.find( nKey );
	if ( it.valid() )
		return *it;
	lock.release();

	// surface not found, create and cache the surface
	PrimitiveSurface::Ref pSurface;
	if ( pImage.valid() && pImage->frameCount() > 0 )
	{
		// find a format for our surface first, findBestFormat() will always try to use the images current format
		// if supported by the hardware.
		ColorFormat::Format eFormat = findBestFormat( pDisplay, pImage, true );
		if ( eFormat == ColorFormat::INVALID )
		{
			TRACE( "ERROR: Failed to find a suitable surface format for texture!" );
			return NULL;
		}

		SizeInt imageSize( pImage->size() );
		SizeInt maxSize( pDisplay->textureMaxSize() );
		SizeInt minSize( pDisplay->textureMinSize() );

		// use the smaller max size
		maxSize.width = Min( sm_MaxTextureSize.width, maxSize.width );
		maxSize.height = Min( sm_MaxTextureSize.height, maxSize.height );

		// validate the texture dimensions
		SizeInt validSize( Max( Min( imageSize.width, maxSize.width ), minSize.width), 
			Max( Min( imageSize.height, maxSize.height ), minSize.height) );
		if ( pDisplay->textureP2() && !pImage->isP2() )
			validSize = SizeInt( 1 << GetLastBit( validSize.width ), 1 << GetLastBit( validSize.height) );
		if ( pDisplay->textureSquare() && validSize.width != validSize.height )
			validSize = SizeInt( Max( validSize.width, validSize.height ), Max( validSize.width, validSize.height) );

		if ( validSize != imageSize || eFormat != pImage->format() )
		{
			// image is the wrong size or format, make a copy so we don't modify the original..
			pImage = new Image( *pImage );

			if ( pImage->size() != validSize )
			{
				// image has to be resized - switch the format to an uncompressed format, DXT compression is too slow
				// to do on the fly..
				eFormat = findBestFormat( pDisplay, pImage, false );
				if ( eFormat != pImage->format() )
				{
					TRACE( CharString().format( "Image: Reformat %s -> %s", ColorFormat::formatText( pImage->format() ),
						ColorFormat::formatText( eFormat ) ) );
					if (! pImage->setFormat( eFormat ) )
						return NULL;
				}

				TRACE( CharString().format( "Image: Resize %dx%d -> %dx%d", imageSize.width, imageSize.height, 
					validSize.width, validSize.height ) );

				pImage->resample( validSize );
				if ( bMipMap && pImage->mipMap() != NULL )
					pImage->createMipMaps();
			}
			else if ( pImage->format() != eFormat )
			{
				TRACE( CharString().format( "Image: Reformat %s -> %s", ColorFormat::formatText( pImage->format() ),
					ColorFormat::formatText( eFormat ) ) );
				if (! pImage->setFormat( eFormat ) )
					return NULL;		// failed to convert to the desired format..
			}
		}

		if ( bMipMap && pImage->mipMap() == NULL )
			bMipMap = false;		// no mipmap levels in image, disable mipmaps

		// create the primitives, note having neither a diffuse or alpha texture is also a valid material
		pDisplay->create( pSurface );

		// create the surface
		SizeInt surfaceSize( pImage->size() );
		pSurface->initialize( 
			surfaceSize.width,
			surfaceSize.height, 
			eFormat,
			bMipMap );

		nFrame = nFrame % pImage->frameCount();

		Image * pMipMap = pImage;
		for(int i=0;i<pSurface->levels();++i)
		{
			if (! pMipMap )
			{
				TRACE( CharString().format("ERROR: Mipmap level %d is missing!", i ) );
				break;
			}

			void * pPixels = pSurface->lock( i );
			if (! pPixels )
			{
				TRACE( "ERROR: Failed to lock surface!" );
				break;
			}

			memcpy( pPixels, pMipMap->frame( nFrame ), pMipMap->frameSize( nFrame ) );
			pSurface->unlock();

			// next mipmap level of our image..
			pMipMap = pMipMap->mipMap();
		}
	}

	// cache the surface now
	lock.set( &sm_SurfaceHashLock );
	sm_SurfaceHash[ nKey ] = pSurface;
	return pSurface;
}
Пример #13
0
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 );
	}
}
Пример #14
0
	TEST_FIXTURE(FixtureRound, PanRoundDown) {
		p.Pan(SizeInt(-1, -1));
		CHECK_EQUAL(PointInt(0, 0), p.TopLeft());
		CHECK_EQUAL(PointInt(717, 448), p.BottomRight());
	}
Пример #15
0
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 );
}
Пример #16
0
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 );
	}
}