(***********************************************************************
   This file is part of GTKpas, an OOP wrapper for GTK+ written
   for Pascal.

   Copyright (C) 2000 by Johann Glaser <Johann.Glaser@gmx.at>

   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 in the file COPYING; if not, write to the 
   Free Software Foundation, Inc., 
   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
***********************************************************************)
Program SpinButton;
{$MODE OBJFPC}
Uses SysUtils,GLib,GDK,GTK,GTKpas;

Type CSpinButtonDemo = Class(CWindow)
                         Function  DeleteEventImpl(aEvent:PGdkEventAny):Gint; virtual; override;
                         Procedure Destroy_; virtual; override;
                         Function  OnCloseButtonClicked(Sender:CButton;Data:GPointer):GBoolean;
                         Function  ToggleSnap(Sender:CToggleButton;Data:GPointer):GBoolean;
                         Function  ToggleNumeric(Sender:CToggleButton;Data:GPointer):GBoolean;
                         Function  ChangeDigits(Sender:CAdjustment;Data:GPointer):GBoolean;
                         Function  GetValue(Sender:CToggleButton;Data:GPointer):GBoolean;
                       End;

Var Kit      : CMain;
    Window   : CSpinButtonDemo;
    Button   : CButton;
    Spinner1 : CSpinButton;

Function CSpinButtonDemo.DeleteEventImpl(aEvent:PGdkEventAny):Gint;
Begin
  inherited DeleteEventImpl(aEvent);
  DeleteEventImpl := 0;
End;
Procedure CSpinButtonDemo.Destroy_;
Begin
  inherited Destroy_;
  Kit.Quit;
End;
Function  CSpinButtonDemo.OnCloseButtonClicked(Sender:CButton;Data:GPointer):GBoolean;
Begin
  OnCloseButtonClicked := True;
  Self.Destroy_;
End;

Function  CSpinButtonDemo.ToggleSnap(Sender:CToggleButton;Data:GPointer):GBoolean;
Begin
  CSpinButton(Data).SnapToTicks := Sender.Active;
  ToggleSnap := False;
End;
Function  CSpinButtonDemo.ToggleNumeric(Sender:CToggleButton;Data:GPointer):GBoolean;
Begin
  CSpinButton(Data).Numeric := Sender.Active;
  ToggleNumeric := False;
End;
Function  CSpinButtonDemo.ChangeDigits(Sender:CAdjustment;Data:GPointer):GBoolean;
Begin
  Spinner1.Digits := CSpinButton(Data).ValueAsInt;
  ChangeDigits := False;
End;
Function  CSpinButtonDemo.GetValue(Sender:CToggleButton;Data:GPointer):GBoolean;
Var Spin : CSpinButton;
    Buf  : AnsiString;
    TheLabel : CLabel;
Begin
  Spin := Spinner1;
  TheLabel := CLabel(Sender.GetUserData);
  if LongInt(Data) = 1 then
    FmtStr(Buf,'%d',[Spin.ValueAsInt])
  else
    FmtStr(Buf,'%0.*f',[Spin.Digits, Spin.ValueAsFloat]);
  TheLabel.Text := @Buf[1];
  GetValue := False;
End;


Var MainVBox : CVBox;
    Frame    : CFrame;
    VBox     : CVBox;
    HBox     : CHBox;
    VBox2    : CVBox;
    TheLabel : CLabel;
    Adj      : CAdjustment;
    Spinner  : CSpinButton;
    Spinner2 : CSpinButton;
    ValLabel : CLabel;
    CheckButton : CCheckButton;

