/* ==================================================== ======== ======= *
 *
 *  demo.cc
 *  Ubit Project [Elc::2002]
 *  Author: Eric Lecolinet
 *
 *  Part of the Ubit Toolkit: A Brick Construction Game Model for Creating GUIs
 *
 *  (C) 1999-2002 Eric Lecolinet @ ENST Paris
 *  WWW: http://www.enst.fr/~elc/ubit   Email: elc@enst.fr (subject: ubit)
 *
 * ***********************************************************************
 * COPYRIGHT NOTICE : 
 * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY AND WITHOUT EVEN THE 
 * IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 
 * YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF THE GNU 
 * GENERAL PUBLIC LICENSE AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION; 
 * EITHER VERSION 2 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.
 * SEE FILES 'COPYRIGHT' AND 'COPYING' FOR MORE DETAILS.
 * ***********************************************************************
 *
 * ==================================================== [Elc:02] ======= *
 * ==================================================== ======== ======= */


#include <ubit/ubit.hpp>
#include <ubit/ugraph.hpp>
#include <ubit/upixmaps.hpp>
#include "dmisc.hh"
#include "dlayout.hh"
#include "dtree.hh"
#include "dchart.hh"
#include "drules.hh"
#include "dbricks.hh"
#include "dstatus.hh"
#include "dtext.hh"
#include "ddraw.hh"
#include "dselect.hh"
#include "dmain.hh"

// forward defs
extern const char *ubit_xpm[], *bricks_xpm[], *term_xpm[], *manual_xpm[];

UPix ubit_pix(ubit_xpm);
UPix bricks_pix(bricks_xpm);
UPix term_pix(term_xpm);
UPix eyes_pix(fvwm_mini_eyes_xpm);
UPix mail_pix(fvwm_mini_mail_xpm);
UPix manual_pix(fvwm_mini_book_xpm);


Shared *shared = null;	// accessible everywhere

// suppose we have this data to display
ChartDialog::CHART chartTab[] = {
  {"Lun", 50},
  {"Mar", 98},
  {"Mer", 135},
  {"Jeu", 44}, 
  {"Ven", 77}, 
  {"Sam", 35}, 
  {"Dim", 120},
  {null, 0}
};

/* ==================================================== [Elc:00] ======= */
/* ==================================================== ======== ======= */

int main(int argc, char *argv[]) {

  UAppli *appli = new UAppli(&argc, argv);
  appli->setImaPath("../../images");

  // Init. the shared objets
  shared = new Shared(appli);

  // Creates the Main Window (also callled the "Main Frame")
  UFrame *mainwin = new MainWin(appli, chartTab);

  // adds the main frame to the UAppli
  appli->add(mainwin);
  mainwin->show(true);

  // starts the event main loop
  return appli->mainLoop();
}


/* ==================================================== [Elc:00] ======= */
/* ==================================================== ======== ======= */


