From: pallas@eng.sun.com (Joseph Pallas)
Subject: Help!  I can't make dynamic Compositions work (3.1-beta3)
Organization: Internet-USENET Gateway at Stanford University
Date: Tue, 10 Nov 1992 00:23:20 GMT

This is probably something stupid on my part, but I cannot get a
composition to update dynamically.  The program below is my test
program.  The Add button appends a red square glyph to the composition
each time it's pressed.  The Clear button erases all of them.  [The
NO_EMPTY_COMPOSITION stuff works around a bug in 3.1-beta3 that barfs
on empty compositions.]

Here's what I see:

With USE_PATCH == 0, the first Add has no visible effect.  Subsequent
ones do.  Clear has no visible effect, but subsequent Adds partially
update the cleared area (use multiple lines' worth of Adds to see
this).  At any time, resizing restores an accurate display.

With USE_PATCH == 1 and USE_REALLOC == 0, Add never has any visible
effect.  Resizing produces an accurate display, and then Clear behaves
as expected.  Subsequently, Add has the expected effect (mostly), and
Clear only clears the area above the bottom of the buttons, until the
next Add.  Resizing after clearing returns to the initial state.

After looking at some of the doc code, I tried Patch::reallocate.  With
USE_PATCH == 1 and USE_REALLOC == 1, Add always works.  Clear, however,
has no immediate visible effect.  Subsequent Adds partially update the
cleared area.

I think I understand why resizing always works, from looking at
Composition::allocate.  But I can't figure out what it is that I should
be doing to get the results I expect.  Can anyone help?

Thanks.

joe

compotest.c follows:

#include <InterViews/background.h>
#include <InterViews/color.h>
#include <InterViews/composition.h>
#include <InterViews/compositor.h>
#include <InterViews/debug.h>
#include <IV-look/kit.h>
#include <InterViews/layout.h>
#include <InterViews/patch.h>
#include <InterViews/session.h>
#include <InterViews/simplecomp.h>
#include <InterViews/window.h>

#define USE_PATCH 1
#define USE_REALLOC 1

#define NO_EMPTY_COMPOSITION 1

class CompoTest : public MonoGlyph {
public:
  CompoTest();
  void add();
  void clear();
private:
  LRComposition *comp_;
#if USE_PATCH
  Patch *patch_;
#endif
};

CompoTest::CompoTest() {
  LayoutKit *layout = LayoutKit::instance();
  comp_ = new LRComposition(layout->vbox(), new SimpleCompositor, nil, 72 * 2);
  comp_->ref();

#if NO_EMPTY_COMPOSITION
  comp_->append(layout->hglue(0, 0, 0));
#endif

  comp_->repair();

#if USE_PATCH
  patch_ = new Patch(comp_);
  patch_->ref();
  body(patch_);
#else
  body(comp_);
#endif

}

void CompoTest::add() {
  LayoutKit *layout = LayoutKit::instance();
  comp_->append(layout->natural(new Background(nil,
					       new Color(1.0, 0.0, 0.0, 1.0)),
				25, 25));
  comp_->repair();

#if USE_PATCH
#if USE_REALLOC
  patch_->reallocate();
#endif
  patch_->redraw();
#endif
}

#if NO_EMPTY_COMPOSITION
#define EMPTY 1
#else
#define EMPTY 0
#endif

void CompoTest::clear() {
  while (comp_->count() > EMPTY)
    comp_->remove(EMPTY);
  comp_->repair();

#if USE_PATCH
#if USE_REALLOC
  patch_->reallocate();
#endif
  patch_->redraw();
#endif
}

declareActionCallback(CompoTest)
implementActionCallback(CompoTest)

int main(int argc, char **argv) {
  Session *session = new Session("Compo", argc, argv);
  LayoutKit *layout = LayoutKit::instance();
  WidgetKit *kit = WidgetKit::instance();

  CompoTest *tester = new CompoTest;

  Glyph *controls = layout->margin(layout->hbox(
    kit->push_button("Add", new ActionCallback(CompoTest)(tester, 
							  CompoTest::add)),
    layout->hspace(18),
    kit->push_button("Clear", new ActionCallback(CompoTest)(tester,
							CompoTest::clear))),
				   18);

  session->run_window(
    new ApplicationWindow(
      new Background(
	layout->hbox(controls, 
		     layout->vcenter(layout->natural(tester,
						     2 * 72, 2 * 72))),
		     new Color(1.0, 1.0, 1.0, 1.0)
		     )
			  )
		      );
}