Make RGYB buttons customizable (attempt 2)

Message ID 504C9156.8080502@tvdr.de
State New
Headers

Commit Message

Klaus Schmidinger Sept. 9, 2012, 12:53 p.m. UTC
  On 09.09.2012 14:10, Gero wrote:
> On Sunday 09 September 2012 - 13:20:24, Klaus Schmidinger wrote:
>> ..., but I don't think it would be a good idea to modify the actual
>> functionality of these buttons
>> ...
>> and it would also affect tools that issue key presses via the SVDRP
>> command HITK.
>>
>> So before I adopt this patch, I want to make it very clear that this is
>> *not* going to be the first step towards a "babylonical" confusion... ;-)
>
> Isn't that a big overkill?
>
> The buttons already have the ability to get labeled and plugin-developers can
> assign individual actions ...
>
> I think, nobody will start to redefine a red button to become magenta or pink.
> ... and if a remote control exists, that have all color keys being black - I
> guess nobody would redefine the color buttons to become black1, black2, ...
> So I don't see the necessity to really change core code.
>
> The only agreed requirement is to be able to change the (visual) order of the
> buttons. The red button will stay red and a green button will continue being
> green. So there's no need to change SetHelp() call or the like. The order of
> the parameters of SetHelp() has very little in common with the visual
> representation - the parameter names of SetHelp() reflect the real button.
>
> Only the visual order needs to be customizable. If that's already a skin
> issue, I guess very little has to be changed in core vdr.

I'm not sure whether you understood what I meant.
Of course "red" will remain "red" etc. But a red button that has,
say, "Open" as its function will still have that function, even if it
is no longer the leftmost button.

Anyway, I have attached a revised version of the patch.
I have changed some variable names to better reflect the distinction
between "keys" on the remote control and "buttons" displayed on the
menus. I have also adjusted drawing the small rectangles to the left
of each color button in the LCARS skin.

Please have a look an let me know if there's anything wrong with this.

Klaus
  

Comments

geronimo Sept. 9, 2012, 3:39 p.m. UTC | #1
On Sunday 09 September 2012 - 14:53:42, Klaus Schmidinger wrote:
> I'm not sure whether you understood what I meant.

Never mind ;)

> Of course "red" will remain "red" etc. But a red button that has,
> say, "Open" as its function will still have that function, even if it
> is no longer the leftmost button.

You know, there's more than one way to skin a  cat.

I sugested to leave the buttons and change their positions only, where as your 
patch changes all but the positions. I think, your way is the hard one, but 
the result for the user would be the same.

Additionally I don't think, the button order is prominent enuf to rise them to 
osd setup menu. Edit /etc/defaults (or similar files) would be fine for that 
(like remote.conf)
 

Just my 2c


cheers Gero
  
Klaus Schmidinger Sept. 9, 2012, 4:11 p.m. UTC | #2
On 09.09.2012 17:39, Gero wrote:
> ...
> I sugested to leave the buttons and change their positions only, where as your
> patch changes all but the positions. I think, your way is the hard one, but
> the result for the user would be the same.

Ah, now I see what you mean. Something along the lines of

      int h = yb15 - yb14;
      int lutX[] = { xb02, xb06, xb10, xb14 };
      int lutW[] = { xb03 - xb02, xb07 - xb06, xb11 - xb10, xb15 - xb14 };
      osd->DrawText(lutX[Setup.ColorKey0], yb14, Red,    Theme.Color(clrButtonRedFg),    Theme.Color(clrButtonRedBg),    font, lutW[Setup.ColorKey0], h, taLeft | taBorder);
      osd->DrawText(lutX[Setup.ColorKey1], yb14, Green,  Theme.Color(clrButtonGreenFg),  Theme.Color(clrButtonGreenBg),  font, lutW[Setup.ColorKey1], h, taLeft | taBorder);
      osd->DrawText(lutX[Setup.ColorKey2], yb14, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, lutW[Setup.ColorKey2], h, taLeft | taBorder);
      osd->DrawText(lutX[Setup.ColorKey3], yb14, Blue,   Theme.Color(clrButtonBlueFg),   Theme.Color(clrButtonBlueBg),   font, lutW[Setup.ColorKey3], h, taLeft | taBorder);