MainWin::MainWin(UAppli *ap, ChartDialog::CHART *chartTab)
  : chartDial(chartTab)		// initializes field 'chartDial'
{
  appli = ap;
  statusbar = null;
  treeDial = null;
  shareDial = null;
  layoutDial = null;

  // callback object that opens an ubiquitous Main Page
  UCall& openUbiqDial = ucall(this, &MainWin::newUbiqMainPage);

 
  /* =================================================== ======== ======= */
  // Creates the treeDial

  UMenu &me =
    umenu(UFont::bold + ubutton(USymbol::right + "Copy")
	  + ubutton(UColor::red
	  + ubox(UBorder::etchedOut+UFont::bold
	  + uhcenter() + "x") + UFont::bold + UFont::italic + " Delete")
	  + ubutton(UPix::edit + "Edit")
	  + ubutton(UPix::ray  + "Exec")
	  );

  treeDial = new MyTreeDialog(&me);


  /* =================================================== ======== ======= */
  // Creates the (HTML-like) Main Page

  // foreground color of the (shared) page
  UColor &fgcolor = ucolor(UColor::black);

  // changing the state of 'check1' will also change 'fgcolor' :
  shared->check1->addlist
    ( 
     UOn::unselect / usetref(&fgcolor, UColor::black)
     + UOn::select / usetref(&fgcolor, UColor::red)
     );

  // this callback function will be called each time 'fgcolor' is changed
  fgcolor.onChange(ucall(this, &MainWin::fgColorChanged));

  // background color of the (shared) page
  UBgcolor &bgcolor = ubgcolor(UColor::grey);

  // changing the state of 'check2' will also change 'bgcolor' :
  shared->check2->addlist
    ( 
     UOn::unselect / usetref(&bgcolor, UColor::grey)
     + UOn::select / usetref(&bgcolor, UColor::orange)
     );

  shared->mainPage.addlist
    (
     uhcenter()
     // Conditional background and foreground colors 
     // 'shared->bgcolor' is initialized in Share::Share()
     // Note that colors are propagated to suboxes when applicable
     + shared->bgcolor
     + fgcolor

     + uvflex()	// the following boxes are H justified
     + uhbox(" ")
     // nb: UFonts can be combined and are propagated to children
     + uhbox(
	     UFont::bold + UFont::x_large
	     + ulabel(fgcolor + bgcolor + "The") 
	     + ubit_pix
	     + ulinkbutton("Ubit" + openUbiqDial)     // opens dialog
	     + ulabel(fgcolor + bgcolor + "Toolkit")
	     )
     + " "
     + uhbox(uvcenter() + UFont::bold 
	     + "A " + ulinkbutton(bricks_pix + "Brick" + brickDial)
	     + "Construction Game Model")
     + uhbox(
	     "   for creating"
	     + UFont::italic + UColor::red
	     + UPix::ray + "Graphical User Interfaces" + UPix::ray
	     )
     + uhbox(" ")
     
     + utop()		// the following boxes are not H justified
     + uhbox(ulabel(UBgcolor::wheat + UFont::bold + UFont::italic
		    + eyes_pix + "Search:") 
	     + shared->shtext
	     )
     
     + uvflex()	// the following boxes are H justified
     + uhbox( ubutton(UPix::ray + "Ubiq" + openUbiqDial)
	      + ubutton(manual_pix + "Share"
			+ UOn::action / ucall(this,&MainWin::openShareDialog))
	      + ubutton(UPix::edit + "Text" + textDial)
	      + ubutton("Colors" + USymbol::down + shared->colorMenu)
	      )
     );

  // ajouter le transparent_postit 
  shared->mainPage.add(shared->transparent_postit);
  shared->mainPage.update();

  /* ==================================================== ======== ======= */
  // (Share) View Menu

  // NOTE: as we don't use pointers but true variables, they
  // can be referenced by other objects before being actually initialized
  // (this is the case here as there objects have already been referenced
  //  by Main Page objects)

  viewMenu.addlist
    (
     utitle("Ubiq Views")
     + ubutton("Update All" + UOn::action / ucall(appli, &UAppli::updateAll))
     + ulabel()
     ); 
  

  /* ==================================================== ======== ======= */
  // Option Menu
  
  // NOTE that variable 'optionMenu' is a C++ reference 
  // - it could not be a plain object because copying gadget boxes
  //   by assigning them is meaningless (and illegal)
  //
  UMenu &optionMenu =
    umenu( ubutton( UPix::colors
		    + " Color:"
		    + shared->optbutton.redBtn // shared Buttons
		    + shared->optbutton.yellowBtn
		    + shared->optbutton.blueBtn
		    + shared->optbutton.whiteBtn
		    )
	   + ubutton( uhflex()
		      + UPix::colors
		      + " Font: " 
		      + utextbox(uhflex() + UFont::bold 
				 + uedit() + "bold" 
				 + uright() + USymbol::down)
		      )
	   + ubutton(uhflex() + UPix::question + " Find: " + shared->shtext)
	   + ubutton(manual_pix
		     + " Current Page " + USymbol::right
		     + umenu(shared->mainPage)
		     )
	   );


  /* ==================================================== ======== ======= */

  UBox &index =
    ubar( UOrient::vertical + utop()
	  + ubutton( UFont::large + UFont::bold + "Index:" )
	  + uvflex()
	  + uvbox( UBorder::etchedIn + uvflex()
		   + UFont::bold + UBgcolor::white 
		   + uitem( ulinkbutton(UPix::rball + "Charts"   + chartDial ))
		   + uitem( ulinkbutton( UPix::rball +"Tree"     + treeDial ))
		   + uitem( ulinkbutton( UPix::rball +"RadioSelect" 
				   + *(new SelectDialog())))
		   // creates Layout Dialog only once
		   + uitem( ulinkbutton( UPix::rball +"Panes" 
				   + UOn::action
				   / ucall(this, &MainWin::openLayoutDialog))
			    )
		   + uitem( ulinkbutton( UPix::rball +"UbiqView" 
				    + udialog( uvflex() + shared->mainPage)
				   ))

		   + uitem( ulinkbutton( UPix::rball +"Options"  + optionMenu ))
			    // shared button containing other buttons
		   + shared->optbutton
		   )
		   );

  /* ==================================================== ======== ======= */
  // Open and SaveAs Dialogs

  // NOTE: these dialog will be added to button parents that will 
  // automatically open them when clicked
  //
  shared->openDial = &udialog(utitle("Open") + ufilebox());

  shared->saveDial = &udialog(utitle("Save As") + ufilebox());

  // CAUTION: the following code is WRONG because variable 'shared->saveDial'
  // is not yet initialized when it is passed as an agument to 'ucall' :
  //
  // shared->saveDial =
  //    &ufileDialog(utitle("Save As")
  //	  	     + ucall(fileCB,"save",shared->saveDial, UOn::action));
  

  /* ==================================================== ======== ======= */
  // Toolbar, MenuBar and FileMenu


  //UBgcolor &timer_color = ubgcolor(UColor::grey);
  /*
    shared->timer->call( 
    .condset(UColor::red, shared->timer->when(0))
    .condset(UColor::blue,shared->timer->when(1))
    .condset(UColor::orange, shared->timer->when(2)))
  */

  UScale &toolScale = uscale();
  
  UBar &toolbar = ubar
    ( 
     uvbox( uhmargin(0)
	    + ubox(USymbol::up +  ucall(&toolScale, +1, &UScale::incr))
	    + ubox(USymbol::down + ucall(&toolScale, -1, &UScale::incr))
	    ) 
     + toolScale
     + ubutton( usrange(-5,3) / UPix::diskette 
		+ usrange(-1,10) / ustr("Save")
		+ shared->saveDial)
     + ubutton( usrange(-5,3) / UPix::ray
		+  usrange(-1,10) / ustr("Ubiq")
		+ openUbiqDial )
     + ubutton( usrange(-5,3) / bricks_pix
		+  usrange(-1,10) / ustr("Bricks")
		+ brickDial)
     + ubutton( usrange(-5,3) / manual_pix
		+  usrange(-1,10) / ustr("Share")
		+ UOn::action / ucall(this, &MainWin::openShareDialog))
     + ubutton( usrange(-5,3) / UPix::edit
		+  usrange(-1,10) / ustr("Edit")
		+ textDial)
     + ubutton( usrange(-5,3) / UPix::colors 
		+  usrange(-1,10) / ustr("Draw")
		+ drawDial)
     /*
       + ubutton( UPix::clock + "Timer"
       + ucall(this, &startStopTimer, UOn::action)
       + timer_color
     */

     + "  "
     + ubutton(USymbol::down + USymbol::down
	       + UOn::action / ucall(&mainScale, -1, &UScale::incr))
     + ubutton(USymbol::up + USymbol::up
	       + UOn::action / ucall(&mainScale, +1, &UScale::incr))
     + uhflex() + ulabel("")
     + uright()
     + ubutton( UPix::stop + "Exit" + UOn::action / ucall(0, exit))
    );


  UMenu& file_menu = 
    umenu( //ubutton( upix("mini-edit.xpm") + "New" + newDial )
	  // NOTE: openDialog and saveDialog will be automatically opened
	  // when clicking the corresponding button
	  ubutton( UPix::doc  + "Open" + shared->openDial)
	  + ubutton( UPix::diskette + "Save")
	  + ubutton( UPix::diskette + "Save As" + shared->saveDial)
	  + ubutton( UPix::stop + "Exit" + UOn::action / ucall(0, exit))
	  );

	   
   UMenubar& mbar = 
     umenubar( ubutton("File" + file_menu)
	       + ubutton("Colors"  + shared->colorMenu)
	       + ubutton("Options" + optionMenu)
	       + ubutton("Views"   + viewMenu)
	       + uhflex() + ulabel(" ")
	       + uright() + ubutton(ubutton(UPix::question))
	       );


  /* ==================================================== ======== ======= */
  // Make the StatusBar
  // WE use a UTimer to display a message

  statusbar = new MyStatusBar
    (/*shared->timer,*/
     ubutton(UPix::ray + openUbiqDial)
     + ubutton(bricks_pix + brickDial)
     + ubutton(UPix::edit + textDial)
     );

  // add to MainWin
  addlist
    (
     mainScale
     + uhflex() + utop()
     + mbar 
     + toolbar

     // this block will be justified vertically
     + uvflex()
     + uhbox( uvflex()
	      // 'mainPage' will be adjusted horizontally
	      + uhflex() + shared->mainPage 
	      // 'index' width will remain constant
	      + uright() + index
	      )
     
     + ubottom()
     + statusbar
     );
}


