Using Description Plugin, trying to improve hover over text visability

Started by Woffle, Tue 09/06/2015 23:49:03

Previous topic - Next topic

Woffle

As mentioned in the title, I'm using the Description module found here: http://www.adventuregamestudio.co.uk/forums/index.php?topic=26306.0

It's working very well but due to some of my background design, the text is sometimes hard to read. I know I can create a GUI element that pops up where the text does but the amount of text varies from object to object so the GUI would have to be big enough to encapsulate every message. That seems clumsy to me.

I wonder if there's a way to change only the font for the hover over text to have a box around it? Or to be a text with a colored in background? I would like to keep the rest of my text the same.

Snarky

No, you can't change the font that way: the background is never part of the font (and can't really be).

However, you can dynamically resize GUIs on the fly (like, whenever you want to display something) by changing its .Width/.Height properties. And there's a way to measure the size of a string, using Game.GetTextWidth() and GetTextHeight(). Together, this lets you fit a GUI to its text content. (Then you'll probably want to put the text on a label on the GUI; that's the easiest way to make sure it displays on top of the GUI. I suppose the module already does it?)

Woffle

Thank you for the help!

So, the limits of my scripting knowledge seem to have reared their ugly head again. I'm not sure how to position the GUI so that it...

A) only appears when the Description module is displaying a description
B) Display behind the description text
C) Display the correct size so that the GUI always covers the text.

Part of this definitely comes from using the ready made module so the scripting is more advanced than anything I've actually done.