Well, either way is OK.

> Additionally I don't think, the button order is prominent enuf to rise them to
> osd setup menu. Edit /etc/defaults (or similar files) would be fine for that
> (like remote.conf)

Strange. First the button order is so important and then it's not important
enough to justify a setup menu option ;-)
But since the code is already there...

Klaus
  
VDRU VDRU Sept. 9, 2012, 5:35 p.m. UTC | #3
On Sun, Sep 9, 2012 at 8:39 AM, Gero <geronimo013@gmx.de> wrote:
> Additionally I don't think, the button order is prominent enuf to rise them to
> osd setup menu. Edit /etc/defaults (or similar files) would be fine for that
> (like remote.conf)

OSD setup options are a matter of convenience. The more the user can
do in the osd, the better. The more the user has to do by manually
editing files, the worse.
  
geronimo Sept. 10, 2012, 4:12 a.m. UTC | #4
On Sunday 09 September 2012 - 19:35:20, VDR User wrote:
> OSD setup options are a matter of convenience. 

Agree.

> The more the user can do in the osd, the better. 
> The more the user has to do by manually editing files, the worse.

Don't agree!

From my point of view, the setup options have to get divided into frontend- 
and backend-settings. Then all settings of each group should get divided into 
installation settings and user-changeable settings.

For me, all FHS-related settings are installation settings. Same is true for 
remote.conf and - of cause - the button order.

If you look at a possible multi-client installation, the button order is a 
frontend-setting, which is an installation setting. You only change it, when 
you buy a new remote control  and then, the button order is not the only 
setting, that needs to get changed.

I consider it ridiculous, being able to change the video-driver by osd.
That video driver is used by xine to render images to frontend, which possibly 
is on a different machine. This way it is possible to crash the vdr without 
possibility of recovery.

So moving a setup entry from osd to i.e. /etc/default/vdr may possibly 
decrease user flexibility, but may increase system stability and safety.

So from my point of view, osd-setup entries are user-changeable backend 
settings (well, currently the frontend user-changeable settings are stil mixed 
within). 
All other entries should be handled differently. 
But that issue will probabely pop up again after 2.0


cheers Gero
  
VDRU VDRU Sept. 10, 2012, 5:03 a.m. UTC | #5
The majority of users I know are using VDR in a dedicated environment
with only a remote control for input. Any maintenance is done via ssh.
Even if that wasn't the case, I still believe the more configuration a
user can do in one place, the better. It makes less sense to me that
users be forced to change settings using different methods depending
on what they want to change. Every user has access to the OSD and a
way to use/navigate it, but not every user can easily go around
manually editing different files.

As far as any potential problems that could arise from giving the user
a more convenient & streamlined experience, that's where well thought
out & proper design come into play. You want enough flexibility to
either deal with those problems, or avoid them altogether.
  

Patch

--- ./MANUAL	2012/06/17 12:16:33	2.19
+++ ./MANUAL	2012/09/09 12:28:27
@@ -601,6 +601,14 @@ 
                          characters in a text input field. You may want to set this
                          to "no" if you are using an actual keyboard to control VDR.
 
+  Color key 0 = 0        By default, VDR assumes that the sequence of the color
+  Color key 1 = 1        keys on the remote control is red-green-yellow-blue. If
+  Color key 2 = 2        your remote control has these keys in a different sequence,
+  Color key 3 = 3        you can adjust these parameters to reorder the corresponding
+                         color buttons in the menus accordingly. Note that this does
+                         not change the functionality of the individual keys; it only
+                         changes the sequence in which the color buttons are displayed.
+
   EPG:
 
   EPG scan timeout = 5   The time (in hours) of user inactivity after which the
--- ./config.c	2012/06/17 12:27:07	2.26
+++ ./config.c	2012/09/09 11:39:06
@@ -424,6 +424,10 @@ 
   UseDolbyDigital = 1;
   ChannelInfoPos = 0;
   ChannelInfoTime = 5;