/* ==================================================== [Elc:00] ======= */
/* ==================================================== ======== ======= */
// Init. the shared data

Shared::Shared(UAppli *appli) {

  //initialized in MainWin::MainWin
  openDial = null;
  saveDial = null;

  // Inits the Timer
  // Three time Lapses - Each time lapse is 1000 msec long
  //int durations[] = {1000, 1000, 1000};
  /////#### timer = new UTimer(durations, 3);
  timer = null;
  // IMPORTANT NOTE: the timer must be added to the UAppli before it is used:
  /////#### appli->add(timer);

  shtext.addlist
    ( 
     uedit() // makes text editable
     + UColor::red + UFont::bold + "Ubi" + UFont::_bold 
     + UColor::blue + UFont::italic + "quitous" + UFont::_italic
     + UPix::question + UFont::bold +"Bricks" 
     );


  /* =================================================== ======== ======= */
  /* =================================================== ======== ======= */
  // Conditional color Checkboxes
  
  check1 = &ucheckbox( manual_pix + "Red" );
  check2 = &ucheckbox( UPix::ray + "Yellow" );


  /* ==================================================== ======== ======= */
  // 'optbutton' is a (shared) button that contains 4 other buttons
  // (the last one being a "down" arrow symbol that opens a menu)

  optbutton.addlist
    ( 
     UBgcolor::orange + UFont::bold + UFont::italic
     + "Try! "
     + optbutton.yellowBtn.addlist( UBgcolor::yellow + " " )
     + optbutton.whiteBtn.addlist( UBgcolor::white + " " )
     + optbutton.blueBtn.addlist( UBgcolor::blue + " " )
     + ubox( //UMode::ghost // button that opens a menu
	    USymbol::down
	    + umenu( ulabel(UFont::italic + "Colors:")
		     + optbutton.whiteBtn
		     + optbutton.redBtn.addlist( UBgcolor::orange + " " )
		     + optbutton.yellowBtn
		     + optbutton.blueBtn
		     )
	    )
     );

  // NB: add '*' before 'check1' and 'check2' because they are pointers
  colorMenu.addlist( *check1 + *check2 + optbutton );

  /* ==================================================== ======== ======= */

  bgcolor.set(UColor::white);  // defaut color

  optbutton.add(           UOn::arm / usetref(&bgcolor, UColor::orange) );
  optbutton.redBtn.add(    UOn::arm / usetref(&bgcolor, UColor::red)    );
  optbutton.yellowBtn.add( UOn::arm / usetref(&bgcolor, UColor::yellow) );
  optbutton.blueBtn.add(   UOn::arm / usetref(&bgcolor, UColor::blue)   );
  optbutton.whiteBtn.add(  UOn::arm / usetref(&bgcolor, UColor::white)  );

  /* ==================================================== ======== ======= */
  // creates the transparent PostIt
  transparent_postit = new Postit(0, 0);
}

