Article View: comp.windows.interviews
Article #588An InterViews3.1 Beta based demo program
From: Imran Bashir
Date: Wed, 02 Sep 1992 16:27
Date: Wed, 02 Sep 1992 16:27
644 lines
18641 bytes
18641 bytes
This is a small InterViews 3.1.beta demo program that performs
animation on various predefined objects. It was written by
Imran Bashir during his summer internship at the MIT X Consortium
flames can be sent to ibashir@cat.syr.edu :-)
-------- snip ------- snip ----------------------- snip ----------------
#!/bin/sh
# To extract, remove the header and type "sh filename"
#
# This archive contains the following files:
#
# ./Imakefile
# ./main.c
#
if `test ! -s ./Imakefile`
then
echo "writing ./Imakefile"
sed 's/^X//' > ./Imakefile << '\End\Of\File\'
XXCOMM
XXCOMM Imran Bashir's animation program.
XXCOMM
X
X#ifdef InObjectCodeDir
X
XUse_libInterViews()
XComplexProgramTarget(animation)
X
XMakeObjectFromSrc(main)
X
X#else
X
XMakeInObjectCodeDir()
X
X#endif
\End\Of\File\
else
echo "will not over write ./Imakefile"
fi
if `test ! -s ./main.c`
then
echo "writing ./main.c"
sed 's/^X//' > ./main.c << '\End\Of\File\'
X////////////////
X// demo.c //
X////////////////
X
X// by Imran Bashir, Syracuse University, Syracuse NY.
X// while working at MIT X Consortium.
X
X// This demo program has three drawings, a rotating palette,
X// a rotating X logo and a bouncing cube. Each is selectable
X// from a pull-down menu.
X// The rotation speed of each can be increased and decreased.
X// The animation speed can also be reduced to zero by repeatedly
X// pressing the "Slow down" push button.
X
X//
X// Some code has been borrowed from the "zoomer" example,
X// distributed with the InterViews3.1 Beta.
X// Send any comment/improvements to ibashir@cat.syr.edu
X//
X
X#include <IV-look/kit.h>
X#include <IV-look/menu.h>
X#include <IV-look/dialogs.h>
X#include <InterViews/bitmap.h>
X#include <InterViews/background.h>
X#include <InterViews/brush.h>
X#include <InterViews/canvas.h>
X#include <InterViews/color.h>
X#include <InterViews/layout.h>
X#include <InterViews/session.h>
X#include <InterViews/window.h>
X#include <InterViews/patch.h>
X#include <InterViews/glyph.h>
X#include <InterViews/monoglyph.h>
X#include <InterViews/tformsetter.h>
X#include <InterViews/transformer.h>
X#include <InterViews/bitmap.h>
X#include <Dispatch/dispatcher.h>
X#include <Dispatch/iocallback.h>
X#include <OS/string.h>
X
X#include <stdlib.h>
X
Xenum drawingName { Palette, Xlogo, Cube, Undefined };
X
Xclass Drawing : public Glyph {
Xpublic:
X Drawing(Coord radius, const Color*, const Brush*);
X virtual ~Drawing();
X
X virtual void request(Requisition&) const;
X virtual void allocate(Canvas*, const Allocation&, Extension&);
X virtual void draw(Canvas*, const Allocation&) const;
X void setLogo();
X void setPalette();
X void setCube();
X drawingName selectedDrawing();
X
Xprivate:
X Coord radius_;
X const Color* color_;
X const Brush* brush_;
X
X drawingName currentDrawing;
X void drawCube(Canvas*, const Allocation&) const;
X void drawXlogo(Canvas*, const Allocation&) const;
X void drawPalette(Canvas*, const Allocation&) const;
X};
X
XDrawing::Drawing(Coord r, const Color* c, const Brush* b){
X radius_ = r;
X Resource::ref(c);
X color_ = c;
X Resource::ref(b);
X brush_ = b;
X currentDrawing = Undefined;
X}
X
XDrawing::~Drawing() {
X Resource::unref(color_);
X Resource::unref(brush_);
X}
X
Xvoid Drawing::request(Requisition& req) const {
X Coord diameter = radius_ + radius_;
X Requirement rx(diameter, 0, 0, 0.5);
X Requirement ry(diameter, 0, 0, 0.5);
X req.require(Dimension_X, rx);
X req.require(Dimension_Y, ry);
X}
X
X
Xvoid Drawing::allocate(Canvas* c, const Allocation& a, Extension& ext) {
X ext.merge(c, a);
X}
X
Xvoid Drawing::setLogo() {
X currentDrawing = Xlogo;
X}
X
Xvoid Drawing::setPalette(){
X currentDrawing = Palette;
X}
X
Xvoid Drawing::setCube(){
X currentDrawing = Cube;
X}
X
XdrawingName Drawing::selectedDrawing() {
X return currentDrawing;
X}
X
X
Xvoid Drawing::draw(Canvas* c, const Allocation& a) const {
X switch(currentDrawing) {
X case Palette:
X drawPalette(c,a);
X break;
X case Xlogo:
X drawXlogo(c,a);
X break;
X case Cube:
X drawCube(c,a);
X break;
X case Undefined:
X default:
X break;
X }
X}
X
Xvoid Drawing::drawPalette(Canvas* c, const Allocation& a) const{
X
X const Coord r = radius_, x = a.x(), y = a.y();
X const Coord p0 = 1.00000000 * r;
X const Coord p1 = 0.89657547 * r; // cos 30 * sqrt(1 + tan 15 * tan 15)
X const Coord p2 = 0.70710678 * r; // cos 45
X const Coord p3 = 0.51763809 * r; // cos 60 * sqrt(1 + tan 15 * tan 15)
X const Coord p4 = 0.26794919 * r; // tan 15
X
X // draw eight slices, each with a different color,
X // to make a complete circle
X
X // black slice
X c->new_path();
X c->line_to(x+p0, y);
X c->curve_to(x+p2, y+p2, x+p0, y+p4, x+p1, y+p3);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(0.0,0.0,0.0));
X
X // blue slice
X c->new_path();
X c->line_to(x+p2, y+p2);
X c->curve_to(x, y+p0, x+p3, y+p1, x+p4, y+p0);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(0.0,0.0,1.0));
X
X // green slice
X c->new_path();
X c->line_to(x, y+p0);
X c->curve_to(x-p2, y+p2, x-p4, y+p0, x-p3, y+p1);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(0.0,1.0,0.0));
X
X // cyan slice
X c->new_path();
X c->line_to(x-p2, y+p2);
X c->curve_to(x-p0, y, x-p1, y + p3, x-p0, y+p4);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(0.0,1.0,1.0));
X
X // red slice
X c->new_path();
X c->line_to(x-p0, y);
X c->curve_to(x-p2, y-p2, x-p0, y-p4, x-p1, y-p3);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(1.0,0.0,0.0));
X
X // magenta slice
X c->new_path();
X c->line_to(x-p2, y-p2);
X c->curve_to(x, y-p0, x-p3, y-p1, x-p4, y-p0);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(1.0,0.0,1.0));
X
X // yellow slice
X c->new_path();
X c->line_to(x, y-p0);
X c->curve_to(x+p2, y-p2, x+p4, y-p0, x+p3, y-p1);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(1.0,1.0,0.0));
X
X // white slice
X c->new_path();
X c->line_to(x+p2, y-p2);
X c->curve_to(x+p0, y, x+p1, y-p3, x+p0, y-p4);
X c->line_to(x,y);
X c->close_path();
X c->fill(new Color(1.0,1.0,1.0));
X
X c->stroke(color_, brush_);
X}
X
X
Xvoid Drawing::drawXlogo(Canvas* c, const Allocation& a) const {
X const Coord x = a.x(), y = a.y();
X
X // draw right half of X logo
X c->new_path();
X c->move_to(0.0, 0.0);
X c->line_to(100.0, 100.0);
X c->line_to(85.0, 100.0);
X c->line_to(-26.0, -12.0);
X c->line_to(65.0, -125.0);
X c->line_to(100.0, -125.0);
X c->close_path();
X c->fill(new Color(0.0,0.0,1.0));
X
X // left half of X logo
X c->new_path();
X c->move_to(-36.0, 0.0);
X c->line_to(-136.0, 100.0);
X c->line_to(-101.0, 100.0);
X c->line_to(-10.0, 12.0);
X c->line_to(-125.0, -125.0);
X c->line_to(-136.0, -125.0);
X c->close_path();
X c->fill(new Color(0.0,0.0,1.0));
X
X c->stroke(color_, brush_);
X}
X
Xvoid Drawing::drawCube(Canvas* c, const Allocation& a) const {
X const Coord x = a.x(), y = a.y();
X
X // draw back of cube first
X c->new_path();
X c->move_to(80.0, 80.0);
X c->line_to(-20.0, 80.0);
X c->line_to(-20.0, -20.0);
X c->line_to(80.0, -20.0);
X c->close_path();
X c->fill(new Color(0.0,1.0,0.0));
X
X // draw left side of cube
X c->new_path();
X c->move_to(-20.0, 80.0);
X c->line_to(-80.0, 20.0);
X c->line_to(-80.0, -80.0);
X c->line_to(-20.0, -20.0);
X c->close_path();
X c->fill(new Color(0.0,0.0,1.0));
X
X // draw right side of cube
X c->new_path();
X c->move_to(20.0, 20.0);
X c->line_to(80.0, 80.0);
X c->line_to(80.0, -20.0);
X c->line_to(20.0, -80.0);
X c->close_path();
X c->fill(new Color(1.0,0.0,.0));
X
X // draw front of cube
X c->new_path();
X c->move_to(20.0, 20.0);
X c->line_to(-80.0, 20.0);
X c->line_to(-80.0, -80.0);
X c->line_to(20.0, -80.0);
X c->close_path();
X c->fill(new Color(0.0,1.0,1.0));
X
X // don't draw the top and bottom of the cube.
X
X c->stroke(color_, brush_);
X}
X
X
Xstruct MenuInfo;
X
Xclass AppArea : public MonoGlyph{
X public:
X AppArea(Drawing*);
X virtual ~AppArea();
X
X virtual void update_area(Patch*);
X virtual void draw(Canvas*, const Allocation&) const;
X
X void run(long, long);
X void start();
X void stop();
X
X void rotPalette();
X void xlogo();
X void cube();
X Menu* menubar();
X
X private:
X Drawing* drawing;
X Coord scale;
X TransformSetter* xform;
X Patch* area;
X Patch* bd;
X void set_xform();
X class IOHandler* tick;
X
X Menu* make_menu(Menu*, MenuInfo*, int options = 0);
X MenuItem* make_submenu(MenuItem*, Menu*);
X MenuItem* make_item(MenuItem*, Action*);
X
X drawingName selectedDrawing;
X};
X
XdeclareIOCallback(AppArea)
XimplementIOCallback(AppArea)
X
XdeclareActionCallback(AppArea)
XimplementActionCallback(AppArea)
X
X
Xstruct MenuInfo {
X const char* str;
X ActionMemberFunction(AppArea) func;
X MenuInfo* submenu;
X int options;
X};
X
XMenuInfo selectionMenu[] = {
X { "palette", &AppArea::rotPalette },
X { "xlogo", &AppArea::xlogo },
X { "cube", &AppArea::cube },
X { nil }
X};
X
X
X void AppArea::update_area(Patch* p) {
X area = p;
X }
X
X void AppArea::draw(Canvas* c, const Allocation& a) const {
X c->push_clipping();
X c->clip_rect(a.left(), a.bottom(), a.right(), a.top());
X MonoGlyph::draw(c, a);
X c->pop_clipping();
X }
X
X void AppArea::run(long /* s */, long /* us */) {
X int scl = (int)scale;
X scl++;
X scl = scl%360;
X scale = scl;
X set_xform();
X bd->redraw();
X area->reallocate();
X bd->redraw();
X Dispatcher::instance().startTimer(0.1, 0.0, tick);
X }
X
X void AppArea::start() {
X run(0.1, 0.0);
X }
X
X void AppArea::stop() {
X Dispatcher::instance().stopTimer(tick);
X }
X
X AppArea::AppArea(Drawing* g) : MonoGlyph(nil) {
X scale = 0.0;
X drawing = g;
X xform = new TransformSetter(g);
X set_xform();
X area = nil;
X bd = new Patch(xform);
X body(bd);
X tick = new IOCallback(AppArea)(this, &AppArea::run);
X WidgetKit* kit_ = WidgetKit::instance();
X LayoutKit* layout_ = LayoutKit::instance();
X }
X
X AppArea::~AppArea() {}
X
X
X void AppArea::set_xform() {
X Transformer t;
X switch(drawing->selectedDrawing()) {
X case Palette:
X t.rotate(3*scale);
X t.skew(1.0, 1.0);
X t.rotate(scale);
X break;
X case Xlogo:
X t.rotate(-3*scale);
X t.skew(-1.0, 1.0);
X break;
X case Cube:
X t.translate(200.0, 200.0);
X t.rotate(5*scale);
X break;
X case Undefined:
X default:
X break;
X }
X xform->transformer(t);
X}
X
X void AppArea::rotPalette() {
X drawing->setPalette();
X }
X
X
X void AppArea::xlogo() {
X drawing->setLogo();
X }
X
Xvoid AppArea::cube() {
X drawing->setCube();
X}
X
X
XMenu* AppArea::menubar() {
X WidgetKit* kit_ = WidgetKit::instance();
X Menu* m = kit_->menubar();
X Menu* select = make_menu(kit_->pulldown(), selectionMenu);
X m->append_item(make_submenu(kit_->menubar_item("Application"), select));
X return m;
X}
X
X
XMenu* AppArea::make_menu(Menu* m, MenuInfo* info, int options) {
X WidgetKit* kit_ = WidgetKit::instance();
X LayoutKit* layout_ = LayoutKit::instance();
X TelltaleGroup* group = nil;
X for (MenuInfo* i = info; i->str != nil; i++) {
X if (i->str[0] == '\0') {
X m->append_item(kit_->menu_item_separator());
X } else {
X Glyph* g = layout_->r_margin(kit_->label(i->str), 0.0, fil, 0.0);
X MenuItem* item;
X switch (options) {
X case 1:
X item = kit_->check_menu_item(g);
X break;
X case 2:
X if (group == nil) {
X group = new TelltaleGroup;
X }
X item = kit_->radio_menu_item(group, g);
X break;
X default:
X item = kit_->menu_item(g);
X break;
X }
X if (i->func == nil) {
X if (i->submenu != nil) {
X make_submenu(
X item,
X make_menu(kit_->pullright(), i->submenu, i->options)
X );
X }
X } else {
X make_item(item, new ActionCallback(AppArea)(this, i->func));
X }
X m->append_item(item);
X }
X }
X return m;
X}
X
X
XMenuItem* AppArea::make_submenu(MenuItem* i, Menu* s) {
X i->menu(s);
X return i;
X}
X
XMenuItem* AppArea::make_item(MenuItem* i, Action* a) {
X i->action(a);
X return i;
X}
X
X
Xstatic OptionDesc options[] = {
X { nil }
X};
X
Xstatic PropertyData props[] = {
X { "rotPalette*font", "-*-lucidatypewriter-bold-r-*-*-14-*" },
X { "rotPalette*title*font", "-*-lucida-bold-r-*-*-14-*" },
X { nil }
X};
X
X
X#define demo_width 64
X#define demo_height 64
Xstatic char demo_bits[] = {
X 0x3f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x80, 0x03,
X 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
X 0xf8, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x70, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0xc0, 0x0f, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x0e, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x3e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x07, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x80, 0x83, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x3f, 0x00,
X 0x00, 0xfc, 0xff, 0x07, 0xe0, 0x00, 0x7e, 0x00, 0x00, 0x06, 0x00, 0x06,
X 0x70, 0x00, 0xfc, 0x00, 0x00, 0x05, 0x00, 0x05, 0x38, 0x00, 0xf8, 0x01,
X 0x80, 0x04, 0x80, 0x04, 0x1c, 0x00, 0xf0, 0x03, 0x40, 0x04, 0x40, 0x04,
X 0x0e, 0x00, 0xe0, 0x07, 0xe0, 0xff, 0x3f, 0x04, 0x07, 0x00, 0x00, 0x00,
X 0x20, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x04,
X 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
X 0x20, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x04,
X 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
X 0x20, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x04,
X 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x04, 0x00, 0xf0, 0x1f, 0x00,
X 0x20, 0x00, 0x20, 0x04, 0x00, 0x0c, 0x61, 0x00, 0x20, 0x00, 0x20, 0x04,
X 0x00, 0x03, 0x81, 0x01, 0x20, 0x00, 0x20, 0x02, 0xc0, 0x00, 0x01, 0x06,
X 0x20, 0x00, 0x20, 0x01, 0x20, 0x00, 0x01, 0x08, 0x20, 0x00, 0xa0, 0x00,
X 0x30, 0x00, 0x01, 0x18, 0x20, 0x00, 0x60, 0x00, 0x48, 0x00, 0x01, 0x24,
X 0xe0, 0xff, 0x3f, 0x00, 0x88, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00, 0x00,
X 0x04, 0x01, 0x01, 0x41, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x81, 0x40,
X 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00,
X 0x02, 0x08, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x11, 0x00,
X 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00,
X 0x01, 0x40, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x00,
X 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
X 0x01, 0x80, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x05, 0x00,
X 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00,
X 0x01, 0x10, 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x08, 0x21, 0x80,
X 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00,
X 0x04, 0x02, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x01, 0x41,
X 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00, 0x00,
X 0x48, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x01, 0x18,
X 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00,
X 0xc0, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x81, 0x01,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00};
X
X
Xint main(int argc, char** argv) {
X Session* session = new Session("rotPalette", argc, argv, options, props);
X WidgetKit& kit = *WidgetKit::instance();
X const LayoutKit& layout = *LayoutKit::instance();
X Drawing* drawing = new Drawing(150, kit.foreground(), new Brush(1.0));
X
X AppArea* aa = new AppArea(drawing);
X Patch* p = new Patch(
X layout.vcenter(layout.fixed_span(aa, 10*72.0, 10*72.0), 1.0)
X );
X aa->update_area(p);
X
X Bitmap* bitmap = new Bitmap(demo_bits, demo_width, demo_height);
X
X ApplicationWindow* AppWin =
X new ApplicationWindow(
X kit.inset_frame(
X layout.vbox(
X layout.center(aa->menubar(), 1.0),
X p,
X layout.vglue(5.0),
X layout.hbox(
X kit.push_button(
X "Start",
X new ActionCallback(AppArea)(aa, &AppArea::start)
X ),
X layout.hglue(5.0),
X kit.push_button(
X "Speed Up",
X new ActionCallback(AppArea)(aa, &AppArea::start)
X ),
X layout.hglue(5.0),
X kit.push_button(
X "Slow Down",
X new ActionCallback(AppArea)(aa, &AppArea::stop)
X ),
X layout.hglue(5.0),
X kit.push_button(
X "Quit",
X kit.quit()
X )
X )
X )
X )
X );
X
X AppWin->icon_bitmap(bitmap);
X return session->run_window(AppWin);
X
X
X}
\End\Of\File\
else
echo "will not over write ./main.c"
fi
echo "Finished archive 1 of 1"
exit
Technical Details
Message-ID:
<1992Sep2.122750.7254@newstand.syr.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!rutgers!psinntp!psinntp!newstand.syr.edu!cat.syr.edu!ibashirShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!rutgers!psinntp!psinntp!newstand.syr.edu!cat.syr.edu!ibashir From: ibashir@cat.syr.edu (Imran Bashir) Newsgroups: comp.windows.interviews Subject: An InterViews3.1 Beta based demo program Message-ID: <1992Sep2.122750.7254@newstand.syr.edu> Date: 2 Sep 92 16:27:50 GMT Organization: CASE Center, Syracuse University Lines: 644