Geom::RectInt TileManager::determineLockableRect(const RectInt& r) const {
		if (IsPositive(r.Dimensions()) == false) {
			DO_THROW(Err::InvalidParam, "Invalid dimensions");
		}

		if (m_topLeftOffset.AtLeastInclusive({ 0, 0 }) == false) {
			DO_THROW(Err::CriticalError, "Invalid offset");
		}

		auto pannedTopLeft = r.TopLeft() + m_topLeftOffset;
		while (pannedTopLeft.X >= MaximumTileEdgeLength) {
			pannedTopLeft.X -= MaximumTileEdgeLength;
		}
		while (pannedTopLeft.Y >= MaximumTileEdgeLength) {
			pannedTopLeft.Y -= MaximumTileEdgeLength;
		}

		auto croppedBottomRight = Geom::Minimum(r.BottomRight(), PointInt(0, 0) + m_topLeftOffset + m_viewSize);
		auto outSize = Maximum(SizeInt(0, 0),
			Minimum(
			SizeInt(MaximumTileEdgeLength, MaximumTileEdgeLength) + (PointInt(0, 0) - pannedTopLeft),
			croppedBottomRight - PointInt(0, 0),
			r.Dimensions()));

		if (IsPositive(outSize) == false) {
			DO_THROW(Err::CriticalError, "Calculation error, rect became empty.");
		}
		return{ pannedTopLeft, outSize };
	}
