Open main menu

CDOT Wiki β

Changes

OOP344 Assignment Two

33,234 bytes added, 12:15, 17 April 2013
m
Undo revision 69911 by MCanaday49 (Talk) - SPAM
== kid carrier ==[[OOP344]] - [[OOP344 Student List]] - [[OOP344 Teams]] - [[OOP344 Assignment One]] - [[OOP344 Assignment Two]] - [[OOP344 IRC Schedules 20093 |OOP344 IRC Schedules]]<br />- [[OOP344 Student Resources]]<br />Under construction...
You've got not too long ago a newborn, and best wishes have been in purchase! But now you're scratching to get out of your house, hit the actual piste or even embark on holiday. One of many most effective to handle your youngster and make your hands totally free is to apply a child provider. The following is the way to go shopping.=Due Dates=
*Saturday, November 28th: Version 0.1 (Initial working version)
*Tuesday, December 8th: Version 1.0 (Working version)
The fundamentals involving Little one Companies*Tuesday, December 8th to Thursday, December 17th: Final debugging and IRC meetings
=File Names=
Save your work in separate files for each class, and name the files to the same name as the classes; each class should have a header file and a code file.
The first choice For example for a new baby can be an child companythe class [[#IO_Field | IO_Field]], create ''IO_Field.h'' and ''IO_Field. This is a easy, frameless load up which snuggles your child in entrance peoplecpp''. Many can The header file should hold a child the class declaration, and several child equipment to your complete fat up any other possible declaration related to 30 or Thirty weightthe class. Child service providers are generally beautifully handy with regard to around-town make use The "cpp" file should hold the definition (implementation) of along with flightsthe class, and its methods and possible functions.
Create a Make file to build your project with respect to dependencies of classes.
=SVN Quick Notes=
A kid provider usually features a framework and it is meant to have a more substantial kid powering anyone# Checkout the code $svn co svn://zenit.senecac. To train on a little one service provider.ca/ops344_093a'''XX'''/trunk/PRJ --username yourUserName <sup>Remember, '''XX''' is your SVN number after your section ('a kid have to be effective at sitting up with no help' etc. The tiniest kid right for a youngster provider is all about Sixteen pounds)</sup># Add selected ciol., which typically means a child about Half a dozen or 7 a few months outdatedh ciol. When doubtful concerning your kid's readiness, seek advice from your current doctor ahead of venturing cpp and if present the class files (all compiled) $svn add filename# Commit the new files $svn commit# Team members check out. The most important child appropriate in order to journey in the carrier is around 40 pounds., with some designs helping higher pounds to accommodate gear, alsoindividually # development starts.
=How to reuse your C code in C++ programs=
Include your already existing C code into your C++ code as follows:
<big><pre>extern "C"{
#include "ciol.h"
};</pre></big>
Child carriers are a good selection for take a tripThis tells to C++ compiler, hiking the included header file contains C functions and employ aboutshould be complied and called as such. Because the additional fat as well as movement of one's kid might cause Remember, you do not need and should not rename your ciol.c to shed balanceciol.cpp, little one providers aren't suitable for backpacking upon unfastened rock, hiking, snow skiing, inline skateboarding, bicycling or another high-speed pursuitssince the compiler is already aware of the C functions in ciol.c.
=Team Project Wiki Pages=
Add a link to your Team project Wiki pages here:
Evaluate Functions[[OOP344_WestSideConnection | West Side Connection]]
[[OOP344_A Team|A Team]]
[[OOP344_All_are_welcome | All are welcome]]
[[OOP344 BITE | BITE]]
[[OOP344_Team_++ | Team ++ website]]
Most little one companies talk about standard characteristics for example variable make and also midsection shoulder straps, flexible child harness, any foldout kickstand with an outer body. Suit is key. Megan Nelson, REI Dallas inventory professional, offers these suggestions: "The in shape is just like a new back pack, except the weight trips greater. Nonetheless, the body weight in fact is not very much of an concern in the event the youngster carrier suits you appropriate.Inch[[ OOP344 BINGO | Team BINGO]]
[[ OOP344_Temporary | Team Temporary Name ]]
[[OOP344_Team_Funktion | Team Funktion website]]
Here are several in the specifics to take into consideration[[OOP344_Group_2 | Best Team Ever :) ]]
[[ OOP344_ASOS | ASOS_Brigade]]
[[ OOP344_Hasselhoff | Team Hasselhoff ]]
Headgear method=General Definition Header file=create a file called: Here is the critical for parental comfort and ease'''io_def. Most kid companies function a good easy-to-adjust step ladder suspension, the same as the types present in several backpacks. A youngster carrierh'''s flexibleness can be assessed by the torso assortment (listed under the Specs tabs upon REI.org product pages). Find out more about how precisely in order <span class="plainlinks">[http://www.thepiggybackrider.com/ <span style="color:black;font-weight:normal; text-decoration:none!important; background:none!important; text-decoration:none;/*CITATION*/">kid carrier</span>]</span> to determine your current core dimension. Upper body modifications are simple: Should you be This file will contain any necessary definitions or inclusions for the taller facet, move your suspensions starting higher for the back again (or perhaps, if you are a shorter grown-up, move the idea to a reduce establishing). A few models come with a fixed insides, which in turn limits adjustability, yet offer you fat savingsproject.
for now add the following define statements in '''io_def.h'''
<big><pre>
Kickstand: This pub provides a secure system with regard to loading along with unloading your son or daughter. The majority of could be by hand prolonged as well as retracted on the launching situation which has a straightforward whip. Various other designs feature a fixed-position kickstand #ifndef _CRT_SECURE_NO_DEPRECATE#define _CRT_SECURE_NO_DEPRECATE#endif#ifndef _CRT_SECURE_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#endif#define IO_NO_ACTION (which usually helps you to save a little bit of pounds0x1u) or perhaps a spring-loaded kickstand #define IO_CLEAR (which in turn runs and also folds up automatically-a great characteristic0x2u)#define IO_SHOW_ALL (0x4u)#define IO_SHOW_ERROR (0x8u)#define IO_SHOW_HELP (0x10u). All of these achieve the identical objective, thus personal personal preference is the determining aspect here.
// frame chars
#define _FRAME_CHARS "|+-+|+-+"
#define _FRAME_UNDERLINE " - "
#define _FRAME_UNDEROVER " - - "
#define _FRAME_LISTS "|/-\\|/-\\"
#define _FRAME_MENUS "|+-+|+-+"
#define _CHECKLIST_CHARS "[X]"
#define _RADIOLIST_CHARS "(o)"
#define _MENU_CHARS "[]"
#define _IO_TEXT_ALLOCATION_LINE_SIZE 1024
Body: Because known previously#ifdef NO_FUNC# undef NO_FUNC#endif#define NO_FUNC ((void(*)(MessageStatus, frameless companies are intended only for children and products amassing approximately Thirty weight. possibly even. Many kid service providers characteristic an outside shape of tubular light weight aluminum. A number of versions make use of an aluminum continue to be for assist, just like those employed in internal-frame backpacks, and could offer a backpack alternative.IO_Form&))(0))
#ifdef NO_VFUNC
# undef NO_VFUNC
#endif
#define NO_VFUNC ((bool(*)(const char*, IO_Form&))(0))
enum MessageStatus{ClearMessage,SetMessage};
enum CheckListMode{CheckBox, Radio};
enum MenuDir{Vertical, Horizontal};
Components: If you intent to employing a youngster service provider hardly ever, you will possibly not be thinking about full functionalities from the elegant designs. Even so, if you plan to head off-road as well as carry lots of items, take into account types with the following additional:#endif</pre></big>
=Mandatory Classes=
As the first part of your project this semester, you are to create few classes to encapsulate [[OOP344 Assignment One|Console Input Output Library]]
==IO_Field==
Gear-storage ability'''IO_Field''' is the base class for all different types of Fields on a Form.<big><pre>class IO_Form;class IO_Field{private: int _row; int _col;protected: void* _data; IO_Form* _owner; int getOwnerTop(void)const; int getOwnerLeft(void)const; void displayOwner(void)const;public: IO_Field(int row, such as detachable diaper hand bags or perhaps day deliversint col, void* data = (void*)0); virtual void* data(void); virtual void display(void)const = 0; virtual int edit(void)= 0; virtual bool editable(void)const = 0; virtual void set(const void *) = 0; virtual void set(IO_Form* owner); int getRow(void)const; int getCol(void)const; virtual ~IO_Field(void);};
Much more flexibleness choices for a much better suit</pre></big>===Constructor===
Diaper-changing sleeping pad<big><pre>IO_Field(int row, int col, void* data = (void*)0);</pre></big>This constructor sets the corresponding attributes to the values of incoming arguments.
Hydration-system ===Protected Methods=======getOwnerTop and left (optional)====<big><pre> int getOwnerTop()const; int getOwnerLeft()const;</pre></big>These two methods return the top and left, coordinates of the frame of the form in which the field exists.They simply return zero, if there is no owner. This can help the display methods of a field to place the field at the correct, relative position according to the form they are displayed in. ====displayOwner() (optional)====<big><pre> void displayOwner()const;</pre></big>This method displays the owner of a field, if it is compatibleexists. This can help a Field to hide itself, by displaying the owner, without displaying itself.===Public Methods=======data()====<big><pre>virtual void* data();</pre></big>Returns the value of the data attribute.
Detachable rain/sun lid ====set(at times distributed independentlyIO_Form*)====
Removable annoy netting <big><pre>virtual void set(usually offered separatelyIO_Form* owner);</pre></big>Sets the '''_owner''' attribute to incoming argument.
Match the Child Carrier for you====getRow()====
<big><pre>
int getRow(void)const;
</pre></big>
*if '''_owner''' is NULL, it returns the '''_row''' attribute
*if '''_owner''' is not NULL it returns the sum of '''_row''' and '''_owner->getTop();''' (see IO_Frame for getTop())
====getCol()====
1st<big><pre>int getCol(void)const;</pre></big>*if '''_owner''' is NULL, modify it returns the child service provider to adjust to anyone. Here '''_col''' attribute*if '''_owner''' is not NULL it returns the main factor sum of '''_col''' and '''_owner->getLeft();''' (see IO_Frame for your comfort and ease. When generating your current first alterations, use publications to be able to bodyweight those as opposed to your son or daughter.getLeft())
===Destructor===
'''<big><pre>
virtual ~IOField();
</pre></big>'''
An empty destructor (the body of the method is blank)
===Pure Virtual Methods===
<big><pre>
virtual void display() = 0;
virtual int edit()= 0;
virtual bool editable() = 0;
virtual void set(const void *) = 0;
</pre></big>
These are pure virtual methods enforcing the creation of the identical methods in the derived classes. This make the IO_Field class an abstract class.
Note: The purpose of passing an IO_Form pointer to the Edit method, is to make the future Edit methods capable of sending a message (errors and help messages)to the Screen they are being Edited on.
==IO_Frame==
Adjust the headgear technique to suit your torso'''IO_Frame''' class, in order that the hipbelt sets on the hip bone fragments (not really the waistline) along encapsulates a frame. It Draws a frame at left top corner of '''left''' and '''top''' with the tie sleep on the neckspecified '''width''' and '''height'''.
Tighten up your hipbelt consequently roughly 80% of the pounds A Frame can be in your hips.instantiated as follows:<big><pre>IO_Frame(int top, int left, int width, int height, const char* frameChars = (const char*)0);</pre></big>
Make tighter the tie so '''frameChars''' are characters used to draw the youngster company is actually sits firmly and the outstanding 20% possibly even of the fat is actually frame, characters in your shoulders.order are:# left side# left top corner# top side# top right corner# right side# right bottom corner# bottom side# bottom left corner
Alter the particular sternum band throughout your torso in order that it will not hinder your own breathing in.So to draw this:<big><pre> /--------\ | | | | | | \--------/</pre></big>
Fit the Child Provider to Your Childframe chars should be:<big><pre>"|/-\|/-\"</pre></big>
If however, the '''frameChars''' argument is missing (it is NULL) then a default, defined value in "io_def.h"; '''_FRAME_CHARS''' should be used.
===Public Methods===
Ahead of placing your kids inside ====display()====<big><pre>void display(int topOffset=0, int leftOffset=0)const;</pre></big>'''display()''', starts from top + topOffset and left + leftOffset and draws the company, change frame to the width and height in the child seat. Ensure the children's shoulder straps tend to be relaxed as well as received from the kickstand is fully lengthyconstructor.
====getLeft()====
<big><pre>
int getLeft();
</pre></big>
Today set your child inside service provider, and make certain their foot come from returns the lower leg openings.'''_left''' attribute;
Belt along with tense up just about all shoulder straps, like the hipbelt, shoulder straps, knee tie alterations and breast bone strap. Be aware: Its not all little one carriers have got all of these straps options.====getTop()====
Tense up the medial side retention connectors, in the event that offered.<big><pre>int getTop();</pre></big>
Examine to make certain returns the infant's band match effortlessly over their shoulder blades knowning that the leg connectors are comfy.''_top''' attribute;
Recommendations on By using a Kid Service provider====void set()====<big><pre>void set(int top, int left);</pre></big>
sets the '''_top and _left''' attributes to corresponding arguments.
===Destructor===
Raising an entertained kid company is similar to hoisting much back pack (notice the pack-hoisting video with regard to recommendations)IO_Frame has a virtual destructor. The first few occasions you need to do therefore, have someone enable you to wear it your current back again. Your measures: Raise the child company by the prime manages, slip on the actual shoulder straps as well as buckle the particular hipbelt. When removing the carrier, undo the actual shoulder straps and unbuckle the particular hipbelt. Getting your take care of guiding your brain, carry your provider close to for a the front, along with grasp the second manage to help you collection the child carrier on the groundThis destructor does nothing.
==IO_Form==
'''[[#IO_Frame | IO_Frame]]''' is inherited into a container class called '''IO_Form'''. '''IO_Form''' organizes the '''[[#IO_Field | IO_Field]]''' classes and give the user a panel to use them sequentially.
A few more pointers:'''IO_Form''' should be able to hold unlimited number of '''[[#IO_Field | IO_Fields]]'''. (Use either a dynamic array, or linked list structure of '''[[#IO_Field | IO_Fields]]''' to implement this)<hr width="50%" />===Constructor===
'''IO_Form''' is constructed as follows:
<big><pre>
IO_Form(bool framed = false,
int row = 0, int col = 0 , int width = 0 , int height = 0,
const char* frameChars = (const char*)0);
</pre></big>
'''framed:''' if true, IO_Form will use its parent to draw a frame around itself when display()ed row, col, width and height are passed to the parent under following conditions:<br />If framed is true and "width or height" are 0 (zero) then the full size of the terminal is used for dimensions of the IO_Frame.
<hr width="50%" />
Do not leave your youngster unattended as he as well as she is in the little one provider.===Destructor===
Children usually get to sleep inside little one service providers<big><pre>virtual ~IO_Form(); sometimes look at child's placement and luxury.
Child service providers </pre></big>When '''IO_Form''' is going out of scope, is being destroyed, all '''dynamic''' IO_Fields are certainly deleted. (the rest will not effectively stable to be used like a chair, nor should they ever be put on raised floors say for example a regular, kitchen table or perhaps sleep.deallocated)
Avoid using a young child carrier when the framework or perhaps nails are usually harmed.<hr width="50%" />
Ensure your youngster is protected from your climate.===Private Methods===
Consider sporting ====Adding a hat Field to the Form====the '''IO_Form''' must be able to add several IO_Field classes to itself, one at a time and then provide the user, the means of editing them in order they were added.  <big><pre>int add(IO_Field* f, bool dynamic, bool submitter);</pre></big>'''IO_Form''' uses this private '''add''' method to provide means of adding fields through several public add methods. this method adds an '''[[#IO_Field | IO_Field]]''' to the end of the '''[[#IO_Field | IO_Fields]]''' in the IO_Form; *'''f''' : Is the address of the '''[[#IO_Field | IO_Field]]''' begin added to the '''IO_Form'''*'''dynamic''' : If set to true, it sets this '''[[#IO_Field | IO_Field]]''' to be deallocated by '''IO_Form''''s destructor at the end;*'''submitter''': If set to true, it tags this '''[[#IO_Field | IO_Field]]''' to terminate the '''IO_Form''''s edit() if ENTER_KEY is hit. see the edit() method for more info. '''add()''' also calls '''set(IO_Form* owner)''' of '''[[#IO_Field | IO_Field]]''' and passes its pointer ''(this)'' to it. By doing this, each '''[[#IO_Field | IO_Field]]''' will know who is its owner.'''add()''' returns the number of fields currently in IO_FORM.<hr width="50%" /> ===Public Methods=======Add methods====<big><pre>int add(IO_Field* f, bool submitter = false);</pre></big>Uses the private add() method to add a dynamic '''[[#IO_Field | IO_Field]]'''.<hr width="50%" /><big><pre>int add(IO_Field& f, bool submitter = false);</pre></big>Uses the private add() method to add a non-dynamic '''[[#IO_Field | IO_Field]]'''.<hr width="50%" /><big><pre>int addHelp(IO_Label* L);</pre></big>Uses the private add() method to add a dynamic '''[[#IO_Field | IO_Field]]''' and also saves its address for the general help message label of the Form.<hr width="50%" /><big><pre>int addHelp(IO_Label& L);</pre></big>Uses the private add() method to add a non-dynamic '''[[#IO_Field | IO_Field]]''' and also saves its address for the general help message label of the Form.<hr width="50%" /><big><pre>int addError(IO_Label* L);</pre></big>Uses the private add() method to add a dynamic '''[[#IO_Field | IO_Field]]''' and also saves its address for the general error message label of the Form.<hr width="50%" /><big><pre>int addError(IO_Label& L);</pre></big>Uses the private add() method to add a non-dynamic '''[[#IO_Field | IO_Field]]''' and also saves its address for the general error message label of the Form.<hr width="50%" /><big><pre>IO_Form& operator<<(IO_Field* f);</pre></big> Uses the private add() method to add a non-submitter, dynamic '''[[#IO_Field | IO_Field]]'''.<hr width="50%" /><big><pre>IO_Form& operator<<(IO_Field& f);</pre></big>Uses the private add() method to add a non-submitter, non-dynamic '''[[#IO_Field | IO_Field]]'''.<hr width="50%" /> ====Setting General Error and Help messages ====<big><pre>void setError(const char* mes);void setHelp(const char* mes);</pre></big>Set the text of the general Error message and the general Help message of the Form.<hr width="50%" />====Number of fields in Form==== <big><pre>int length();</pre></big>Returns number of fields currently in IO_Form.<hr width="50%" /> ====Accessing Field Data====<big><pre>void* data(unsigned int fieldnumber=0);</pre></big>Returns address of the data of "fieldnumber"th, '''[[#IO_Field | IO_Field]]''' in the IO_Form. If "fieldnumber" is zero, then it returns the data of the current '''[[#IO_Field | IO_Field]]'''. ====The index operator====<big><pre>IO_Field& operator[](unsigned int index);</pre></big>Returns the reference of the '''[[#IO_Field | IO_Field]]''', number "fieldnumber-1". First Field has the index 0;<hr width="50%" /> ====Displaying the Form====<big><pre>void display(unsigned int how = IO_CLEAR | IO_SHOW_ALL ,unsigned int fieldnumber = 0 ); </pre></big> Displays the Form and all the Fields on it.  '''fieldnumber''' is the number of the field that was returned by any of the '''add()''' functions. '''how:''' is a binary mask, and following bits can be set in it:<blockquote>IO_CLEAR (0x2u)<br />IO_SHOW_ALL (0x4u)<br />IO_SHOW_ERROR (0x8u)<br />IO_SHOW_HELP (0x10u)<br /></blockquote>The display function work in the following order:# If IO_CLEAR bit is set in '''how''', then before anything the screen should be cleared.# If the field number is 0 (zero) then ## if IO_SHOW_ALL is set in '''how''', then all the fields are displayed in the order they were added## otherwise either of IO_SHOW_ERROR or IO_SHOW_HELP is set, only their corresponding designated IO_Label will be displayed.# if the field number is not zero, then the IO_Field number "fieldnumber" will be displayed. If the number is larger than the number of fields in the IO_Form then it will be rotated back from the beginning. (i.e. if there are 4 fields in the form and fieldnumber is 5, then filed number 1 will be displayed) <hr width="50%" /> ====Editing(running) the Form====<big><pre>int edit(unsigned int* fieldnumber = (unsigned int*)0, bool Clear = true);</pre></big> If neither of the '''[[#IO_Field | IO_Fields]]''' is editable, it displays all the '''[[#IO_Field | IO_Fields]]''', then waits for a key entry and then ends the function by returning the key entered. If the fieldnumber pointer is NULL, it should use a local variable’s address with the value of “0” zero instead. If *fieldnumber is (0) zero, then display all the fields before editing the fields and then set *fieldnumber to (1) one. Start editing from field number *fieldnumber.  Call the edit of each field and depending on the value returned, do the following: * For '''TAB_KEY''' and '''DOWN_KEY''', go to next editable '''[[#IO_Field | IO_Field]]''', if this is the last editable '''[[#IO_Field | IO_Field]]''' then restart from '''[[#IO_Field | IO_Field]]''' number one. * For '''UP_KEY''' go to the previous editable '''[[#IO_Field | IO_Field]]''', if there is no previous editable '''[[#IO_Field | IO_Field]]''', go to the last editable '''[[#IO_Field | IO_Field]]''' of the ''IO_Form'' and continue the search for an editable '''[[#IO_Field | IO_Field]]'''.  * For '''ENTER_KEY''' do exactly as '''TAB_KEY''', except that if the current '''[[#IO_Field | IO_Field]]''' is a submitter (is tagged to be a submitter when added), in which case terminate the edit function returning the '''ENTER_KEY'''. * For any other key, terminate the edit function returning the character which caused the termination. <hr width="50%" /> ==IO_Label=='''IO_Label''' class mostly, encapsulates the '''[[OOP344_Assignment_One#void_io_display.28const_char_.2Astr.2C_int_row.2C_int_col.2C_int_len.29|io_display()]]''' function.Inherit a new class called IO_Label from IO_Field to Display a text message on IO_Form. In addition to the attributes of its parent IO_Field, IO_Label has a private integer attribute called _len. _len is used to hold the length of Field in which the text is to be displayed.IO_Label holds its data dynamically and will never point to an external one. '''IO_Label''' can be created in two ways;<big><pre> IO_Label(int row, int col, int len);</pre></big>This constructor will create an empty (blank) IO_Label with capacity of len characters.In this case '''row''' and '''col''' are passed to the parent for initialization and '''_len''' (the attribute) is set to the incoming argument '''len'''.Then IO_Field::_data will be set to the address of a newly allocated memory to the size of '''_len + 1 ''' bytes which also will be set to an empty string.''Note that '''data''' is a void pointer; to use it here, you must cast it to a character pointer!''<br /><big><pre> IO_Label(const char* str, int row, int col, int len = -1);</pre></big>If '''len''' is greater than zero, This constructor will create an IO_Label by allocating len + 1 characters pointed by IO_Field::_data, and then the contents of '''str''' is copied into IO_Field::_data up to '''len''' characters. '''_len''' attribute is set to '''len''';If '''len''' is less than or equal to zero, then '''len''' will be set to the length of '''str''' and then constructor will work as previous case.Like the previous constructor it will pass '''row''' and '''col''' to its parent.===Public Methods===<big><pre>void display(void);</pre></big>'''Display()''' is a direct call to '''io_display()''' function printing '''_data''', at '''getRow()''' and '''getCol()''' up to '''_len''' characters. If '''_len''' is less than zero, then '''_data''' will be printed to the end.<big><pre> void set(const void* str);</pre></big>'''Set()''' will copy the content of '''str''' into '''IO_Field::_data''' up to '''_len''' characters, if '''_len''' is not negative.<big><pre>bool editable(void)const;</pre></big>'''Editable()''' returns false!.<big><pre> int edit(void);</pre></big>'''Edit()''', Calls '''Display()''' and returns '''0'''. This method ignores the '''Owner''', IO_Form pointer.<big><pre> ~IO_Label(void);</pre></big>The destructor, delete[]s the '''_data'''. (make sure '''_data''' is casted to char* before deleting.<big><pre> IO_Label& operator=(const char* str);</pre></big>'''operator=()''', Calls '''set()''' and returns itself. ==IO_Edit== Inherit IO_Field and IO_Frame into a new class called IO_Edit. (Read: Practical Programming Techniques Using C++, pages 94 to 96, ''Multiple Inheritance'' topic)  IO_Edit, encapsulates the '''[[OOP344_Assignment_One#Line_and_Selection_Editor|io_edit()]]''' function of ciol library when isTextEditor is false. IO_Edit calls the io_edit function to edit a string that is either created dynamically by the IO_Edit itself, or a string that is external and is received through the constructor arguments. Also IO_Edit gives the user the option of surrounding the editing line with a frame. Editing without a frame at row:2 col:5<big><pre>0123456789012345678901234567890123456789012345678912 Hello! I am editing a text_345</pre></big>Editing with a frame at row:2 col:5 (the actual editing happens at row:2+1 and col: 5+1<big><pre>0123456789012345678901234567890123456789012345678912 +-------------------------------------+3 |Hello! I am editing a text_ |4 +-------------------------------------+5</pre></big> ==Constructors and Destructor== ====Constructors====IO_Edit can be created in two ways:<big><pre>IO_Edit::IO_Edit(int row, int col, int fieldlen, int maxdatalen, int* insertmode, bool framed = false, const char* frameChars = (const char*)0);</pre></big>This constructor dynamically creates an array of '''maxdatalen''' + 1 chars (an empty string) and sets IO_Field::_data to point to it. '''row and col and frameChars''' will be passed directly to the Frame class's '''top and left and frameChars''', respectively. But since an IO_Frame needs to surround the edit field, it has to have one char extra for each side. Therefore, (fieldlen + 2) should be passed to IO_Frame as width and 3 should be passed to IO_Frame as height. On the other hand, the IO_Field class holds the actual coordinate at which, the editing should happen. So, depending on the value of the '''framed''' being false or true the values, '''(row and col)''' or '''(row+1 and col+1)''' will be passed to IO_Field's constructor respectively.  The IO_Edit In this case is marked to be dynamic, so at destruction time, the memory is deallocated.  All the arguments needed for ciol's io_edit() function should be kept as attributes so they can be used at edit() time. <big><pre> IO_Edit::IO_Edit(char* str, int row, int col, int fieldlen, int maxdatalen, int* insertmode, bool framed = false, const char* frameChars = (const char*)0);</pre></big>This constructor works exactly like the above constructor, with one exception. The data being edited is not dynamic here. So the IO_Fields::_data should point where the '''str''' argument is pointing to. Obviously, in this case IO_Edit should be marked as non-dynamic so at destruction time, the memory is NOT deallocated. ====Destructor==== The IO_Edit's destructor, checks to see if the object is marked to be dynamic. In this case it will delete[] the character content of IO_Field's _data. ===Public Methods=== ====display()====<big><pre>void IO_Edit::display()const;</pre></big>display, first checks to see if IO_Edit is framed. if it is it will call the IO_Frame's display(), using _owner->getTop() and _owner->getLeft() as its topOffset and leftOffset arguments.Then it will makes a direct call to ciol's io_display() function passing IO_Field's data, getRow() and getCol() and also the fieldlen value form IO_Edit's attributes.<blockquote>Passing _owner->getTop() and _owner->getLeft() to IO_Frame's display() and also, using getRow() and getCol() for extracting row and col from IO_Field, makes row and col of the IO_Edit, relative to top, left of the form it is on. (if IO_Edit belongs to an IO_Form, that is, if _owner is not NULL)</blockquote > ====edit()==== <big><pre>int IO_Edit::edit();</pre></big>edit() makes a direct call to ciol's io_edit with corresponding data from the IO_Edit's attributes. the '''Owner''' argument is simply ignored. edit() returns the value returned by ciol's io_edit. ====editable()====<big><pre>bool IO_Edit::editable()const;</pre></big> Always returns true; ====set()==== <big><pre>void IO_Edit::set(const void *str);</pre></big> set() copies the incoming string '''str''' into the IO_Field's '''_data''' up to '''maxdatalen''' characters.  (note: if using strncpy() make sure the string is null terminated)   ==IO_Vedit==Inherit IO_Edit to a Validated line editor called IO_Vedit.IO_Vedit, works exactly like an IO_Edit, with two differences.IO_Vedit has two extra attributes that are pointers to Validation and Help functions:<big><pre> void (*_Help)(MessageStatus, IO_Form&); bool (*_Validate)(const char*, IO_Form&);</pre></big> ===Constructors===<big><pre> IO_Vedit(int row, int col, int fieldlen, int maxdatalen, int* insertmode, bool framed = false, bool (*Validate)(const char* , IO_Form&) = NO_VFUNC, void (*Help)(MessageStatus, IO_Form&) = NO_FUNC, const char* frameChars = (const char*)0); IO_Vedit(char* str, int row, int col, int fieldlen, int maxdatalen, int* insertmode, bool framed = false, bool (*Validate)(const char*, IO_Form&) = NO_VFUNC, void (*Help)(MessageStatus, IO_Form&) = NO_FUNC, const char* frameChars = (const char*)0);</pre></big> These two constructors pass all the information directly to IO_Edit's constructor and then set the "function pointers" attributes to their corresponding arguments. ===Public Function=== <big><pre> int edit();</pre></big> * if '''_owner''' of IO_Vedit is null, then it simply calls the IO_Edit's '''edit()''' and terminates (returning the same value as IO_Edit::edit())* if '''_owner''' is not null** if the help function pointer attribute is not NULL, it will call it passing '''SetMesssage'' , and '''*_owner''' as arguments (This will show the help message for this field, before editing begins.)** if the validation function pointer is not null then it will call the IO_Edit::edit() and validate the data with it by keep repeating the IO_Edit::edit() until either validation function return true or the IO_Edit::edit() was terminated by a non navigation key.** Navigation keys are: '''UP_KEY DOWN_KEY TAB_KEY and ENTER_KEY'''** Right before the IO_Vedit::edit() Terminates, if the help function pointer attribute is not NULL, it will call it again passing '''ClearMesssage'' , and '''*_owner''' as arguments (this will clear the help message after editing is done.)** IO_Vedit::edit() will return the return value of IO_Edit::edit(). ==IO_CheckList==IO_Checklist a child of IO_Field and IO_Frame and is responsible to create an option list for user, letting her choose one or many of them and submit the selection.IO_Checklist can work in two modes: *Radio mode; were the selection is exclusive and each selection deselects the rest of the selections. *CheckBox mode; where the selection is inclusive and many selections can be done at the same time. ''Note that IO_CheckList is always framed...''===Constructor===Checklist is created as follows:<big><pre> IO_CheckList(CheckListMode mode, int row, int col, const char* items, const char* format = (const char*)0, const char* frameChars = _FRAME_LISTS);</pre></big>*'''mode''' is one of the two selection of <big><code>enum CheckListMode{CheckBox, Radio}</code></big> that should be defined in io_def.h.*'''row''' and '''col''' are the top, left corner of the frame surrounding the options.*'''items''' is a "newline" separated list of options in a string.*'''format''' is a 3 char string that holds the shape of a checked option(i.e. "[X]" or "<@>"),if the format is zero, then depending of the value of '''mode''' being '''Radio''' or '''CheckBox''', frame will be defaulted to '''_RADIOLIST_CHARS''' or '''_CHECKLIST_CHARS''' respectively.*'''frameChars''' is a string with the characters building the frame. '''Member Variables:'''*'''char** _items''' is a pointer to an array of character pointers.*'''int _len''' contains the number of character pointers in _items. In other words, the number of items in the checklist.*'''int _titlelen''' contains the length of the longest item in the list.  ===Public Methods=== <big><pre> void display()const;</pre></big>*display every item in one line. It first call the IO_Frame's display(), using _owner->getTop() and _owner->getLeft() as its topOffset and leftOffset arguments. Then display the checkbox and check item. <big><pre> int edit(void);</pre></big>*This function can change the status for each check item. Use UPKEY and DOWNKEY to select the individual check item, SPACE key to toggle the check status, and other keys to exit the edit mode. This function returns the last key value. <big><pre> int selectedIndex(void);</pre></big>*return the index of the first checked item. return -1 if none of them checked. <big><pre> bool editable()const;</pre></big>*always return true. <big><pre> void set(const void *flags);</pre></big>*set the status (checked or unchecked)for each item. <big><pre> bool& operator[](unsigned int index);</pre></big>*return the checked status for the item indexed by parameter index. <big><pre> int length(void);</pre></big>*return the number of items---incomplete--- ==IO_Menu==IO_Menu is a child of IO_Field and IO_Frame and is responsible for creating a menu in which means the user can select one item and submit the selection. IO_Menu can be organized in two ways, Vertical and Horizontal. *Vertical:<blockquote> The menu items will be displayed vertically and the list will be framed.</blockquote>*Horizontally<blockquote> The menu items will be displayed horizontally and the list will NOT be framed.</blockquote> ===Constructor===This is how an IO_Menu is created:<big><pre> IO_Menu(int row, int col, const char* items,int selIndex = 0,MenuDir dir = Vertical, const char* format = _MENU_CHARS, const char* frameChars = _FRAME_MENUS);</pre></big>*'''row''' and '''col''' are the top, left of where the menu will be displayed.*'''items''' is a "newline" separated list of menu items.*'''selIndex''' is the selected index of the menu, when it is initially displayed.*'''dir''' is one of the <big><code>enum MenuDir{Vertical, Horizontal}</code></big> values defined in io_def.h.*'''format''' is a 2 char, string, holding the surrounding chars of a selected menu item.*'''frameChars''' are the characters building the frame (if the object is framed). ===Public Methods===<big><pre>void display()const;</pre></big>This function displays menu items horizontally or vertically.For vertical menu, the menu items will be framed. <big><pre>int edit(void);</pre></big>This function allows users to navigate through menu items by pressing page down& up keys for vertical menu and right & left keys for horizontal menu. By pressing space key,current menu item would be selected, our previous selected menu item would be displayed then deselected.Other keys just terminates the function and returns the key.<big><pre>int selectedIndex(void);</pre></big><big><pre>void selectedIndex(int);</pre></big><big><pre>bool editable()const;</pre></big><big><pre>void set(const void *index);</pre></big><big><pre>void set(int index);</pre></big><big><pre>bool operator[](unsigned int index);</pre></big><big><pre>int length(void);</pre></big>This function returns length of menu. In other words, it returns number of menuitems. ==IO_TextEdit==Inherit IO_Field and IO_Frame into a new class called IO_TextEdit. (Read: Practical Programming Techniques Using C++, pages 94 to 96, Multiple Inheritance topic) IO_TextEdit, uses the io_edit() function of ciol library having its isTextEditor flag set to true (1). IO_TextEdit calls the io_edit function repeatedly to edit series of strings that is created dynamically by the IO_TextEdit. If initially a newline-separated (\n) string is provided, IO_TextEdit will split the string into several strings and copy them into dynamically allocated series of strings.  IO_TextEdit will do the edit in a framed multiline text field. Editing begins with the cursor at the top left of the field or from the position the editing was terminated last time.  Each line can be edited using the io_edit. If during the process of editing the string is shifted, make sure all lines are shifted together. If in overstrike mode hitting the enter key goes to next line. Otherwise (in insert mode) it should insert a new line after the current line and if there is any data after the current position, the data should be cut, and pasted to the newly created line. The cursor should stand at the beginning of the new line. Up and Down arrows should focus the editing on previous and next lines respectfully and if needed, to accommodate this the lines should shift to up and down. However, if UP and Down keys are hit on the first or last line of data, then the function will terminate returning those values. Page up and down should scroll the lines in the text field up and down "height-2" times, or better to say, scroll the text a page up or down if possible. if paging is not possible, then the keys are ignored. Each line in the text can be the maximum of "_IO_TEXT_ALLOCATION_LINE_SIZE" characters, defined in io_def.h ===Constructors=== IO_TextEdit can be created as follows: ===Dynamic Data=== <big><pre>IO_TextEdit(int row, int col, int width, int height,int* insertmode, int maxLines = -1,const char* frameChars = (const char*)0);</pre></big> This constructor set the class to dynamically create "series of strings" to be edited by io_edit function in the edit method when needed.The arguments, row and column are top and left coordinates of the text field and width and height are the width and height of the text field.  insertMode is where the insert flag status is kept. frameChars hold the optional characters to build the frame. The "single dimension string" representation of the "series of the strings" holding the text, in this case, will be allocated and kept dynamically. maxLines argument will limit the number of the lines in text, unless it is set to -1. ===Non-dynamic Data=== <big><pre>IO_TextEdit(char* str, int row, int col, int width, int height,int* insertmode, int maxLines = -1,const char* frameChars = (const char*)0);</pre></big> This constructor initially splits the newline separated data from the "str" argument into series of lines that are created dynamically to be edited by the io_edit function in the edit method. The arguments, row and column are top and left coordinates of the text field and width and height are the width and height of the text field.  insertMode is where the insert flag status is kept. frameChars hold the optional characters to build the frame. The "single dimension string" representation of the "series of the strings" holding the text will then be where str argument is pointing to. No dynamic memory is allocated for this.It is the caller program's responsibility to accommodate enough space for the data; maxLines argument will limit the number of the lines in text, unless it is set to -1. Make sure you store the address of where str is pointing in the _data of IO_Field for future use. ==Public Methods== ===void display()const;=== Displays the frame, and in the frame it will display the text from the top left being the first character of the first line or otherwise any position it was been right before the editing was terminated the last time. ===void *data();=== first converts back the series of string to a single dimension newline separated string of characters pointed by the IO_Field's data, and then returns it. If object is dynamic (created by the first constructor) then you may have to reallocate memory to make room for conversion. If object is not dynamic, (made by the second constructor) then the conversion's target will be the _data of IO_Field that was set by the constructor. No dynamic memory allocation should be done for the conversion. It is the user program of the object's responsibility to provide enough memory for this. Make sure you modify void IO_Field::data(); method to virtual for this to work; ===int edit();=== Edits the text one line at a the framed text field created by the constructor as mentioned in the description of the class. ===bool editable()const;=== Always returns true; ===void set(const void *str);=== splits the newline separated data from the "str" argument into "series of strings" that are created dynamically to be edited by the io_edit function in the edit method. ===virtual ~IO_TextEdit();=== deallocates the "series of strings" created for editing purposes. Also if object holds the data dynamically (created by fist constructor) it will deallocate memory pointed by the IO_Fields _data; =The Application= =Tips= ==Sample Main==<big><pre>#include "io_def.h"#include "io_form.h"#include "io_label.h"#include "io_edit.h"#include "io_vedit.h"#include <string.h>#include <stdio.h>bool ValidYear(const char* data, IO_Form& F){ bool res = true; int i = atoi(data); if( i < 1895 || i > 2010){ res = false; F[4].set("Invalid"); } else{ res = true; F[4].set(""); } F[4].display(); return res;}bool ValidRating(const char*data, IO_Form& F){ bool res = true; double d = atof(data); if( d<0.0 || d>10 ){ res = false; F[6].set("Invalid"); } else{ res = true; F[6].set(""); } F[6].display(); return res;}void YearHelp(MessageStatus m, IO_Form& F){ if(m == SetMessage){ F.setHelp("years valid between 1895 and 2010"); } else{ F.setHelp(""); } F.display(IO_SHOW_HELP);}void RateHelp(MessageStatus m, IO_Form& F){ if(m == SetMessage){ F.setHelp("Numbers between 0.0 and 10"); } else{ F.setHelp(""); } F.display(IO_SHOW_HELP);} int main(void){ io_init(); int insert = 1; char str[51] = "testing this"; IO_Form F(true, 1, 3, 70,21 ); F <<new IO_Label("| Movie Information Entry |", 0, 3) <<new IO_Label("Name:", 2,2)<<new IO_Label("Director:", 5, 2) <<new IO_Label("Release Date:", 8, 2)<<new IO_Label(8, 21, 10) <<new IO_Label("User rating 1->10:", 11, 2)<<new IO_Label(11, 25, 10) <<new IO_Label("Classification:", 14, 2) <<new IO_Label("Genre:", 2, 36) <<new IO_Label("Comment:", 13, 29) <<new IO_Edit(1, 7, 15, 25, &insert, true, _FRAME_UNDERLINE) <<new IO_Edit(4, 11, 15, 30, &insert, true, _FRAME_UNDERLINE) <<new IO_Vedit(7,15, 5, 4, &insert, true, ValidYear, YearHelp, _FRAME_UNDERLINE) <<new IO_Vedit(10,20,4, 3, &insert, true, ValidRating, RateHelp, _FRAME_UNDERLINE); F.addHelp(new IO_Label(19,2, 60)); F.edit(); io_end(); return 0;};</pre></big> Screen Shot of the above program: <big><pre> +--| Movie Information Entry |---------------------------------------+ | | | Name: Genre: | | --------------- | | | | Director: | | --------------- | | | | Release Date: | | ----- | | | | User rating 1->10: | | ---- | | Comment: | | Classification: | | | | | | | | | | | +--------------------------------------------------------------------+</pre></big> ==IO_Form== If you want to use a linkedlist to implement IO_Form having a node like this would be a good idea: <big><pre>class IO_Node{ IO_Field* _f; bool _dynamic; bool _submitter; IO_Node* next; IO_Node* prev; ... ... ...};</pre></big>And then make your IO_Form a linkedlist of IO_Nodes.... With this you can have the IO_field kept in the node and at the same time keep track of the IO_Field being dynamically created and if it is a submitter or not. So the data of the node will be the three attributes; '''_f''', '''_dynamic''', and '''_submitter'''. ==Fardad adds io_textedit== This is an edited dialogue copied from an IRC meeting '''fardad:''' I am going to do (the skeleton of) IO_TextEdit as an example. I will write the steps as I am doing it #I am adding a headerfile and cpp file to my visual studio this will add the headerfile and the cpp file to the working copy.#In solution exp. rightclick on headerfiles, add / new item#Added code/headerfile: "io_textedit.h"#Now i am rightclicking on sourcefiles/newitem code/cpp file#Added inclusion guards code to the headerfile (#ifndef __IO_TEXTEDIT_H__.....)#Included general headerfile in io_textedit.h. It will have all necessary definitions and includes for the project#Adding io_textedit.h and io_textdit.cpp to working copy($svn add ..., this tags them to be added to repository the next time svn is committed) #Compiled and it was successful, so I will commit now '''fardad:''' Done, you can now update you working copy and see what I did. You should do the same for all the other classes. It should not take you more than 30 minutes to do your kid cannot part, just pick up nice haira class and write it. ==Compiling under linux== If anyone is actually trying to compile under linux, they will notice quickly it fails. To compile in matrix, use: g++ yada.cpp yadoo.cpp -x c ciol.c -lncurses  If you have many cpp's, you may also do g++ *.cpp -x c ciol.c -lncurses
3
edits