/* ==================================================== [Elc:00] ======= */
/* ==================================================== ======== ======= */

Postit::Postit(u_pos x, u_pos y, UArgs a) : UVbox(a) {
  pos      = &upos(x, y);
  backgd   = &ubackground(UBgcolor::none); //transparent background
  txtcolor = &ucolor(UColor::red);         //text colors

  // the handle for moving the Postit
  handle = &ulabel
    (
     UBgcolor::blue + UColor::white + UFont::bold 
     + " Transparent Postit "
     );

  ctrlbtn = &ubutton
    ( 
     UBgcolor::none
     + UMode::canSelect //acts as a checkbox
     + UOn::arm / UBgcolor::red
     + UOn::enter / UBgcolor::orange
     + UPix::ray
     + UOn::unselect / ustr("O")
     + UOn::select / ustr("T")
     + UOn::action / ucall(this, 1, &Postit::setBackgd)
     + (ctrlbtn2 = &ubutton( UBgcolor::none
			     + UMode::canSelect 
			     + UOn::arm / UBgcolor::red
			     + UOn::enter / UBgcolor::orange
			     + UFont::bold
			     + UOn::unselect / UPix::cross
			     + UOn::select / ustr(" ")
			     + UOn::action / ucall(this, 2, &Postit::setBackgd)
			     )
	)
     );
	      
  // the main box of the postit
  addlist
    ( 
     *pos + backgd 
     + UOrient::vertical + UBorder::etchedIn + uhflex() + uvflex()
     // this box can't be resized (==> avoid useless refreshes)
     + uwidth(UWidth::KEEP_SIZE) + uheight(UHeight::KEEP_SIZE)
     + handle
     + uhbox( UFont::small + UFont::bold + UFont::italic
	      + UColor::navy + uhcenter()
	      + "--Drag title to move--"
	      )

     // text area
     + uflowbox( uheight(60) + uwidth(60)
		 + uedit() // editable
		 + UFont::bold + txtcolor
		 + "you can write your\nnotes here"
		 )

     // control bar
     + uhbox( UFont::bold + UFont::small 
	      + ctrlbtn
	      + ubutton( UBgcolor::none
			 + USymbol::right + uhspacing(0)
			 + ubutton( UBgcolor::red + "  "
				    + UOn::action / usetref(txtcolor, UColor::red))
			 + ubutton( UBgcolor::navy + "  " 
				    + UOn::action / usetref(txtcolor, UColor::navy))
			 + ubutton( UBgcolor::orange + "  "
				    + UOn::action / usetref(txtcolor, UColor::orange))
			 + ubutton( UBgcolor::black + "  "
				    + UOn::action / usetref(txtcolor, UColor::black))
			 )
	      )
     );

  // pressing/dragging the handle will move the Postit
  handle->add(UOn::mpress / ucall(this, &Postit::press));
  handle->add(UOn::mdrag  / ucall(this, &Postit::drag));

  // this callback paints the circle in the Postit
  this->add(UOn::viewPaint / ucall(this, &Postit::paintGraphics));
  this->show(true);
  this->update();
}