+  ColorKey0 = 0;
+  ColorKey1 = 1;
+  ColorKey2 = 2;
+  ColorKey3 = 3;
   OSDLeftP = 0.03;
   OSDTopP = 0.03;
   OSDWidthP = 0.93;
@@ -620,6 +624,10 @@ 
   else if (!strcasecmp(Name, "UseDolbyDigital"))     UseDolbyDigital    = atoi(Value);
   else if (!strcasecmp(Name, "ChannelInfoPos"))      ChannelInfoPos     = atoi(Value);
   else if (!strcasecmp(Name, "ChannelInfoTime"))     ChannelInfoTime    = atoi(Value);
+  else if (!strcasecmp(Name, "ColorKey0"))           ColorKey0          = atoi(Value);
+  else if (!strcasecmp(Name, "ColorKey1"))           ColorKey1          = atoi(Value);
+  else if (!strcasecmp(Name, "ColorKey2"))           ColorKey2          = atoi(Value);
+  else if (!strcasecmp(Name, "ColorKey3"))           ColorKey3          = atoi(Value);
   else if (!strcasecmp(Name, "OSDLeftP"))            OSDLeftP           = atof(Value);
   else if (!strcasecmp(Name, "OSDTopP"))             OSDTopP            = atof(Value);
   else if (!strcasecmp(Name, "OSDWidthP"))         { OSDWidthP          = atof(Value); ChkDoublePlausibility(OSDWidthP, 0.87); }
@@ -719,6 +727,10 @@ 
   Store("UseDolbyDigital",    UseDolbyDigital);
   Store("ChannelInfoPos",     ChannelInfoPos);
   Store("ChannelInfoTime",    ChannelInfoTime);
+  Store("ColorKey0",          ColorKey0);
+  Store("ColorKey1",          ColorKey1);
+  Store("ColorKey2",          ColorKey2);
+  Store("ColorKey3",          ColorKey3);
   Store("OSDLeftP",           OSDLeftP);
   Store("OSDTopP",            OSDTopP);
   Store("OSDWidthP",          OSDWidthP);
--- ./config.h	2012/07/15 10:51:56	2.50
+++ ./config.h	2012/09/09 11:40:08
@@ -294,6 +294,7 @@ 
   int UseDolbyDigital;
   int ChannelInfoPos;
   int ChannelInfoTime;
+  int ColorKey0, ColorKey1, ColorKey2, ColorKey3;
   double OSDLeftP, OSDTopP, OSDWidthP, OSDHeightP;
   int OSDLeft, OSDTop, OSDWidth, OSDHeight;
   double OSDAspect;
--- ./menu.c	2012/09/09 09:19:15	2.59
+++ ./menu.c	2012/09/09 12:23:00
@@ -2510,6 +2510,7 @@ 
 class cMenuSetupOSD : public cMenuSetupBase {
 private:
   const char *useSmallFontTexts[3];
+  const char *keyColorTexts[4];
   int osdLanguageIndex;
   int numSkins;
   int originalSkinIndex;
@@ -2560,6 +2561,10 @@ 
   useSmallFontTexts[0] = tr("never");
   useSmallFontTexts[1] = tr("skin dependent");
   useSmallFontTexts[2] = tr("always");
+  keyColorTexts[0] = tr("Key$Red");
+  keyColorTexts[1] = tr("Key$Green");
+  keyColorTexts[2] = tr("Key$Yellow");
+  keyColorTexts[3] = tr("Key$Blue");
   Clear();
   SetSection(tr("OSD"));
   Add(new cMenuEditStraItem(tr("Setup.OSD$Language"),               &osdLanguageIndex, I18nNumLanguagesWithLocale(), &I18nLanguages()->At(0)));
@@ -2589,6 +2594,10 @@ 
   Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"),  &data.RecordingDirs));
   Add(new cMenuEditBoolItem(tr("Setup.OSD$Folders in timer menu"),  &data.FoldersInTimerMenu));
   Add(new cMenuEditBoolItem(tr("Setup.OSD$Number keys for characters"), &data.NumberKeysForChars));
+  Add(new cMenuEditStraItem(tr("Setup.OSD$Color key 0"),            &data.ColorKey0, 4, keyColorTexts));
+  Add(new cMenuEditStraItem(tr("Setup.OSD$Color key 1"),            &data.ColorKey1, 4, keyColorTexts));
+  Add(new cMenuEditStraItem(tr("Setup.OSD$Color key 2"),            &data.ColorKey2, 4, keyColorTexts));
+  Add(new cMenuEditStraItem(tr("Setup.OSD$Color key 3"),            &data.ColorKey3, 4, keyColorTexts));
   SetCurrent(Get(current));
   Display();
 }
