Logo Search packages:      
Sourcecode: vdkbuilder2 version File versions  Download package

vdkb_menu.cc

/*
 * ===========================
 * VDK Builder
 * Version 0.1.1
 * Revision 0.0
 * March 1999
 * ===========================
 *
 * Copyright (C) 1998,1999 Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 *
 * Based on VDK Library
 * Copyright (C) 1998, Mario Motta
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 */
#if HAVE_CONFIG_H
#include <config.h>
#endif

#if !HAVE_GNOME
  #if ENABLE_NLS
    #include <libintl.h>
//#define _(str) gettext(str)
#define _(str) \
    ( g_utf8_validate(gettext(str),-1,NULL) ? \
    gettext(str) : \
    g_locale_to_utf8(gettext(str),-1,NULL,NULL,NULL) )
#define N_(str) str
  #else
    #define _(str) str
    #define N_(str) str 
  #endif
#else
 #include <gnome.h>
#endif

#include <vdkb2/vdkb_evcontain.h>
//#include <vdkb2/vdkb_labelbutton.h>
#include <vdkb2/vdkb_form.h>
#include <vdk/vdk.h>
#include <vdkb2/vdkb_utils.h>
#include <vdkb2/vdkb_parser.h>
#include <vdkb2/vdkb_prjman.h>
#include <vdkb2/vdkb_objinspect.h>
#include <stdlib.h>
#include <vdkb2/vdkb_menuitem.h>
#include <vdkb2/vdkb_menu.h>
#include <vdkb2/vdkb_fixed.h>
#include <vdkb2/vdkb_orderdlg.h>
static char buff[128];
extern char* wi_widget_prompts[];
int VDKBMenu::Counter = 0;

DEFINE_EVENT_LIST(VDKBMenu,VDKBEventContainer);
DEFINE_SIGNAL_LIST(VDKBMenu,VDKBEventContainer);

/*
 */
bool
VDKBMenu:: DelBox(VDKObject* sender)
{
  // unlock menu if locked
  if(Locked)
      Locked = false;
  // destroy inner gtk+ placeholder widget
  gtk_widget_destroy(container);
  // remove menu from parent list
  VDKBMenuItem* p = dynamic_cast<VDKBMenuItem*>(Parent());
  if(p)
    {
      p->RemoveItem(this);
      p->boxlist.flush();
    }
  // notify to inspector that object was deleted
  VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
  if(ownerform)
    {
      // set active widget to NULL
      ownerform->Active = NULL;
      VDKBProjectManager* prjman =
      dynamic_cast<VDKBProjectManager*>(ownerform->Owner());
      if(prjman && prjman->objInspector)
      prjman->objInspector->SetActive(NULL);
    }
  return true;
}

/*
 */
bool
VDKBMenu::SetBoxSize(VDKObject* sender)
{
  VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
  if(ownerform)
      ownerform->SetBoxSize(NULL);
  return true;
}
/*
we use a little trick here:
since VDKBMenuItem::MakeWidget(ownerform, GdkEvent* = NULL)
we use (GdkEvent*) l_justify or r_justify or pos_justify+<x>
in order to appen,prepend or inser a menu item into menubar.
 */