void Postit::press(UEvent&e) {
  last_x = e.getXwin();
  last_y = e.getYwin();
}

void Postit::drag(UEvent&e) {
  u_pos x = pos->getX() + (e.getXwin() - last_x);
  u_pos y = pos->getY() + (e.getYwin() - last_y);
  pos->set(x,y);
  last_x = e.getXwin();
  last_y = e.getYwin();
}

void Postit::setBackgd(UEvent&e, int b) {
  if (ctrlbtn->isSelected()) {
    if (ctrlbtn2->isSelected())
      backgd->set(UPix::cross);
    else backgd->set(UBgcolor::wheat);
  }
  else backgd->set(UBgcolor::none);
  backgd->update();
}

void Postit::paintGraphics(UEvent&e) {
  UGraph g(e.getView());
  g.setColor(UColor::navy);
  g.setThickness(2);
  g.drawArc(50, 50, 45, 35, 0, 360);
}

/* ==================================================== [Elc:00] ======= */
/* ==================================================== ======== ======= */

void MainWin::fgColorChanged() {
  printf("Color has changed\n");
}

void MainWin::startStopTimer(UEvent&) {
  /*#########
  if (shared->timer->isRunning())
    shared->timer->stop();
  else shared->timer->start();
  #######*/
}

void delCB(UEvent&e, UBrick *any) {
  UButton *deletingButton = (UButton*)e.getSource();
  UGroup *par = deletingButton->getParent(0);
  delete any; // deletes the dialog
  delete deletingButton; // deletes the button
  par->update();
}

