Home About Applications Software License Documentation Download Community

Documentation

1 July 2005
Installing Developers Reference Tutorial SVG Data Driven Version History

An Introduction to Keystone Framework

A more documented tutorial will follow. For now, here are the complete sources. The tutorial is included with main Keystone Framework source, and also binaries for this are avaliable on the download page.

lightdemo1.c
lightdemo2.c
lightdemo3.c
lightdemo.xml
lightdemo1.svg
lightdemo2.svg

LightDemo1.c

/*==========================================================================*/
MODULE::IMPORT/*============================================================*/
/*==========================================================================*/

#include "framework.c"

/*==========================================================================*/
MODULE::INTERFACE/*=========================================================*/
/*==========================================================================*/

class CLightDemo : CApplication {
 public:
   ALIAS<"lightdemo">;     
 
   void main(ARRAY<CString> *args);
};

/*==========================================================================*/
MODULE::IMPLEMENTATION/*====================================================*/
/*==========================================================================*/

OBJECT<CLightDemo, lightdemo>;

int CLightDemo::main(ARRAY<CString> *args) {
   CGDialogMessage message;
   new(&message).CGDialogMessage("Light Demo", "SVG Light Demo", NULL);
   CGWindowDialog(&message).execute();
   delete(&message);
   return 0;
}/*CLightDemo::main*/

/*==========================================================================*/
MODULE::END/*===============================================================*/
/*==========================================================================*/

LightDemo2.c

/*==========================================================================*/
MODULE::INTERFACE/*=========================================================*/
/*==========================================================================*/

#include "framework.c"

class CLights : CObjPersistent {
 public:
   ALIAS<"lights">;

   void CLights(void);
};

class CLight : CObjPersistent {
 public:
   ALIAS<"light">;
   ATTRIBUTE<bool state>;

   void CLight(void);
};

class CLightDemo : CApplication {
 private:
   void new(void);
   void ~CLightDemo(void);
 public:
   ALIAS<"lightdemo">;
 
   ELEMENT:OBJECT<CLights lights>;
   ATTRIBUTE:ARRAY<bool switchState>;
 
   void main(ARRAY<CString> *args);
};

/*==========================================================================*/
MODULE::IMPLEMENTATION/*====================================================*/
/*==========================================================================*/

OBJECT<CLightDemo, lightdemo>;

void CLightDemo::new(void) {
   ARRAY(&this->switchState).new();
   new(&this->lights).CLights();    
   CObject(&this->lights).parent_set(CObject(this));    
}/*CLightDemo::new*/

void CLightDemo::~CLightDemo(void) {
   delete(&this->lights);
   ARRAY(&this->switchState).delete();
}/*CLightDemo::~CLightDemo*/

void CLights::CLights(void) {
}/*CLights::CLights*/

int CLightDemo::main(ARRAY<CString> *args) {
   CFile file;    
   CString filename, message;
   CGDialogMessage dialog;

   new(&message).CString(NULL);
   new(&filename).CString(NULL);    
    
   /* read input file chosen on command line and write it back to standard output */
   if (ARRAY(args).count() < 2) {
      CString(&filename).set("lightdemo.xml");
   }
   else {
      CString(&filename).set(CString(&ARRAY(args).data()[1]).string());
   }
   if (CObjPersistent(this).state_xml_load_file(CString(&filename).string(), TRUE, &message)) {
      new(&file).CFile();
      CIOObject(&file).open_handle(STDOUT);
      CObjPersistent(this).state_xml_store(CIOObject(&file));
      delete(&file);
   }

   if (CString(&message).length()) {
      new(&dialog).CGDialogMessage("Light Demo Error", CString(&message).string(), NULL);
      CGWindowDialog(&dialog).execute();
      delete(&dialog);
   }
   
   delete(&filename);
   delete(&message);

   return 0;
}/*CLightDemo::main*/

/*==========================================================================*/
MODULE::END/*===============================================================*/
/*==========================================================================*/

lightdemo.xml

<?xml version="1.0" encoding="UTF-8"?>
<lightdemo switchState="FALSE TRUE FALSE FALSE">
   <lights>
      <light state="FALSE"/>
      <light state="TRUE"/>
      <light state="FALSE"/>
      <light state="FALSE"/>
      <light state="TRUE"/>
   </lights>
</lightdemo>

lightdemo3.c

/*==========================================================================*/
MODULE::INTERFACE/*=========================================================*/
/*==========================================================================*/

#include "framework.c"