bool
VDKBMenu::AddMenuItem(VDKObject* sender)
{
  VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
  if(ownerform)
    {
      GdkEventButton event;
      event.state =  l_justify;
      VDKBMenuItem::MakeWidget(ownerform, (GdkEvent*) &event);
      VDKBProjectManager* prjman =
      dynamic_cast<VDKBProjectManager*>(ownerform->Owner());
      if(prjman && prjman->objInspector)
      {
        prjman->objInspector->LoadTree(ownerform);
        ownerform->Changed = true;
      }
    }
  return true;
}
bool
VDKBMenu::PrependMenuItem(VDKObject* sender)
{
  VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
  if(ownerform)
    {
      GdkEventButton event;
      event.state =  r_justify;
      VDKBMenuItem::MakeWidget(ownerform, (GdkEvent*) &event);
      VDKBProjectManager* prjman =
      dynamic_cast<VDKBProjectManager*>(ownerform->Owner());
      if(prjman && prjman->objInspector)
      {
        prjman->objInspector->LoadTree(ownerform);
        ownerform->Changed = true;
      }
    }
  return true;
}
bool
VDKBMenu::InsertMenuItem(VDKObject* sender)
{
  VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
  if(ownerform)
    {
      // widget reorder dialog will receive
      // boxlist address and an int* to fill
      // with inserting pos (answer < 0 if user cancelled)
      int pos = -1;
      Vdkb_reorderdlgForm* child =
      new Vdkb_reorderdlgForm(ownerform,
                        &boxlist,
                        &pos,
                        NULL);
      child->Setup();
      child->ShowModal(GTK_WIN_POS_MOUSE);
      if(pos > 0)
      {
        GdkEventButton event;
        event.state =  pos_justify+pos;
        VDKBMenuItem::MakeWidget(ownerform,(GdkEvent*) &event);
        VDKBProjectManager* prjman =
          dynamic_cast<VDKBProjectManager*>(ownerform->Owner());
        if(prjman && prjman->objInspector)
          {
            prjman->objInspector->LoadTree(ownerform);
            ownerform->Changed = true;
          }
      }
    }
  return true;
}
/*
Adds a new menu item

bool
VDKBMenu::AddMenuItem(VDKObject* sender)
{
VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
if(ownerform)
VDKBMenuItem::MakeWidget(ownerform);
return true;
}
*/
/*
handle button press on menus.
Dblclick toggles  menu "Locked" status.
When locked menu does not answer to signals.
When not locked pass signal trough hierarchy to be
anwsered by container parent.
 */
bool
VDKBMenu::OnButtonPressed(VDKObject* sender, GdkEvent* ev)
{
  GdkEventButton* event = (GdkEventButton*) ev;
  // pass to ancestor so widget will be marked
  if(event && event->type == GDK_2BUTTON_PRESS)
    Locked = Locked ? false : true;
  if(Locked)
    {
      gtk_signal_emit_stop_by_name(GTK_OBJECT(ObjectFromVDK()->WrappedWidget()),
                     "button_press_event");
      VDKBEventContainer::OnButtonPressed(sender/*this*/,ev);
      return true;
    }
  else
    ClearMark();
  return false;
}
/*
  -
 */
bool
VDKBMenu::OnButtonReleased(VDKObject* sender, GdkEvent* event)
{
  /*
    When locked menu  shouldn't react to events,
    signal is stopped here.
  */
  if(Locked)
    gtk_signal_emit_stop_by_name(GTK_OBJECT(WrappedWidget()),
                         "button_release_event");
 return Locked;
}
/*
  - handle enter event
 */
bool
VDKBMenu::OnEnter(VDKObject* sender, GdkEvent* ev)
{
  if(Locked)
    gtk_signal_emit_stop_by_name(GTK_OBJECT(WrappedWidget()),
                         "enter_notify_event");
  return Locked;
}
/*
  - handle enter event
 */
bool
VDKBMenu::OnLeave(VDKObject* sender, GdkEvent* ev)
{
  if(Locked)
    gtk_signal_emit_stop_by_name(GTK_OBJECT(WrappedWidget()),
                         "leave_notify_event");
  return Locked;
}

//===========================================
/*
 */
VDKBMenu::VDKBMenu(char* name, VDKForm* owner):
  VDKBEventContainer(name,owner)
{
  Counter++;
  VDKBObject::object = this;
  VDKBEventContainer::mode = mode;
  Init();
}

/*
 */
VDKBMenu::VDKBMenu(char* name,VDKBEventContainer* outer):
    VDKBEventContainer(name,outer->Owner())
{
  VDKBObject::object = this;
  Counter++;
  outerbox = outer;
  Init();
 }
/*
 */
