Commit 0e20e307 authored by Sebastien Barre's avatar Sebastien Barre
Browse files

enh: add entry set

parent 47ae16fb
......@@ -20,6 +20,7 @@ SET( KWWidgets_SRCS
vtkKWCornerAnnotation.cxx
vtkKWDialog.cxx
vtkKWEntry.cxx
vtkKWEntrySet.cxx
vtkKWExtent.cxx
vtkKWFrame.cxx
vtkKWGenericComposite.cxx
......
/*=========================================================================
Module: vtkKWEntrySet.cxx
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkKWEntrySet.h"
#include "vtkKWApplication.h"
#include "vtkKWEntry.h"
#include "vtkLinkedList.txx"
#include "vtkLinkedListIterator.txx"
#include "vtkObjectFactory.h"
//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkKWEntrySet);
vtkCxxRevisionMacro(vtkKWEntrySet, "1.1");
int vtkvtkKWEntrySetCommand(ClientData cd, Tcl_Interp *interp,
int argc, char *argv[]);
//----------------------------------------------------------------------------
vtkKWEntrySet::vtkKWEntrySet()
{
this->PackHorizontally = 0;
this->MaximumNumberOfWidgetInPackingDirection = 0;
this->PadX = 0;
this->PadY = 0;
this->Entries = vtkKWEntrySet::EntriesContainer::New();
}
//----------------------------------------------------------------------------
vtkKWEntrySet::~vtkKWEntrySet()
{
// Delete all entries
vtkKWEntrySet::EntrySlot *entry_slot = NULL;
vtkKWEntrySet::EntriesContainerIterator *it =
this->Entries->NewIterator();
it->InitTraversal();
while (!it->IsDoneWithTraversal())
{
if (it->GetData(entry_slot) == VTK_OK)
{
if (entry_slot->Entry)
{
entry_slot->Entry->Delete();
entry_slot->Entry = NULL;
}
delete entry_slot;
}
it->GoToNextItem();
}
it->Delete();
// Delete the container
this->Entries->Delete();
}
//----------------------------------------------------------------------------
vtkKWEntrySet::EntrySlot*
vtkKWEntrySet::GetEntrySlot(int id)
{
vtkKWEntrySet::EntrySlot *entry_slot = NULL;
vtkKWEntrySet::EntrySlot *found = NULL;
vtkKWEntrySet::EntriesContainerIterator *it =
this->Entries->NewIterator();
it->InitTraversal();
while (!it->IsDoneWithTraversal())
{
if (it->GetData(entry_slot) == VTK_OK && entry_slot->Id == id)
{
found = entry_slot;
break;
}
it->GoToNextItem();
}
it->Delete();
return found;
}
//----------------------------------------------------------------------------
vtkKWEntry* vtkKWEntrySet::GetEntry(int id)
{
vtkKWEntrySet::EntrySlot *entry_slot =
this->GetEntrySlot(id);
if (!entry_slot)
{
return NULL;
}
return entry_slot->Entry;
}
//----------------------------------------------------------------------------
int vtkKWEntrySet::HasEntry(int id)
{
return this->GetEntrySlot(id) ? 1 : 0;
}
//----------------------------------------------------------------------------
void vtkKWEntrySet::Create(vtkKWApplication *app, const char *args)
{
// Call the superclass to create the widget and set the appropriate flags
if (!this->Superclass::Create(app, "frame", args))
{
vtkErrorMacro("Failed creating widget " << this->GetClassName());
return;
}
// Update enable state
this->UpdateEnableState();
}
//----------------------------------------------------------------------------
void vtkKWEntrySet::UpdateEnableState()
{
this->Superclass::UpdateEnableState();
vtkKWEntrySet::EntrySlot *entry_slot = NULL;
vtkKWEntrySet::EntriesContainerIterator *it =
this->Entries->NewIterator();
it->InitTraversal();
while (!it->IsDoneWithTraversal())
{
if (it->GetData(entry_slot) == VTK_OK)
{
entry_slot->Entry->SetEnabled(this->Enabled);
}
it->GoToNextItem();
}
it->Delete();
}
//----------------------------------------------------------------------------
int vtkKWEntrySet::AddEntry(int id,
vtkKWObject *object,
const char *method_and_arg_string,
const char *balloonhelp_string)
{
// Widget must have been created
if (!this->IsCreated())
{
vtkErrorMacro("The entry set must be created before any entry "
"is added.");
return 0;
}
// Check if the new entry has a unique id
if (this->HasEntry(id))
{
vtkErrorMacro("A entry with that id (" << id << ") already exists "
"in the entry set.");
return 0;
}
// Add the entry slot to the manager
vtkKWEntrySet::EntrySlot *entry_slot =
new vtkKWEntrySet::EntrySlot;
if (this->Entries->AppendItem(entry_slot) != VTK_OK)
{
vtkErrorMacro("Error while adding a entry to the set.");
delete entry_slot;
return 0;
}
// Create the entry
entry_slot->Entry = vtkKWEntry::New();
entry_slot->Id = id;
entry_slot->Entry->SetParent(this);
entry_slot->Entry->Create(this->GetApplication(), 0);
entry_slot->Entry->SetEnabled(this->Enabled);
// Set balloon help, if any
if (object && method_and_arg_string)
{
entry_slot->Entry->BindCommand(object, method_and_arg_string);
}
if (balloonhelp_string)
{
entry_slot->Entry->SetBalloonHelpString(balloonhelp_string);
}
// Pack the entry
this->Pack();
return 1;
}
// ----------------------------------------------------------------------------
void vtkKWEntrySet::Pack()
{
if (!this->IsCreated())
{
return;
}
ostrstream tk_cmd;
tk_cmd << "catch {eval grid forget [grid slaves " << this->GetWidgetName()
<< "]}" << endl;
vtkKWEntrySet::EntrySlot *entry_slot = NULL;
vtkKWEntrySet::EntriesContainerIterator *it =
this->Entries->NewIterator();
int col = 0;
int row = 0;
it->InitTraversal();
while (!it->IsDoneWithTraversal())
{
if (it->GetData(entry_slot) == VTK_OK)
{
tk_cmd << "grid " << entry_slot->Entry->GetWidgetName()
<< " -sticky news"
<< " -column " << (this->PackHorizontally ? col : row)
<< " -row " << (this->PackHorizontally ? row : col)
<< " -padx " << this->PadX
<< " -pady " << this->PadY
<< endl;
col++;
if (this->MaximumNumberOfWidgetInPackingDirection &&
col >= this->MaximumNumberOfWidgetInPackingDirection)
{
col = 0;
row++;
}
}
it->GoToNextItem();
}
it->Delete();
// Weights
int i;
int maxcol = (row > 0) ? this->MaximumNumberOfWidgetInPackingDirection : col;
for (i = 0; i < maxcol; i++)
{
tk_cmd << "grid " << (this->PackHorizontally ? "column" : "row")
<< "configure " << this->GetWidgetName() << " "
<< i << " -weight 1" << endl;
}
for (i = 0; i <= row; i++)
{
tk_cmd << "grid " << (this->PackHorizontally ? "row" : "column")
<< "configure " << this->GetWidgetName() << " "
<< i << " -weight 1" << endl;
}
tk_cmd << ends;
this->Script(tk_cmd.str());
tk_cmd.rdbuf()->freeze(0);
}
// ----------------------------------------------------------------------------
void vtkKWEntrySet::SetPackHorizontally(int _arg)
{
if (this->PackHorizontally == _arg)
{
return;
}
this->PackHorizontally = _arg;
this->Modified();
this->Pack();
}
// ----------------------------------------------------------------------------
void vtkKWEntrySet::SetMaximumNumberOfWidgetInPackingDirection(int _arg)
{
if (this->MaximumNumberOfWidgetInPackingDirection == _arg)
{
return;
}
this->MaximumNumberOfWidgetInPackingDirection = _arg;
this->Modified();
this->Pack();
}
// ----------------------------------------------------------------------------
void vtkKWEntrySet::SetPadding(int x, int y)
{
if (this->PadX == x && this->PadY == y)
{
return;
}
this->PadX = x;
this->PadY = y;
this->Modified();
this->Pack();
}
//----------------------------------------------------------------------------
void vtkKWEntrySet::HideEntry(int id)
{
this->SetEntryVisibility(id, 0);
}
//----------------------------------------------------------------------------
void vtkKWEntrySet::ShowEntry(int id)
{
this->SetEntryVisibility(id, 1);
}
//----------------------------------------------------------------------------
void vtkKWEntrySet::SetEntryVisibility(int id, int flag)
{
vtkKWEntrySet::EntrySlot *entry_slot =
this->GetEntrySlot(id);
if (entry_slot && entry_slot->Entry)
{
this->Script("grid %s %s",
(flag ? "" : "remove"),
entry_slot->Entry->GetWidgetName());
}
}
//----------------------------------------------------------------------------
int vtkKWEntrySet::GetNumberOfVisibleEntries()
{
if (!this->IsCreated())
{
return 0;
}
return atoi(this->Script("llength [grid slaves %s]", this->GetWidgetName()));
}
//----------------------------------------------------------------------------
void vtkKWEntrySet::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "PackHorizontally: "
<< (this->PackHorizontally ? "On" : "Off") << endl;
os << indent << "MaximumNumberOfWidgetInPackingDirection: "
<< (this->MaximumNumberOfWidgetInPackingDirection ? "On" : "Off") << endl;
}
/*=========================================================================
Module: vtkKWEntrySet.h
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkKWEntrySet - a "set of entries" widget
// .SECTION Description
// A simple widget representing a set of entries. Entries
// can be created, removed or queried based on unique ID provided by the user
// (ids are not handled by the class since it is likely that they will be
// defined as enum's or #define by the user for easier retrieval, instead
// of having ivar's that would store the id's returned by the class).
// Entries are packed (gridded) in the order they were added.
#ifndef __vtkKWEntrySet_h
#define __vtkKWEntrySet_h
#include "vtkKWWidget.h"
class vtkKWApplication;
class vtkKWEntry;
//BTX
template<class DataType> class vtkLinkedList;
template<class DataType> class vtkLinkedListIterator;
//ETX
class VTK_EXPORT vtkKWEntrySet : public vtkKWWidget
{
public:
static vtkKWEntrySet* New();
vtkTypeRevisionMacro(vtkKWEntrySet,vtkKWWidget);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Create the widget (a frame holding all the entries).
virtual void Create(vtkKWApplication *app, const char *args);
// Description:
// Add a entry to the set.
// The id has to be unique among the set.
// Object and method parameters, if any, will be used to set the command.
// A help string will be used, if any, to set the baloon help.
// Return 1 on success, 0 otherwise.
int AddEntry(int id,
vtkKWObject *object = 0,
const char *method_and_arg_string = 0,
const char *balloonhelp_string = 0);
// Description:
// Get a entry from the set, given its unique id.
// It is advised not to temper with the entry var name or value :)
// Return a pointer to the entry, or NULL on error.
vtkKWEntry* GetEntry(int id);
int HasEntry(int id);
// Description:
// Convenience method to hide/show a entry
void HideEntry(int id);
void ShowEntry(int id);
void SetEntryVisibility(int id, int flag);
int GetNumberOfVisibleEntries();
// Description:
// Set the widget packing order to be horizontal (default is vertical).
void SetPackHorizontally(int);
vtkBooleanMacro(PackHorizontally, int);
vtkGetMacro(PackHorizontally, int);
// Description:
// Set the maximum number of widgets that will be packed in the packing
// direction (i.e. horizontally or vertically). Default is 0, meaning that
// all widgets are packed along the same direction. If 3 (for example) and
// direction is horizontal, you end up with 3 columns.
void SetMaximumNumberOfWidgetInPackingDirection(int);
vtkGetMacro(MaximumNumberOfWidgetInPackingDirection, int);
// Description:
// Set the widgets padding.
virtual void SetPadding(int x, int y);
// Description:
// Update the "enable" state of the object and its internal parts.
// Depending on different Ivars (this->Enabled, the application's
// Limited Edition Mode, etc.), the "enable" state of the object is updated
// and propagated to its internal parts/subwidgets. This will, for example,
// enable/disable parts of the widget UI, enable/disable the visibility
// of 3D widgets, etc.
virtual void UpdateEnableState();
protected:
vtkKWEntrySet();
~vtkKWEntrySet();
int PackHorizontally;
int MaximumNumberOfWidgetInPackingDirection;
int PadX;
int PadY;
//BTX
// A entry slot associates a entry to a unique Id
// I don't want to use a map between those two, for the following reasons:
// a), we might need more information in the future, b) a map
// Register/Unregister pointers if they are pointers to VTK objects.
class EntrySlot
{
public:
int Id;
vtkKWEntry *Entry;
};
typedef vtkLinkedList<EntrySlot*> EntriesContainer;
typedef vtkLinkedListIterator<EntrySlot*> EntriesContainerIterator;
EntriesContainer *Entries;
// Helper methods
EntrySlot* GetEntrySlot(int id);
//ETX
void Pack();
private:
vtkKWEntrySet(const vtkKWEntrySet&); // Not implemented
void operator=(const vtkKWEntrySet&); // Not implemented
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment