home *** CD-ROM | disk | FTP | other *** search
-
- // 2926 lines, includes inline Object.hpp, Button.hpp, Slider.hpp, TextArea.hpp
- // Friend.hpp, Dispatch.cpp, Ishdmous.cpp, YOU MUST MAKE THESE SEPARATE
- // files else (1) insuf memory to compile (2) my includes will fail.
- // ^^^^^^^^^^^^ ^^^^^^^^^^
- // Browses current directory for *.c, *.cpp, *.hpp files and shows
- // objects in use, many with no labels or handles at all using a group
- // concept. Demonstrates limites multitasking with a busy wheel and a
- // counter.
- //
- // Uses Zortech C++ compiler supporting AT&T version 2.0, use:-
- // " -a -g -w -ml fg.lib " to compile it
- //
- // For C++ before 2.0 USE -1 -g -w -ml fgl.lib AND alter static class
- // data initialisers from being outside the class to being back in the
- // class. I could have used a special constructor making static inits
- // language level independant.
- //
- // Bugs exist, are trivial. Intent to spur interest in object oriented
- // programming for workstation logic. See OBJECT.C and OBJECT.CPP that
- // were uploaded earlier. Intent is to use objects where useful, but not
- // to over do it. Does NOT use any Zortech classes, only the fg functions.
-
- //------------------------------------------------> config.hpp <-------------
- /* [ ] ---CONFIG.HPP------ PC OR COMPANY SPECIFIC DATA ---------------- [ ] */
- /* | | */
- /* | Needed because fg_init_all() does not always detect vga12 in | */
- /* | 2.0, even though it does prior to 2.0 | */
- /* | | */
- /* [ ] ---------------------------------------------------------------- [ ] */
-
- #ifndef confighpp
- #define confighpp
-
- /////// How to get fg_init_all to work under c++ 2.0
- //
- #define ISHDGraphicsOpen fg_init_all
- // fg_init_vga12 vga systems (AMEX)
- // fg_init_all ega and general systems
- //
- /////// Under 1.7 fg_init_all works on vga
-
-
-
-
- /////// Key c++ 2.0 and 1.7 differences ///// Static initialised data
- //
- // c++ 1.7 c++ 2.0
- //
- // class A { static int a=2; class A { static int a;
- // } }
- // A::a=2;
- //
- //
- /////// Key C++ 2.0 and 1.7 differences ///// function definitions
- //
- // C++ 1.7 C++ 2.0
- //
- // Subr() { ; } void Subr(void) { ; }
- //
- //
- // in 1.7 a function with no return type is int, as is 2.0, however
- // in 2.0 if declared as int (no void) then the function MUST return
- // a value. Similarly you will get burned on paramaters, so always
- // put void if none is intended.
- //
-
- /////// Key c++ 2.0 and 1.7 differences ///// Pointers to functions
- //
- // c++ 1.7 c++ 2.0
- //
- // class Button { class Button {
- //1 void (* Notifier)(); void (* Notifier)(Button *);
- //
- //2 Button(,void (*fn)(),) Button(,void (*fn)(Button *),)
- //
- //3 Notifier = fn; Notifier = fn;
- // }; };
- //4 notify() { ; } void notify(Button *) { ; }
- //5 main() { new Button(,notify,); main() { new Button(,notify,);
- //
- //
- // 1. A pointer to a function, in 2.0 the pointer must by typed.
- // 2. As a parameter of a function the return and parameter types
- // of the function being passed must be typed.
- // 3. Assignment of the parameter to the pointer is the same.
- // 4. All functions referenced MUST be typed, even if nulls.
- // 5. Invoking a function passing a pointer to a function is the same.
-
- #endif
- /* END of config.hpp */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //------------------------------------------------------> object.hpp <--------
- /* [ ] - - - - - - - - - - - - - O B J E C T - - - - - - - - - - - - - - [ ] */
- /* | | */
- /* | CLASS HIEARCHY: Object <1> | */
- /* | | | */
- /* | +----------+----------+----------+----------+----------+ | */
- /* | | | | | | | | */
- /* | Button TextArea HostLU2 Network o o | */
- /* | | <2> | | | | */
- /* | Slider o o o | */
- /* | | | */
- /* | o | */
- /* | | */
- /* | | */
- /* | | */
- /* | | */
- /* | | */
- /* | <1> Object includes Friend.hpp the friends of derived classes | */
- /* | <2> Button includes Dispatch.hpp as Dispatch uses a Button | */
- /* | Button includes Ishdmous.cpp as Button absolutley needs it | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- /* [ ] - - - - - - - - - - - - - O B J E C T - - - - - - - - - - - - - - [ ] */
- /* | Object.hpp defines a class "Object" for other system compatability | */
- /* | | */
- /* | SetClassTraceOn() Off() Enable or disable debugging. | */
- /* | GetFreeGroupId() Get a group id, two forms allowed, | */
- /* | Returns an id for Group concept objects. | */
- /* | | */
- /* | obj->GetClassName() Returns the class name of an object | */
- /* | obj->GetClassCode() Returns an integer identifyinh the class | */
- /* | | */
- /* | Object-----Button Mouse selectable button | */
- /* | Text Text area | */
- /* | Hostlu2 Host sessions with HLLAPI | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- #include "Config.hpp" // local system configuration
- #ifndef ObjectDefined // compiler switch to not re compile
- #define ObjectDefined
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <conio.h>
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | Object.hpp defines a class, "Object" to be compatible with other | */
- /* | systems, for example Objective C and Smalltalk. Our constructor | */
- /* | is be called before the sub or derived class. | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- #define ObjectMaxEverAllowed 500 // current objects in existance
- class Object { //
- // //
- // class variables //
- static Object * ObjectMasterList[ObjectMaxEverAllowed];
- static int ObjectCountNow; // objects right now
- static int ObjectFirstTime;// first time logic
- public:
- static int ObjectTrace; // 0=notrace, 1=text
- private:
- static int ObjectGroupNow; // group number allocator
-
-
-
-
-
- // instance variables // code 0001 = Object class
- protected: // code 0010 = Button "
- int ObjectType; // code 0011 = Slider "
- // 0 = null // code 0020 = TextArea "
- // 1-999 = graphic // code 0030 = Hostlu2 "
- // 1000-2000 = non graphic // code 1000 = Network "
-
-
-
- public:
- Object(); // constructor - tracks new objects
- virtual ~Object(); // virtual for friend.hpp GroupDelete
-
-
-
-
-
-
-
-
-
-
- public:
-
- // Instance methods/functions needing an object to do their work,
- // derived classes must implement these to get action,
- // these are all considered to be common to all objects.
- virtual void GetClassName(char *); // return the name of the class
- virtual void GetClassCode(int&); // return the code of the class
- virtual int GetClassCode(); // overload of the above
- virtual void Show() { ; } // Show is virtual
- virtual void Hide() { ; } // Hide is virtual
- virtual void Select() { ; } // Slect is virtual
- virtual void Use() { ; } // Use is virtual
- virtual void Busy() { ; } // Busy is virtual
- virtual void Swap() { ; } // Swap is virtual
- virtual void Fade() { ; } // Fade is virtual
- virtual void Read() { ; } // Read is virtual
- virtual int GetThisGroup(); // Return the group id when obj built
-
-
-
-
-
- // Friend functions that need no object to perform their work
- // these need access to the master list of objects that
- // is why they must be friends.
-
- friend void SetClassTraceOn(); // turn traces on
- friend void SetClassTraceOff(); // turn traces off
- friend int GetFreeGroupId(); // get a unique group id code
- friend void GroupShow(int); // show all of a group
- friend void GroupHide(int); // hide all of a group
- friend void GroupDelete(int); // delete all of a group
- };
-
- // STATIC VARIABLE INITIALISERS - VERSION 2.0 OF C++
- int Object::ObjectCountNow=0; // objects right now
- int Object::ObjectFirstTime=0; // first time logic
- int Object::ObjectTrace=0; // 0=notrace, 1=text
- int Object::ObjectGroupNow=0; // group number allocator
-
- // STATIC VARIABLE INITIALISERS IN PRE VERSION 2.0 OF C++ ARE
- // placed in the class and coded as:- "" static int ObjectCountNow=0; ""
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | STANDARD MASTER CONSTRUCTOR | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- Object::Object() // standard constructor
- { ObjectCountNow++; // add to live objects right now
- ObjectType=1; // derived class may alter
- if ( ObjectFirstTime++ ) // startup code if any
- { int * test; // check 2 or 4 bytes for memory
- if ( sizeof(test) != 4 )
- { printf("Compile with large memory model\n");
- }
- }
- for (int i=0; i<ObjectMaxEverAllowed; i++)
- { if ( ObjectMasterList[i] == (Object *) 0 )
- { ObjectMasterList[i] = this;
- break; // exit as operation completed
- }
- }
- if ( ObjectTrace ) printf("Object created\n");
- } // end of constructor
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | STANDARD MASTER DESTRUCTOR | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- Object::~Object() // standard destructor
- { ObjectCountNow--; // sub from live objects right now
-
- if ( ObjectTrace ) printf("Object deleted\n");
-
- if ( !ObjectCountNow ) // if no objects left
- { if ( ObjectTrace) printf("Down to zero objects\n");
- }
-
- for (int i=0; i<ObjectMaxEverAllowed; i++)
- { if ( ObjectMasterList[i] == this )
- { ObjectMasterList[i] = (Object *) 0;
- break; // exit as actual object found
- }
- }
- } // end of destructor
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | FRIEND TO TURN TRACES ON OR OFF | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- // Friend functions allowing direct function call as opposed to via object
-
- inline void SetClassTraceOn()
- { Object::ObjectTrace=1; // class variable set on
- printf("Object traces are on\n");
- }
-
-
-
-
-
-
- inline void SetClassTraceOff()
- { Object::ObjectTrace=0; // class variable set off
- printf("Object traces are off\n");
- }
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | FRIEND TO RETURN A FREE-GROUP-ID TO ALLOW LOGICAL GROUPS | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- inline int GetFreeGroupId() // get a unique group id code
- { Object::ObjectGroupNow++; // add to unique code
- return(Object::ObjectGroupNow); // return value
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | MEMBER TO RETURN A CLASS NAME char OR CLASS CODE int | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- void Object::GetClassCode(int &i) // return the name of the class
- { i=ObjectType; // return the object item type
- }
-
- int Object::GetClassCode() // overload of the above
- { return(ObjectType);
- }
-
-
- void Object::GetClassName(char * cl) // return the name of the class
- { strcpy(cl,"Object "); // default is cl8'object'
- }
-
- int Object::GetThisGroup() // return a group id
- { return(0); // no group code as is "Object" class
- }
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | GENERAL CONCLUDING NOTES ABOUT Object CLASS | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- /* The general structure of a program using these classes created is:-
- include <stdio.h> // must be first 0
- include "object.hpp" // base class file 1----+
- include "button.hpp" // derived class file 2--+ |
- include "textarea.hpp" // derived class file 2 | |
- include "hostlu2.hpp" // derived class file 2 | |
- include "slider.hpp" // derived from Button 3 | |
- include "dispatch.hpp" // dispatcher for subtasks 4<-+ |
- include "ishdmous.cpp" // mouse handler 5<-+ v
- inclide "friend.hpp" // friend functions 6<---+
- ... user program ...
- */
- #include "Friend.hpp" // friends of derived classes that
- #endif // are common to most classes
-
- /* END of Object.hpp */
-
-
- //------------------------------------------------------> friend.hpp <-------
- /* [ ]--- FRIEND.HPP------- C L A S S R U L E S --------------------[ ] */
- /* | | */
- /* | GroupShow(int) Show all of a button group | */
- /* | GroupHide(int) Hide all of a button group | */
- /* | GroupDelete(int) Delete all of a button group | */
- /* | | */
- /* | *** INCLUDED BY OBJECT *** | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
- #ifndef FriendDefined
- #define FriendDefined
-
-
- // friend functions - group delete needs list access
- // friend GroupHide(int); // group HIDE
- // friend GroupShow(int); // group show variation
- // friend GroupDelete(int); // group delete variation
-
-
- void GroupShow(int g) // FRIEND of Object base class
-
- { // function as a friend and not a class member
- // given a integer group, show all of them
- // this is public and is a friend
- // works for Buttons and Textareas etc as Show is virtual
-
- for (int i=0; i<ObjectMaxEverAllowed; i++)
- { if ( Object::ObjectMasterList[i] != (void *) 0 )
- { if ( Object::ObjectMasterList[i]->GetThisGroup() == g )
- { Object::ObjectMasterList[i]->Show();
- }
- }
- }
- }
-
-
-
-
-
-
-
- void GroupHide(int g) // Friend of Object base class
-
- { for (int i=0; i<ObjectMaxEverAllowed; i++)
- { if ( Object::ObjectMasterList[i] != (void *) 0 )
- { if ( Object::ObjectMasterList[i]->GetThisGroup() == g )
- { Object::ObjectMasterList[i]->Hide();
- }
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- void GroupDelete(int g) // Friend of Object base class
-
- { // this uses the list and given a group identifier it deletes for
- // the same user group (first parm on the button constructor) it
- // finds all matching objects and deletes them.
-
- for (int i=0; i<ObjectMaxEverAllowed; i++)
- { if ( Object::ObjectMasterList[i] != (void *) 0 )
- { if ( Object::ObjectMasterList[i]->GetThisGroup() == g )
- { // The destructors of each class that have
- // groups MUST BE VIRTUAL, if not then the
- // destructor is not found and the objects
- // remain i=on the screen and in memory.
- delete Object::ObjectMasterList[i];
- }
- }
- }
- }
-
-
-
-
- /******
- * END *
- ******/
-
- #endif
-
- /* [] END of friend.hpp [] */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //----------------------------------------------> ishdmous.cpp <------------
- /* [ ] ------- ISHDMOUS.CPP ------------------------------------------ [ ] */
- /* | | */
- /* | This handles the primitive operations use by the mouse handler | */
- /* | in the Button Class. This is for Zortech and NOT for Borland. | */
- /* | | */
- /* | MOPEN() Open the mouse for general use | */
- /* | | */
- /* | int MINFO(&x,&y, Acquire current state and if any | */
- /* | &l,&m,&r, changes have happened. | */
- /* | &stus) | */
- /* | | */
- /* [ ] --------------------------------------------------------------- [ ] */
-
- #include <stdio.h> /* *** INCLUDED BY BUTTON.HPP *** */
- #include <msmouse.h>
- #ifndef ishdmouscpp
- #define ishdmouscpp
-
- // static means it has file scope only
- static unsigned int MouseLastX=20, MouseLastY=20;// remember where we are
-
- /* [ ] --------------------------------------------------------------- [ ] */
- /* | NEXT HIGHER LEVEL CODE, AS USED BY A NOTIFIER PROCESS | */
- /* [ ] --------------------------------------------------------------- [ ] */
-
- MOPEN()
- { if ( ! (msm_init() == -1) )
- { fputs("Cannot initialize mouse.", stderr) ;
- fputs("\nNeed mouse driver to be installed (GOMOUSE).\n", stderr) ;
- getch();
- return(0); /* RETURN 0 if error */
- }
- msm_setcurpos(MouseLastX,MouseLastY);
- msm_showcursor();
- return(1); /* RETURN 1 if it went ok */
- }
-
-
- MCLOSE()
- { msm_hidecursor() ;
- msm_term() ;
- }
-
- /* [ ] --------------------------------------------------------------- [ ] */
- /* | My logic as opposed to the original authors logic | */
- /* [ ] --------------------------------------------------------------- [ ] */
-
- int MINFO_LC(int *x, int *y, int *l, int *m, int *r)
- { int bits;
- static unsigned int lx,ly, ll,lm,lr; int stus;
-
- ll=lr=lm=0;
- bits = msm_getstatus(&lx, &ly); /* update button status */
- if ( bits == 1 ) ll=1;
- if ( bits == 2 ) lr=1;
- if ( bits == 4 ) lm=1;
-
- lx=lx/8+1; ly=ly/8+1; stus=0;
- if ( *x!=lx || *y!=ly || *l!=ll ||*m!=lm || *r!=lr )
- stus=1;
- *x=lx; *y=ly; *l=ll; *m=lm; *r=lr;
-
- return(stus);
- }
-
- /* [ ] --------------------------------------------------------------- [ ] */
- /* | My logic as opposed to the original authors logic | */
- /* [ ] --------------------------------------------------------------- [ ] */
-
- int MINFO_XY(int *x, int *y, int *l, int *m, int *r)
- { int bits;
- static unsigned int lx,ly, ll,lm,lr; int stus;
-
- ll=lr=lm=0;
- bits = msm_getstatus(&lx, &ly); /* update button status */
- if ( (bits & 1) == 1 ) ll=1;
- if ( (bits & 2) == 2 ) lr=1;
- if ( (bits & 4) == 4 ) lm=1;
-
- stus=0;
- if ( *x!=lx || *y!=ly || *l!=ll ||*m!=lm || *r!=lr )
- stus=1;
- *x=lx; *y=ly; *l=ll; *m=lm; *r=lr;
- MouseLastX=lx; MouseLastY=ly;
- return(stus);
- }
-
- /* ...
-
- main()
- { int X,Y,x,y, l,m,r, stus;
- MOPEN(); system("cls");
-
- while( !kbhit() )
- { if ( stus=MINFO_LC(&x,&y, &l,&m,&r) )
- {
- printf("\n x:y= %3d, %3d ", x,y ) ;
- l ? printf(" Left DOWN ") : printf(" Left UP ") ;
- r ? printf(" Right DOWN ") : printf(" Right UP ") ;
- MINFO_XY(&X,&Y, &l,&m,&r);
- printf("X:Y= %3d, %3d \n", X,Y ) ;
- }
- }
-
-
-
-
-
-
-
- char c = getch();
- while( !kbhit() )
- { if ( stus=MINFO_LC(&x,&y, &l,&m,&r) )
- {
- MINFO_XY(&X,&Y, &l,&m,&r);
- if ( l+m+r>0 ) break;
- }
- }
- MCLOSE();
- }
-
- ... */
-
-
- /* END of ishdmous.cpp */
-
- #endif
-
-
-
-
- //----------------------------------------------> button.hpp <---------------
- /* [ ]--- BUTTON.HPP ------ C L A S S R U L E S --------------------[ ] */
- /* | | */
- /* | Each Button is defind with NEW and needs a group id, x, y and | */
- /* | startup text. The group is an integer and collects buttons as | */
- /* | groups, so that SELECT, USE etc automatically cause all others | */
- /* | in the group to go to a state of SHOW. The group can be used for | */
- /* | a group delete or group hide. Groups and in fact all buttons are | */
- /* | held in a private list, and PvtGroupShow ( above function) is also | */
- /* | private. Group funcions are in Object class and are not here! | */
- /* | | */
- /* | Functions are "new", SHOW/HIDE, SELECT, USE, SWAP, FADE, BUSY, | */
- /* | READ and Notify. Notify is invoked when the mouse is in the box | */
- /* | and clicked, or when USE is invoked. | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- MOPEN();
- MCLOSE();
- int MINFO_LC(int *x, int *y, int *l, int *m, int *r);
- int MINFO_XY(int *x, int *y, int *l, int *m, int *r);
-
- /* [ ]--- BUTTON ---------- O B J E C T S T A T E S -----------------[ ] */
- /* | | */
- /* | STATE: 0 initialised, hidden | */
- /* | 1 show (dark blue, text=white) (border=cyan) | */
- /* | 2 select (light blue, " ) ( " ) | */
- /* | U use (white, " black) ( " ) | */
- /* | B busy (white, " black) ( " ) | */
- /* | S* swap (white, " black) ( " ) | */
- /* | F* fade (white, " black) ( " ) | */
- /* | | */
- /* | * swap and fade set state to S or F only if prior state | */
- /* | was not numeric. | */
- /* | | */
- /* | 0 hide (see above) | */
- /* | - read (no change) | */
- /* | | */
- /* | *** INCLUDES DISPATCH.HPP AND ISHDMOUS.CPP *** | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
-
- /* [ ]--- BUTTON ---------- RELATIONSHIPS ------------------------------ [ ]
- | |
- | The Button class is related to the Textarea class, and polymorphism |
- | is extant, as are overloaded functions. Refer to Textarea.HPP and |
- | Friend.HPP and Dispatch.HPP. |
- | |
- | Below are some examples of overloading and polymorphism. Other |
- | cases exist. |
- | |
- | polymorphics: Show(), Hide(), Select(), Use(), ... |
- | |
- | group functions in |
- | Object class: GroupShow() |
- | GroupDelete() |
- | GroupHide() |
- | |
- [ ] ----------------------------------------------------------------- [ ] */
-
- #ifndef ButtonDefined
- #define ButtonDefined
-
-
- /* [ ]--- CRTCLASS ---- M A S T E R V A R I A B L E S ----------------[ ] */
- /* | | */
- /* | ObjectCompile a compiler #define to avoid duplication of | */
- /* | | */
- /* | 1. #include <fg.h> for function prototypes | */
- /* | 2. ObjectMaxYpx has many uses | */
- /* | 3. ObjectGraphOpen graphics open switch | */
- /* | | */
- /* | The above appear at the start of Button & Textarea class defns. | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
- /* [ ]--- Button ------ M A S T E R V A R I A B L E S ----------------[ ] */
- /* | | */
- /* | ButtonWide width of the button box in pixels | */
- /* | ButtonTall height of the button box in pixels | */
- /* | ButtonMax maximum number of instantiated Button instances | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
- /* [ ]--- Button ------ S P E C I A L N O T E S ---------------------[ ] */
- /* | | */
- /* | Notifier the class structure includes a pointer to a | */
- /* | user provided function. | */
- /* | void (* Notifier)(); Declared in the class structure | */
- /* | void (*fn)(), Function prototype in constructor | */
- /* | Notifier=fn; Usage when saved in constructor | */
- /* | (Notifier)(this); Usage in the Button::Use() function | */
- /* | | */
- /* | GROUP is the first parameter in the constructor, allows caller | */
- /* | to specify logical GROUPS of buttons. | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
-
-
-
-
-
-
-
- /* [ ]--- Button ------ M E M B E R F U N C T I O N S ---------------[ ] */
- /* | Show() Dark blue with cyan border | */
- /* | Select() Light blue and all others in the group go Show() | */
- /* | Use() White and all others in the group go to Show(). | */
- /* | then the Notifier function is invoked. | */
- /* | Busy() A diagnal line rotates clipped in the button. | */
- /* | Swap("...") The button compresses, expansa with new text | */
- /* | Fade("...") The button faeds and grows with new text | */
- /* | Hide() The button is blanked out | */
- /* | Read(char *) The button text is returned, useful in notify | */
- /* | #GroupDelete() Hide buttons not hidden then delete them. | */
- /* | #GroupShow() Public function, given any one button of the | */
- /* | user defined group, SHOW all of the group. | */
- /* | GetThisGroup() return the group id of this button. | */
- /* | PvtGroupShow(int) Set all buttons not in SHOW state just for this | */
- /* | user defined group, and excluding the present | */
- /* | button, to SHOW state, dark blue, this is a | */
- /* | private internal function. | */
- /* | MouseButtonNotify() A mouse button otifier given a group | */
- /* | # - - - - - - - > These are in Object and use a list | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | S T A R T O F O B J E C T T Y P E B U T T O N | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- // globals needed for all class items are here with compile test switch
- #ifndef ObjectCompile /* this IFDEF logic in other classes */
- #define ObjectCompile /* stops future global includes */
- #include <fg.h> /* include if needed for ztc grafics */
- #include "Object.hpp" /* base class */
- int ObjectMaxYpx; /* convert y=0 to top */
- int ObjectGraphOpen = 0; /* INITIALISED GRAPHICS YET? 1=yes */
- #include "ishdmous.cpp" /* mouse routines */
- #endif
-
-
- // globals needed for button class items are here
- int ButtonWide=70, /* BOX SIZE horizontally */
- ButtonTall=20; /* BOX SIZE vertically */
- const int ButtonMax = 150; /* number to be remembered - limit */
-
-
-
- class Button : public Object
-
- { /* general button control parameters needed are first */
- protected:
- int ObjectType; /* 0010 is a button type */
-
- // state of the button itself
- char ObjectState; /* last action */
- int ObjectGroup; /* logical group buttons for control */
-
- /* graphics part of the box */
- int top, left; /* top and left of the box */
- fg_box_t border; /* coordinates for box border */
- fg_box_t box; /* coordinates for box */
- int box_wide, /* size of the box in x units */
- box_tall; /* size of a box in y units */
-
- /* text part of the button */
- int t, l; /* words start at top and left */
- char word[40]; /* word base is t,l */
-
-
- // globals to this class of objects - one for the entire class
- // static type implies private to others outside of this class
-
- // list used for GROUP functions of all types, routines accessed via
- // list contents do not need to be virtual since list AND the routines
- // are defined in the SAME class.
- static Button * list[ButtonMax]; /* for control of the groups */
-
-
- // We need a pointer to a routine to be called when Notifier is
- // needed, so here it is. This is the USER'S EXIT ROUTINE.
- // He calls ButtonMouseNotify and it invokes the users Notifier
- // associated with clicked button, then returns to original caller
- // of ButtonMouseNotify(group).
- void (* Notifier)(Button *); // defines a pointer to a function
- // ^ ^ tells it a pointer as opposed to
- // a declaration of a function.
-
- void * DerivedAddr; // a pointer of any derived class
- // // lets derived class entered by a
- // // notify exit find the derived data.
-
- // DECLARATIONS FOR CONSTRUCTOR AND DESTRUCTOR FUNCTIONS
- public: Button(int, int, int, char *, void (*fn)(Button *), int, int);
- virtual ~Button(); // virtual for GroupDelete in friend.hpp
-
-
-
- // DECLARATIONS OF member functions below, definition later
- virtual void Show(); /* BLUE -- also invoked by GroupShow */
- virtual void Select(); /* LIGHT BLUE */
- virtual void Use(); /* WHITE */
- virtual void Busy(); /* WHITE -- also shows activities */
- virtual void Swap(char *); /* WHITE..WHITE */
- virtual void Fade(char *); /* WHITE..WHITE */
- virtual void Hide(); /* BLACK */
- virtual void Read(char *); /* no color change */
- virtual int GetThisGroup(); /* return group id */
-
-
-
-
-
-
- // Poymorphic methods/functions needing an object to do their work
- // implemented as Object needs them for correctness
- virtual void GetClassName(char *); // return the name of the class
- virtual void GetClassCode(int&); // return the code of the class
- virtual int GetClassCode(); // return the code of the class
-
-
- // friend functions - group delete needs list access
- friend ButtonMouseNotify(int); // mouse/cursor invoke notifier
- friend void SliderNotify(Button *);
-
- // dispatch doesnt actually need friend status but what the heck
- // it does work with us.
- friend int Dispatch(); // dispatcher is a friend
-
-
- // private group members - group reset to show status
- private:
- void PvtGroupShow(int); /* BLUE for items not in SHOW state */
- }; // end of the button class
-
-
- // C++ constructor for the button class of objects
-
- Button::Button (int xgroup, int xleft, int xtop, char * xword,
- void (*fn)(Button *),int xsz=ButtonWide, int ysz=ButtonTall)
- { if (!ObjectGraphOpen) /* first button logic */
- { ObjectGraphOpen=1; /* say not first now */
- ISHDGraphicsOpen(); // fg_init_all(); EGA
- // // fg_init_vga12(); VGA
- ObjectMaxYpx = (int) fg_displaybox[FG_Y2]-5 ;
- for (int i=0; i<ButtonMax; i++) /* list allows control*/
- list[i] = (Button *) 0; /* of button groups */
- }
-
- // Set DerivedAddr to 0 assuming no special cases exist, let any
- DerivedAddr = (void *) 0; // derived classes fill it in
-
- /* build top and left, ZTZ y=0=bottom, we tell user 0=top */
- top=ObjectMaxYpx-xtop; /* convert y=0 to top */
- left=xleft; /* x is standard */
- box_wide=xsz; /* set up box size */
- box_tall=ysz;
-
- /* build a bounbary box for (1) clipping and (2) easy drawing */
- border[FG_X1] = left;
- border[FG_Y1] = top-box_tall;
- border[FG_X2] = left+box_wide;
- border[FG_Y2] = top;
-
- /* build the internal box for easy drawing */
- box[FG_X1] = left+1;
- box[FG_Y1] = top-box_tall+1;
- box[FG_X2] = left+box_wide-1;
- box[FG_Y2] = top-1;
-
- /* copy over the text string */
- strcpy(word,xword);
- t=top-17;
- l=left+2;
-
- /* set the state to initial */
- ObjectState='0';
-
-
-
- // set up the notify address for mouse/cursor Notifier
- Notifier = fn;
-
- /* set the group to as specified - group is a group of related */
- ObjectGroup=xgroup; /* buttons for control */
-
- ObjectType=10; /* type = 10 means button */
-
- for (int i=0; i<ButtonMax; i++) /* list to allow */
- { if ( list[i] == (Button *) 0 ) /* control of */
- { list[i] = this; /* buttons and */
- break;
- } /* groups of them */
- }
- } // END OF CONSTRUCTOR LOGIC
-
-
-
-
-
-
-
- // C++ destructor fot the button class of objects
-
- Button::~Button()
- { // Hide(); cant invoke HIDE here as it says it is not a class
- // member, so we do it inline. Dont hide if already hidden!
-
- if (ObjectState!='0') fg_fillbox(FG_BLACK,FG_MODE_SET,~0,border);
-
- // remove from he array of buttons
- for (int i=0; i<ButtonMax; i++)
- { if ( list[i] != (Button *) 0 )
- if ( list[i] == this )
- list[i] = (void *) 0;
- }
- }
-
-
-
-
-
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | MEMBER TO RETURN A CLASS NAME char OR CLASS CODE int | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- void Button::GetClassCode(int &i) // return the name of the class
- { i=ObjectType; // return the object item type
- }
-
- int Button::GetClassCode() // return the name of the class
- { return(ObjectType); // return the object item type
- }
-
-
- void Button::GetClassName(char * cl) // return the name of the class
- { strcpy(cl,"Button "); // default is cl8'object'
- }
-
-
-
-
-
-
- void Button::PvtGroupShow(int xgroup) // private internal function
-
- { // this is private - used internally when SELECT/USE issued
-
- // if I select or use this button then all others of the same group
- // drop to a state of show, the following code does that
-
- for (int i=0; i<ButtonMax; i++)
- { if ( list[i] != (Button *) 0 )
-
- if ( list[i]->ObjectGroup == xgroup
- && list[i] != this
- && list[i]->ObjectState != '1' )
-
- { list[i]->Show();
- }
- }
- }
-
-
-
-
- void Button::Show()
- { // this is invoked by GroupShow function also
- if ( ObjectState!='1' ) // optimise for speed
- { // border for the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_BLUE,FG_MODE_SET,~0,box);
-
- // now show the text
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
-
- // set state to SHOW (BLUE) state
- ObjectState='1';
- }
- }
-
-
-
-
-
- void Button::Select()
- { if ( ObjectState!='2' ) // optimise for speed
- { // ensure all other buttons in group are at show state
- // must do this before SELECT so SELECT is on top of SHOWs
- PvtGroupShow(ObjectGroup); // do first in case ovlpng btns
-
- // border for the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,box);
-
- // now show the text
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
-
- // make state now selected, but not yet in use
- ObjectState='2';
- if ( DerivedAddr ) (*Notifier)(this); // call Slider notifier
- } // special case for derived class, mouse cursor is off now.
- }
-
- void Button::Use()
- {
- // ensure all other buttons in group are at show state BEFORE work
- PvtGroupShow(ObjectGroup);
-
- // border for the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // now show the text and specify we are in a new state
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
- ObjectState='U';
-
- (*Notifier)(this); // call users notify proc he wanted
- // at button build time - passing
- // "this" instance of the object
- // member of this class.
- }
-
-
- void Button::Busy()
- { fg_line_t tln;
-
- // first build a line parameter box from the box (not border) values
- for (int i=0; i<3; i++)
-
- { tln[FG_X1] = left+1;
- tln[FG_Y1] = top-1;
- tln[FG_X2] = left+box_wide-1;
- tln[FG_Y2] = top-box_tall+1;
-
- // then we will roll the line by working x keeping y or
- // working y and keeping x, we let fg_functions use "box"
- // as opposed to border to clip the line, making it look
- // nice.
-
-
-
-
-
-
-
- while ( tln[FG_Y1]>box[FG_Y1] )
- { fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
- // fg_drawline(FG_RED,FG_MODE_SET,~0,FG_LINE_SOLID,tln);
- fg_drawthickline(FG_RED,FG_MODE_SET,~0,FG_LINE_SOLID,tln,box,6);
- tln[FG_Y1] --;
- tln[FG_Y2] ++;
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,
- fg_displaybox);
- Dispatch(); // give some time to multi tasker
- }
-
- while ( tln[FG_X1]<box[FG_X2] )
- { fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
- // fg_drawline(FG_RED,FG_MODE_SET,~0,FG_LINE_SOLID,tln);
- fg_drawthickline(FG_RED,FG_MODE_SET,~0,FG_LINE_SOLID,tln,box,6);
- tln[FG_X1] ++; tln[FG_X2] --;
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,
- fg_displaybox);
- Dispatch(); // give some time to multi tasker
- }
-
-
- // we have now finished the line rolling logic
- } // end of the for loop
-
- // set state to busy
- ObjectState='B';
-
- // draw the border
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // now redisplay text as probably clobbered
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,
- fg_displaybox);
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
-
- void Button::Swap(char * text)
- { fg_box_t tbx;
-
- // box itself temporarily set up as we will reduce/expand x values
- tbx[FG_X1] = border[FG_X1]; // use border not box so the border
- tbx[FG_Y1] = border[FG_Y1]; // will shrisk also, if you used box
- tbx[FG_X2] = border[FG_X2]; // the border would stay while the
- tbx[FG_Y2] = border[FG_Y2]; // insides shrank, looks tacky
-
- while ( tbx[FG_X1]<tbx[FG_X2] )
- { fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,tbx);
- for (int j=0; j<1000; j++) ; // 1000 to 4000
- fg_fillbox(FG_BLACK,FG_MODE_SET,~0,tbx);
- tbx[FG_X1] ++;
- tbx[FG_X2] --;
- // allow multi tasking one call in 4 (4 use 0003)
- if ( !(tbx[FG_X1] & 0x0003) ) Dispatch();
- }
-
-
-
-
- while ( tbx[FG_X2]<left+box_wide )
- { fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,tbx);
- for (int j=0; j<1000; j++) ; // 1000 to 4000
- tbx[FG_X1] --;
- tbx[FG_X2] ++;
- // allow multi tasking one call in 4 ( 8 use 0007)
- if ( !(tbx[FG_X1] & 0x0003) ) Dispatch();
- }
-
- // finally redraw the border and the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,border,fg_displaybox);
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // then redraw the text and reset the state
- strcpy(word,text);
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
- ObjectState='B';
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
- void Button::Fade(char * text)
-
- { int rx,ry;
- /* fade out */
- for (int i=0;i<4000;i++)
- { rx= left + ( rand()%box_wide );
- ry= top - ( rand()%box_tall );
- fg_drawdot(FG_BLACK,FG_MODE_SET,~0,rx,ry);
- // allow multi tasking one call in 64
- if ( !(i & 0x003f) ) Dispatch();
- }
- /* fade in */
- for (i=0;i<3000;i++)
- { rx= left + ( rand()%box_wide );
- ry= top - ( rand()%box_tall );
- fg_drawdot(FG_WHITE,FG_MODE_SET,~0,rx,ry);
- // allow multi tasking one call in 64
- if ( !(i & 0x003f) ) Dispatch();
- }
-
-
-
- // draw the border again
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // draw the box inside the border
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // reshow the text in the box
- strcpy(word,text);
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
-
- // specify box state now
- ObjectState='F';
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
-
-
-
-
- void Button::Hide()
-
- { fg_fillbox(FG_BLACK,FG_MODE_SET,~0,border);
- ObjectState='0';
- }
-
-
- void Button::Read(char * text)
- { // used to return the text string in a button, usefull for generic
- // button list notify processing, so uses doesnt need to remember
- // all the buttons he created.
-
- strcpy(text,word);
- }
-
-
- int Button::GetThisGroup()
- { // used in case someone needs to know their group
- return(ObjectGroup);
- }
-
-
- /*FRIEND*/ButtonMouseNotify(int g) // public friend runs the mouse
-
- #define TB Button::list[i] // TB means this button - shorthand
- #define BD fg_displaybox // BD is Boundary Border - shorthand
-
- { // given a integer group (not a button), track the cursor till
- // the mouse hits a button.
-
- // once in a button, must do a msm_hidecursor BEFORE we work graphics
- // on the screen, and a msm_showcursor after to reenable mouse. If
- // you dont do this then the graphics inteferes and color fades and
- // text is shown garbled. <- IMPORTANT NOTICE
-
- // the "list" processed is processed from back to front +---------
- // so that overlaps are processed ih the box that | +--x--
- // was displayed last rather than in the box that +--|
- // technically owns that geographic area. Thus location +-----
- // "x" is in the lower box as displayed not in the upper
- // box as it is geographically owned. <- IMPORTANT NOTICE
-
-
-
- int x, y, // x,y are PRESENT values
- l, m, r, // l,m,r are the buttons hit
- stus, // stus id mouse status
- flag; // flag is our control flag
- char X[5], Y[5]; // debugging values only
-
- MOPEN(); // fire up the mouse
-
- l=m=r=0; // say no button hit yet
- x=y=0; // set initial coordinates to 0,0
- stus=1; // set up initial values
- flag=1; // primes the loop
-
- while ( flag ) // while no keys depressed at all
- //
- //
- // following loop run till FLAG!=0
- //
- //
- //
-
-
- // below WHILE group watches the mouse in the buttons
- // this loop breaks when flag is set to non zero
-
- { Dispatch(); // <<==== friendly multi tasker
- if ( stus=MINFO_XY(&x,&y, &l,&m,&r) )
-
- { // fix the Y value from MOUSE to FG_ values
- y = ObjectMaxYpx - y;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- // start end to front to handle box overlap properly.
- for (int i=ButtonMax-1; i>-1 ; i--)
- { // multitasker 1 in 15 could be done here
- if ( TB != (Button *) 0 & TB->ObjectGroup == g )
- { if ( x>TB->left && x<(TB->left+TB->box_wide)
- && y<TB->top && y>(TB->top-TB->box_tall) )
- if ( !(l+m+r) )
- { msm_hidecursor(); // avoid bad video
- TB->Select(); // clean video
- msm_showcursor(); // allow mouse video
- break; // skip rest
- }
- else
- { msm_hidecursor(); // avoid bad video
- //Button::list[i]->Use();
- TB->Use(); // clean video
- msm_showcursor(); // allow mouse video
- flag=0; break; // skip rest
- }
- } // end of is it valid & in our group
- } // end of FOR loop checking all buttons
-
- // at this point the whole array has been run and if no key
- // hit on the mouse then buttons overlaid are highlighted
- // IF they were not already highlighted.
-
- // also if a button was hit in a button then the button
- // was USED and this fires up the notify routine.
-
- // this ends the IF that tested for new mouse status
-
- } // end of IF ( STUS=INFO_XY()...
-
- // this ends the WHILE loop that runs until one action is clicked on
- // and it is up to the user calling program whether he will re issue
- // the ButtonMouseNotify() code or not. For example, if the button
- // had the word "quit" in it he may break his endless Notifier() loop.
-
- } // end of WHILE loop
- MCLOSE(); // either way we are stopping mice
- }
-
-
-
- /******
- * END *
- ******/
-
-
-
-
-
-
-
-
-
-
-
- #include "dispatch.hpp" // dispatch uses a button
- // "ishdmous.cpp" // included earlier as always needed
-
- #endif
-
- /* [] END of button.hpp [] */
-
-
- //----------------------------------------------> dispatch.hpp <------------
- /* [ ] --- DISPATCH.HPP ---- D I S P A T C H --------------------------- [ ]
- | |
- | This is a function called whenever anyone has any free CPU time. |
- | The very first time we show a box, and build parameters. |
- | This is a friend of Button and also can be of TEXT. Called whenever |
- | the mouse or the keyboard nitifier are running. |
- | From then on we rotate the busy line one rotation unit and also |
- | allow work that needs to be "simulated" "time shared" or in other |
- | words effectivley multitasked. |
- | |
- | usercode-->| *** INCLUDED BY BUTTON *** |
- | ^ | |
- | | | Button_MOUSE_NOTIFY() |
- | | | | |
- | | | DISPATCH() -----> asynch code to be |
- | | | pseudo multi tasked |
- | | | | |
- | +<--|---------------------------------+ |
- | |
- [ ] --------------------- D I S P A T C H --------------------------- [ ] */
-
- #ifndef DispatchDefined
- #define DispatchDefined
-
-
-
-
- #include "object.hpp" // dispatch needs object
- #include "button.hpp" // dispatch uses button
-
-
-
- // This is a prototype to keep the compiler happy.
- void Sub_Task_Runner(); // prototype
-
-
-
- // This is the dispatcher list.
- #define DispatchMaxTasks 10
- static void (* DispatchTaskList [DispatchMaxTasks]) (void);
-
-
-
- // To use the DISPATCHER, do the following:
- //
- // Attach(subtask); if 0 returned then not added as no room
- // Detach(subtask); if 0 returned then subtask was not found
- //
- // In code at conveniant points add
- //
- // Dispatch();
- //
- // For examples, refer to Button class where the MOUSE is run.
-
-
-
-
-
-
-
-
-
-
-
-
- // This is the Attach subtask routine
- int Attach( void (*fn)(void) )
- { for (int i=0; i<DispatchMaxTasks; i++)
- { if ( DispatchTaskList[i] == (void *) 0 )
- { DispatchTaskList[i] = fn;
- return(1);
- }
- }
- return(0); // dispatch returns 0 if no room
- }
-
- // This is the Detach subtask routine
- int Detach(void (*fn)() )
- { for (int i=0; i<DispatchMaxTasks; i++)
- { if ( DispatchTaskList[i] == (void *) fn )
- { DispatchTaskList[i] = (void *) 0;
- return(1);
- }
- }
- return(0); // dispatch returns 0 if not found
- }
-
- // Global switch and functions to enable or disable the rotating wheel
- static int SubTaskWheel=1; // master rotating wheel flag
-
-
- // Stop rotating wheel
- void DispatchWheelOff()
- { SubTaskWheel=0; // stop rotating wheel
- }
-
- // Start rotating wheel
- void DispatchWheelOn()
- { SubTaskWheel=1; // enable rotating wheel
- }
-
-
-
-
-
-
-
-
-
- int Dispatch()
- { static int status = 0; // first time or not
- static Button * DispatchButton;
- static fg_line_t tln; // a line boundary box
- static int do_down=0, do_along=0; // what to rotate next
-
- if ( !SubTaskWheel ) goto bypass; // bypass wheel GOTO used to
- // save indentations !
- // if first time then build up a busy symbol and build a border box
- if ( !status)
- { status=1; // cancel first time setup switch
- DispatchButton = new Button(0, 550, 13, " ",0, 25,14);
- DispatchButton->Show(); // enable the button to be visible
- tln[FG_X1] = DispatchButton->left+2;
- tln[FG_Y1] = DispatchButton->top-2;
- tln[FG_X2] = DispatchButton->left+
- DispatchButton->box_wide-2;
- tln[FG_Y2] = DispatchButton->top-
- DispatchButton->box_tall+2;
- do_down=1; // where to start
- }
-
- // coming in here there may or may not be a box, and it may have a
- // partially rotated line or it may not. the first thing we do is
- // to redraw the box and remove the old line so we can draw a new
- // line.
-
- // draw the border
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- DispatchButton->border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,DispatchButton->box);
-
- // there is no text to be displayed
-
-
-
-
-
-
-
-
-
- // coming in here on the first and subsequent times, we are rotating
- // the line one rotation unit.
-
- // up one side...
- if ( do_down )
- { do_along=0; // no need yet for along
- if ( tln[FG_Y1] > DispatchButton->box[FG_Y1] )
- { fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,
- DispatchButton->box);
- fg_drawthickline(FG_WHITE,FG_MODE_SET,~0,FG_LINE_SOLID,
- tln,DispatchButton->box,2);
- tln[FG_Y1] --;
- tln[FG_Y2] ++;
- }
- else
- { do_along=1; // need "along" now
- do_down=0; // and stop "down"
- }
- }
-
-
-
- // down the other...
-
- if ( do_along )
- { do_down=0; // no need for "down" yet
- if ( tln[FG_X1] < DispatchButton->box[FG_X2] )
- { fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,
- DispatchButton->box);
- fg_drawthickline(FG_WHITE,FG_MODE_SET,~0,FG_LINE_SOLID,
- tln,DispatchButton->box,2);
- tln[FG_X1] ++;
- tln[FG_X2] --;
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,
- DispatchButton->l,DispatchButton->t,
- DispatchButton->word,fg_displaybox);
- }
-
- else
-
-
-
-
-
-
- { do_along=0; // no "along" now
- do_down=1; // but do "down"
-
- tln[FG_X1] = DispatchButton->left+2;
- tln[FG_Y1] = DispatchButton->top-2;
- tln[FG_X2] = DispatchButton->left+
- DispatchButton->box_wide-2;
- tln[FG_Y2] = DispatchButton->top-
- DispatchButton->box_tall+2;
- }
- }
-
- bypass: // end of bypass wheel
-
- // now the line has been rotated in the box we can call routines that
- // need time sharing
- // =========>> put here calls to asynch tasks ==========>>
- Sub_Task_Runner();
- // =========>> put here calls to asynch tasks ==========>>
-
-
- // The theory is that the crt class objects all have spare time, this
- // may be the mouse notifier (Button CLASS RELATED) or the keyboard
- // notifier, not related to the TEXT class as such but included in
- // the TEXT class as it is conceptually there. The theory also thinks
- // that other functions in the class methods have some spare time.
- // Even an application can decide it has spare time.
-
- // All places where spare time exists simply do a call DISPATCH();
- // and on each call the wheel is rotated one pixel and the subtask
- // is invoked, if there is one. The subtask may not wait, it must
- // do work, albeit based on READY-TO-RUN switches, or exit. It
- // must track itself by state switches, they must thus be static.
-
- // This allows the DISPATCHer to call routines, they could access
- // the serial ports, or anything else. The busy wheel controlled
- // by the DISPATCHER simply shows the CPU is running ok and how much
- // spare cpu time there is.
- }
-
-
-
-
- void Sub_Task_Runner()
- { // This function can invoke as many routines as it desires, it could
- // use a LIST kept some where, and Attach would add functions, and
- // Detach would remove functions.
-
- // Attached and Detached functions could be communications hanlers,
- // low prioroty disk to print routines
-
- // Where for each invocation the subtask would do ONE iteration of
- // its work.
-
- for (int i=0; i<DispatchMaxTasks; i++)
- { if ( DispatchTaskList[i] != (void *) 0 )
- { DispatchTaskList[i](); // <---- this is what actually
- } // calls user suntasks
- }
-
- }
-
- #endif
- /* [] END of dispatch.hpp [] */
-
- //----------------------------------------------> textarea.hpp <-------------
- /* [ ]--- TEXTAREA.HPP ------ C L A S S R U L E S ------------------[ ] */
- /* | | */
- /* | Each "TEXTAREA" is defind with NEW and needs a group id, x, y and | */
- /* | startup text. The group is an integer and collects "TEXTAREAs" as | */
- /* | groups, so that SELECT, USE etc automatically cause all others | */
- /* | in the group to go to a state of SHOW. The group can be used for | */
- /* | a group delete or group hide. Groups and in fact all "TEXTAREAs" | */
- /* | are held in a private list, and PvtGroupShow ( above function) is | */
- /* | also private. | */
- /* | | */
- /* | Functions are "new", SHOW/HIDE, SELECT, USE, SWAP, FADE, BUSY, | */
- /* | READ and Notifier. Notifier is invoked when the textarea needs | */
- /* | some work. | */
- /* | | */
- /* | The only difference between TEXTAREA and BUTTON is that TEXTAREA | */
- /* | is usually bigger and some functions do different things. | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- #ifndef TextAreaDefined // avoid recompiling if not needed
- #define TextAreaDefined
-
- /* [ ]--- TEXTAREA -------- O B J E C T S T A T E S -----------------[ ] */
- /* | | */
- /* | STATE: 0 initialised, hidden | */
- /* | 1 show (dark blue, text=white) (border=cyan) | */
- /* | 2 select (light blue, " ) ( " ) | */
- /* | U use (white, " black) ( " ) | */
- /* | B busy (white, " black) ( " ) | */
- /* | S* swap (white, " black) ( " ) | */
- /* | F* fade (white, " black) ( " ) | */
- /* | | */
- /* | * swap and fade set state to S or F only if prior state | */
- /* | was not numeric. | */
- /* | | */
- /* | 0 hide (see above) | */
- /* | - read (no change) | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
-
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | S T A R T O F O B J E C T T Y P E T E X T A R E A | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- // globals needed for all sws class items are here
- #ifndef ObjectCompile /* this IFDEF logic in other classes */
- #define ObjectCompile /* stops future global includes */
- #include <fg.h> /* include if needed for ztc grafics */
- #include "Object.hpp" /* base class */
- #include "friend.hpp"
- int ObjectMaxYpx; /* convert y=0 to top */
- int ObjectGraphOpen = 0; /* INITIALISED GRAPHICS YET? 1=yes */
- //#include "ishdmous.cpp" /* mouse routines */
- #endif
-
- // globals needed for all sws text class items are here
- int TextWide=250, TextTall=125; /* TEXT BOX SIZES */
- const int MaxTextAreas = 10; /* number to be remembered - limit */
-
-
-
-
- class TextArea : public Object
- { /* control area of the box */
- int ObjectType; /* 0020 is a text type */
- char ObjectState; /* last action */
- int ObjectGroup; /* groups buttons for control */
-
- // globals to this class of objects - one for the entire class
- // static type implies private to others outside of this class
- static TextArea * list[MaxTextAreas ]; /* for control of the groups */
-
- /* graphics part of the box */
- int top, left; /* top and left */
- fg_box_t border; /* coordinates for box border */
- fg_box_t box; /* coordinates for box */
- int box_wide,
- box_tall; /* size of a box */
- /* text part of the button */
- int t, l;
- char word[80]; /* word base is t,l */
-
-
-
- // we need a pointer to a routine to be called when Notifier is
- // needed, so here it is.
- void (* Notifier)(TextArea *);
-
-
- // data areas to support line at a time writes in the box
- int cur_line;
- int cur_line_max;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- // Class constructor and destructor prottypes
- public: TextArea (int,int,int,char *,void (*fn)(TextArea *),int,int);
- virtual ~TextArea(); // virtual for GroupDelete in friend.hpp
-
-
- // member functions declared below, definition later
- virtual void Show(); /* BLUE -- also invoked by GroupShow */
- virtual void Select(); /* LIGHT BLUE */
- virtual void Use(); /* WHITE */
- virtual void Busy(); /* WHITE -- also shows activities */
- int Type(char *,int ); /* line at a time into the box */
- virtual void Swap(char *); /* WHITE..WHITE */
- virtual void Fade(char *); /* WHITE..WHITE */
- virtual void Hide(); /* BLACK */
- virtual void Read(char *); /* no color change */
-
-
- // friend functions - none defined yet
- friend int Dispatch(); // same dispatch as the buttons
-
-
-
- // Instance methods/functions needing an object to do their work
- virtual void GetClassName(char *); // return the name of the class
- virtual void GetClassCode(int&); // return the code of the class
- virtual int GetClassCode(); // return the code of the class
- virtual int GetThisGroup(); // return group code
-
- // associated function - need not be a friend as such as is simply
- // a keyboard reader - it is here as an equivalent to the BUTTON
- // ButtonMouseNotify() but does not need access to any list so
- // is not a friend. In fact it has nothing to do with TEXTAREA class
- // and is only here as is is the TEXTAREA equivalent to the BUTTON
- /// notifier.
- void TextKeyboardNotify(); // keyboard waiter
-
- // private group members - group reset to show status
- private:
- void PvtGroupShow(int); /* BLUE for items not in SHOW state */
- };
-
-
-
-
- /* C++ constructor function */
-
- TextArea::TextArea (int xgroup, int xleft, int xtop, char * xword,
- void (*fn)(TextArea *),int xsz=TextWide , int ysz=TextTall )
-
- { if (!ObjectGraphOpen) /* first button logic */
- { ObjectGraphOpen=1; /* say not first now */
- ISHDGraphicsOpen(); // fg_init_all(); EGA
- // // fg_init_vga12(); VGA
- ObjectMaxYpx = (int) fg_displaybox[FG_Y2] - 5 ;
- for (int i=0; i<MaxTextAreas ; i++) /* list allows control*/
- list[i] = (TextArea *) 0; /* of button groups */
- }
-
- /* build top and left, ZTZ y=0=bottom, we tell user 0=top */
- top=ObjectMaxYpx-xtop; /* convert y=0 to top */
- left=xleft; /* x is standard */
- box_wide=xsz; /* set up box size */
- box_tall=ysz;
-
-
-
- /* build a boundary box for (1) clipping and (2) easy drawing */
- border[FG_X1] = left;
- border[FG_Y1] = top-box_tall;
- border[FG_X2] = left+box_wide;
- border[FG_Y2] = top;
-
- /* build the internal box for easy drawing */
- box[FG_X1] = left+1;
- box[FG_Y1] = top-box_tall+1;
- box[FG_X2] = left+box_wide-1;
- box[FG_Y2] = top-1;
-
- /* copy over the text string */
- strcpy(word,xword);
- t=top-17;
- l=left+5;
-
- /* set the state to initial */
- ObjectState='0';
-
-
-
- // set up the notify address for mouse/cursor Notifier
- Notifier = fn;
-
- /* set the group to as specified - group is a group of related */
- ObjectGroup=xgroup; /* buttons for control */
-
- ObjectType=20; /* 20 means text item */
-
- cur_line=0; /* line at a time function support */
- cur_line_max = ysz / (4 + fg_charbox[FG_Y2]) ;
-
- for (int i=0; i<MaxTextAreas ; i++) /* list to allow */
- { if ( list[i] == (TextArea *) 0 ) /* control of */
- { list[i] = this; /* buttons and */
- break; /* groups of them */
- }
- }
- } // end of constructor logic
-
-
-
-
- /* C++ destructor must remove the text box from view */
-
- TextArea::~TextArea()
-
- { // Hide(); cant invoke as it says not a class member at this time
- // so we are doinf the code inline. Dont if already hidden!
-
- if (ObjectState!='0') fg_fillbox(FG_BLACK,FG_MODE_SET,~0,border);
-
- // remove from the array of buttons
- for (int i=0; i<MaxTextAreas; i++)
- { if ( list[i] != (TextArea *) 0 )
- if ( list[i] == this )
- list[i] = (void *) 0;
- }
- }
-
-
-
-
-
-
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
- /* | MEMBER TO RETURN A CLASS NAME char OR CLASS CODE int | */
- /* [ ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ ] */
-
- void TextArea::GetClassCode(int &i) // return the name of the class
- { i=ObjectType; // return the object item type
- }
-
- int TextArea::GetClassCode() // return the name of the class
- { return(ObjectType); // return the object item type
- }
-
- void TextArea::GetClassName(char * cl) // return the name of the class
- { strcpy(cl,"TextArea"); // default is cl8'object'
- }
-
- int TextArea::GetThisGroup() // return group code
- { return(ObjectGroup);
- }
-
-
-
- void TextArea::PvtGroupShow(int xgroup) // private internal function
-
- { // if I select or use this text then all others of the same group
- // drop to a state of show, the following code does that
-
- for (int i=0; i<MaxTextAreas ; i++)
- { if ( list[i] != (TextArea *) 0 )
-
- if ( list[i]->ObjectGroup == xgroup
- && list[i] != this
- && list[i]->ObjectState != '1' )
-
- { list[i]->Show();
- }
- }
- }
-
-
-
-
-
-
- void TextArea::Show()
- { if ( ObjectState!='1')
- // dont reshow if already in show state because text may already have
- // been TYPEd into the area
- { // this is invoked by GroupShow function also
-
- // border for the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_BLUE,FG_MODE_SET,~0,box);
-
- // now show the text
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
- }
- cur_line=0; /* line at a time function support */
- // set state to SHOW (BLUE) state
- ObjectState='1';
- }
-
-
- void TextArea::Select()
- { // border for the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_LIGHT_BLUE,FG_MODE_SET,~0,box);
-
- // now show the text
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
-
- // make state now selected, but not yet in use - EG Notifier/CURSOR
- ObjectState='2';
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
-
-
-
-
- void TextArea::Use()
- { // border for the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // box itself
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // now show the text
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
- ObjectState='U';
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
-
-
-
-
-
-
- //void nulprc(Button * p) { ; }
- void TextArea_NULLPROC(Button * p) { ; }
-
- void TextArea::Busy()
- { // we use a group of 256 higher so there is no chance of group screwups
- Button * TXTBTN;
- TXTBTN = new Button(0,left,ObjectMaxYpx-top,
- " ", TextArea_NULLPROC, 30,20);
- // TXTBTN = new Button(0,10,10," ", nulprc, 30,20);
- TXTBTN->Busy();
- delete TXTBTN;
- // end of the temporary button group number group+256
-
- // redraw the border and the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,
- fg_displaybox);
- ObjectState='B';
- }
-
- void TextArea::Swap(char * text)
- { fg_box_t tbx;
-
- // redraw the border and the box
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // then redraw the text and reset the state
- strcpy(word,text);
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,
- fg_displaybox);
- ObjectState='B';
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
-
-
-
-
- int TextArea::Type(char * text, int ln=0) /* line at a time print */
- { int x,y, i,j; /* temporary variables */
- x=l; y=ln; /* x and y coordinates */
-
- if ( ObjectState != '1' ) { this->Show(); } // auto show if is needed
-
- i=0;
- while (text[i]) /* loop til \0 - strips bad codes */
- { if (text[i]<' ' || text[i]>'~')
- text[i]=' '; /* repl bad code with a blank code */
- i++; /* add to counter */
- }
-
- if ( !y ) y=cur_line++; /* if no line assume next and incr it*/
- if ( y+1>cur_line_max ) y=cur_line=0; /* wrap to start of textbox */
- else
- { y= t - (y * (4 + /* fg_charbox[FG_Y2] */ 14) ); /* y coord */
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,x,y,text,fg_displaybox);
- }
- return(cur_line_max); /* return max lines for info */
- }
-
- void TextArea::Fade(char * text)
-
- { // draw the border again
- fg_drawbox(FG_CYAN,FG_MODE_SET,~0,FG_LINE_SOLID,
- border,fg_displaybox);
-
- // draw the box inside the border
- fg_fillbox(FG_WHITE,FG_MODE_SET,~0,box);
-
- // reshow the text in the box
- strcpy(word,text);
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,l,t,word,fg_displaybox);
-
- // specify box state now
- ObjectState='F';
-
- // ensure all other buttons in group are at show state
- PvtGroupShow(ObjectGroup);
- }
-
-
-
- void TextArea::Hide()
-
- { fg_fillbox(FG_BLACK,FG_MODE_SET,~0,border);
- ObjectState='0';
- }
-
-
- void TextArea::Read(char * text)
- {
- strcpy(text,word);
- }
-
- void TextKeyboardNotify()
- { while ( !kbhit() ) Dispatch();
- getch();
- }
-
-
- #endif
- /* [] END of textarea.hpp [] */
-
-
- //------------------------------------------------> slider.hpp <-------------
- /* [ ]--- SLIDER.HPP ------ C L A S S R U L E S --------------------[ ] */
- /* | | */
- /* | A slider is used exactly like a button except that we dont have | */
- /* | a user defined notify. | */
- /* | | */
- /* | This is derived from the Button class. | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- #ifndef SliderDefined
- #define SliderDefined
-
- // globals needed for all class items are here without compile test switch
- #include "Object.hpp" /* base classes base class */
- #include "Button.hpp" /* my base class */
- #include "dispatch.hpp"
- #include "ishdmous.cpp"
- #include "friend.hpp"
- #include "sound.h"
-
-
- /* [ ]--- SLIDER ---------- O B J E C T S T A T E S ------------------[ ]
- | |
- | STATE: same as Buttton and TextArea classes. |
- | |
- [ ]-------------------------------------------------------------------[ ] */
-
- /* [ ]--- SLIDER ---------- RELATIONSHIPS ------------------------------ [ ]
- | |
- | The Slider class is related to the Textarea class, and polymorphism |
- | is extant, as are overloaded functions. Refer to Textarea.HPP and |
- | Friend.HPP and Dispatch.HPP. |
- | |
- | |
- [ ] ----------------------------------------------------------------- [ ] */
-
- // Prototypes
- MOPEN();
- MCLOSE();
- int MINFO_LC(int *x, int *y, int *l, int *m, int *r);
- int MINFO_XY(int *x, int *y, int *l, int *m, int *r);
-
-
- /* [ ]--- CRTCLASS ---- M A S T E R V A R I A B L E S ----------------[ ] */
- /* | | */
- /* | ObjectCompile a compiler #define to avoid duplication of | */
- /* | | */
- /* | 1. #include <fg.h> for function prototypes | */
- /* | 2. ObjectMaxYpx has many uses | */
- /* | 3. ObjectGraphOpen graphics open switch | */
- /* | | */
- /* | The above appear at the start of Slider & Textarea class defns. | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
- /* [ ]--- Slider ------ M A S T E R V A R I A B L E S ----------------[ ] */
- /* | | */
- /* | SliderWide width of the button box in pixels | */
- /* | SliderTall height of the button box in pixels | */
- /* | SliderMax does not exist - Slider is a Button special case | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
- /* [ ]--- Slider ------ S P E C I A L N O T E S ---------------------[ ] */
- /* | | */
- /* | Notifier the class structure includes a pointer to a | */
- /* | user provided function. | */
- /* | void (* Notifier)(); Declared in the class structure | */
- /* | void (*fn)(), Function prototype in constructor | */
- /* | Notifier=fn; Usage when saved in constructor | */
- /* | (*Notifier)(this); Usage in the Slider::Use() function | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
-
- // globals needed for button class items are here
- int SliderWide=70, /* BOX SIZE horizontally */
- SliderTall=20; /* BOX SIZE vertically */
- #define SliderMax ButtonMax /* number to be remembered - limit */
-
- #define HV fg_puts(FG_LIGHT_BLUE,FG_MODE_SET,~0,FG_ROT0,lastx,lasty,"-",fg_displaybox);
- #define HH fg_puts(FG_LIGHT_BLUE,FG_MODE_SET,~0,FG_ROT0,lastx,lasty,"I",fg_displaybox);
- #define DV fg_puts(FG_RED,FG_MODE_SET,~0,FG_ROT0,lastx,lasty,"-",fg_displaybox);
- #define DH fg_puts(FG_RED,FG_MODE_SET,~0,FG_ROT0,lastx,lasty,"I",fg_displaybox);
-
- class Slider : public Button
-
- { /* general button control parameters needed are first */
- int ObjectType; /* 0011 is a button special case */
-
- char SliderText[20]; /* descriptor */
-
- public:
- int value; /* relative x or y value returned */
- private:
-
- char mode; /* continuous notify or end notify */
- char style; /* vertical or horizontal */
-
- void (* BNotifier)(Slider *); // defines a pointer to a function
- // ^ ^ The ^tells it a pointer as opposed
- // to a function
- // This is the user's exit when we get
- // a new slider value. We ourselves use
- // the button exit for our own evil
- // purposes.
-
- // DECLARATIONS FOR CONSTRUCTOR AND DESTRUCTOR FUNCTIONS
- public:
-
- // C++ constructor for the button class of objects
- Slider (int xgroup, int xleft, int xtop,char * str,
- void(*fn)(Slider*),int xsz, int ysz)
- : Button(xgroup,xleft,xtop,"",SliderNotify,xsz,ysz)
- { ObjectType=11; /* type = 11 means button.slider */
- strcpy(SliderText,str); /* get slider text */
- BNotifier=fn; /* get users exit to be given value */
- DerivedAddr=this; // save derived address IN Button area
- SliderContinuous(); // set continuous default
- SliderVertical(); // assume vertical but..
- if (xsz>ysz) SliderHorizontal(); // check out horizontal
- } // END OF CONSTRUCTOR LOGIC
-
- virtual ~Slider() { ; } // virtual
-
-
-
-
-
- // Slider specific methods - run time mode
- void SliderContinuous() { mode='c'; }
- void SliderNotContinuous(){ mode='n'; }
-
- // Slider specific methods -
- void SliderVertical() { style='v'; }
- void SliderHorizontal() { style='h'; }
-
-
- // DECLARATIONS OF member functions below, definition later
- virtual void Busy() { ; } // null functions
- virtual void Swap(char *) { ; }
- virtual void Fade(char *) { ; }
-
-
- // Slider Friends
- friend void SliderNotify(Button *);
- }; // end of the slider class
-
-
- /* [ ] ----- END OF CLASS ----- [ ] */
-
- void SliderNotify(Button * tb)
- { // slider exit will steal the mouse and do good things - special code
- // in Button enters this notifier on a Select as opposed to Use.
- int x, y, // x,y are PRESENT values
- l, m, r, // l,m,r are the buttons hit
- stus, // stus id mouse status
- flag; // flag is our control flag
-
- int lastx,lasty; // for the line used as a slider cursor
-
- int X, Y; // working values of x,y
-
- // Get the slider associated with the Button - slider is derived from
- // // Button and has Sliders typed address
- Slider * ts; // temporary slider pointer for the
- // slider associated with this Button
- ts=tb->DerivedAddr; // Get our Sliders address
-
- //MOPEN(); // fire up the mouse - is already BUT
- msm_showcursor(); // allow mouse video as Button tnd off
-
-
- // Setup the initial cross bar in the slider
- lastx=lasty=l=m=r=0; // set all values to 0
- stus=MINFO_XY(&x,&y, &l,&m,&r); // prime values for later
- lastx=0; // say no "last" values yet
- lasty=0;
- l=m=r=0;
-
- // Prime the slider loop run until a click to exit
- stus=1; // set up initial values
- flag=1; // primes the loop
- while ( flag ) // while no keys depressed at all
- { Dispatch(); // <<==== friendly multi tasker
- if ( stus=MINFO_XY(&x,&y, &l,&m,&r) )
- { // (0) fix the Y value from MOUSE to FG_ values
- // and make x,y->X,Y so we dont alter x,y for
- // mouse, making false mouse detects.
- Y=ObjectMaxYpx-y;
- X=x;
-
-
-
-
- // (1) calculate what we would return to user exit
- if (ts->style == 'h')
- ts->value = ((long)(X - tb->left)*100) /
- (tb->box_wide);
- if (ts->style == 'v')
- ts->value = ((long)(tb->top - Y )*100) /
- (tb->box_tall);
-
- if (ts->value < 0) ts->value=0;
- if (ts->value > 99) ts->value=100;
-
-
-
-
-
-
-
-
-
-
-
-
- // (2) If outside slider go back to prior operation, ie
- // prior mouse work, WELL away from slider area is 30
- if ( X<(tb->left-30) || X>(tb->left + tb->box_wide+30)
- || Y>(tb->top+30) || Y<(tb->top-(tb->box_tall+30)))
- { flag=0; // make sure while halts
- msm_hidecursor(); // avoid bad video
- tb->Show(); // Drop from Select to Show
- if (ts->style=='v') DV;
- if (ts->style=='h') DH;
- msm_showcursor(); // avoid bad video
- break; // stop further tests
- }
-
- // (3) restrict the dimension not in use if style is
- // V or H to make slider less wobbly
- if (ts->style=='v')
- X=tb->left -5 +(tb->box_wide)/2;
- if (ts->style=='h')
- Y=tb->top -5 -(tb->box_tall)/2;
-
-
-
- // (4) Check if WELL within the slider area - pad used
- if ( X > tb->left+1 && // 1
- X < (tb->left+(tb->box_wide-6)) && // 6
- Y < tb->top-8 && // 8
- Y > (tb->top-(tb->box_tall-1)) ) // 1
- { if ( !(l+m+r) )
- { msm_hidecursor(); // avoid bad video
- tb->Select(); // change to active
-
- if ( lastx>0 && lasty>0 )
- { if (ts->style=='v') HV;
- if (ts->style=='h') HH;
- }
- lastx=X ; lasty=Y ;
- if (ts->style=='v') DV;
- if (ts->style=='h') DH;
-
- if (ts->mode=='c') /*1*/
- { sound_click(); ts->BNotifier(ts); }
- msm_showcursor(); // allow mouse video
- }
-
- else
- { msm_hidecursor(); // avoid bad video
- ts->BNotifier(ts); /*1*/
- tb->Show(); // slider to SHOW
- if (ts->style=='v') DV;
- if (ts->style=='h') DH;
- msm_showcursor(); // avoid bad video
- flag=0; // Show from Select
- break; // skip rest
- } // end of FOR loop checking all buttons
- } // end of IF mouse was in our slider
- } // end of IF any relevant mouse action
- } // end of WHILE loop*
- //MCLOSE(); // Dont close as still in Button Mouse
- }
-
- // /*1*/ object passes object as parm since function called cant
- // use "this" as it is not a member function.
-
- #endif
- /* [] END of slider.hpp [] */
-
- // Sample program to use Slider and Button. Button is used to QUIT
- //efine samples
- #ifdef samples
- int loopflag;
- void myexitS(Slider * v)
- { static int x=450; static int y=10; static char s[10];
- // fg_drawdot(FG_WHITE,FG_MODE_SET,~0,x,y);
- // if (x++>500) { x=10; y+=2; }
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,x,y,s,fg_displaybox);
- sprintf(s,"%4d",v->value);
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,x,y,s,fg_displaybox);
- }
- void myexitT(Slider * v)
- { static int x=410; static int y=10; static char s[10];
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,x,y,s,fg_displaybox);
- sprintf(s,"%4d",v->value);
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,x,y,s,fg_displaybox);
- }
- void myexitB(Button *)
- { loopflag=1;
- }
-
- main()
- { Button * b;
- Slider * s;
- Slider * t;
- b = new Button(1, 10, 10, "QUIT", myexitB);
- s = new Slider(1, 600, 50, "s", myexitS,20,200);
- t = new Slider(1, 100, 100, "t", myexitT,350,50);
- // t->SliderNotContinuous();
- GroupShow(1); // s->Show(); etc...
- loopflag=0;
- while (!loopflag)
- { ButtonMouseNotify(1);
- }
- fg_term();
- int i,j;
- i=s->value;
- j=t->value;
- printf("%4d\n", i);
- printf("%4d\n", j);
- }
- #endif
-
- //---------------------------------------------------> browser.cpp (program)
- /* [ ]--- BROWSER --------- DIRECTORY ANALYSER FOR C++ -----------------[ ] */
- /* | NOV 16 1989 Simon Wheaton-SMith | */
- /* [ ]------------------------------------------------------------------[ ] */
- /* | | */
- /* | ASSOCIATIONS: cl3'CPP' and int 'j' | */
- /* | cl3'C ' and int 'k' | */
- /* | cl3'HPP' and int 'l' | */
- /* | cl4'HOST' and int 'm' | */
- /* | | */
- /* | QUIT BUTTON 10,10 master quit | */
- /* | 20,20 next level quit - eg directory select | */
- /* | 30,30 lower level quit - eg browse/edit | */
- /* | | */
- /* | WORK TO DO: HOST: use HLLAPI class to logon to tso and do | */
- /* | a listds and capture the results | */
- /* | | */
- /* | EDIT: add notifier code | */
- /* | PRINT: add print code | */
- /* | | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- // standard includes for our classes, code and system functions
- #include "stdio.h" // first to bypass autoprototyping
- #include "Button.hpp" // implies ishdmous.cpp and dispatch.hpp
- #include "TextArea.hpp" // keyboard text area
- #include "slider.hpp" // slider derived from class button
-
-
-
- // subtasking functions and their global parameters
- void printer(Button *); // declaration for file printer
- char printer_file_name[20]; // file name if busy, else blank
- FILE * printer_file_handle; // global file handle
- int printer_file_recno=0; // current record in the file
-
-
- // editing function is not subtasked but has global parameters
- void editor(Button *); // declaration for file editor
- char editor_file_name[20]; // file name being edited
- FILE * editor_file_handle; // global file handle
-
-
-
- // declarations of functions defined later
- void c_button(Button *); // declaration of a later USE function
- void file_button(Button *); // declaration of a later USE function
- void file_quit_button(Button *); // declaration of a later function
- void quit(Button *); // declaration of a later function
- int showfile(int, int, char *); // declaration for a file display
- buildlib(int, int, char *); // declaration for directory load
- void cpu_button(Button *); // hllapi interface
- void sliderexit(Slider *); // slider for text area
- void slidernull(Slider *) {;} // slider for text area
-
-
- // functions that do nothing
- void text_button(TextArea *) { ; } // actual null function for text area
- void notify(Button *) { ; } // actual null function for buttons
-
-
- // a subtask prototype - however this subtask only counts numbers!
- void browser_subtask(); // an asynchronous task
-
-
-
- // preprocessor equates for Mouse (in Button) and Keyboard (in TextArea).
- // these routines are used in application code whenever we wish to give
- // up control to the "system" and we take over in the two notifier routines
- // and do two things, we nudge the global busy wheel and we run asynchronous
- // code, such as could run an rs232 port activity, this is the DispatchER().
-
- #define Keyboard() TextKeyboardNotify() // pause on keyboard - text entry
- #define Mouse(a) ButtonMouseNotify(a) // pause on mouse - button notift
-
-
-
- // used for endless loop on the Mouse notifier until someting says
- // not to loop anymore.
- int loopexit; // mouse loop stops after SHOWFILE sw
-
- /* ----- useful debug code -----
- char pp[50]; sprintf(pp,"%4d",j);
- fg_puts(FG_WHITE,FG_MODE_SET,~0,FG_ROT0,50,
- 50,pp,fg_displaybox);
- */
-
-
- // used for the current group of entities to work on
- char suffix[5]; // global file suffix
- int workinggroup; // global group being played with
-
-
-
-
- // Globals for group id association - avoiding need for ANY object pointers
- int cppgroup;
- int cgroup;
- int hppgroup;
- int hostgroup; // global for host interface group id
-
-
-
-
- // configuration limiting defines
- #define MAXFILES 100 // arbitrary limit
- #define LOOPLIMIT 5000 // arbitrary loop detect
-
-
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | MAIN BROWSER PROCEDURE | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- main()
- { int i,j,k,l,m; /* group id codes for clasification */
-
-
- // get group ids so we can reference objects by group
- i = GetFreeGroupId(); // group id's allow us to access a
- j = GetFreeGroupId(); // group of objects and not needing
- k = GetFreeGroupId(); // to have a pointer to them
- l = GetFreeGroupId();
- m = GetFreeGroupId(); // we need host code for SHOW code
-
-
- // assign global names for other functions
- cppgroup=j;
- cgroup=k;
- hppgroup=l;
- hostgroup=m; // below, so save it for later
-
- // build directories using group names
- buildlib(j,110,"CPP"); // we define group j to be C++ code
- buildlib(k,210,"C "); // k C code
- buildlib(l,310,"HPP"); // l classes
- // host build deferred till requested m host
-
-
- if ( !Attach(browser_subtask) ) // attach asynch task
- { printf("Attach failed\n");
- exit(1);
- }
-
- // G X Y TEXT NOTIFY
- new Button(i, 10, 10, "QUIT", quit ,70,20); // group
- new Button(i, 110, 10, "CPP", c_button); // j
- new Button(i, 210, 10, "C ", c_button); // k
- new Button(i, 310, 10, "HPP", c_button); // l
- new Button(i, 410, 10, "HOST", cpu_button); // m
-
- GroupShow(i);
-
-
- // reset printer globals to show printer is free
- strcpy(printer_file_name," ");
- printer_file_recno=0;
-
-
- loopexit=1; // loop till reset
- workinggroup=1; // current group
- while (loopexit)
- { Mouse(i); // run above top row buttons
- // DispatchWheelOff(); // stop the rotating wheel now forever
- GroupHide(j); // hide the lower layers
- GroupHide(k);
- GroupHide(l);
- GroupHide(m); // after hide, reshow upper layers
- GroupHide(i); // force state off so SHOW relights
- GroupShow(i); // the top row of buttons
- }
- } // end of MAIN()
-
-
-
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | READ A DIRECTORY FOR A SUFFIX AND CREATE A Button GROUP | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- buildlib(int g, int x, char * sfx)
- { char cmd[256], tfn[64], str[256];
- char *vp;
- FILE *tfp; /* file to read DOS DIR command */
-
- strcpy(cmd,"dir *.");
- strcat(cmd,sfx); // add file suffix
- strcat(cmd," > tempfil.tmp"); /* build dos command */
- strcpy(tfn,"tempfil.tmp"); /* save file name */
- system(cmd); /* run the directory display */
-
- if ((tfp=fopen(tfn,"r")) == NULL) /* see if we got a directory */
- { printf("*** tempfil.tmp cant open:memory? ***\n");
- printf("%x\n",*tfp);
- printf("%x\n",tfp);
- return(-1);
- }
-
- int y=100, i=0; /* x,y for dynamic buttons */
-
- while ( i<MAXFILES )
- { if ( !(fgets(str,80,tfp)) ) break; // break at eof
-
- if ( strlen(str)>38 && str[25]=='-' ) // DIR format ?
- { strncpy(cmd,str,20); // copy file name in
- vp=cmd; // locate flname and
- *(vp+8)='\0'; // force size to 8
-
- new Button ( g,x,y,cmd,file_button);
- i++;
- x+=10;
- y+=15;
- if (y>300) { y=100; x+=0;}
- }
- }
-
- new Button (g,20,20,"quit", file_quit_button); /* quit button */
-
-
-
- unlink(tfn); /* delete temp file */
- fclose(tfp); /* also close it */
-
- // What we have just done is built a lot of objects and let Button
- // keep track of them in its array. We told Button they were all
- // group XX, any unique hiearchical number would have done.
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* [ ]-------------------------------vvvv-------------------------------[ ] */
- /* | TOP ROW BUTTON depressed - QUIT cpp c hpp host | */
- /* [ ]-------------------------------^^^^-------------------------------[ ] */
-
- void quit(Button * notify_button)
- { Detach(browser_subtask); // suspend sub task demo code
- notify_button->Fade("ENDING"); // <-- this is an overloaded function
- fg_term();
- exit(0); // mouse clicked quit
- } // end of DIR_BUTTON()
-
-
-
-
-
-
-
-
-
-
-
-
- /* [ ]------------------------------------vvv-vvv-vvv-------------------[ ] */
- /* | TOP ROW BUTTON depressed - quit CPP C HPP host | */
- /* [ ]------------------------------------^^^-^^^-^^^-------------------[ ] */
-
- void c_button(Button * notify_button)
- { notify_button->Read(suffix); // get the group
- if (!strcmp(suffix,"CPP")) workinggroup=cppgroup;
- if (!strcmp(suffix,"C ")) workinggroup=cgroup;
- if (!strcmp(suffix,"HPP")) workinggroup=hppgroup;
- notify_button->Swap(suffix);
- GroupShow(workinggroup); // group show - uses an integer
- loopexit = 1; // loop till notify wants stop
- while ( loopexit )
- { GroupHide(workinggroup); // file name buttons
- GroupShow(workinggroup);
- Mouse(workinggroup); // run the mouse notifier
- }
- notify_button->Swap(suffix);
- loopexit=1; // allow lower MOUSE loop to run
- } // end of DIR_BUTTON()
-
-
- /* [ ]-------------------------------------------------vvvv-------------[ ] */
- /* | TOP ROW BUTTON depressed - quit cpp c hpp HOST | */
- /* [ ]-------------------------------------------------^^^^-------------[ ] */
-
- void cpu_button(Button * bb)
-
- { int m; // get the code used for HOST GROUP
- m=hostgroup;
- new Button (m,20, 20, "quit", notify ); /* quit */
- new Button (m,410,100,"none", notify ); /* quit */
- GroupShow(m);
- Detach(browser_subtask); // suspend sub task demo code
- Mouse(m); // wait for any group 23 hit
-
- Attach(browser_subtask); // resume subtask demo code
- GroupDelete(m);
- loopexit=1; // force refresh of MOUSE loop
- }
-
-
-
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | A specific file button has been selected | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- void file_button(Button * notify_button)
- { char filnam[20];
- // the button we got passed is a pointer to the button hit.
-
- notify_button->Read(filnam); // get filename from the button
-
- if ( strncmp("quit",filnam,3) ) // strcmp ret !0 if not match - remember
- {
- showfile( 10,80,filnam); // ----------> two pages on
- }
- if ( !strncmp("quit",filnam,3)) // strcmp returns 0 if true - remember
- { loopexit = 0; } // halt mouse - BUT file_quit_button
- // should actually get the notify --->
- } // end of FILE_BUTTON()
-
-
-
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | A file button was hit but it was the file directory quit | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- void file_quit_button(Button * bb)
- { loopexit = 0; // halt mouse loop
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | Subroutine to display a disk file, neednt be separate code. | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- char *recs[500]; long int nrecs; // global for slider exit - holds up
- TextArea * t; // to 500 records of the file
-
- int showfile(int ax, int ay, char * tx)
- { char * vp;
- char tfn[65], str[256];
- char frslt; // file results
- FILE * tfp;
- int i,j,k, y; // integers and a Y working area
- int G1, G2; // group codes for buttons and etc
-
- strcpy(tfn,tx); /* tfn now a file name____0 */
- for (i=0; i<64; i++) if (tfn[i]==' ') tfn[i]='\0';
- strcat(tfn,"."); /* tfn now a proper file name */
- strcat(tfn,suffix);
-
- y = ay-15; // y is zortech coord
-
- if ((tfp=fopen(tfn,"r")) == NULL) return(-1);
-
- for (i=0;i<500;i++) // build the 500 null entries for data
- { recs[i]= (void *)0;
- }
-
- G1=GetFreeGroupId(); // get a group for use and a
- G2=GetFreeGroupId(); // group for show but not use
-
- t = new TextArea(G1,ax,ay," ",text_button,600,235);
- //GroupShow(G1); // or t->Show() to show text area
-
-
-
-
-
-
-
-
-
-
-
- i=0; j=1; k=9999; // i=recno, j=size of data read in
- // k=max lines in the present textarea
- while ( (j) )
- { j=(int)(fgets(str,80,tfp)) ;
-
- if ( j>0 && i<500 ) // do as long as not file|array end
- { vp=str;
- if ( strlen(vp)>70 ) *(vp+70)='\0';
- Dispatch(); // once each record run DispatchER
- if (i<k) // if textarea not full show text
- { k=t->Type(str);
- } //if(i>k){t->Hide();t->Show();i=0;} // <<<<<<< debug
- // get memory, copy text to buffer array points to
- recs[i]=malloc(5+strlen(str));
- strcpy(recs[i],str);
- nrecs=i; // save file size
-
- i++; // add to record counter
- }
- else j=0; // stop on EOF or End of array
- }
-
- new Button(G1,30,30, "exit", notify);
- new Button(G1,10, y, "PRINT", printer); // needs future
- new Button(G1,110,y, "EDIT", editor); // code
- new Button(G2,250,y, tfn, notify, 210, 20);
- new Slider(G1,ax+605,ay,"vert", sliderexit,20, 235);
- new Slider(G1,ax,ay+240,"horz", slidernull,600, 15 ); // no use yet
- GroupShow(G1); // show the exit button
- GroupShow(G2); // show the file name also
-
- // either a keyboard
- // Keyboard();
- // or a mouse
- Mouse(G1); // wait for any CLICK to mean quit
-
- delete t; // delete text window
- GroupDelete(G1); // delete clickable buttons
- GroupDelete(G2); // delete unclickable file name button
-
- (void) fclose(tfp);
- for (i=0;i<500;i++) if (recs[i] != (void *)0) free(recs[i]);
- }
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | The textarea slider exit is here | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- void sliderexit(Slider * ts)
- { static long int record=0; // record is a percent, not rec
- if ( record != (ts->value) )
- { record=((ts->value) * nrecs)/100;
- t->Hide(); // now record is a record no
- t->Show(); // by hide then show
- int j=9999; int i=1; // count lines typed>Textarea
- while ( (record+20<nrecs) ) // dont run over array, pad 20
- { if ( (void *) recs[record] )
- { j=t->Type(recs[record]);
- if (i++>j) record=nrecs+1; // halt on full txt
- }
- record++; // add to record number
- }
- }
- record=ts->value; // remember start point as %
- }
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | The named file is to be printer | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- void printer(Button *) // printer function
- { // AT EOF - reset printer globals to show printer is free
- strcpy(printer_file_name," ");
- printer_file_recno=0;
- }
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | The named file is to be edited | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- void editor(Button *) // editor function
- { ;
- }
-
-
-
-
-
- /* [ ]------------------------------------------------------------------[ ] */
- /* | A useless asynchronous thread for no good reason at all | */
- /* [ ]------------------------------------------------------------------[ ] */
-
- // BROWSER SUB TASK FOR NO GOOD REASON - just shows a number
-
- void browser_subtask() // RULES: you do one quanta of work
- { static int value=0; // for each invocation.
- char w[20];
-
- sprintf(w,"%8d",value);
- // erase the file name from the screen and exit
- fg_puts(FG_BLACK,FG_MODE_SET,~0,FG_ROT0,10,1,w,fg_displaybox);
-
- if (value++>LOOPLIMIT) exit(1); // loop abend DEBUG PURPOSES
- sprintf(w,"%8d",value);
- // show the data
- fg_puts(FG_RED,FG_MODE_SET,~0,FG_ROT0,10,1,w,fg_displaybox);
- }
- /* [] END OF browser.cpp C++ V2.0 BROWSER OF C,CPP,HPP FILES WITH TASKING [] */
- /* end of the whole nine yards*/
-
-
-
-
-
-