void
VDKBMenu::Init()
{
  // FIX ME: lang support
  // add  frame properties
  // names. (Others props are prepended  by VDKBObject constructor)
  Locked = false;
  AddBox();
  // makes a pop menu
  popmenu = new VDKMenu(Owner());
  VDKMenuItem* nope =  new VDKMenuItem(popmenu,"Nop");
  nope->Enabled = false;
  popmenu->Separator();
  addmenuitem = new VDKMenuItem(popmenu,_("Append a menu item"));
  prependmenuitem = new VDKMenuItem(popmenu,_("Prepend a menu item"));
  insertmenuitem = new VDKMenuItem(popmenu,_("Insert a menu item"));
  popmenu->Separator();

  setsize = new VDKMenuItem(popmenu,_(wi_widget_prompts[19]));
  popmenu->Separator();
  delBox = new VDKMenuItem(popmenu,_("Remove menu"));

  SignalConnect(delBox,"activate",&VDKBMenu::DelBox);
  SignalConnect(setsize,"activate",&VDKBMenu::SetBoxSize);
  SignalConnect(addmenuitem,"activate",&VDKBMenu::AddMenuItem);
  SignalConnect(prependmenuitem,"activate",&VDKBMenu::PrependMenuItem);
  SignalConnect(insertmenuitem,"activate",&VDKBMenu::InsertMenuItem);

  EventConnect("button_press_event", &VDKBMenu::OnButtonPressed);
  EventConnect("button_release_event", &VDKBMenu::OnButtonReleased);
  EventConnect("enter_notify_event", &VDKBMenu::OnEnter);
  EventConnect("leave_notify_event", &VDKBMenu::OnLeave);
  /* assign this as parent so this can receive signals  */
  popmenu->Parent(this);
  /*
    better add it to owner, so will be surely
    destroyed even if never popped
  */
  Owner()->AddItem(popmenu);
}
/*
Assigns new menu to container
 */
void
VDKBMenu::AddBox()
{
  widget = sigwid = container = gtk_menu_new();
  gtk_widget_set_size_request(widget,100,-1);
  gtk_widget_show(container);
}

/*
Does not call VDKBObjectContainer since
is not a VDKContainer.
 */
void
VDKBMenu::AddWidget(VDKObject* wid, int justify,
                int expand, int fill , int padding,
                bool forceArgs)
{
  VDKMenuItem* menuitem = dynamic_cast<VDKMenuItem*>(wid);
  if(menuitem)
    {
      if(justify >= pos_justify)
      {
        gtk_menu_shell_insert(GTK_MENU_SHELL(container),
                        wid->Widget(),
                        justify-pos_justify);
        boxlist.insertAt(wid,justify-pos_justify);
      }
      else
      {
        switch(justify)
          {
          case r_justify:
            gtk_menu_shell_prepend(GTK_MENU_SHELL(container),wid->Widget());
            boxlist.addH(wid);
            break;
          case l_justify:
          default:
            gtk_menu_shell_append(GTK_MENU_SHELL(container),wid->Widget());
            boxlist.add(wid);
          }
      }
      VDKBGuiForm* ownerform = dynamic_cast<VDKBGuiForm*>(Owner());
      if(ownerform)
      ownerform->Changed = true;
      items.add(wid);
      wid->Parent(this);
      gtk_widget_show(wid->Widget());
    }
  else
    ; // FIX ME: warn user
}
/*
extra args unused
 */
void
VDKBMenu::Add(VDKObject* wid, int justify,
                  int expand, int fill , int padding,
                  bool forceArgs)
{
AddWidget(wid);
}
/*
  This method is called by global MakeWidget() in vdkb_design.cc
  MakeWidget() scans a table that maps class id's with each
  static MakeWidget() for each class. Class id's are generated
  during clicks on widget palette.
  On return:
  0 - successfull
  1 - unsupported widget
  2 - target is not a container
  3 - no active widget
  4 - unuseful call
*/
int
VDKBMenu::MakeWidget(VDKBGuiForm* owner, GdkEvent* ev)
{
  // autogenerate first suitable frame counter
  // to ensure unicity
  int result = 0;
  for(sprintf(buff,"Menu%d",VDKBMenu::Counter);
      owner->ChildWithName(buff)!= (VDKObject*) NULL;
      VDKBMenu::Counter++)
    sprintf(buff,"Menu%d",VDKBMenu::Counter);
  VDKBMenu* box = new VDKBMenu(buff,owner);
  if(owner->Active)
    {
      VDKBEventContainer* container =
      dynamic_cast<VDKBEventContainer*>(owner->Active);
      if(container)
      {
        if(ev && dynamic_cast<VDKBFixed*>(container))
          result = 2;
        else
          container->AddWidget(box);
        box->outerbox = container;
      }
      else if(! owner->Active->AddToParent(box,ev))
      // target isn't a container
        result =  2;
    }
  else
    // no active widget
    result = 3;
  // 0 on success
  if(result)
    box->Destroy();
 return result;
}
////////////////////////////////////////////////////////////////////
/*
 */