Exemple #2
0
bool ff::Value::CreateRect(const RectInt &rect, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (!rect.IsNull())
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::Rect);
		(*ppValue)->InternalGetRect() = rect;
	}
	else
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::Rect);
				s_val->InternalGetRect().SetRect(0, 0, 0, 0);
			}
		}

		*ppValue = s_val;
	}

	return true;
}
Exemple #3
0
bool WindowEdit::onCursorMove( const RectInt & window, const PointInt & position, const PointInt & delta )
{
	if ( window.inRect( position ) || m_Editing )
	{
		setCursorState( EDIT );
		return true;
	}

	return false;
}
Exemple #4
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 );
	}
}
Exemple #5
0
bool
TaskClampSW::run(RunParams&) const
{
	RectInt r = target_rect;
	if (!r.valid())
	{
		VectorInt offset = get_offset();
		RectInt ra = sub_task()->target_rect + r.get_min() + get_offset();
		if (ra.valid())
		{
			etl::set_intersect(ra, ra, r);
			if (ra.valid())
			{
				LockWrite ldst(this);
				if (!ldst) return false;
				LockRead lsrc(sub_task());
				if (!lsrc) return false;

				const synfig::Surface &a = lsrc->get_surface();
				synfig::Surface &c = ldst->get_surface();

				for(int y = ra.miny; y < ra.maxy; ++y)
				{
					const Color *ca = &a[y - r.miny + offset[1]][ra.minx - r.minx + offset[0]];
					Color *cc = &c[y][ra.minx];
					for(int x = ra.minx; x < ra.maxx; ++x, ++ca, ++cc)
						clamp_pixel(*cc, *ca);
				}
			}
		}
	}

	return true;
}
Exemple #6
0
bool WindowEdit::onLeftUp( const RectInt & window, const PointInt & position )
{
	if ( window.inRect( position ) )
	{
		return true;
	}
	else
	{
		if ( m_Editing )
		{
			onEndEdit();
			return true;
		}
	}

	return false;
}
Exemple #7
0
bool WindowButton::onCursorMove( const RectInt & window, const PointInt & position, const PointInt & delta )
{
	bool bInRect = false;
	if ( !m_HotKeyDown )
	{
		if ( visible() && window.inRect( position ) )
			bInRect = true;
	}

	if ( bInRect )
	{
		if ( !m_bGreyed )
		{
			// display the press button
			context()->setCursorState( SELECT );

			if ( m_HotKey != 0 )
			{
				updateTip( CharString().format("%s  '%s'", m_Tip, 
					keyText( Keyboard::unmap( m_HotKey ) ) ) );
			}
			else
				updateTip( m_Tip );
		}

		if ( !m_CursorOver )
		{
			if ( !m_bGreyed )
			{
				postMessage( WB_OVERBUTTON, (dword)this, 0 );
				hoverSound();
			}

			m_CursorOver = true;
			return false;			// return false on the first time a cursor is over a button, so that the other button can set m_CursorOver to false
		}

		return true;
	}
	else if ( m_CursorOver )
		m_CursorOver = false;

	return NodeWindow::onCursorMove( window, position, delta );
}
Exemple #8
0
bool WindowTree::onCursorMove( const RectInt & window, const PointInt & position, const PointInt & delta )
{
	if ( visible() )
	{
		if ( window.inRect( position ) )
		{
			m_CursorInWindow = true;
			m_LastCursorPosition = windowToScreen( position );

			setCursorState( SELECT );
			return true;
		}
		else
		{
			m_CursorInWindow = false;
		}
	}

	return NodeWindow::onCursorMove( window, position, delta );
}
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 );
	}
}
Exemple #10
0
bool WindowEdit::onLeftDown( const RectInt & window, const PointInt & position )
{
	if ( window.inRect( position ) )
	{
		if ( m_Editing )
		{
			Font * pFont = windowStyle()->font();
			ASSERT( pFont );

			// get pixel offset from left side of window
			int offset = position.m_X - window.m_Left;
			// move cursor to position in text
			int i = m_EditBegin;
			for(;i<=m_EditEnd && offset > 0;i++)
				offset -= pFont->characterWidth( m_Text[i] );
			// set the cursor position
			m_Cursor = i;

			return true;
		}

		// begin editing
		onBeginEdit();
		return true;
	}
	else
	{
		if ( m_Editing )
		{
			onEndEdit();
			return true;
		}
	}

	return false;
}
Exemple #11
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 );
	}
}
Exemple #12
0
bool
TaskBlendSW::run(RunParams & /* params */) const
{
	const synfig::Surface &a =
		SurfaceSW::Handle::cast_dynamic( sub_task_a()->target_surface )->get_surface();
	const synfig::Surface &b =
		SurfaceSW::Handle::cast_dynamic( sub_task_b()->target_surface )->get_surface();
	synfig::Surface &c =
		SurfaceSW::Handle::cast_dynamic( target_surface )->get_surface();

	//debug::DebugSurface::save_to_file(a, "TaskBlendSW__run__a");
	//debug::DebugSurface::save_to_file(b, "TaskBlendSW__run__b");

	RectInt r = get_target_rect();
	if (r.valid())
	{
		RectInt ra = sub_task_a()->get_target_rect() + r.get_min() + offset_a;
		if (ra.valid())
		{
			etl::set_intersect(ra, ra, r);
			if (ra.valid() && &a != &c)
			{
				synfig::Surface::pen p = c.get_pen(ra.minx, ra.maxx);
				const_cast<synfig::Surface*>(&a)->blit_to(
					p,
					ra.minx - r.minx - offset_a[0],
					ra.miny - r.miny - offset_a[1],
					ra.maxx - ra.minx,
					ra.maxy - ra.miny );
			}
		}

		RectInt fill[] = { ra, RectInt::zero(), RectInt::zero(), RectInt::zero() };
		RectInt rb = sub_task_b()->get_target_rect() + r.get_min() + offset_b;
		if (rb.valid())
		{
			etl::set_intersect(rb, rb, r);
			if (rb.valid())
			{
				synfig::Surface::alpha_pen ap(c.get_pen(rb.minx, rb.miny));
				ap.set_blend_method(blend_method);
				ap.set_alpha(amount);
				const_cast<synfig::Surface*>(&b)->blit_to(
					ap,
					rb.minx - r.minx - offset_b[0],
					rb.miny - r.miny - offset_b[1],
					rb.maxx - rb.minx,
					rb.maxy - rb.miny );

				if (ra.valid())
				{
					// mark unfilled regions
					fill[0] = fill[1] = fill[2] = fill[3] = ra;
					fill[0].maxx = fill[2].minx = fill[3].minx = std::max(ra.minx, std::min(ra.maxx, rb.minx));
					fill[1].minx = fill[2].maxx = fill[3].maxx = std::max(ra.minx, std::min(ra.maxx, rb.maxx));
					fill[2].maxy = std::max(ra.miny, std::min(ra.maxy, rb.miny));
					fill[3].miny = std::max(ra.miny, std::min(ra.maxy, rb.maxy));
				}
			}
		}

		if (Color::is_straight(blend_method))
		{
			for(int i = 0; i < 4; ++i)
			{
				if (fill[i].valid())
				{
					synfig::Surface::alpha_pen ap(
						c.get_pen(fill[i].minx, fill[i].miny) );
					ap.set_blend_method(blend_method);
					ap.set_alpha(amount);
					c.fill( Color(0, 0, 0, 0), ap,
							fill[i].maxx - fill[i].minx,
							fill[i].maxy - fill[i].miny );
				}
			}
		}
	}

	//debug::DebugSurface::save_to_file(c, "TaskBlendSW__run__c");

	return true;
}
Exemple #13
0
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 );
			}
		}
	}
}
bool
synfig::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
{
	const RendDesc &rend_desc(desc);

	etl::clock total_time;
	etl::clock::value_type work_time(0);
	etl::clock::value_type find_tile_time(0);
	etl::clock::value_type add_tile_time(0);
	total_time.reset();

	// If the quality is set to zero, then we
	// use the parametric scanline-renderer.
	if(get_quality()==0)
	{
		Surface surface;

		RendDesc tile_desc;
		RectInt rect;
		int i = 0;
		etl::clock tile_timer;
		tile_timer.reset();
		while(next_tile(rect))
		{
			find_tile_time+=tile_timer();

			SuperCallback super(cb,i,i+1,10000);
			if(!super.amount_complete(0,1000))
				return false;
			++i;

			// Perform clipping on the tile
			if(clipping_)
				etl::set_intersect(rect, rect, RectInt(0, 0, rend_desc.get_w(), rend_desc.get_h()));

			tile_desc=rend_desc;
			tile_desc.set_subwindow(rect.minx, rect.miny, rect.maxx - rect.minx, rect.maxy - rect. miny);
			if(!parametric_render(context, surface, tile_desc,&super))
			{
				// For some reason, the parametric renderer failed.
				if(cb)cb->error(_("Parametric Renderer Failure"));
				return false;
			}
			else
			{
				if(!surface)
				{
					if(cb)cb->error(_("Bad surface"));
					return false;
				}
				switch(get_alpha_mode())
				{
					case TARGET_ALPHA_MODE_FILL:
						for(int i=0;i<surface.get_w()*surface.get_h();i++)
							surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
						break;
					case TARGET_ALPHA_MODE_EXTRACT:
						for(int i=0;i<surface.get_w()*surface.get_h();i++)
						{
							float a=surface[0][i].get_a();
							surface[0][i] = Color(a,a,a,a);
						}
						break;
					case TARGET_ALPHA_MODE_REDUCE:
						for(int i=0;i<surface.get_w()*surface.get_h();i++)
							surface[0][i].set_a(1.0f);
						break;
					default:
						break;
				}

				// Add the tile to the target
				if(!add_tile(surface, rect.minx, rect.miny))
				{
					if(cb)cb->error(_("add_tile():Unable to put surface on target"));
					return false;
				}
			}
			tile_timer.reset();
		}
		SuperCallback super(cb,i,10000,10000);
	}
	else // If quality is set otherwise, then we use the accelerated renderer
	{
		etl::clock tile_timer;
		tile_timer.reset();

		// Gather tiles
		std::vector<RectInt> tiles;
		RectInt rect;
		while(next_tile(rect)) {
			if (clipping_)
				if (rect.minx >= rend_desc.get_w() || rect.miny >= rend_desc.get_h())
					continue;
			tiles.push_back(rect);
		}
		find_tile_time += tile_timer();

		// Render tiles
		for(std::vector<RectInt>::iterator i = tiles.begin(); i != tiles.end(); ++i)
		{
			// Progress callback
			int index = i - tiles.begin();
			int count = (int)tiles.size();
			SuperCallback super(cb, (count-index)*1000, (count-index+1)*1000, count*1000);
			if(!super.amount_complete(0,1000))
				return false;

			// Render tile
			tile_timer.reset();

			rect = *i;
			if (clipping_)
				etl::set_intersect(rect, rect, RectInt(0, 0, rend_desc.get_w(), rend_desc.get_h()));

			if (!rect.valid())
				continue;

			RendDesc tile_desc=rend_desc;
			tile_desc.set_subwindow(rect.minx, rect.miny, rect.maxx - rect.minx, rect.maxy - rect.miny);

			async_render_tile(rect, context, tile_desc, &super);
		}
	}

	if (!wait_render_tiles(cb))
		return false;

	if(cb && !cb->amount_complete(10000,10000))
		return false;

#ifdef SYNFIG_DISPLAY_EFFICIENCY
	synfig::info(">>>>>> Render Time: %fsec, Find Tile Time: %fsec, Add Tile Time: %fsec, Total Time: %fsec",work_time,find_tile_time,add_tile_time,total_time());
	synfig::info(">>>>>> FRAME EFFICIENCY: %f%%",(100.0f*work_time/total_time()));
#endif
	return true;
}
Exemple #15
0
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 );
	}
}
Exemple #16
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 );
	}
}
Exemple #17
0
Surface::Handle
SurfaceResource::get_surface(
	const Surface::Token::Handle &token,
	bool exclusive, // for write access
	bool full,
	const RectInt &rect,
	bool create,
	bool any )
{
	if (!token && !any)
		return Surface::Handle();
	if (!full && !rect.is_valid())
		return Surface::Handle();

	Glib::Threads::Mutex::Lock lock(mutex);

	if (width <= 0 || height <= 0)
		return Surface::Handle();
	if (!full && !etl::contains(RectInt(0, 0, width, height), rect))
		return Surface::Handle();

	Surface::Handle surface;

	Map::const_iterator i = surfaces.find(token);
	if (i != surfaces.end())
		surface = i->second;
	else
	if (any && !surfaces.empty())
		surface = surfaces.begin()->second;
	else
	if (!create)
		return Surface::Handle();

	if (!surface) {
		surface = token->fabric();
		if (!surface)
			return Surface::Handle();

		if (blank) {
			if (!surface->create(width, height))
				return Surface::Handle();
		} else {
			bool found = false;
			for(Map::const_iterator i = surfaces.begin(); i != surfaces.end() && !found; ++i)
				if (i->second->get_pixels_pointer() && surface->assign(*i->second))
					found = true;
			for(Map::const_iterator i = surfaces.begin(); i != surfaces.end() && !found; ++i)
				if (!i->second->get_pixels_pointer() && surface->assign(*i->second))
					found = true;
			if (!found)
				return Surface::Handle();
		}

		if (exclusive) surfaces.clear(); // all other surfaces invalidated
		surfaces[token] = surface;
	}

	if (exclusive) {
		if (surfaces.size() != 1) // keep only current surface in map
			{ surfaces.clear(); surfaces[token] = surface; }
		surface->touch();
		blank = false;
	}
	return surface;
}
Exemple #18
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 );
}