aboutsummaryrefslogblamecommitdiffstats
path: root/src/menu/UMenuButton.pas
blob: 509c140b3f6866faecc3f70729ebe4dbe6e3aef5 (plain) (tree)
























                                                                        



                 



                

                 




            

                


                             
 

                 
                            
 

                             
 


                
                         
 

          
                                                


                                                                                                        
                                         









                                                                                                          
                                      
 
           
                                         
 
                                         
 
                                                              
                    
 



                 




                         




                         





                                  
                                                   




                                                      
                                                                 
 
                                
 
                                     

                                                                 
                                    

                                                



              

           
           
               




















                                    

                          


















                                    
                  














                                    
                  







                             
                                             
   
             

                      






                                



                                
                               














                                 






                                  



                                  
                                 

















                                  



                                 


                    
     

                 









                                                       
 






                                                 
                                       




                                                                    
 

            
 


                                   



                                                                              


                                     



                                       
 



                                          
 
                                       
 




                                           
 
                          




                                                                       

                                             













                                                                         

                                             













                                                                         

                                             













                                                                         

                                             




















                                                                         






                                     




                                

                              




















                                            
                                                         















































                                                                                                              

          
                             
           





















                                                                   
















                                                                       

                               




                   

                                                  
                                                 
       















                                            
 





                                            
 





                                            
 





                                            




          





                           



































                                         


                                              





                             
                           

    


                                                                   


                                                         





                               
                          


    
{* UltraStar Deluxe - Karaoke Game
 *
 * UltraStar Deluxe is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *}

unit UMenuButton;

interface

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

{$I switches.inc}

uses
  TextGL,
  UTexture,
  gl,
  UMenuText,
  SDL,
  UMenuInteract;

type
  CButton = class of TButton;

  TButton = class
    protected
      SelectBool:   boolean;

      FadeProgress: real;
      FadeLastTick: cardinal;

      DeSelectW,
      DeSelectH,
      PosX,
      PosY:         real;


    public
      Text:                      array of TText;
      Texture:                   TTexture; // Button Screen position and size
      Texture2:                  TTexture; // second texture only used for fading full resolution covers

      Colorized:                 boolean;
      DeSelectTexture:           TTexture; // texture for colorized hack

      FadeTex:                   TTexture; //Texture for beautiful fading
      FadeTexPos:                byte;     //Pos of the FadeTexture (0: Top, 1: Left, 2: Bottom, 3: Right)

      DeselectType:              integer;  // not used yet
      Visible:                   boolean;

      Reflection:                boolean;
      Reflectionspacing,
      DeSelectReflectionspacing: real;

      Fade,
      FadeText:                  boolean;

      Selectable:                boolean;

      //Number of the Parent Collection, 0 if in no Collection
      Parent:  byte;

      SelectColR,
      SelectColG,
      SelectColB,
      SelectInt,
      SelectTInt:   real;
      //Fade Mod
      SelectW:      real;
      SelectH:      real;

      DeselectColR,
      DeselectColG,
      DeselectColB,
      DeselectInt,
      DeselectTInt: real;

      procedure SetY(Value: real);
      procedure SetX(Value: real);
      procedure SetW(Value: real);
      procedure SetH(Value: real);

      procedure SetSelect(Value: boolean); virtual;
      property X: real read PosX write SetX;
      property Y: real read PosY write SetY;
      property Z: real read Texture.z write Texture.z;
      property W: real read DeSelectW write SetW;
      property H: real read DeSelectH write SetH;
      property Selected: boolean read SelectBool write SetSelect;

      procedure   Draw; virtual;

      constructor Create(); overload;
      constructor Create(Textura: TTexture); overload;
      constructor Create(Textura, DSTexture: TTexture); overload;
      destructor  Destroy; override;

      function GetMouseOverArea: TMouseOverRect;
  end;

implementation

uses 
  SysUtils,
  UDisplay,
  UDrawTexture;