// creates a new page EACH TIME the button is clicked
//
void MainWin::newUbiqMainPage(UEvent&) {
  static int copy_no = 0;
  copy_no++;

  char t[100];
  sprintf(t, "Ubiquitous View No:%d", copy_no);

  UDialog &d = udialog
    (
     utitle(t)
     + utop()
     + uhbox( UBorder::etchedOut
	      + shared->check1      // shared checkboxes
	      + shared->check1
	      + shared->check1
	      + shared->check2     // shared checkboxes
	      + shared->check2
		   )
     + uvflex() + shared->mainPage
     + ubottom()
     + uhbox(uhcenter()
	     // closes the dialog box when OK or Cancel are pressed
	     + ubutton( UPix::ray + "OK" + UOn::action / ucloseWin())
	     + ubutton("Cancel" + ucloseWin())
	     + ubutton( UPix::question + "Help")
	     )
     );


  // add the newly created dialog to the Main Frame, then makes it appear
  add(d);
  d.show(true);

  // add a "Delete" Button in the Windows menu 
  sprintf(t, "Delete View #%d", copy_no);
  viewMenu.add(ubutton(t + UOn::action / ucall((UBrick*)&d, delCB)));
}

/* ==================================================== [Elc:00] ======= */
/* ==================================================== ======== ======= */
// Creates Dialog (only once) and opens it

void MainWin::openLayoutDialog(UEvent&) {
  if (!layoutDial) {
    layoutDial = new MyLayoutDialog();
    add(layoutDial);
  }
  layoutDial->show(true);
}


class MyShareDialog : public UDialog {
public:
  UStr scrollval;
  UListbox listbox;
  MyShareDialog();
  void changeScroll(UEvent&);
};

// Creates Dialog (only once) amd opens it
//
void MainWin::openShareDialog(UEvent&) {
  if (!shareDial) {
    shareDial = new MyShareDialog();
    add(shareDial);
  }
  shareDial->show(true);
}

// A Dialog that contains many shared objects
//
MyShareDialog::MyShareDialog() {
 
  scrollval.set("10");

  UTextbox &comptext =
    utextbox( uedit()  // makes text editable 
	   + uwidth(150)
	   + UFlowView::style // flow layout
	   + "A " + ulinkbutton(bricks_pix + "Brick")
	   + "Construction Game Model" 
	   + " for creating"
	   + UFont::italic + UColor::red
	   + UPix::cross + "Graphical User Interfaces" + UPix::cross

	   + ulabel(UBgcolor::wheat + UFont::bold + UFont::italic
		    + manual_pix + "Search:") 

	   + UFont::_italic + UColor::blue
	   + shared->shtext // shared textfield
	   + UColor::teal
	   + "aaaaaa bbbbbbbbbbbbbbbbb cccccccccccc cccccccc "
	   + UPix::diskette 
	   + UColor::green + UFont::italic +
	   + "FFFFFFFFFFFF hhhh hhhh hhh hhhhhhh" +  UFont::_italic
	   +  UColor::black + UFont::bold
	   + ubutton("clic clic")
	   + "OOOOOOO" + UFont::_bold + " ooooooo ooooooo .......\nxxxxxxx" 
	   + "zzzzzzzzzz zzzzzzzz    zzzzzz  cccccccc eeeeeeeee"
	   );

  listbox.addlist
    (
     ulabel("one")
     + ulabel("two")
     + ucheckbox("three")
     + utextbox(uedit() + UColor::blue+ "mytext")
     + ucheckbox("four") 
     + ubutton("five") 
     + ubutton("six") 
     + uhbox(
	     ubutton(ubit_pix)
	     +ucheckbox(UPix::ray + "truc")
	     +ubutton(eyes_pix + "truc")
	     )
     + ulabel("height") 
     + ulabel("nine") 
     + ulinkbutton("ten") 
     + ubutton("eleven") 
     + ubutton("twelve") 
     );

  UScrollpane &spane =		// vertical scrollbar only
    uscrollpane(true, false, uwidth(130) + comptext);

  UHbox &bb =
    uhbox( uheight(200)
	   + uhflex()

	   // vertical scrollbar only
	   + uscrollpane(true, false, uheight(200) + listbox)
	   + spane

	   // vertical scrollbar only
	   + uscrollpane(true, false,
			 uwidth(130) + uscale(3) + UFont::times + comptext)

	       + uleft()
	       + uvbox(UBorder::shadowIn
		       + ulabel("Scroll")
		       + utextbox(uwidth(55) + uedit() 
				  + ulinkbutton("Set:" 
					  + ucall(this, &MyShareDialog::changeScroll)
					  )
				  + scrollval 
				  )
		       + ubutton("Ok" + ucloseWin())
		       + ubutton("Cancel" + ucloseWin())
		       + ubutton("Help")
		       )
	       );

  
  addlist
    (
     utitle("Many shared objects...")
     + uhflex() + utop()
     + "A Composite List with a Scrollbar"
     + uvflex()
     + bb
     + uscale(2) + UFont::times 
     + bb			// repete et synchronise
     );
}