I'm even having a hard time finding the appropriate tutorials that might address this problem. I've watched this guys (https://www.youtube.com/playlist?list=PL21DB402CB4DAEAEF) GUI videos and text overlay videos but it doesn't seem to help. I know how to change the GUI backdrop for Display text but not for the hover over that's part of the Description module.

Any help is appreciated. I feel like after all the assistance I've received from the forum, I should make a donation or something.

In case you are willing to help and it is useful having the Description Module script handy, here it is:

Code: ags

// Main script for module 'Description'

Descriptions Description;
export Description;


function Descriptions::OLTidy() {
  if (this.DisplayType==eDescDisplayOverlay && this.ol!=null &&
		  this.ol.Valid) {
    this.ol.Remove();
  }
}

function Descriptions::GUIMode(GUIControl *gc) {
  this.OLTidy();
  if (gc==null) { 
		Display("ERROR! null GUIControl passed to Description.GUIMode, contact game author");
		return -1;
  }		
  this.DisplayType=eDescDisplayGUIControl;
  this.gc=gc;
}

function Descriptions::OverlayMode() {
  this.DisplayType=eDescDisplayOverlay;
}

function Descriptions::StringOnly() {
  this.OLTidy();
  this.DisplayType=eDescDisplayNone;
}


protected function Descriptions::Update_String() {
  // Special case of busy cursor
  if ((mouse.Mode==this.NoDescriptionWhenMode) ||
			(this.NoDescriptionWhenNotMode>=0 && mouse.Mode!=this.NoDescriptionWhenNotMode) ||
		  (this.NoDescriptionWhenMode==eModeWait && IsInterfaceEnabled()==0)) { 
		this.Text=""; return;
	}
  String hs=Game.GetLocationName(mouse.x, mouse.y);
  if (this.IncludeInventory && InventoryItem.GetAtScreenXY(mouse.x, mouse.y)!=null) {
    InventoryItem *ii=InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
    hs=ii.Name;
	}
#ifdef AGS_SUPPORTS_IFVER
	if (this.ButtonsWithFont>=0 && GUIControl.GetAtScreenXY(mouse.x, mouse.y)!=null) {
	  GUIControl *bb=GUIControl.GetAtScreenXY(mouse.x, mouse.y);
	  if (bb.AsButton!=null && bb.AsButton.Font==this.ButtonsWithFont) hs=bb.AsButton.Text;
	}
#endif
  String verb="";
  if (this.VerbMode==eDescVerbModeNever || (hs=="" && this.NoVerbOverNothing) ) {
		this.Text=hs;
		return;
  } else if (player.ActiveInventory!=null && mouse.Mode==eModeUseinv) {
    String ai=player.ActiveInventory.Name;
    if (this.VerbMode==eDescVerbModeUser && this.VerbS!=null) verb=this.VerbS;
    else verb=this.UseS;
    this.Text=String.Format("%s %s %s %s", verb, ai, this.PrepositionS, hs);
  } else if (this.VerbMode==eDescVerbModeUseOnly) {
		this.Text=hs;
		return;
  } else {
    if (this.VerbMode==eDescVerbModeAuto) {
      if (mouse.Mode==eModeLookat) verb=this.LookS;
      if (mouse.Mode==eModePickup) verb=this.GetS;
      if (mouse.Mode==eModeTalkto) verb=this.TalkS;
      if (mouse.Mode==eModeInteract) verb=this.UseS;
      if (mouse.Mode==eModeWalkto) verb=this.WalkS;
    } else if (this.VerbS!=null) verb=this.VerbS;
    
    this.Text=String.Format("%s %s", verb, hs);
	}
	if (this.NoDescriptionWhenNoVerb && verb=="") this.Text="";
}

protected function Descriptions::Update_Position(int font, int width) {
  if (this.Location==eDescLocationFollow || 
			(this.Location==eDescLocationSticky && this.Text!="" && this.Text != this.last)) {
		this.width=GetTextWidth(this.Text, font);
		this.height=GetTextHeight(this.Text, font, width);
		this.x = mouse.x + this.OffsetX;
    if (this.OLAlignment==eAlignCentre) this.x-=this.width/2;
    else if (this.OLAlignment==eAlignRight) this.x-=this.width;
		if ((this.x + this.width) > this.MaxX) this.x = this.MaxX - this.width;
		if (this.x < this.MinX) this.x = this.MinX;
		this.y = mouse.y + this.OffsetY;
		if ((this.y + this.height) > this.MaxY) this.y = this.MaxY - this.height;
		if (this.y < this.MinY) this.y = this.MinY;
	}
}

protected function Descriptions::Update_DS() {
  this.ds=DynamicSprite.Create(this.OLWidth, this.height);
  DrawingSurface *dsds=this.ds.GetDrawingSurface();
  dsds.DrawingColor=this.OLColor;
  dsds.DrawStringWrapped(0, 0, this.OLWidth, this.OLFont, eAlignLeft, this.Text);
  dsds.Release();
}

protected function Descriptions::Update_Overlay() {
  if (this.Text=="") {
    this.OLTidy();
  } else {
		this.Update_Position(this.OLFont, this.OLWidth);	
		if (this.ol!=null && this.ol.Valid) {
      if (this.OLSierraBG) {
        this.Update_DS();
        this.ol=Overlay.CreateGraphical(this.x, this.y, this.ds.Graphic, true);
      } else {
        this.ol.SetText(this.OLWidth, this.OLFont, this.OLColor, this.Text);
        this.ol.X = this.x; // so the position of the overlay will be adjusted every game loop
        this.ol.Y = this.y;
      }
		} else {
      if (this.OLSierraBG) {
        this.Update_DS();
        this.ol=Overlay.CreateGraphical(this.x, this.y, this.ds.Graphic, true);
      } else {
			  this.ol=Overlay.CreateTextual(this.x, this.y, this.OLWidth, this.OLFont, this.OLColor, this.Text);
      }
		}  
	}
}      

protected function Descriptions::Update_GUI() {
	int font;
	if (this.gc.AsLabel!=null) font=this.gc.AsLabel.Font;
#ifdef AGS_SUPPORTS_IFVER
	else if (this.gc.AsButton!=null) font=this.gc.AsButton.Font;
#endif
	
	if (this.CropGUIToo) this.Update_Position(font, this.MaxX-this.MinX);
	else this.Update_Position(font, this.gc.OwningGUI.Width);

	if (this.Location!=eDescLocationStatic) {
		this.gc.OwningGUI.X=this.x;
		this.gc.OwningGUI.Y=this.y;
		this.gc.Width=this.width+1;
		if (this.CropGUIToo) this.gc.OwningGUI.Width=this.width+2;
	}	
  if (this.gc.AsLabel!=null) this.gc.AsLabel.Text=this.Text;
  else if (this.gc.AsButton!=null) this.gc.AsButton.Text=this.Text;
  
  // Fade control
	if ((this.Text=="") && (this.gc.OwningGUI.Visible) && (this.alpha<this.FadeStart)) {
    this.alpha+=this.FadeOutSpeed;
    if (this.alpha>=this.FadeStart) this.gc.OwningGUI.Visible=false;
  } else if (this.Text!="") {
    if (!this.gc.OwningGUI.Visible) {
      this.gc.OwningGUI.Visible=true;
      this.alpha=this.FadeStart;
    } else if (this.alpha>this.FadeEnd) {
      this.alpha-=this.FadeInSpeed;
    }
	}
	if (this.alpha>100) this.alpha=100;
	else if (this.alpha<0) this.alpha=0;
	this.gc.OwningGUI.Transparency=this.alpha;
}
  
function Descriptions::rep_ex() {
  this.last=this.Text;
  this.Update_String();
  if (this.DisplayType==eDescDisplayGUIControl) {
    this.Update_GUI();
  } else if (this.DisplayType==eDescDisplayOverlay) {
		this.Update_Overlay();
	}
}


function repeatedly_execute_always() {
  // Should this go in rep_ex_always?
  // easy enough for user to change, if required
  Description.rep_ex();
}

function on_event(EventType event, int data) {
  if (event==eEventLeaveRoom) Description.OLTidy();
}

function game_start() {
  // Set up defaults
  Description.LookS="Look at";
  Description.GetS="Get";
  Description.UseS="Use";
  Description.PrepositionS="on";
  Description.TalkS="Talk to";
  Description.WalkS="Walk to";
  Description.IncludeInventory=true;
  Description.NoVerbOverNothing=true;
  Description.OLWidth=100;
  Description.OLAlignment=eAlignLeft;
  Description.FadeStart=100;
  Description.FadeEnd=0;
  Description.FadeInSpeed=20;
  Description.FadeOutSpeed=5;
  Description.OffsetX=-16;
  Description.OffsetY=16;
  Description.MinX=0;
  Description.MinY=0;
  Description.MaxX=system.viewport_width-1;
  Description.MaxY=system.viewport_height-1;
  // Default to Overlay mode
  Description.OLColor=15000;
  Description.ButtonsWithFont=-1;
  Description.NoDescriptionWhenMode=-1;
  Description.NoDescriptionWhenNotMode=-1;
  Description.OverlayMode();
}


Snarky

Hi Woffle, sorry for the delay in responding. I've had a look at SSH's Description module, and it looks to me like it supports what you want "out of the box."

The relevant setting is, I believe, Description.CropGUIToo, which tells the module to only make the GUI as big as you need to display the current text.

Using the module code as-is, something like this should work to set it up (untested):

-Create a GUI with the background you want to use. Make it the max size of the hovertext you would ever want to display.
-Put a Label on the GUI, similarly sized. Call it, for example, lblDescription

Now edit the game_start() function in your global script, adding the initialization of the module:

Code: ags
function game_start() // called when the game starts, before the first room is loaded
{
  Description.GUIMode(lblDescription); // <--- This is what makes it use the GUI you created. Use the name of your label here
  Description.CropGUIToo = true; // <--- And this should make it resize the GUI to fit the text 

  // The rest of these settings can be whatever you like...
  Description.Location = eDescLocationSticky;
  Description.VerbMode = eDescVerbModeNever;
  Description.OffsetX = 10;
  Description.OffsetY = 5;
  // (more settings here...)
}


Hope that helps!

SMF spam blocked by CleanTalk