From: denisb@leland.Stanford.EDU (Denis Bohm)
Subject: Re: 2D scrolling?
Organization: DSG, Stanford University, CA 94305, USA
Date: Sat, 29 Aug 92 05:25:46 GMT

Here is the class that I am using for 2D scrolling and zooming.
It uses a transformer for scaling, but just reallocates for panning.
The class is like an Adjustable Page.

Denis Bohm (denis@redwood.com -or- denisb@leland.stanford.edu)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  main.C ruiScene.C ruiScene.h
# Wrapped by denisb@elaine17.Stanford.EDU on Fri Aug 28 22:20:27 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'main.C' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.C'\"
else
echo shar: Extracting \"'main.C'\" \(1212 characters\)
sed "s/^X//" >'main.C' <<'END_OF_FILE'
X#include <InterViews/background.h>
X#include <InterViews/image.h>
X#include <InterViews/layout.h>
X#include <InterViews/raster.h>
X#include <InterViews/session.h>
X#include <InterViews/style.h>
X#include <InterViews/tiff.h>
X#include <InterViews/window.h>
X#include <IV-look/kit.h>
X#include <OS/string.h>
X#include <ruiScene.h>
X
X//////////
X// Main //
X//////////
X
Xint main(int argc, char** argv) {
X  static OptionDesc options[] = {
X    { nil }
X  };
X  static PropertyData properties[] = {
X    { nil }
X  };
X
X  Session* session = new Session("Test", argc, argv, options, properties);
X  WidgetKit* kit = WidgetKit::instance();
X  Style* style = session->style();
X  LayoutKit* layout = LayoutKit::instance();
X
X  ruiScene* scene = new ruiScene;
X
X  Raster* raster = TIFFRaster::load("macaw.tif");
X  Image* image = new Image(raster);
X  scene->append(image);
X
X  Background* background = new Background(
X    layout->hbox(
X      layout->vbox(kit->hscroll_bar(scene), scene),
X      kit->vscroll_bar(scene)
X//    , layout->vbox(kit->enlarger(scene), kit->reducer(scene), layout->vglue())
X    ),
X    kit->background());
X
X  ApplicationWindow* window = new ApplicationWindow(background);
X  window->map();
X
X  session->run();
X
X  return 0;
X}
END_OF_FILE
if test 1212 -ne `wc -c <'main.C'`; then
    echo shar: \"'main.C'\" unpacked with wrong size!