--- ./skinclassic.c	2012/04/23 08:48:03	2.7
+++ ./skinclassic.c	2012/09/09 11:39:06
@@ -291,16 +291,19 @@ 
 void cSkinClassicDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
 {
   const cFont *font = cFont::GetFont(fontOsd);
+  const char *lutText[] = { Red, Green, Yellow, Blue };
+  tColor lutFg[] = { clrButtonRedFg, clrButtonGreenFg, clrButtonYellowFg, clrButtonBlueFg };
+  tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
   int w = x3 - x0;
   int t0 = x0;
   int t1 = x0 + w / 4;
   int t2 = x0 + w / 2;
   int t3 = x3 - w / 4;
   int t4 = x3;
-  osd->DrawText(t0, y4, Red,    Theme.Color(clrButtonRedFg),    Red    ? Theme.Color(clrButtonRedBg)    : Theme.Color(clrBackground), font, t1 - t0, 0, taCenter);
-  osd->DrawText(t1, y4, Green,  Theme.Color(clrButtonGreenFg),  Green  ? Theme.Color(clrButtonGreenBg)  : Theme.Color(clrBackground), font, t2 - t1, 0, taCenter);
-  osd->DrawText(t2, y4, Yellow, Theme.Color(clrButtonYellowFg), Yellow ? Theme.Color(clrButtonYellowBg) : Theme.Color(clrBackground), font, t3 - t2, 0, taCenter);
-  osd->DrawText(t3, y4, Blue,   Theme.Color(clrButtonBlueFg),   Blue   ? Theme.Color(clrButtonBlueBg)   : Theme.Color(clrBackground), font, t4 - t3, 0, taCenter);
+  osd->DrawText(t0, y4, lutText[Setup.ColorKey0], Theme.Color(lutFg[Setup.ColorKey0]), lutText[Setup.ColorKey0] ? Theme.Color(lutBg[Setup.ColorKey0]) : Theme.Color(clrBackground), font, t1 - t0, 0, taCenter);
+  osd->DrawText(t1, y4, lutText[Setup.ColorKey1], Theme.Color(lutFg[Setup.ColorKey1]), lutText[Setup.ColorKey1] ? Theme.Color(lutBg[Setup.ColorKey1]) : Theme.Color(clrBackground), font, t2 - t1, 0, taCenter);
+  osd->DrawText(t2, y4, lutText[Setup.ColorKey2], Theme.Color(lutFg[Setup.ColorKey2]), lutText[Setup.ColorKey2] ? Theme.Color(lutBg[Setup.ColorKey2]) : Theme.Color(clrBackground), font, t3 - t2, 0, taCenter);
+  osd->DrawText(t3, y4, lutText[Setup.ColorKey3], Theme.Color(lutFg[Setup.ColorKey3]), lutText[Setup.ColorKey3] ? Theme.Color(lutBg[Setup.ColorKey3]) : Theme.Color(clrBackground), font, t4 - t3, 0, taCenter);
 }
 
 void cSkinClassicDisplayMenu::SetMessage(eMessageType Type, const char *Text)