class CGWindowLightDemo : CGWindow {
 private:
   CGLayout layout;     
   bool notify_request_close(void);
 public:
   void CGWindowLightDemo(CObjServer *obj_server);
};

class CLights : CObjPersistent {
 public:
   ALIAS<"lights">;

   void CLights(void);
};

class CLight : CObjPersistent {
 public:
   ALIAS<"light">;
   ATTRIBUTE<bool state>;

   void CLight(void);
};

class CLightDemo : CApplication {
 private:
   void new(void);
   void ~CLightDemo(void);
   CGWindowLightDemo window;
   CObjServer obj_server;
 public:
   ALIAS<"lightdemo">;
 
   ELEMENT:OBJECT<CLights lights>;
   ATTRIBUTE:ARRAY<bool switchState>;
 
   void main(ARRAY<CString> *args);
};


/*==========================================================================*/
MODULE::IMPLEMENTATION/*====================================================*/
/*==========================================================================*/

OBJECT<CLightDemo, lightdemo>;

void CGWindowLightDemo::CGWindowLightDemo(CObjServer *obj_server) {
   new(&this->layout).CGLayout(0, 0, obj_server, obj_server->server_root);
   CGLayout(&this->layout).load_svg_file("lightdemo1.svg", NULL);
    
   CGWindow(this).CGWindow("Light Demo", CGCanvas(&this->layout), NULL);
}/*CGWindowLightDemo::CGWindowLightDemo*/

bool CGWindowLightDemo::notify_request_close(void) {
   CFramework(&framework).kill();
   return FALSE;
}/*CGWindowLightDemo::notify_close*/

void CLightDemo::new(void) {
   ARRAY(&this->switchState).new();
   new(&this->lights).CLights();    
   CObject(&this->lights).parent_set(CObject(this));    
}/*CLightDemo::new*/

void CLightDemo::~CLightDemo(void) {
   delete(&this->lights);
   ARRAY(&this->switchState).delete();
}/*CLightDemo::~CLightDemo*/

void CLights::CLights(void) {
}/*CLights::CLights*/

int CLightDemo::main(ARRAY<CString> *args) {
   CFile file;    
   CString filename, message;
   CGDialogMessage dialog;

   new(&message).CString(NULL);
   new(&filename).CString(NULL); 
   
   if (ARRAY(args).count() < 2) {
      CString(&filename).set("lightdemo.xml");
   }
   else {
      CString(&filename).set(CString(&ARRAY(args).data()[1]).string());
   }
   CObjPersistent(this).state_xml_load_file(CString(&filename).string(), TRUE, &message);   

   if (CString(&message).length()) {
      new(&dialog).CGDialogMessage("Light Demo Error", CString(&message).string(), NULL);
      CGWindowDialog(&dialog).execute();
      delete(&dialog);
   }
   else {   
      new(&this->obj_server).CObjServer(CObjPersistent(this));

      new(&this->window).CGWindowLightDemo(&this->obj_server);
      CGObject(&this->window).show(TRUE);    
   
      CFramework(&framework).main();   

      delete(&this->obj_server);
   }
       
   delete(&filename);
   delete(&message);

   return 0;
}/*CLightDemo::main*/

/*==========================================================================*/
MODULE::END/*===============================================================*/
/*==========================================================================*/

lightdemo1.svg

<svg min-width="320" min-height="40">
   <defs>
      <symbol id="light">
         <circle stroke-width="2" cx="0" cy="0" r="10" stroke="darkred" fill="darkred">
            <animateColor attributeName="fill" from="darkred" 
                          to="red" begin="0.0" end="1.0" fill="freeze"
                          binding="."/>
         </circle>
       </symbol>
    </defs>
    
    <array transform="translate(20,20)" xlink:href="#light" symbolPath="/lightdemo/lights/light[$i]/@state"
           spacingX="40">
       <bind attributeName="elements" binding="count(/lightdemo/lights)"/>
    </array>
</svg>

lightdemo4.c

/*==========================================================================*/
MODULE::INTERFACE/*=========================================================*/
/*==========================================================================*/

#include "framework.c"

class CGWindowLightDemo : CGWindow {
 private:
   CGLayout layout;
   CGSplitter splitter;
   CGLayout layout_main;
   CGLayout tree_layout;
   CGTree tree;
 
   bool notify_request_close(void);
 public:
   void CGWindowLightDemo(CObjServer *obj_server);
};

class CLights : CObjPersistent {
 public:
   ALIAS<"lights">;