fi
# end of 'main.C'
fi
if test -f 'ruiScene.C' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ruiScene.C'\"
else
echo shar: Extracting \"'ruiScene.C'\" \(14516 characters\)
sed "s/^X//" >'ruiScene.C' <<'END_OF_FILE'
X#include <iostream.h>
X#include <InterViews/canvas.h>
X#include <InterViews/event.h>
X#include <InterViews/hit.h>
X#include <InterViews/printer.h>
X#include <InterViews/window.h>
X#include <OS/list.h>
X#include <OS/math.h>
X#include <ruiScene.h>
X
Xstatic const float epsilon = 1e-4;
X
X////////////////
X// Scene Info //
X////////////////
X
XruiSceneInfo::ruiSceneInfo() {
X  glyph_ = nil;
X  x_ = 0;
X  y_ = 0;
X  status_ = 0;
X}
X
Xvoid ruiSceneInfo::finalize() {
X  Resource::unref(glyph_);
X  glyph_ = nil;
X}
X
X/////////////////////
X// Scene Info List //
X/////////////////////
X
XimplementList(ruiSceneInfoList,ruiSceneInfo);
X
X///////////
X// Scene //
X///////////
X
XruiScene::ruiScene() {
X  info_ = new ruiSceneInfoList;
X  defined_ = false;
X  curLowerX_ = 0;
X  curLowerY_ = 0;
X  curScaleX_ = 1;
X  curScaleY_ = 1;
X  canvas_ = nil;
X  small_scroll(Dimension_X, 10.0);
X  small_scroll(Dimension_Y, 10.0);
X}
X
XruiScene::~ruiScene() {
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    info.finalize();
X  }
X  delete info_;
X  info_ = nil;
X  canvas_ = nil;
X}
X
XCoord ruiScene::left() const {
X  return allocation_.left();
X}
X
XCoord ruiScene::right() const {
X  return allocation_.right();
X}
X
XCoord ruiScene::bottom() const {
X  return allocation_.bottom();
X}
X
XCoord ruiScene::top() const {
X  return allocation_.top();
X}
X
XCoord ruiScene::x() const {
X  return allocation_.x();
X}
X
XCoord ruiScene::y() const {
X  return allocation_.y();
X}
X
Xvoid ruiScene::move(GlyphIndex index, Coord x, Coord y) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  boolean moved = (! Math::equal(info.x_, x, epsilon)) ||
X    (! Math::equal(info.y_, y, epsilon));
X  info.x_ = x;
X  info.y_ = y;
X  if (moved) {
X    Allocation oa = info.newAllocation_;
X    Allocation& na = info.newAllocation_;
X    Allotment& ax = na.allotment(Dimension_X);
X    Allotment& ay = na.allotment(Dimension_Y);
X    na.allot(Dimension_X, Allotment(x, ax.span(), ax.alignment()));
X    na.allot(Dimension_Y, Allotment(y, ay.span(), ay.alignment()));
X    boundingBox(oa, na);
X    if (info.status_ & ruiSceneInfo::Allocated) {
X      Extension& b = info.extension_;
X      if (canvas_ != nil) {
X        damage(b);
X      }
X      b.clear();
X      canvas_->push_transform();
X      canvas_->transformer(transformer_);
X      info.glyph_->allocate(canvas_, na, b);
X      canvas_->pop_transform();
X      info.allocation_ = na;
X      if (canvas_ != nil) {
X        damage(b);
X      }
X    }
X  }
X}
X
Xvoid ruiScene::location(GlyphIndex index, Coord& x, Coord& y) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  x = info.x_;
X  y = info.y_;
X}
X
Xvoid ruiScene::show(GlyphIndex index, boolean showing) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  if (((info.status_ & ruiSceneInfo::Hidden) == 0) != showing) {
X    if (canvas_ != nil) {
X      Extension& b = info.extension_;
X      damage(b);
X    }
X    if (showing) {
X      info.status_ &= ~ruiSceneInfo::Hidden;
X    } else {
X      info.status_ |= ruiSceneInfo::Hidden;
X    }
X  }
X}
X
Xboolean ruiScene::showing(GlyphIndex index) const {
X  return (info_->item_ref(index).status_ & ruiSceneInfo::Hidden) == 0;
X}
X
XCanvas* ruiScene::canvas() const {
X  return canvas_;
X}
X
Xconst Transformer& ruiScene::transformer() const {
X  return transformer_;
X}
X
Xconst Allocation& ruiScene::allocation() const {
X  return allocation_;
X}
X
Xconst Extension& ruiScene::extension() const {
X  return extension_;
X}
X
Xvoid ruiScene::redraw() const {
X  Canvas* c = canvas_;
X  if (c != nil) {
X    c->damage(extension_);
X  }
X}
X
Xvoid ruiScene::reallocate() {
X  Canvas* c = canvas_;
X  if (c != nil) {
X    c->push_transform();
X    c->transformer(transformer_);
X    extension_.clear();
X    allocate(c, allocation_, extension_);
X    c->pop_transform();
X  }
X}
X
Xvoid ruiScene::repick(int depth, Hit& h) {
X  Canvas* c = canvas_;
X  if (c != nil) {
X    c->push_transform();
X    c->transformer(transformer_);
X    pick(c, allocation_, depth, h);
X    c->pop_transform();
X  }
X}
X
Xvoid ruiScene::request(Requisition& requisition) const {
X  Coord w = 1.0;
X  Coord h = 1.0;
X
X  if (defined()) {
X    w = bbRight() - bbLeft() + 1.0;
X    h = bbTop() - bbBottom() + 1.0;
X  }
X
X  requisition.require(Dimension_X, Requirement(w, fil, w, 0));
X  requisition.require(Dimension_Y, Requirement(h, fil, h, 0));
X}
X
Xvoid ruiScene::allocate(Canvas* c, const Allocation& a, Extension& ext) {
X  boolean transformed = (transformer_ != c->transformer()) ||
X    (! allocation_.equals(a, epsilon));
X  updateMatrix();
X  c->push_transform();
X  c->transform(matrix_);
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    if (info.glyph_ != nil) {
X      Allocation na = info.newAllocation_;
X      Allotment& nax = na.allotment(Dimension_X);
X      Allotment& nay = na.allotment(Dimension_Y);
X      nax.offset(a.left() - curLowerX_);
X      nay.offset(a.bottom() - curLowerY_);
X      Allocation& a = info.allocation_;
X      Allotment& ax = a.allotment(Dimension_X);
X      Allotment& ay = a.allotment(Dimension_Y);
X      Extension& b = info.extension_;
X      if (
X        !(info.status_ & ruiSceneInfo::Allocated)
X        || transformed
X        || !ax.equals(na.allotment(Dimension_X), epsilon)
X        || !ay.equals(na.allotment(Dimension_Y), epsilon)
X      ) {
X        if (info.status_ & ruiSceneInfo::Extended) {
X          damage(b);
X        }
X        b.clear();
X        info.glyph_->allocate(c, na, b);
X        a = na;
X        damage(b);
X      }
X      info.status_ |= ruiSceneInfo::Allocated|ruiSceneInfo::Extended;
X    }
X  }
X  c->pop_transform();
X  ext.merge(c, a);
X
X  canvas_ = c;
X  transformer_ = c->transformer();
X  allocation_ = a;
X  extension_ = ext;
X}
X
Xvoid ruiScene::draw(Canvas* c, const Allocation& a) const {
X  c->push_clipping();
X  c->clip_rect(a.left(), a.bottom(), a.right(), a.top());
X  c->push_transform();
X  c->transform(matrix_);
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    if (info.glyph_ != nil && !(info.status_ & ruiSceneInfo::Hidden)) {
X      Extension& b = info.extension_;
X      if (c->damaged(b)) {
X        Allocation& a = info.allocation_;
X        info.glyph_->draw(c, a);
X      }
X    }
X  }
X  c->pop_transform();
X  c->pop_clipping();
X}
X
Xvoid ruiScene::print(Printer* printer, const Allocation& a) const {
X  printer->push_clipping();
X  printer->clip_rect(a.left(), a.bottom(), a.right(), a.top());
X  printer->push_transform();
X  printer->transform(matrix_);
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    if (info.glyph_ != nil && !(info.status_ & ruiSceneInfo::Hidden)) {
X      Extension& b = info.extension_;
X      if (printer->damaged(b)) {
X        Allocation& a = info.allocation_;
X        info.glyph_->print(printer, a);
X      }
X    }
X  }
X  printer->pop_transform();
X  printer->pop_clipping();
X}
X
Xvoid ruiScene::pick(Canvas* c, const Allocation&, int depth, Hit& h) {
X  c->push_transform();
X  c->transform(matrix_);
X  h.push_transform();
X  h.transform(matrix_);
X  Coord left = h.left();
X  Coord bottom = h.bottom();
X  Coord right = h.right();
X  Coord top = h.top();
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    if (info.glyph_ != nil && !(info.status_ & ruiSceneInfo::Hidden)) {
X      Allocation& a = info.allocation_;
X      if (
X        right >= a.left() && left <= a.right()
X        && top >= a.bottom() && bottom <= a.top()
X      ) {
X        h.begin(depth, this, index);
X        info.glyph_->pick(c, a, depth + 1, h);
X        h.end();
X      }
X    }
X  }
X  h.pop_transform();
X  c->pop_transform();
X}
X
Xvoid ruiScene::undraw() {
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    if (info.glyph_ != nil && !(info.status_ & ruiSceneInfo::Hidden)) {
X      info.glyph_->undraw();
X    }
X  }
X  canvas_ = nil;
X}
X
Xvoid ruiScene::append(Glyph* glyph) {
X  ruiSceneInfo info;
X  info.glyph_ = glyph;
X  info.status_ = 0;
X  info.x_ = 0;
X  info.y_ = 0;
X  info_->append(info);
X  Resource::ref(glyph);
X  place(info_->count() - 1);
X}
X
Xvoid ruiScene::prepend(Glyph* glyph) {
X  ruiSceneInfo info;
X  info.glyph_ = glyph;
X  info.status_ = 0;
X  info.x_ = 0;
X  info.y_ = 0;
X  info_->prepend(info);
X  Resource::ref(glyph);
X  place(0);
X}
X
Xvoid ruiScene::insert(GlyphIndex index, Glyph* glyph) {
X  ruiSceneInfo info;
X  info.glyph_ = glyph;
X  info.status_ = 0;
X  info.x_ = 0;
X  info.y_ = 0;
X  info_->insert(index, info);
X  Resource::ref(glyph);
X  place(index);
X}
X
Xvoid ruiScene::remove(GlyphIndex index) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  if (canvas_ != nil && (info.status_ & ruiSceneInfo::Allocated)) {
X    Extension b = info.extension_;
X    damage(b);
X  }
X  info.glyph_->undraw();
X  Resource::unref(info.glyph_);
X  Allocation a = info.newAllocation_;
X  info_->remove(index);
X  boundingBox(a);
X}
X
Xvoid ruiScene::replace(GlyphIndex index, Glyph* glyph) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  if (canvas_ != nil && (info.status_ & ruiSceneInfo::Allocated)) {
X    Extension& b = info.extension_;
X    damage(b);
X  }
X  info.glyph_->undraw();
X  Resource::ref(glyph);
X  Resource::unref(info.glyph_);
X  info.glyph_ = glyph;
X  info.status_ &= ~(ruiSceneInfo::Allocated);
X  Allocation a = info.newAllocation_;
X  boundingBox(a);
X  place(index);
X}
X
Xvoid ruiScene::change(GlyphIndex index) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  info.status_ &= ~(ruiSceneInfo::Allocated);
X  Allocation a = info.newAllocation_;
X  boundingBox(a);
X  place(index);
X}
X
XGlyphIndex ruiScene::count() const {
X  return info_->count();
X}
X
XGlyph* ruiScene::component(GlyphIndex index) const {
X  return info_->item_ref(index).glyph_;
X}
X
Xvoid ruiScene::allotment(GlyphIndex i, DimensionName res, Allotment& a) const {
X  a = info_->item_ref(i).allocation_.allotment(res);
X}
X
XCoord ruiScene::lower(DimensionName dimension) const {
X  return dimension == Dimension_X ? left_ : bottom_;
X}
X
XCoord ruiScene::upper(DimensionName dimension) const {
X  return dimension == Dimension_X ? right_ : top_;
X}
X
XCoord ruiScene::length(DimensionName dimension) const {
X  return upper(dimension) - lower(dimension);
X}
X
XCoord ruiScene::cur_lower(DimensionName dimension) const {
X  return dimension == Dimension_X ? curLowerX_ : curLowerY_;
X}
X
XCoord ruiScene::cur_upper(DimensionName dimension) const {
X  return cur_lower(dimension) + cur_length(dimension);
X}
X
XCoord ruiScene::cur_length(DimensionName dimension) const {
X  return allocation_.allotment(dimension).span() / (dimension == Dimension_X ?
X    curScaleX_ : curScaleY_);
X}
X
Xvoid ruiScene::scroll_to(DimensionName dimension, Coord lower) {
X  *(dimension == Dimension_X ? &curLowerX_ : &curLowerY_) = lower;
X  reallocate();
X  redraw();
X  notify(dimension);
X}
X
Xvoid ruiScene::scale_to(DimensionName dimension, float fraction_visible) {
X  *(dimension == Dimension_X ? &curScaleX_ : &curScaleY_) =
X    length(dimension) * fraction_visible;
X  reallocate();
X  redraw();
X  notify(dimension);
X}
X
Xvoid ruiScene::zoom_to(float magnification) {
X  curScaleX_ = magnification;
X  curScaleY_ = magnification;
X  reallocate();
X  redraw();
X  notify(Dimension_X);
X  notify(Dimension_Y);
X}
X
Xvoid ruiScene::damage(const Extension& e) const {
X  if (canvas_) {
X    Coord l = Math::max(e.left(), extension_.left());
X    Coord b = Math::max(e.bottom(), extension_.bottom());
X    Coord r = Math::min(e.right(), extension_.right());
X    Coord t = Math::min(e.top(), extension_.top());
X    if ((l < r) && (b < t)) {
X      canvas_->damage(l, b, r, t);
X    }
X  }
X}
X
Xvoid ruiScene::updateMatrix() {
X  matrix_ = Transformer();
X  matrix_.scale(curScaleX_, curScaleY_);
X}
X
Xvoid ruiScene::place(GlyphIndex index) {
X  ruiSceneInfo& info = info_->item_ref(index);
X  if (info.glyph_) {
X    Allocation& a = info.newAllocation_;
X    Requisition s;
X    info.glyph_->request(s);
X    Allotment ax = Allotment(
X      info.x_,
X      s.requirement(Dimension_X).natural(),
X      s.requirement(Dimension_X).alignment()
X    );
X    Allotment ay = Allotment(
X      info.y_,
X      s.requirement(Dimension_Y).natural(),
X      s.requirement(Dimension_Y).alignment()
X    );
X    a.allot(Dimension_X, ax);
X    a.allot(Dimension_Y, ay);
X    boundingBox(a);
X  }
X}
X
Xboolean ruiScene::inside(const Allocation& a) const {
X  return (a.left() > left_) && (a.bottom() > bottom_) &&
X    (a.right() < right_) && (a.top() < top_);
X}
X
Xboolean ruiScene::boundingBox(const Allocation& oa, const Allocation& na)
X  const {
X  if (inside(oa) && inside(na)) {
X    return false;
X  }
X  return boundingBox();
X}
X
Xboolean ruiScene::boundingBox(const Allocation& a) const {
X  if (inside(a)) {
X    return false;
X  }
X  return boundingBox();
X}
X
Xboolean ruiScene::boundingBox() const {
X  ruiScene& self = *((ruiScene*) this);
X
X  boolean defined = false;
X  Coord left   = 0;
X  Coord bottom = 0;
X  Coord right  = 0;
X  Coord top    = 0;
X  GlyphIndex count = info_->count();
X  for (GlyphIndex index = 0; index < count; ++index) {
X    ruiSceneInfo& info = info_->item_ref(index);
X    if (! info.glyph_) {
X      continue;
X    }
X
X    // use new allocation so can compute bounding box before allocate. -denis
X    Allocation& a = info.newAllocation_;
X    Allotment ax = a.allotment(Dimension_X);
X    Allotment ay = a.allotment(Dimension_Y);
X    if (! defined) {
X      left   = ax.begin();
X      bottom = ay.begin();
X      right  = ax.end();
X      top    = ay.end();
X      defined = true;
X    } else {
X      left   = Math::min(left, ax.begin());
X      bottom = Math::min(bottom, ay.begin());
X      right  = Math::max(right, ax.end());
X      top    = Math::max(top, ay.end());
X    }
X  }
X
X  boolean xChanged = (defined != defined_) || (left != left_) ||
X    (right != right_);
X  boolean yChanged = (defined != defined_) || (bottom != bottom_) ||
X    (top != top_);
X
X  self.defined_ = defined;
X  self.left_   = left;
X  self.bottom_ = bottom;
X  self.right_  = right;
X  self.top_    = top;
X
X  if (xChanged || yChanged) {
X    if (xChanged) {
X      notify(Dimension_X);
X    }
X    if (yChanged) {
X      notify(Dimension_Y);
X    }
X  }
X
X  return xChanged || yChanged;
X}
X
Xboolean ruiScene::defined() const {
X  return defined_;
X}
X
XCoord ruiScene::bbLeft() const {
X  return left_;
X}
X
XCoord ruiScene::bbBottom() const {
X  return bottom_;
X}
X
XCoord ruiScene::bbRight() const {
X  return right_;
X}
X
XCoord ruiScene::bbTop() const {
X  return top_;
X}
END_OF_FILE
if test 14516 -ne `wc -c <'ruiScene.C'`; then
    echo shar: \"'ruiScene.C'\" unpacked with wrong size!