--- ./skinlcars.c	2012/06/13 13:27:31	2.13
+++ ./skinlcars.c	2012/09/09 12:16:50
@@ -975,10 +975,11 @@ 
   osd->DrawEllipse  (xa08 + lineHeight / 2, yb14, xa09 - 1, yb15 - 1, frameColor, 5);
   osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder);
   // Color buttons:
-  osd->DrawRectangle(xb00, yb14, xb01 - 1, yb15 - 1, Theme.Color(clrButtonRedBg));
-  osd->DrawRectangle(xb04, yb14, xb05 - 1, yb15 - 1, Theme.Color(clrButtonGreenBg));
-  osd->DrawRectangle(xb08, yb14, xb09 - 1, yb15 - 1, Theme.Color(clrButtonYellowBg));
-  osd->DrawRectangle(xb12, yb14, xb13 - 1, yb15 - 1, Theme.Color(clrButtonBlueBg));
+  tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
+  osd->DrawRectangle(xb00, yb14, xb01 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey0]));
+  osd->DrawRectangle(xb04, yb14, xb05 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey1]));
+  osd->DrawRectangle(xb08, yb14, xb09 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey2]));
+  osd->DrawRectangle(xb12, yb14, xb13 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey3]));
 }
 
 void cSkinLCARSDisplayMenu::DrawDate(void)
@@ -1458,19 +1459,22 @@ 
 
 void cSkinLCARSDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
 {
+  const char *lutText[] = { Red, Green, Yellow, Blue };
+  tColor lutFg[] = { clrButtonRedFg, clrButtonGreenFg, clrButtonYellowFg, clrButtonBlueFg };
+  tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
   const cFont *font = cFont::GetFont(fontSml);
   if (MenuCategory() == mcMain) {
-     DrawMainButton(Red,    xd00, xd01, xd02, xd03, yd02, yd03, Theme.Color(clrButtonRedFg),    Theme.Color(clrButtonRedBg),    font);
-     DrawMainButton(Green,  xd04, xd05, xd06, xd07, yd02, yd03, Theme.Color(clrButtonGreenFg),  Theme.Color(clrButtonGreenBg),  font);
-     DrawMainButton(Yellow, xd00, xd01, xd02, xd03, yd04, yd05, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font);
-     DrawMainButton(Blue,   xd04, xd05, xd06, xd07, yd04, yd05, Theme.Color(clrButtonBlueFg),   Theme.Color(clrButtonBlueBg),   font);
+     DrawMainButton(lutText[Setup.ColorKey0], xd00, xd01, xd02, xd03, yd02, yd03, Theme.Color(lutFg[Setup.ColorKey0]), Theme.Color(lutBg[Setup.ColorKey0]), font);
+     DrawMainButton(lutText[Setup.ColorKey1], xd04, xd05, xd06, xd07, yd02, yd03, Theme.Color(lutFg[Setup.ColorKey1]), Theme.Color(lutBg[Setup.ColorKey1]), font);
+     DrawMainButton(lutText[Setup.ColorKey2], xd00, xd01, xd02, xd03, yd04, yd05, Theme.Color(lutFg[Setup.ColorKey2]), Theme.Color(lutBg[Setup.ColorKey2]), font);
+     DrawMainButton(lutText[Setup.ColorKey3], xd04, xd05, xd06, xd07, yd04, yd05, Theme.Color(lutFg[Setup.ColorKey3]), Theme.Color(lutBg[Setup.ColorKey3]), font);
      }
   else {
      int h = yb15 - yb14;
-     osd->DrawText(xb02, yb14, Red,    Theme.Color(clrButtonRedFg),    Theme.Color(clrButtonRedBg),    font, xb03 - xb02, h, taLeft | taBorder);
-     osd->DrawText(xb06, yb14, Green,  Theme.Color(clrButtonGreenFg),  Theme.Color(clrButtonGreenBg),  font, xb07 - xb06, h, taLeft | taBorder);
-     osd->DrawText(xb10, yb14, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, xb11 - xb10, h, taLeft | taBorder);
-     osd->DrawText(xb14, yb14, Blue,   Theme.Color(clrButtonBlueFg),   Theme.Color(clrButtonBlueBg),   font, xb15 - xb14, h, taLeft | taBorder);
+     osd->DrawText(xb02, yb14, lutText[Setup.ColorKey0], Theme.Color(lutFg[Setup.ColorKey0]), Theme.Color(lutBg[Setup.ColorKey0]), font, xb03 - xb02, h, taLeft | taBorder);
+     osd->DrawText(xb06, yb14, lutText[Setup.ColorKey1], Theme.Color(lutFg[Setup.ColorKey1]), Theme.Color(lutBg[Setup.ColorKey1]), font, xb07 - xb06, h, taLeft | taBorder);
+     osd->DrawText(xb10, yb14, lutText[Setup.ColorKey2], Theme.Color(lutFg[Setup.ColorKey2]), Theme.Color(lutBg[Setup.ColorKey2]), font, xb11 - xb10, h, taLeft | taBorder);
+     osd->DrawText(xb14, yb14, lutText[Setup.ColorKey3], Theme.Color(lutFg[Setup.ColorKey3]), Theme.Color(lutBg[Setup.ColorKey3]), font, xb15 - xb14, h, taLeft | taBorder);
      }
 }
 