   void CLights(void);
};

class CLight : CObjPersistent {
 public:
   ALIAS<"light">;
   ATTRIBUTE<bool state>;

   void CLight(void);
};

class CLightDemo : CApplication {
 private:
   void new(void);
   void ~CLightDemo(void);
   CGWindowLightDemo window;
   CObjServer obj_server;
   static inline switch_set(int index, bool state);
 public:
   ALIAS<"lightdemo">;
 
   ELEMENT:OBJECT<CLights lights>;
   ATTRIBUTE:ARRAY<bool switchState> {
       CLightDemo(this).switch_set(attribute_element, ARRAY(&this->switchState).data()[attribute_element]);
   };
 
   void main(ARRAY<CString> *args);
};

static inline CLightDemo::switch_set(int index, bool state) {
    CLight *light = CLight(CObject(&this->lights).child_n(index));
    
    if (light) {
        CObjPersistent(light).attribute_update(ATTRIBUTE<CLight,state>);
        CObjPersistent(light).attribute_set_int(ATTRIBUTE<CLight,state>, state);
        CObjPersistent(light).attribute_update_end();
    }
}/*CLightDemo::switch_set*/

/*==========================================================================*/
MODULE::IMPLEMENTATION/*====================================================*/
/*==========================================================================*/

OBJECT<CLightDemo, lightdemo>;

void CGWindowLightDemo::CGWindowLightDemo(CObjServer *obj_server) {
   new(&this->layout_main).CGLayout(0, 0, obj_server, obj_server->server_root);
   CGLayout(&this->layout_main).load_svg_file("lightdemo2.svg", NULL);

   new(&this->tree_layout).CGLayout(0, 0, NULL, NULL);
   new(&this->tree).CGTree(obj_server, obj_server->server_root, 0, 0, 0, 0);
   CObject(&this->tree_layout).child_add(CObject(&this->tree));

   new(&this->splitter).CGSplitter(0, 0, 0, 0);
   CObject(&this->splitter).child_add(CObject(&this->tree_layout));
   CObject(&this->splitter).child_add(CObject(&this->layout_main));

   new(&this->layout).CGLayout(0, 0, NULL, NULL);
   CObject(&this->layout).child_add(CObject(&this->splitter));
    
   CGWindow(this).CGWindow("Light Demo", CGCanvas(&this->layout), NULL); 
}/*CGWindowLightDemo::CGWindowLightDemo*/

bool CGWindowLightDemo::notify_request_close(void) {
   CFramework(&framework).kill();
   return FALSE;
}/*CGWindowLightDemo::notify_close*/

void CLightDemo::new(void) {
   ARRAY(&this->switchState).new();
   new(&this->lights).CLights();    
   CObject(&this->lights).parent_set(CObject(this));    
}/*CLightDemo::new*/

void CLightDemo::~CLightDemo(void) {
   delete(&this->lights);
   ARRAY(&this->switchState).delete();
}/*CLightDemo::~CLightDemo*/

void CLights::CLights(void) {
}/*CLights::CLights*/

int CLightDemo::main(ARRAY<CString> *args) {
   CFile file;    
   CString filename, message;
   CGDialogMessage dialog;

   new(&message).CString(NULL);
   new(&filename).CString(NULL);    
    
   if (ARRAY(args).count() < 2) {
      CString(&filename).set("lightdemo.xml");
   }
   else {
      CString(&filename).set(CString(&ARRAY(args).data()[1]).string());
   }
   CObjPersistent(this).state_xml_load_file(CString(&filename).string(), TRUE, &message);   

   if (CString(&message).length()) {
      new(&dialog).CGDialogMessage("Light Demo Error", CString(&message).string(), NULL);
      CGWindowDialog(&dialog).execute();
      delete(&dialog);
   }
   else {   
      new(&this->obj_server).CObjServer(CObjPersistent(this));

      new(&this->window).CGWindowLightDemo(&this->obj_server);
      CGObject(&this->window).show(TRUE);    
      CGWindow(&this->window).maximize(TRUE);           
   
      CFramework(&framework).main();
       
      delete(&this->obj_server);
   }
   
   delete(&filename);   
   delete(&message);       

   return 0;
}/*CLightDemo::main*/

/*==========================================================================*/
MODULE::END/*===============================================================*/
/*==========================================================================*/

lightdemo2.svg