fi
# end of 'ruiScene.C'
fi
if test -f 'ruiScene.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ruiScene.h'\"
else
echo shar: Extracting \"'ruiScene.h'\" \(3462 characters\)
sed "s/^X//" >'ruiScene.h' <<'END_OF_FILE'
X#ifndef ruiScene_h
X#define ruiScene_h
X
X#include <InterViews/adjust.h>
X#include <InterViews/glyph.h>
X#include <InterViews/transformer.h>
X#include <OS/list.h>
X
X#include <InterViews/_enter.h>
X
Xclass ruiScene : public Glyph, public Adjustable {
Xpublic:
X  ruiScene();
X  virtual ~ruiScene();
X
X  // like Page (but not a page because ruiScene can pan and zoom) -denis
X  virtual Coord left() const;
X  virtual Coord right() const;
X  virtual Coord bottom() const;
X  virtual Coord top() const;
X  virtual Coord x() const;
X  virtual Coord y() const;
X
X  virtual void move(GlyphIndex, Coord x, Coord y);
X  virtual void location(GlyphIndex, Coord& x, Coord& y);
X  virtual void show(GlyphIndex, boolean);
X  virtual boolean showing(GlyphIndex) const;
X
X  // like Patch (but not a patch because ruiScene is not a MonoGlyph) -denis
X  virtual Canvas* canvas() const;
X  virtual const Transformer& transformer() const;
X  virtual const Allocation& allocation() const;
X  virtual const Extension& extension() const;
X
X  virtual void redraw() const;
X  virtual void reallocate();
X  virtual void repick(int depth, Hit&);
X
X  // Glyph
X  virtual void request(Requisition&) const;
X  virtual void allocate(Canvas*, const Allocation&, Extension&);
X  virtual void draw(Canvas*, const Allocation&) const;
X  virtual void print(Printer*, const Allocation&) const;
X  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
X  virtual void undraw();
X
X  virtual void append(Glyph*);
X  virtual void prepend(Glyph*);
X  virtual void insert(GlyphIndex, Glyph*);
X  virtual void remove(GlyphIndex);
X  virtual void replace(GlyphIndex, Glyph*);
X  virtual void change(GlyphIndex);
X
X  virtual GlyphIndex count() const;
X  virtual Glyph* component(GlyphIndex) const;
X  virtual void allotment(GlyphIndex, DimensionName, Allotment&) const;
X
X  // Adjustable
X  virtual Coord lower(DimensionName) const;
X  virtual Coord upper(DimensionName) const;
X  virtual Coord length(DimensionName) const;
X  virtual Coord cur_lower(DimensionName) const;
X  virtual Coord cur_upper(DimensionName) const;
X  virtual Coord cur_length(DimensionName) const;
X
X  virtual void scroll_to(DimensionName, Coord lower);
X  virtual void scale_to(DimensionName, float fraction_visible);
X  virtual void zoom_to(float magnification);
X
Xprotected:
X  virtual void damage(const Extension&) const;
X  virtual void updateMatrix();
X  virtual void place(GlyphIndex);
X  virtual boolean inside(const Allocation& a) const;
X  virtual boolean boundingBox(const Allocation& oa, const Allocation& na) const;
X  virtual boolean boundingBox(const Allocation& a) const;
X  virtual boolean boundingBox() const;
X  virtual boolean defined() const;
X  virtual Coord bbLeft() const;
X  virtual Coord bbBottom() const;
X  virtual Coord bbRight() const;
X  virtual Coord bbTop() const;
X
X  class ruiSceneInfoList* info_;
X
X  boolean defined_:1;
X  Coord left_;
X  Coord bottom_;
X  Coord right_;
X  Coord top_;
X
X  Coord curLowerX_;
X  Coord curLowerY_;
X  Coord curScaleX_;
X  Coord curScaleY_;
X
X  Transformer matrix_;
X
X  Canvas* canvas_;
X  Allocation allocation_;
X  Extension extension_;
X  Transformer transformer_;
X};
X
Xclass ruiSceneInfo {
Xpublic:
X  enum {Allocated = 0x01, Extended = 0x02, Positioned = 0x04, Hidden = 0x08};
X
X  ruiSceneInfo();
X  void finalize();
X
X  Glyph* glyph_;
X  Allocation newAllocation_;
X  Allocation allocation_;
X  Extension extension_;
X  Coord x_;
X  Coord y_;
X  int status_;
X};
X
XdeclareList(ruiSceneInfoList,ruiSceneInfo);
X
X#include <InterViews/_leave.h>
X
X#endif
END_OF_FILE
if test 3462 -ne `wc -c <'ruiScene.h'`; then
    echo shar: \"'ruiScene.h'\" unpacked with wrong size!
fi
# end of 'ruiScene.h'
fi
echo shar: End of shell archive.
exit 0
-- 
Denis Bohm (denis@redwood.com -or- denisb@leland.stanford.edu)