--- ./skinsttng.c	2012/04/23 08:39:11	2.15
+++ ./skinsttng.c	2012/09/09 11:39:06
@@ -571,6 +571,9 @@ 
 
 void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
 {
+  const char *lutText[] = { Red, Green, Yellow, Blue };
+  tColor lutFg[] = { clrButtonRedFg, clrButtonGreenFg, clrButtonYellowFg, clrButtonBlueFg };
+  tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
   cString date = DayDateTime();
   const cFont *font = cFont::GetFont(fontSml);
   int d = 2 * Gap;
@@ -585,10 +588,10 @@ 
   osd->DrawRectangle(t1 + d2, y6, t2 - d2, y7 - 1, clrBlack);
   osd->DrawRectangle(t2 + d2, y6, t3 - d2, y7 - 1, clrBlack);
   osd->DrawRectangle(t3 + d2, y6, t4 - d2, y7 - 1, clrBlack);
-  osd->DrawText(t0 + d, y6, Red,    Theme.Color(clrButtonRedFg),    Theme.Color(clrButtonRedBg),    font, t1 - t0 - 2 * d, 0, taCenter);
-  osd->DrawText(t1 + d, y6, Green,  Theme.Color(clrButtonGreenFg),  Theme.Color(clrButtonGreenBg),  font, t2 - t1 - 2 * d, 0, taCenter);
-  osd->DrawText(t2 + d, y6, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, t3 - t2 - 2 * d, 0, taCenter);
-  osd->DrawText(t3 + d, y6, Blue,   Theme.Color(clrButtonBlueFg),   Theme.Color(clrButtonBlueBg),   font, t4 - t3 - 2 * d, 0, taCenter);
+  osd->DrawText(t0 + d, y6, lutText[Setup.ColorKey0], Theme.Color(lutFg[Setup.ColorKey0]), Theme.Color(lutBg[Setup.ColorKey0]), font, t1 - t0 - 2 * d, 0, taCenter);
+  osd->DrawText(t1 + d, y6, lutText[Setup.ColorKey1], Theme.Color(lutFg[Setup.ColorKey1]), Theme.Color(lutBg[Setup.ColorKey1]), font, t2 - t1 - 2 * d, 0, taCenter);
+  osd->DrawText(t2 + d, y6, lutText[Setup.ColorKey2], Theme.Color(lutFg[Setup.ColorKey2]), Theme.Color(lutBg[Setup.ColorKey2]), font, t3 - t2 - 2 * d, 0, taCenter);
+  osd->DrawText(t3 + d, y6, lutText[Setup.ColorKey3], Theme.Color(lutFg[Setup.ColorKey3]), Theme.Color(lutBg[Setup.ColorKey3]), font, t4 - t3 - 2 * d, 0, taCenter);
 }
 
 void cSkinSTTNGDisplayMenu::SetMessage(eMessageType Type, const char *Text)