<svg min-width="320" min-height="40">
   <defs>
      <symbol id="lightbulb">
         <ellipse stroke="black" fill="white" cx="20" cy="20" rx="-20" ry="-20">
            <animateColor attributeName="fill" begin="0" dur="1" fill="freeze" 
                          from="white" to="yellow" binding="."/>
         </ellipse>
         <polyline stroke-width="1" stroke="grey" fill="none" 
                   points="12,16 16,12 20,16 24,12 28,16 28,16">
            <animateColor attributeName="stroke" begin="0" dur="1" fill="freeze" 
                          from="grey" to="orange" binding="."/>
            <animate attributeName="stroke-width" begin="0" dur="1" fill="freeze" 
                     from="1" to="3" binding="."/>
          </polyline>
          <rect stroke="black" fill="lightcoral" x="8" y="32" width="24" height="32" rx="0" ry="0"/>
          <line stroke="black" fill="white" stroke-width="3" x1="4" y1="44" x2="36" y2="40"/>
          <line stroke="black" fill="white" stroke-width="3" x1="4" y1="48" x2="36" y2="44"/>
          <line stroke="black" fill="white" stroke-width="3" x1="4" y1="52" x2="36" y2="48"/>
          <line stroke="black" fill="white" stroke-width="3" x1="4" y1="56" x2="36" y2="52"/>
          <line stroke="black" fill="white" stroke-width="3" x1="4" y1="60" x2="36" y2="56"/>
          <line stroke="black" fill="white" stroke-width="3" x1="4" y1="64" x2="36" y2="60"/>
          <line stroke="black" fill="white" x1="16" y1="32" x2="12" y2="12"/>
          <line stroke="black" fill="white" x1="24" y1="32" x2="28" y2="12"/>
      </symbol>
      <symbol id="switch">
          <rect stroke="red" fill="brown" x="0" y="0" width="25" height="50" rx="0" ry="0"/>
          <line stroke="lightcoral" x1="5" y1="5" x2="20" y2="5"/>
          <line stroke="lightcoral" x1="5" y1="10" x2="20" y2="10"/>            
          <line stroke="lightcoral" x1="5" y1="15" x2="20" y2="15"/>
          <line stroke="lightcoral" x1="5" y1="20" x2="20" y2="20"/>
          <line stroke="lightcoral" x1="5" y1="25" x2="20" y2="25"/>            
          <line stroke="lightcoral" x1="5" y1="30" x2="20" y2="30"/>            
          <line stroke="lightcoral" x1="5" y1="35" x2="20" y2="35"/>            
          <line stroke="lightcoral" x1="5" y1="40" x2="20" y2="40"/>            
          <line stroke="lightcoral" x1="5" y1="45" x2="20" y2="45"/>                        
          <rect stroke="none" fill="#000000" x="10" y="20" width="5" height="10" rx="0" ry="0"/>
          <g visibility="hidden">
             <bind attributeName="visibility" binding="not(.)"/>
             <animateInputEvent binding=".=0" eventType="click"/>
             <rect stroke="red" fill="white" x="5" y="5" width="5" height="20" rx="0" ry="0"/>
             <rect stroke="red" fill="white" x="15" y="5" width="5" height="20" rx="0" ry="0"/>
             <rect stroke="red" fill="yellow" x="5" y="5" width="15" height="5" rx="0" ry="0"/>
          </g>
          <g visibility="hidden">
             <bind attributeName="visibility" binding="."/>
             <animateInputEvent binding=".=1" eventType="click"/>
             <rect stroke="red" fill="white" x="5" y="25" width="5" height="20" rx="0" ry="0"/>
             <rect stroke="red" fill="white" x="15" y="25" width="5" height="20" rx="0" ry="0"/>
             <rect stroke="red" fill="yellow" x="5" y="40" width="15" height="5" rx="0" ry="0"/>
          </g>
          <rect stroke="none" fill="#000000" x="20" y="20" width="5" height="10" rx="0" ry="0"/>
          <rect stroke="none" fill="#000000" x="0" y="20" width="5" height="10" rx="0" ry="0"/>
      </symbol>
   </defs>
    
   <array transform="translate(20,20)" xlink:href="#lightbulb" symbolPath="/lightdemo/lights/light[$i]/@state"
          spacingX="50">
      <bind attributeName="elements" binding="count(/lightdemo/lights)"/>
   <array>

   <array transform="translate(28,120)" xlink:href="#switch" symbolPath="/lightdemo/@switchState[$i]"
          spacingX="50">
      <bind attributeName="elements" binding="count(/lightdemo/@switchState)"/>
   </array>
</svg>