|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 12235 (0x2fcb)
Types: TextFile
Names: »ibmanips.c«
└─⟦8648bda34⟧ Bits:30007244 EUUGD5_II: X11R5
└─⟦87c3ac0e0⟧ »./contrib-3/contrib-3.00«
└─⟦de8ce1454⟧
└─⟦this⟧ »contrib/lib/iv/src/bin/ibuild/ibmanips.c«
/*
* Copyright (c) 1991 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Implementation of user interface builder-specific manipulators.
* $Header: /master/3.0/iv/src/bin/ibuild/RCS/ibmanips.c,v 1.2 91/09/27 14:10:58 tang Exp $
*/
#include "ibcmds.h"
#include "ibmanips.h"
#include "ibtools.h"
#include "ibglobals.h"
#include "ibinteractor.h"
#include "ibclasses.h"
#include <InterViews/control.h>
#include <InterViews/event.h>
#include <InterViews/frame.h>
#include <InterViews/message.h>
#include <InterViews/rubgroup.h>
#include <InterViews/rubline.h>
#include <InterViews/sensor.h>
#include <InterViews/shape.h>
#include <InterViews/world.h>
#include <Unidraw/iterator.h>
#include <Unidraw/selection.h>
#include <Unidraw/viewer.h>
#include <Unidraw/unidraw.h>
#include <Unidraw/editor.h>
#include <Unidraw/Components/grview.h>
#include <Unidraw/Components/pin.h>
/*****************************************************************************/
PopupManip::PopupManip (Viewer* viewer, PopupMenu* popup, Tool* tool) {
_viewer = viewer;
_popup = popup;
_tool = tool;
}
PopupManip::~PopupManip () { delete _popup; }
void PopupManip::Grasp (Event& e) { _popup->Popup(e); }
void PopupManip::Effect (Event&) { _popup->Unselect(); }
boolean PopupManip::Manipulating (Event& e) {
e.target->Handle(e);
return e.leftmouse;
}
void PopupManip::SetViewer (Viewer* viewer) { _viewer = viewer; }
void PopupManip::SetTool (Tool* tool) { _tool = tool; }
Viewer* PopupManip::GetViewer () { return _viewer; }
Tool* PopupManip::GetTool () { return _tool; }
/*****************************************************************************/
NarrowManip::NarrowManip (Viewer* viewer) {
_viewer = viewer;
_parent = _kid = nil;
}
void NarrowManip::Grasp (Event& e) {
Iterator i;
GraphicView* views = _viewer->GetGraphicView();
Selection* s = _viewer->GetSelection(), *newSel = new Selection;
boolean success = true;
s->Clear();
ComputeViewPath(e, views, newSel);
if (!newSel->IsEmpty()) {
newSel->First(i);
GraphicView* gv = newSel->GetView(i);
s->Append(gv);
s->Update();
_parent = gv->GetGraphicComp();
newSel->Next(i);
if (!newSel->Done(i)) {
gv = newSel->GetView(i);
_kid = gv->GetGraphicComp();
}
}
delete newSel;
}
boolean NarrowManip::Manipulating (Event& e) {
if (e.eventType == MotionEvent) {
Iterator i;
GraphicView* views = _viewer->GetGraphicView();
Selection* s = _viewer->GetSelection(), *newSel = new Selection;
ComputeViewPath(e, views, newSel);
if (!newSel->IsEmpty()) {
newSel->First(i);
GraphicView* gv = newSel->GetView(i);
if (!s->Includes(gv)) {
s->Clear();
s->Append(gv);
s->Update();
_parent = gv->GetGraphicComp();
newSel->Next(i);
if (!newSel->Done(i)) {
GraphicView* gv = newSel->GetView(i);
_kid = gv->GetGraphicComp();
} else {
_kid = nil;
}
}
} else {
s->Clear();
_parent = _kid = nil;
}
delete newSel;
} else if (e.eventType == UpEvent) {
return false;
}
return true;
}
/*****************************************************************************/
void IComputeViewPath (Event& e, GraphicView* views, Selection* s){
Selection* newSel =
views->ViewIntersecting(e.x-SLOP, e.y-SLOP, e.x+SLOP, e.y+SLOP);
Iterator i;
for (newSel->First(i); !newSel->Done(i); newSel->Next(i)) {
GraphicView* gv = newSel->GetView(i);
if (gv != nil && gv->IsA(INTERACTOR_VIEW)) {
s->Append(gv);
IComputeViewPath(e, gv, s);
}
}
delete newSel;
}
inline boolean SameFirewall (InteractorComp* src, InteractorComp* dest) {
GetFirewallCmd sCmd(src);
GetFirewallCmd dCmd(dest);
sCmd.Execute();
dCmd.Execute();
return sCmd.GetFirewall() == dCmd.GetFirewall();
}
/*****************************************************************************/
RelateManip::RelateManip (Viewer* v, Tool* tool) {
_viewer = v;
_tool = tool;
_drag = nil;
_src = _dest = nil;
_cont = true;
}
boolean RelateManip::CreatePopupMenu(Event& e, RelateMenu*& menu) {
Iterator i, j;
GraphicView* views = _viewer->GetGraphicView();
Selection* s = _viewer->GetSelection(), *newSel = new Selection;
s->Clear();
IComputeViewPath(e, views, newSel);
menu = nil;
boolean hit = false;
if (!newSel->IsEmpty()) {
hit = true;
newSel->Last(j);
GraphicView* gv = newSel->GetView(j);
InteractorComp* icomp = (InteractorComp*) gv->GetGraphicComp();
if (_src == nil || SameFirewall(icomp, _src)) {
newSel->First(j);
GraphicView* gv = newSel->GetView(j);
s->Append(gv);
s->Update();
menu = new RelateMenu();
for (newSel->First(i); !newSel->Done(i); newSel->Next(i)) {
GraphicView* view = s->GetView(i);
InteractorComp* comp = (InteractorComp*)view->GetGraphicComp();
menu->Include(new RelateItem(GetName(comp),Center,comp,menu));
}
}
}
delete newSel;
return hit;
}
void RelateManip::GetSrcDest(InteractorComp*& src, InteractorComp*& dest) {
src = _src;
dest = _dest;
}
RelateManip::~RelateManip () {
if (_drag != nil) {
delete _drag;
}
}
static boolean Relatable (InteractorComp* src) {
boolean success = false;
if (src->IsRelatable()) {
success = true;
} else {
Iterator i;
for(src->First(i); !src->Done(i); src->Next(i)) {
InteractorComp* kid = (InteractorComp*) src->GetComp(i);
success = Relatable(kid);
if (success) {
break;
}
}
}
return success;
}
static boolean Relatable (InteractorComp* src, InteractorComp* dest) {
boolean success = false;
if (src->IsRelatableTo(dest) || dest->IsRelatableTo(src)) {
success = true;
} else if (src->IsAScene() && !dest->IsAScene()) {
Iterator i;
for(src->First(i); !src->Done(i); src->Next(i)) {
InteractorComp* kid = (InteractorComp*) src->GetComp(i);
success = Relatable(kid, dest);
if (success) {
break;
}
}
} else if (dest->IsAScene() && !src->IsAScene()) {
Iterator i;
for (dest->First(i); !dest->Done(i); dest->Next(i)) {
InteractorComp* kid = (InteractorComp*) dest->GetComp(i);
success = Relatable(src, kid);
if (success) {
break;
}
}
}
return success;
}
void RelateManip::Manipulate(Manipulator* m, Event& e) {
m->Grasp(e);
do {
_viewer->Read(e);
} while (m->Manipulating(e));
m->Effect(e);
}
void RelateManip::Grasp (Event& e) {
RelateMenu* src_menu;
Coord cx = e.x, cy = e.y;
CreatePopupMenu(e, src_menu);
if (src_menu != nil) {
PopupManip* popup = new PopupManip(_viewer, src_menu, _tool);
Manipulate(popup, e);
_src = src_menu->GetInteractorComp();
delete popup;
if (_src != nil && Relatable(_src)) {
_drag = new RubberGroup(nil, nil);
_drag->Append(
new SlidingPin(nil, nil, cx, cy, PIN_RAD, cx, cy),
new RubberLine(nil, nil, cx, cy, cx, cy),
new FixedPin(nil, nil, cx, cy, PIN_RAD)
);
_viewer->InitRubberband(_drag);
_drag->Track(cx, cy);
}
}
}
boolean RelateManip::Manipulating (Event& e) {
RelateMenu* dest_menu;
if (_drag == nil) {
_cont = false;
} else if (e.eventType == MotionEvent) {
_drag->Track(e.x, e.y);
} else if (e.eventType == DownEvent) {
boolean hit = CreatePopupMenu(e, dest_menu);
if (dest_menu != nil) {
PopupManip* popup = new PopupManip(_viewer, dest_menu, _tool);
Manipulate(popup, e);
_dest = dest_menu->GetInteractorComp();
delete popup;
if (SemanticCheck()) {
_cont = false;
}
} else {
_cont = hit;
}
}
return _cont;
}
void RelateManip::Effect(Event&) {
if (_drag != nil) {
_drag->Erase();
}
}
boolean RelateManip::SemanticCheck () {
boolean ok = false;
return (
_src != nil && _dest != nil &&
Relatable(_src, _dest) &&
SameFirewall(_src, _dest)
);
}
void RelateManip::SetViewer (Viewer* viewer) { _viewer = viewer; }
void RelateManip::SetTool (Tool* tool) { _tool = tool; }
Viewer* RelateManip::GetViewer () { return _viewer; }
Tool* RelateManip::GetTool () { return _tool; }
RelateItem::RelateItem(
const char* string, Alignment al, InteractorComp* icomp, RelateMenu* m
) : MenuItem(string, al) {
_relatedcomp = icomp;
_menu = m;
}
void RelateItem::Do () {
_menu->SetInteractorComp(_relatedcomp);
}
/*************************************************************************/
ExamineMenu::ExamineMenu() {}
void ExamineMenu::InsertBody(IntCoord x, IntCoord y) {
Interactor* i = GetScene();
PopupMenu::InsertBody(x, y - i->GetShape()->height/4);
}
/*************************************************************************/
H_PopupMenu::H_PopupMenu() {
_count = 0;
_center = 0;
}
void H_PopupMenu::Include(Control* menu) {
PopupMenu::Include(menu);
_count++;
}
void H_PopupMenu::InsertBody(IntCoord x, IntCoord y) {
Interactor* i = GetScene();
float height = float(i->GetShape()->height);
float fratio = float(_center)/float(_count);
int adjustment = round(height * (1.0/2.0 - fratio + 0.5/float(_count)));
IntCoord adjy = y-adjustment;
PopupMenu::InsertBody(x, adjy);
}
/*************************************************************************/
H_PullrightMenu::H_PullrightMenu(Interactor* i) : PullrightMenu(i) {
_count = 0;
}
void H_PullrightMenu::Include(Control* menu) {
PullrightMenu::Include(menu);
_count++;
}
void H_PullrightMenu::InsertBody(IntCoord x, IntCoord y) {
Interactor* i = GetScene();
float height = float(i->GetShape()->height);
int adjustment = round(height * (1.0 - 1.0/float(_count)));
IntCoord adjy = y + adjustment + 1;
PullrightMenu::InsertBody(x, adjy);
}
/*************************************************************************/
RelateMenu::RelateMenu() { Init(); }
void RelateMenu::Init() {
SetClassName("RelateMenu");
SetState(new ControlState);
SetAlign(TopCenter);
_relatedcomp = nil;
_count = 0;
}
void RelateMenu::Include(Control* menu) {
PopupMenu::Include(menu);
_count++;
}
void RelateMenu::InsertBody(IntCoord x, IntCoord y) {
Interactor* i = GetScene();
Shape* s = i->GetShape();
PopupMenu::InsertBody(x, y + s->height/2 - s->height/_count/2);
}