void
VDKBMenu::WriteOnFrm(FILE* fp, VDKBObject* parentobj)
{
  VDKBObject::WriteOnFrm(fp,parentobj);
}

char*
VDKBMenu::CreateSource(char* buffer,VDKBParser& parser)
{
  char* source;
  char obj_name[128];
  char obj_parent[128];
  char temp[256];
  //  char arg[128];
  // get name, mode and parent
  if ( !parser.GetParam(obj_name,buffer,"this:") ||
       !parser.GetParam(obj_parent,buffer,"parent:")
       )
    return NULL;
  else
    source = new char[1024];
  sprintf(temp,"\n%s = new VDKMenu(this);" ,obj_name);
  strcpy(source,temp);
  // get size
  VDKPoint size = parser.Size(buffer);
  if(size.X() > 0 || size.Y() > 0)
    {
      sprintf(temp,"\n%s->SetSize(%d,%d);",obj_name,size.X(),size.Y());
      strcat(source,temp);
    }
  if(strcmp(obj_parent,NIHIL_PROP))
    sprintf(temp,"\n%s->Add(%s);",obj_parent,obj_name);
  else
    sprintf(temp,"\nAdd(%s);",obj_name);
  strcat(source,temp);
  return source;
}
/*
 */
bool
VDKBMenu::CreateWidget(VDKBGuiForm* owner, char* buffer,VDKBParser& parser)
{
  char obj_name[128];
  char obj_parent[128];
  VDKBMenu* box;
  // get name, mode and parent
  if ( !parser.GetParam(obj_name,buffer,"this:") ||
       !parser.GetParam(obj_parent,buffer,"parent:")
       )
    return false;
  // get mode and size
  VDKPoint size = parser.Size(buffer);
  // get packing args
  int justification = l_justify;
  int expand=0,fill=0,padding=0;
  char arg[32];
  if(parser.GetParam(arg,buffer,PROP_JUSTIFY_INTERNAL))
    justification = atoi(arg);
  if(parser.GetParam(arg,buffer,PROP_EXPAND_INTERNAL))
    expand = atoi(arg);
  if(parser.GetParam(arg,buffer,PROP_FILL_INTERNAL))
    fill = atoi(arg);
  if(parser.GetParam(arg,buffer,PROP_PADDING_INTERNAL))
    padding = atoi(arg);
  // no parent, widget will be added to owner form innerbox
  if(!strcmp(obj_parent,NIHIL_PROP))
    {
      box = new VDKBMenu(obj_name,owner->InnerBox());
      owner->AddWidget(box,justification,expand,fill,padding);
    }
  // get parent container address
  else
    {
      VDKObject* p = owner->ChildWithName(obj_parent);
      VDKBMenuItem* container = p ?
      dynamic_cast<VDKBMenuItem*>(p) : (VDKBMenuItem*) NULL;
      if(container)
      {
        box = new VDKBMenu(obj_name,owner);
        container->AddWidget(box,justification,expand,fill,padding,true);
        //box->outerbox = container;
      }
      else
      // FIX ME: user warning
      return false;
    }
  // call ancestor to set common properties
  VDKBObject::CreateWidget(box,buffer,parser);
  if(size.X() > 0 || size.Y() > 0)
    box->ObjectFromVDK()->SetSize(size.X(),size.Y());
return true;
}





Generated by  Doxygen 1.6.0   Back to index