//
// Copyright (c) 1997 by the University of Southern California
// All rights reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation in source and binary forms for non-commercial purposes
// and without fee is hereby granted, provided that the above copyright
// notice appear in all copies and that both the copyright notice and
// this permission notice appear in supporting documentation. and that
// any documentation, advertising materials, and other materials related
// to such distribution and use acknowledge that the software was
// developed by the University of Southern California, Information
// Sciences Institute. The name of the University may not be used to
// endorse or promote products derived from this software without
// specific prior written permission.
//
// THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
// the suitability of this software for any purpose. THIS SOFTWARE IS
// PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Other copyrights might apply to parts of this software and are so
// noted when applicable.
//
// $Header: /cvsroot/nsnam/nam-1/tag.cc,v 1.6 2001/07/30 22:16:43 mehringe Exp $
#ifdef WIN32
#include <windows.h>
#endif
#include <string.h>
#include <tcl.h>
#include "animation.h"
#include "tag.h"
#include "view.h"
#include "node.h"
#include "editview.h"
Tag::Tag()
: Animation(0, 0), nMbr_(0), name_(NULL)
{
mbrHash_ = new Tcl_HashTable;
Tcl_InitHashTable(mbrHash_, TCL_ONE_WORD_KEYS);
}
Tag::Tag(const char *name)
: Animation(0, 0), nMbr_(0)
{
size_t len = strlen(name);
if (len == 0)
name_ = NULL;
else {
name_ = new char[len+1];
strcpy(name_, name);
}
mbrHash_ = new Tcl_HashTable;
Tcl_InitHashTable(mbrHash_, TCL_ONE_WORD_KEYS);
}
Tag::~Tag()
{
remove();
Tcl_DeleteHashTable(mbrHash_);
delete mbrHash_;
if (name_ != NULL)
delete []name_;
}
void Tag::setname(const char *name)
{
if (name_ != NULL)
delete name_;
size_t len = strlen(name);
if (len == 0)
name_ = NULL;
else {
name_ = new char[len+1];
strcpy(name_, name);
}
}
void Tag::add(Animation *a)
{
int newEntry = 1;
Tcl_HashEntry *he =
Tcl_CreateHashEntry(mbrHash_,(const char *)a->id(), &newEntry);
if (newEntry && (he != NULL)) {
// Do not handle exception he == NULL. Don't know how.
Tcl_SetHashValue(he, (ClientData)a);
nMbr_++;
a->merge(bb_);
// Let that object know about this group
a->addTag(this);
}
}
void Tag::remove()
{
// Remove this tag from all its members
Animation *p;
Tcl_HashEntry *he;
Tcl_HashSearch hs;
int i = 0;
for (he = Tcl_FirstHashEntry(mbrHash_, &hs);
he != NULL;
he = Tcl_NextHashEntry(&hs), i++) {
p = (Animation *) Tcl_GetHashValue(he);
p->deleteTag(this);
Tcl_DeleteHashEntry(he);
nMbr_--;
}
bb_.clear();
}
void Tag::remove(Animation *a)
{
Tcl_HashEntry *he = Tcl_FindHashEntry(mbrHash_, (const char *)a->id());
if (he != NULL) {
a->deleteTag(this);
Tcl_DeleteHashEntry(he);
nMbr_--;
update_bb();
}
}
void Tag::draw(View *v, double now) {
// XXX don't draw anything except it's selected. Or draw
// 4 black dots in the 4 corners.
v->rect(bb_.xmin, bb_.ymin, bb_.xmax, bb_.ymax,
Paint::instance()->thin());
}
// Used for xor-draw only
void Tag::xdraw(View *v, double now) const
{
// Draw every object of this group
Tcl_HashEntry *he;
Tcl_HashSearch hs;
Animation *a;
for (he = Tcl_FirstHashEntry(mbrHash_, &hs);
he != NULL;
he = Tcl_NextHashEntry(&hs)) {
a = (Animation *) Tcl_GetHashValue(he);
a->draw(v, now);
}
}
void Tag::update_bb(void)
{
Tcl_HashEntry *he;
Tcl_HashSearch hs;
Animation *a;
bb_.clear();
for (he = Tcl_FirstHashEntry(mbrHash_, &hs);
he != NULL;
he = Tcl_NextHashEntry(&hs)) {
a = (Animation *) Tcl_GetHashValue(he);
a->merge(bb_);
}
}
void Tag::reset(double /*now*/)
{
}
//----------------------------------------------------------------------
// void
// Tag::move(EditView *v, float wdx, float wdy)
// -- Move all tagged object and update the bounding box
//----------------------------------------------------------------------
void
Tag::move(EditView *v, float wdx, float wdy) {
Tcl_HashEntry *he;
Tcl_HashSearch hs;
Animation *a;
bb_.clear();
for (he = Tcl_FirstHashEntry(mbrHash_, &hs);
he != NULL;
he = Tcl_NextHashEntry(&hs)) {
a = (Animation *) Tcl_GetHashValue(he);
a->move(v, wdx, wdy);
a->merge(bb_);
}
}
const char *Tag::info() const
{
static char str[256];
strcpy(str, "Tag");
return str;
}
//----------------------------------------------------------------------
// void
// Tag::addNodeMovementElements(EditView * editview,
// double x, double y, double current_time)
// - Used by the nam editor
// - If any nodes in the tagged selection are mobile then the
//----------------------------------------------------------------------
void
Tag::addNodeMovementDestination(EditView * editview,
double dx, double dy, double current_time) {
Tcl_HashEntry * hash_entry;
Tcl_HashSearch hash_search;
Animation * animation_object;
Node * node;
float x,y;
for (hash_entry = Tcl_FirstHashEntry(mbrHash_, &hash_search);
hash_entry != NULL;
hash_entry = Tcl_NextHashEntry(&hash_search)) {
animation_object = (Animation *) Tcl_GetHashValue(hash_entry);
if (animation_object->classid() == ClassNodeID) {
node = (Node *) animation_object;
x = node->x();
y = node->y();
editview->map(x,y);
x += dx;
y += dy;
editview->imap(x,y);
node->addMovementDestination(x, y, current_time);
}
}
}
//----------------------------------------------------------------------
// int
// Tag::getNodeMovementTimes(char * buffer, int buffer_size)
// - returns a string of the form
// {{<node id> <time> <time_2>...} {node_id2 <time> <time2>...}...}
//----------------------------------------------------------------------
int
Tag::getNodeMovementTimes(char * buffer, int buffer_size) {
Tcl_HashEntry * hash_entry;
Tcl_HashSearch hash_search;
Animation * animation_object;
Node * node;
int chars_written, just_written;
chars_written = 0;
for (hash_entry = Tcl_FirstHashEntry(mbrHash_, &hash_search);
hash_entry != NULL;
hash_entry = Tcl_NextHashEntry(&hash_search)) {
animation_object = (Animation *) Tcl_GetHashValue(hash_entry);
if (animation_object->classid() == ClassNodeID) {
node = (Node *) animation_object;
if (chars_written < buffer_size) {
just_written = sprintf(buffer + chars_written, "{%d ", node->number());
if (just_written != -1) {
chars_written += just_written;
chars_written += node->getMovementTimeList(buffer + chars_written,
buffer_size - chars_written) -1;
chars_written += sprintf(buffer + chars_written, "}");
} else {
chars_written = -1;
break;
}
}
}
chars_written += sprintf(buffer + chars_written, " ");
}
return chars_written;
}
syntax highlighted by Code2HTML, v. 0.9.1