procedure TButton.SetX(Value: real);
{var
  dx:   real;
  T:    integer;    // text}
begin
  {dY := Value - Texture.y;

  Texture.X := Value;

  for T := 0 to High(Text) do
    Text[T].X := Text[T].X + dY;}

  PosX := Value;
  if (FadeTex.TexNum = 0) then
    Texture.X := Value;

end;

procedure TButton.SetY(Value: real);
{var
  dY: real;
  T:  integer;    // text}
begin
  {dY := Value - PosY;


  for T := 0 to High(Text) do
    Text[T].Y := Text[T].Y + dY;}

  PosY := Value;
  if (FadeTex.TexNum = 0) then
    Texture.y := Value;
end;

procedure TButton.SetW(Value: real);
begin
  if SelectW = DeSelectW then
    SelectW := Value;

  DeSelectW := Value;

  if not Fade then
  begin
    if SelectBool then
      Texture.W := SelectW
    else
      Texture.W := DeSelectW;
  end;
end;

procedure TButton.SetH(Value: real);
begin
  if SelectH = DeSelectH then
    SelectH := Value;

  DeSelectH := Value;

  if not Fade then
  begin
    if SelectBool then
      Texture.H := SelectH
    else
      Texture.H := DeSelectH;
  end;
end;

procedure TButton.SetSelect(Value : boolean);
var
  T: integer;
begin
  SelectBool := Value;

  if (Value) then
  begin
    Texture.ColR  := SelectColR;
    Texture.ColG  := SelectColG;
    Texture.ColB  := SelectColB;
    Texture.Int   := SelectInt;

    Texture2.ColR := SelectColR;
    Texture2.ColG := SelectColG;
    Texture2.ColB := SelectColB;
    Texture2.Int  := SelectInt;

    for T := 0 to High(Text) do
      Text[T].Int := SelectTInt;

    //Fade Mod
    if Fade then
    begin
      if (FadeProgress <= 0) then
        FadeProgress := 0.125;
    end
    else
    begin
      Texture.W := SelectW;
      Texture.H := SelectH;
    end;
  end
  else
  begin
    Texture.ColR  := DeselectColR;
    Texture.ColG  := DeselectColG;
    Texture.ColB  := DeselectColB;
    Texture.Int   := DeselectInt;

    Texture2.ColR := DeselectColR;
    Texture2.ColG := DeselectColG;
    Texture2.ColB := DeselectColB;
    Texture2.Int  := DeselectInt;

    for T := 0 to High(Text) do
      Text[T].Int := DeselectTInt;

    //Fade Mod
    if Fade then
    begin
      if (FadeProgress >= 1) then
        FadeProgress := 0.875;
    end
    else
    begin
      Texture.W := DeSelectW;
      Texture.H := DeSelectH;
    end;
  end;
end;

// ***** Public methods ****** //

procedure TButton.Draw;
var
  T:       integer;
  Tick:    cardinal;
  Spacing: real;
begin
  if Visible then
  begin
    //Fade Mod
    T:=0;
    if Fade then
    begin
      if (FadeProgress < 1) and (FadeProgress > 0) then
      begin
        Tick := SDL_GetTicks() div 16;
        if (Tick <> FadeLastTick) then
        begin
          FadeLastTick := Tick;

          if SelectBool then
            FadeProgress := FadeProgress + 0.125
          else
            FadeProgress := FadeProgress - 0.125;

          if (FadeText) then
          begin
            for T := 0 to high(Text) do
            begin
              Text[T].MoveX := (SelectW - DeSelectW) * FadeProgress;
              Text[T].MoveY := (SelectH - DeSelectH) * FadeProgress;
            end;
          end;

        end;
      end;

      //Method without Fade Texture
      if (FadeTex.TexNum = 0) then
      begin
        Texture.W         := DeSelectW + (SelectW - DeSelectW) * FadeProgress;
        Texture.H         := DeSelectH + (SelectH - DeSelectH) * FadeProgress;
        DeSelectTexture.W := Texture.W;
        DeSelectTexture.H := Texture.H;
      end
      else //method with Fade Texture
      begin
        Texture.W         := DeSelectW;
        Texture.H         := DeSelectH;
        DeSelectTexture.W := Texture.W;
        DeSelectTexture.H := Texture.H;

        FadeTex.ColR      := Texture.ColR;
        FadeTex.ColG      := Texture.ColG;
        FadeTex.ColB      := Texture.ColB;
        FadeTex.Int       := Texture.Int;

        FadeTex.Z         := Texture.Z;

        FadeTex.Alpha     := Texture.Alpha;
        FadeTex.TexX1     := 0;
        FadeTex.TexX2     := 1;
        FadeTex.TexY1     := 0;
        FadeTex.TexY2     := 1;

        case FadeTexPos of
          0: //FadeTex on Top
            begin
              //Standard Texture
              Texture.X := PosX;
              Texture.Y := PosY + (SelectH - DeSelectH) * FadeProgress;
              DeSelectTexture.X := Texture.X;
              DeSelectTexture.Y := Texture.Y;
              //Fade Tex
              FadeTex.X := PosX;
              FadeTex.Y := PosY;
              FadeTex.W := Texture.W;
              FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
              FadeTex.ScaleW := Texture.ScaleW;
              //Some Hack that Fixes a little Space between both Textures
              FadeTex.TexY2 := 0.9;
            end;
          1: //FadeTex on Left
            begin
              //Standard Texture
              Texture.X := PosX + (SelectW - DeSelectW) * FadeProgress;
              Texture.Y := PosY;
              DeSelectTexture.X := Texture.X;
              DeSelectTexture.Y := Texture.Y;
              //Fade Tex
              FadeTex.X := PosX;
              FadeTex.Y := PosY;
              FadeTex.H := Texture.H;
              FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
              FadeTex.ScaleH := Texture.ScaleH;
              //Some Hack that Fixes a little Space between both Textures
              FadeTex.TexX2 := 0.9;
            end;
          2: //FadeTex on Bottom
            begin
              //Standard Texture
              Texture.X := PosX;
              Texture.Y := PosY;
              DeSelectTexture.X := Texture.X;
              DeSelectTexture.Y := Texture.Y;
              //Fade Tex
              FadeTex.X := PosX;
              FadeTex.Y := PosY  + (SelectH - DeSelectH) * FadeProgress;;
              FadeTex.W := Texture.W;
              FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
              FadeTex.ScaleW := Texture.ScaleW;
              //Some Hack that Fixes a little Space between both Textures
              FadeTex.TexY1 := 0.1;
            end;
          3: //FadeTex on Right
            begin
              //Standard Texture
              Texture.X := PosX;
              Texture.Y := PosY;
              DeSelectTexture.X := Texture.X;
              DeSelectTexture.Y := Texture.Y;
              //Fade Tex
              FadeTex.X := PosX + (SelectW - DeSelectW) * FadeProgress;
              FadeTex.Y := PosY;
              FadeTex.H := Texture.H;
              FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
              FadeTex.ScaleH := Texture.ScaleH;
              //Some Hack that Fixes a little Space between both Textures
              FadeTex.TexX1 := 0.1;
            end;
        end;
      end;
    end
    else if (FadeText) then
    begin
      Text[T].MoveX := (SelectW - DeSelectW);
      Text[T].MoveY := (SelectH - DeSelectH);
    end;

    if SelectBool or (FadeProgress > 0) or not Colorized then
      DrawTexture(Texture)
    else
    begin
      DeSelectTexture.X := Texture.X;
      DeSelectTexture.Y := Texture.Y;
      DeSelectTexture.H := Texture.H;
      DeSelectTexture.W := Texture.W;
      DrawTexture(DeSelectTexture);
    end;

    //Draw FadeTex
    if (FadeTex.TexNum > 0) then
      DrawTexture(FadeTex);

    if Texture2.Alpha > 0 then
    begin
      Texture2.ScaleW := Texture.ScaleW;
      Texture2.ScaleH := Texture.ScaleH;

      Texture2.X := Texture.X;
      Texture2.Y := Texture.Y;
      Texture2.W := Texture.W;
      Texture2.H := Texture.H;

      Texture2.ColR := Texture.ColR;
      Texture2.ColG := Texture.ColG;
      Texture2.ColB := Texture.ColB;
      Texture2.Int := Texture.Int;

      Texture2.Z := Texture.Z;

      DrawTexture(Texture2);
    end;

    //Reflection Mod
    if (Reflection) then // Draw Reflections
    begin
      if (FadeProgress <> 0) and (FadeProgress <> 1) then
      begin
        Spacing := DeSelectReflectionspacing - (DeSelectReflectionspacing - Reflectionspacing) * FadeProgress;
      end
      else if SelectBool then
        Spacing := Reflectionspacing
      else
        Spacing := DeSelectReflectionspacing;

      if SelectBool or not Colorized then
      with Texture do
      begin
        //Bind Tex and GL Attributes
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);

        glDepthRange(0, 10);
        glDepthFunc(GL_LEQUAL);
        glEnable(GL_DEPTH_TEST);

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBindTexture(GL_TEXTURE_2D, TexNum);

        //Draw
        glBegin(GL_QUADS);//Top Left
          glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
          glTexCoord2f(TexX1*TexW, TexY2*TexH);
          glVertex3f(x, y+h*scaleH+ Spacing, z);

          //Bottom Left
          glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
          glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
          glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);


          //Bottom Right
          glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
          glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
          glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);

          //Top Right
          glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
          glTexCoord2f(TexX2*TexW, TexY2*TexH);
          glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
        glEnd;

        glDisable(GL_TEXTURE_2D);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_BLEND);
      end
      else
      with DeSelectTexture do
      begin
        //Bind Tex and GL Attributes
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);

        glDepthRange(0, 10);
        glDepthFunc(GL_LEQUAL);
        glEnable(GL_DEPTH_TEST);

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBindTexture(GL_TEXTURE_2D, TexNum);

        //Draw
        glBegin(GL_QUADS);//Top Left
          glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
          glTexCoord2f(TexX1*TexW, TexY2*TexH);
          glVertex3f(x, y+h*scaleH+ Spacing, z);

          //Bottom Left
          glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
          glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
          glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);

          //Bottom Right
          glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
          glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
          glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);

          //Top Right
          glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
          glTexCoord2f(TexX2*TexW, TexY2*TexH);
          glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
        glEnd;

        glDisable(GL_TEXTURE_2D);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_BLEND);
      end;
    end;

    for T := 0 to High(Text) do
    begin
      Text[T].Draw;
    end;
  end;
end;

function TButton.GetMouseOverArea: TMouseOverRect;
begin
  if (Display.Cursor_HiddenByScreen = false) then
  begin
    if (FadeTex.TexNum = 0) then
    begin
      Result.X := Texture.X;
      Result.Y := Texture.Y;
      Result.W := Texture.W;
      Result.H := Texture.H;
    end
    else
    begin
      case FadeTexPos of
        0: begin // fade tex on top
          Result.X := Texture.X;
          Result.Y := FadeTex.Y;
          Result.W := Texture.W;
          Result.H := FadeTex.H + Texture.H;
        end;

        1: begin // fade tex on left side
          Result.X := FadeTex.X;
          Result.Y := Texture.Y;
          Result.W := FadeTex.W + Texture.W;
          Result.H := Texture.H;
        end;

        2: begin // fade tex on bottom
          Result.X := Texture.X;
          Result.Y := Texture.Y;
          Result.W := Texture.W;
          Result.H := FadeTex.H + Texture.H;
        end;

        3: begin // fade tex on right side
          Result.X := Texture.X;
          Result.Y := Texture.Y;
          Result.W := FadeTex.W + Texture.W;
          Result.H := Texture.H;
        end;
      end;
    end;
  end;
end;


destructor TButton.Destroy;
begin
  inherited;
