Can't find the cause of the error

#include <SubPGraphics.h>
enum Colors
{
  Black,        // Button color
  DarkBlue,
  DarkGreen,
  DarkCyan,
  DarkRed,
  DarkViolet,
  DarkYellow,
  DarkGray,
  
  Gray,
  Blue,
  Green,
  Cyan,
  Red,
  Violet,
  Yellow,
  Steel,
  
  LightGray,
  LightBlue,
  LightGreen,
  LightCyan,
  LightRed,
  LightViolet,
  LightYellow,
  White,
};
byte rgb[][3] =
{
  0x00, 0x00, 0x00,    // Black
  0x00, 0x00, 0x40,    // DarkBlue
  0x00, 0x40, 0x00,    // DarkGreen
  0x00, 0x40, 0x40,    // DarkCyan
  0x40, 0x00, 0x00,    // DarkRed
  0x40, 0x00, 0x40,    // DarkViolet
  0x40, 0x40, 0x00,    // DarkYellow
  0x40, 0x40, 0x40,    // DarkGray
  
  0x80, 0x80, 0x80,    // Gray
  0x00, 0x00, 0x80,    // Blue
  0x00, 0x80, 0x00,    // Green
  0x00, 0x80, 0x80,    // Cyan
  0x80, 0x00, 0x00,    // Red
  0x80, 0x00, 0x80,    // Violet
  0x80, 0x80, 0x00,    // Yellow
  0xA0, 0xA0, 0xA0,    // Steel
  
  0xC0, 0xC0, 0xC0,    // LightGray
  0x00, 0x00, 0xFF,    // LightBlue
  0x00, 0xFF, 0x00,    // LightGreen
  0x00, 0xFF, 0xFF,    // LightCyan
  0xFF, 0x00, 0x00,    // LightRed
  0xFF, 0x00, 0xFF,    // LightViolet
  0xFF, 0xFF, 0x00,    // LightYellow
  0xFF, 0xFF, 0xFF,    // White
};
struct ButtonObj
{
  int idx;
  int X;
  int Y;
  Colors color;
  void ( *MouseHandler )( );
};

struct OldButton
{
  int idx;
  int X;
  int Y;
};
ButtonObj normal  = { 0, 39, 3, LightBlue, Manual );
ButtonObj bulb  = { 1, 109, 3, LightCyan, Manual };
ButtonObj tl  = { 2, 179, 3, LightViolet, Manual };
ButtonObj triggered  = { 3, 249, 3, LightGreen, Manual };
OldButton OldBtn = { 0, 0, 0 };
void DrawButton( ButtonObj &button )
{
  DrawButton( button.idx, button.X, button.Y );
}

void DrawButton( int idx,  int x,  int y)
{
  switch (idx) 
    {
      case 0:
        image(loadImage("hand.bmp"), x, y);
        break;
      case 1:
        image(loadImage("bulb.bmp"), x, y);
        break;
      case 2:
        image(loadImage("timelapse.bmp"), x, y);
        break;
      case 3:
        image(loadImage("triggered.bmp"), x, y);
        break;
    }
}
boolean ButtonDown( ButtonObj &button )
{
  if( mouseX >= button.X && mouseX <= button.X + 32 && mouseY >= button.Y && mouseY <= button.Y + 32 )
  { 
    noFill();
    if (OldBtn.idx != button.idx)
    {
      stroke( rgb[Black][0], rgb[Black][1], rgb[Black][2] );  
      rect(OldBtn.X-3, OldBtn.Y-3, 37, 37);
      OldBtn.X=button.X;
      OldBtn.Y=button.Y;
      OldBtn.idx=button.idx;
    }
    stroke( rgb[button.color][0], rgb[button.color][1], rgb[button.color][2] );
    rect(button.X-3, button.Y-3, 37, 37);
    button.MouseHandler( );
    return true;
  }
  return false;
}
void CheckButtonPressed( )
{
  gettouch( );
  if( ButtonDown( normal ) )
    Display7SegmentDigit( 50, 50, 0, 8 );
  else if( ButtonDown( bulb ) )
    Display7SegmentDigit( 50, 50, 1, 8 );
  else if( ButtonDown( tl ) )
    Display7SegmentDigit( 50, 50, 2, 8 );
  else if( ButtonDown( triggered ) )
    Display7SegmentDigit( 50, 50, 3, 8 );
}
void DrawScreen( )
{
  DrawButton( normal );
  DrawButton( bulb );
  DrawButton( tl );
  DrawButton( triggered );
}
void setup()
{
  background(0);
  //open(FlashTransfer); 
  DrawScreen( );
}
void loop()
{
  CheckButtonPressed( );
}


void Manual( )
{
}

The error is

[apply] C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\build424336811633203936.tmp\tmp\GVI_Touch/GVI_Touch.pde:82: error: expected `}’ before ‘)’ token
[apply] C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\build424336811633203936.tmp\tmp\GVI_Touch/GVI_Touch.pde:82: error: expected ‘,’ or ‘;’ before ‘)’ token

Can anyone tell me what i’m missing here?

EDIT: Turns out I'm completely wrong here. See deSilva's comment below.

One problem at least is that you have a comma after the last value in your rgb[] array. It should end with

 0xFF };

Same problem in your enum too.

Andrew

No, that is fine - even considered good C-practice....

The culprit is

ButtonObj normal  = { 0, 39, 3, LightBlue, Manual );

Sometimes difficult to see whether it's a ) or a }...

Well I never, I would have sworn I'd had compiler error messages from leaving in a trailing comma, and in Java too. I've just tried it in both and you're right, it works fine. Sorry about that.

Can't see why it would be good practice though...

Andrew

It simplifies editing: You can add or delete lines without caring whether it's the last one or not. In C the comma and the semi-colon are considered to be terminators rather than separators, but in some cases it is allowed to ommit them. Some consider that to be a design fault in the language :-)

Thanks guys I guess i have to change my gases

I guess i have to change my gases

I'm not sure how that is going to help, but good luck anyway. ;D

I've spend 30min last night trying to figure it out, bu i didn't see that )