Begin
  Kit := CMain.Create(@ArgC,@ArgV,False);

  Window := CSpinButtonDemo.Create(GTK_WINDOW_TOPLEVEL);
  Window.Title := 'Spin Button';

  MainVBox := CVBox.Create(False, 5);
  MainVBox.BorderWidth := 10;
  Window.Add(MainVBox);

  Frame := CFrame.Create('Not accelerated');
  MainVBox.PackStart(Frame, True, True, 0);
  
  VBox := CVBox.Create(False, 0);
  VBox.BorderWidth := 5;
  Frame.Add(VBox);
  
  (* Day, month, year Spinners *)
  
  HBox := CHBox.Create(False, 0);
  VBox.PackStart(HBox, True, True, 5);
  
  VBox2 := CVBox.Create(False, 0);
  HBox.PackStart(VBox2, True, True, 5);
  
  TheLabel := CLabel.Create('Day :');
  TheLabel.SetAlignment(0, 0.5);
  VBox2.PackStart(TheLabel, False, True, 0);
  
  Adj := CAdjustment.Create(1.0, 1.0, 31.0, 1.0, 5.0, 0.0);
  Spinner := CSpinButton.Create(Adj, 0, 0);
  Spinner.Wrap := True;
  Spinner.ShadowType := GTK_SHADOW_OUT;
  VBox2.PackStart(Spinner, False, True, 0);
  
  VBox2 := CVBox.Create(False, 0);
  HBox.PackStart(VBox2, True, True, 5);
  
  TheLabel := CLabel.Create('Month :');
  TheLabel.SetAlignment(0, 0.5);
  VBox2.PackStart(TheLabel, False, True, 0);
  
  Adj := CAdjustment.Create(1.0, 1.0, 12.0, 1.0, 5.0, 0.0);
  Spinner := CSpinButton.Create(Adj, 0, 0);
  Spinner.Wrap := True;
  Spinner.ShadowType := GTK_SHADOW_ETCHED_IN;
  VBox2.PackStart(Spinner, False, True, 0);
  
  VBox2 := CVBox.Create(False, 0);
  HBox.PackStart(VBox2, True, True, 5);
  
  TheLabel := CLabel.Create('Year :');
  TheLabel.SetAlignment(0, 0.5);
  VBox2.PackStart(TheLabel, False, True, 0);
  
  Adj := CAdjustment.Create(1998.0, 0.0, 2100.0, 1.0, 100.0, 0.0);
  Spinner := CSpinButton.Create(Adj, 0, 0);
  Spinner.Wrap := False;
  Spinner.ShadowType := GTK_SHADOW_IN;
  Spinner.SetUSize(55, 0);
  VBox2.PackStart(Spinner, False, True, 0);
  
  Frame := CFrame.Create('Accelerated');
  MainVBox.PackStart(Frame, True, True, 0);
  
  VBox := CVBox.Create(False, 0);
  VBox.BorderWidth := 5;
  Frame.Add(VBox);
  
  HBox := CHBox.Create(False, 0);
  VBox.PackStart(HBox, False, True, 5);
  
  VBox2 := CVBox.Create(False, 0);
  HBox.PackStart(VBox2, True, True, 5);
  
  TheLabel := CLabel.Create('Value :');
  TheLabel.SetAlignment(0, 0.5);
  VBox2.PackStart(TheLabel, False, True, 0);
  
  Adj := CAdjustment.Create(0.0, -10000.0, 10000.0, 0.5, 100.0, 0.0);
  Spinner1 := CSpinButton.Create(Adj, 1.0, 2);
  Spinner1.Wrap := True;
  Spinner1.SetUSize(100, 0);
  VBox2.PackStart(Spinner1, False, True, 0);
  
  VBox2 := CVBox.Create(False, 0);
  HBox.PackStart(VBox2, True, True, 5);
  
  TheLabel := CLabel.Create('Digits :');
  TheLabel.SetAlignment(0, 0.5);
  VBox2.PackStart(TheLabel, False, True, 0);
  
  Adj := CAdjustment.Create(2, 1, 5, 1, 1, 0);
  Spinner2 := CSpinButton.Create(Adj, 0.0, 0);
  Spinner2.Wrap := True;
  Adj.OnValueChanged := @Window.ChangeDigits;
  Adj.OnValueChangedData := GPointer(Spinner2);
  VBox2.PackStart(Spinner2, False, True, 0);
  
  HBox := CHBox.Create(False, 0);
  VBox.PackStart(HBox, False, True, 5);
  
  CheckButton := CCheckButton.Create('Snap to 0.5-ticks');
  CheckButton.OnToggled := @Window.ToggleSnap;
  CheckButton.OnToggledData := Spinner1;
  VBox.PackStart(CheckButton, True, True, 0);
  CheckButton.Active := True;
  
  CheckButton := CCheckButton.Create('Numeric only input mode');
  CheckButton.OnToggled := @Window.ToggleNumeric;
  CheckButton.OnToggledData := Spinner1;
  VBox.PackStart(CheckButton, True, True, 0);
  CheckButton.Active := True;
  
  ValLabel := CLabel.Create('');
  
  HBox := CHBox.Create(False, 0);
  VBox.PackStart(HBox, False, True, 5);
  Button := CButton.Create('Value as Int');
  Button.SetUserData(ValLabel);
  Button.OnClicked := @Window.GetValue;
  Button.OnClickedData := 1;
  HBox.PackStart(Button, True, True, 5);
  
  Button := CButton.Create('Value as Float');
  Button.SetUserData(ValLabel);
  Button.OnClicked := @Window.GetValue;
  Button.OnClickedData := 2;
  HBox.PackStart(Button, True, True, 5);
  
  VBox.PackStart(ValLabel, True, True, 0);
  ValLabel.Text := '0';
  
  HBox := CHBox.Create(False, 0);
  MainVBox.PackStart(HBox, False, True, 0);
  
  Button := CButton.Create('Close');
  Button.OnClicked := @Window.OnCloseButtonClicked;
  HBox.PackStart(Button, True, True, 5);

  Window.ShowAll;

  (* Enter the event loop *)
  Kit.Run;
End.