end;

constructor TButton.Create();
begin
  inherited Create;
  // We initialize all to 0, nil or false
  Visible        := true;
  SelectBool     := false;
  DeselectType   := 0;
  Selectable     := true;
  Reflection     := false;
  Colorized      := false;

  SelectColR     := 1;
  SelectColG     := 1;
  SelectColB     := 1;
  SelectInt      := 1;
  SelectTInt     := 1;

  DeselectColR   := 1;
  DeselectColG   := 1;
  DeselectColB   := 1;
  DeselectInt    := 0.5;
  DeselectTInt   := 1;

  Fade           := false;
  FadeTex.TexNum := 0;
  FadeProgress   := 0;
  FadeText       := false;
  SelectW        := DeSelectW;
  SelectH        := DeSelectH;

  PosX           := 0;
  PosY           := 0;

  Parent         := 0;
end;

constructor TButton.Create(Textura: TTexture);
begin
  Create();
  Texture         := Textura;
  DeSelectTexture := Textura;
  Texture.ColR    := 0;
  Texture.ColG    := 0.5;
  Texture.ColB    := 0;
  Texture.Int     := 1;
  Colorized       := false;
end;

// Button has the texture-type "colorized"
// Two textures are generated, one with Col the other one with DCol
// Check UMenu.pas line 680 to see the call ( AddButton() )
constructor TButton.Create(Textura, DSTexture: TTexture);
begin
  Create();
  Texture         := Textura;
  DeSelectTexture := DSTexture;
  Texture.ColR    := 1;
  Texture.ColG    := 1;
  Texture.ColB    := 1;
  Texture.Int     := 1;
  Colorized       := true;
end;

end.