From: sanjay@iitmax.iit.edu (Sanjay Mehta)
Newsgroups: comp.windows.interviews
Subject: Correctly placing Unidraw Component after Reshape (long)
Keywords: Unidraw, Reshape, Placing
Date: 20 Aug 92 20:05:02 GMT
Article-I.D.: iitmax.1992Aug20.200502.28013
Organization: Illinois Institute of Technology / Academic Computing Center


Hello, me again.  I am developing a Unidraw application, and I have been
making some progress.  However, lately I have been beating my head against
a problem.   I have defined a composite component, which has a text field
within it.  Wielding a Reshape tool anywhere on the component causes the
text field to be reshaped, allowing the user to edit it.  When the tool is
done, the component is updated to the new size of the text field.  

This works--once.  The second time the component is Reshaped, it is moved
to the lower left corner of the Editor window, presumably (0,0).  I have
been working on this for three or four days, and it is driving me crazy.
I have tried Translations, Transformers, and anything else I could think
of.  Nothing worked properly.

I hope I am missing something very simple.  Anyone care to help me out on
this one?  The code of the component is included below.  I suspect the problem
is in PrimView::InterpretManipulator, but given my lack of success perhaps
I should not presume to have an opinion.

I would be, as always, eternally grateful for any help, for at least a 
couple of hours.

Sanjay Mehta.

----------------------   Cut here for primitive.h   ----------------

#ifndef primitive_h
#define primitive_h

#include <Unidraw/classes.h>
#include <Unidraw/Components/text.h>
#include <Unidraw/Graphic/util.h>
#include <Unidraw/manips.h>
#include <Unidraw/Tools/tool.h>
#include <Unidraw/viewer.h>
#include <Unidraw/editor.h>

class PrimComp: public GraphicComps {
  public:
  PrimComp();
  PrimComp(TextGraphic*);
  virtual ClassId GetClassId();
  virtual boolean IsA(ClassId);
  private:
  TextGraphic* _text;
};

class PrimView: public GraphicViews {
  public:
  PrimView(PrimComp* subj = nil);
  Manipulator* CreateManipulator(Viewer*, Event&, Transformer*, Tool*);
  Command* InterpretManipulator(Manipulator*);
  virtual ClassId GetClassId();
};

#define PRIM_COMP 9106
#define PRIM_VIEW Combine(PRIM_COMP, COMPONENT_VIEW)

#endif primitive_h

-----------------   Cut here for primitive.c   -----------------

#include "primitive.h"
#include "stream.h"
#include <string.h>
#include <Unidraw/Graphic/polygons.h>
#include <Unidraw/Graphic/lines.h>
#include <Unidraw/Graphic/graphic.h>
#include <Unidraw/Graphic/pspaint.h>
#include <Unidraw/Components/line.h>
#include <Unidraw/Components/rect.h>
#include <Unidraw/Components/text.h>
#include <Unidraw/Commands/edit.h>
#include <Unidraw/iterator.h>
#include <InterViews/painter.h>
#include <InterViews/transformer.h>
#include <Unidraw/manips.h>
#include <Unidraw/clipboard.h>

PrimComp::PrimComp () {
	TextGraphic* text = new TextGraphic("Label", stdgraphic);
	Append(new TextComp(text));
	SF_Rect* rect = new SF_Rect(0, 0, 50, 50, stdgraphic);
	rect->SetPattern(psnonepat);
	Append (new RectComp(rect));
	rect->Align(Center, text, Center);
}

PrimComp::PrimComp (TextGraphic* text) {
	float top, bottom, left, right;
	text->GetBounds(left, bottom, right, top);
	Append(new TextComp(text));

	if (50.0 > top - bottom)
	  top = bottom + 50;
	right += 20;
	SF_Rect* rect = new SF_Rect(left, bottom, right, top, stdgraphic);

	rect->SetBrush(new PSBrush(0, 1));
	rect->SetPattern(psnonepat);
	Append (new RectComp(rect));
	rect->Align(Center, text, Center);
}

ClassId PrimComp::GetClassId () { return PRIM_COMP; }

boolean PrimComp::IsA(ClassId id) {
	return (PRIM_COMP == id) || GraphicComps::IsA(id);
}

ClassId PrimView::GetClassId() { return PRIM_VIEW; }

PrimView::PrimView (PrimComp* subj) {}

Command* PrimView::InterpretManipulator (Manipulator* m) {
    Viewer* v = m->GetViewer();
    Editor* ed = v->GetEditor();
    Tool* tool = m->GetTool();
    Command* cmd = nil;

    if (tool->IsA(RESHAPE_TOOL)) {
        TextManip* tm = (TextManip*) m;
        int size;
        const char* text = tm->GetText(size);

        if (size == 0) {
                cmd = new DeleteCmd(ed);
        } else {
            Painter* p = tm->GetPainter();
            int lineHt = tm->GetLineHeight();
	    Graphic* pg = GetGraphicComps()->GetGraphic();

            TextGraphic* textgr = new TextGraphic(text, lineHt, pg);

            textgr->FillBg(false);
            textgr->SetFont((PSFont*) p->GetFont());
            textgr->SetColors((PSColor*) p->GetFgColor(), nil);

	    cmd = new ReplaceCmd(ed, new PrimComp(textgr));
        }
    } else {
        cmd = GraphicView::InterpretManipulator(m);
    }
    return cmd;
}

Manipulator* PrimView::CreateManipulator(
   Viewer* v, Event& e, Transformer* rel, Tool* tool) {
    Manipulator* m = nil;
   
    if (tool->IsA(RESHAPE_TOOL)) {
	Iterator i;

	First(i);
	while(!Done(i))
	{
		if (GetView(i)->IsA(TEXT_VIEW))
			return GetView(i)->CreateManipulator(v, e, rel, tool);
		Next(i);
	}
    } else {
        m = GraphicView::CreateManipulator(v, e, rel, tool);
    }
    return m;
  }
Newsgroups: comp.windows.interviews