void MyShareDialog::changeScroll(UEvent&) {
  const char *s = scrollval.chars();
  int i = s ? atoi(s) : 0;
  printf("set = '%d'\n\n", i);
  listbox.choice().setIndex(i);
}


const char *ubit_xpm[] = {
/* width height num_colors chars_per_pixel */
"    50    51        2            1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"#################################################.",
"#################################################.",
"#################################################.",
"#################################################.",
"#################################################.",
"####################........#####################.",
"################.................################.",
"##############......................#############.",
"############.........................############.",
"###########............................##########.",
"##########..........########............#########.",
"#########........###############.........########.",
"########.......###################........#######.",
"#######.......#####################.......#######.",
"######.......#######################.......######.",
"#####.......#########################......######.",
"#####......###########################......#####.",
"####......########...##################.....#####.",
"####......#######.....#########..######.....#####.",
"####.....#######......########....#####......####.",
"###......######......#########.....#####.....####.",
"###.....######.......########......#####.....####.",
"###.....######......#########......#####.....####.",
"##......#####......#########......######.....####.",
"##.....######......#########......######.....####.",
"##.....######.....##########.....#######.....####.",
"##.....#####......#########......######.....#####.",
"##.....#####.....##########.....#######.....#####.",
"##.....#####.....#########......#######.....#####.",
"##.....#####.....#########......######.....######.",
"##.....#####.....########.......######.....######.",
"##.....#####.....#######........#####......######.",
"##......####......#####..........###......#######.",
"##......#####......##......#..............#######.",
"###......####..............#.............########.",
"###......#####............###...........#########.",
"###.......#####.........######.........##########.",
"####.......######......########......############.",
"####........#####################################.",
"#####........####################################.",
"######.........##################################.",
"#######..........################################.",
"########............#######.......###############.",
"#########..........................##############.",
"##########.........................##############.",
"############.......................##############.",
"###############..................################.",
"####################.........####################.",
"#################################################.",
"#################################################.",
"#################################################."
};

const char *term_xpm[] = {
  "    16    14        6            1",
  "  c None s None",
  ". c Black",
  "# c gray50",
  "a c blue",
  "b c White",
  "c c gray85",
  "     #########  ",
  "    #cccccccc#. ",
  "   #bbbbbbbb##. ",
  "   #b......b##. ",
  "   #b.aaaaab##. ",
  "   #b.aaaaab##. ",
  "   #b.aaaaab##. ",
  "   #bbbbbbbb#.##",
  "   #.........#c.",
  "  #bbbbbbbbb#c#.",
  "  ##.#.#.#.#.##.",
  " #c.c.c.c.c.c.. ",
  "#bbbbbbbbbbbc.  ",
  ".............   "
};

const char *bricks_xpm[] = {
  "16 14 5 1",
  "       c None s None",
  ".      c gray50",
  "X      c yellow",
  "o      c black",
  "O      c red",
  "                ",
  "                ",
  "     ......     ",
  "     .XXXXo     ",
  "     .XOOOo     ",
  "     .XOOOo     ",
  "     .XOOOo     ",
  "......OOOOoooooo",
  ".XXXXOXXXXOXXXXo",
  ".XOOOOXOOOOXOOOo",
  ".XOOOOXOOOOXOOOo",
  ".XOOOOXOOOOXOOOo",
  ".ooooooooooooooo",
  "                "};


