(***********************************************************************
   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 MenuExample;
{$MODE OBJFPC}
Uses SysUtils,GLib,GDK,GTK,GTKpas;

Type CMenuWin = Class(CWindow)
                  Function  DeleteEventImpl(aEvent:PGdkEventAny):Gint; virtual; override;
                  Procedure Destroy_; virtual; override;
                  Function  OnButtonPressed(Sender:CButton;Data:GPointer):GBoolean;
                  Function  MenuItemResponse(Sender:CMenuItem;Data:GPointer):GBoolean;
                End;

Var Kit       : CMain;
    Window    : CWindow;
    Menu      : CMenu;
    MenuItems : CMenuItem;
    RootMenu  : CMenuItem;
    VBox      : CVBox;
    MenuBar   : CMenuBar;
    Button    : CButton;

(* It's a good idea to do this for all windows. *)
Function CMenuWin.DeleteEventImpl(aEvent:PGdkEventAny):Gint;
Begin
  inherited DeleteEventImpl(aEvent);
  DeleteEventImpl := 0;
End;
Procedure CMenuWin.Destroy_;
Begin
  inherited Destroy_;
  WriteLn('Destroy_');
  Kit.Quit;
End;

(* Respond to a button-press by posting a menu passed in as widget.
 *
 * Note that the "widget" argument is the menu being posted, NOT
 * the button that was pressed.
 *)
Function  CMenuWin.OnButtonPressed(Sender:CButton;Data:GPointer):GBoolean;
Begin
  CMenu(Data).Popup(NULL, NULL, NULL, NULL,1,2{, bevent->button, bevent->time}); { !!! }
  (* Tell calling code that we have handled this event; the buck
   * stops here. *)
  Result := True;
End;

(* Print a string when a menu item is selected *)
Function  CMenuWin.MenuItemResponse(Sender:CMenuItem;Data:GPointer):GBoolean;
Begin
  WriteLn(PGChar(Data));
  Result := True;
End;


Const ButtonName : PGChar = 'cool button';

Var I          : LongInt;
    Buf        : AnsiString;

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

  (* Create a new window *)
  Window := CMenuWin.Create(GTK_WINDOW_TOPLEVEL);
{  (* Sets the border width of the window. *)
  Window.BorderWidth := 10;}
  Window.SetUSize(200,100);
  Window.Title := 'GTK Menu Test';
  Window.Realize;

  (* Init the menu-widget, and remember -- never
   * gtk_show_widget() the menu widget!! 
   * This is the menu that holds the menu items, the one that
   * will pop up when you click on the "Root Menu" in the app *)

  Menu := CMenu.Create;

  (* Next we make a little loop that makes three menu-entries for "test-menu".
   * Notice the call to gtk_menu_append.  Here we are adding a list of
   * menu items to our menu.  Normally, we'd also catch the "clicked"
   * signal on each of the menu items and setup a callback for it,
   * but it's omitted here to save space. *)

  For I := 0 to 2 do
    Begin
      (* Copy the names to the buf. *)
      FmtStr(Buf,'Test-undermenu - %d',[I]);
      (* Create a new menu-item with a name... *)
      MenuItems := CMenuItem.Create(PGChar(Buf));

      (* ...and add it to the menu. *)
      Menu.Append(MenuItems);

      (* Do something interesting when the menuitem is selected *)
      MenuItems.OnActivate := @CMenuWin(Window).MenuItemResponse;
      MenuItems.OnActivateData := g_strdup(PGChar(Buf));
      
      (* Show the widget *)
      MenuItems.Show;
    End;

  (* This is the root menu, and will be the label
   * displayed on the menu bar.  There won't be a signal handler attached,
   * as it only pops up the rest of the menu when pressed. *)
  RootMenu := CMenuItem.Create('Root Menu');
  RootMenu.Show;

  (* Now we specify that we want our newly created "menu" to be the menu
   * for the "root menu" *)
  RootMenu.SetSubmenu(CMenu(Menu));

  (* A vbox to put a menu and a button in: *)
  VBox := CVBox.Create(FALSE,0);
  Window.Add(VBox);
  VBox.Show;

  (* Create a menu-bar to hold the menus and add it to our main window *)
  MenuBar := CMenuBar.Create;
  VBox.PackStart(MenuBar, FALSE, FALSE, 2);
  MenuBar.Show;

  (* Create a button to which to attach menu as a popup *)
  Button := CButton.Create('press me');
  Button.OnPressed := @CMenuWin(Window).OnButtonPressed;
  Button.OnPressedData := Menu;
  VBox.PackEnd(Button, TRUE, TRUE, 2);
  Button.Show;

  (* And finally we append the menu-item to the menu-bar -- this is the
   * "root" menu-item I have been raving about =) *)
  MenuBar.Append(RootMenu);

  (* always display the window as the last step so it all splashes on
   * the screen at once. *)
  Window.Show;

  (* Rest in Run and wait for the fun to begin! *)
  Kit.Run;
End.
