Changes

Jump to: navigation, search

Project A2 20141 - OOP344

13,113 bytes added, 20:28, 15 March 2014
Tester: Added binaries.
= Introduction =
The basic information of A2 is on the BTP300 site linked [https://cs.senecac.on.ca/~btp300/pages/assignments/a2.html here]. A number of issues have been found identified within the assignment spec and so a series of changes amendments is required in order for the spec to produce a correct assignment. The changes amendments are listed here. In addition, we are also listing a number of clarifications and suggestions that you may find helpful while implementing this assignment. Those will follow the spec code changesamendments.
== Custom Additions ==You may add functions to your design of this assignment as long as they stay true to the "spirit" of the assignment. For example, adding a protected function in CFrame that returns whether the frame is currently in fullscreen mode or not. This function can then be used by all functions that care about whether the frame is currently fullscreen (eg width, height). = Tester =Please use [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2testing_mar092014.zip this updated tester package] for testing. It includes an updated a2tester.cpp, cdialog.h, cdialog.cpp. There are 4 testing levels. You can change which level you are testing at by changing the '''TEST_NO''' #define at the top of a2test.cpp. It may be any one of 0,1,2,3,4. Additionally, here are 5 official example windows binaries. These are compiled versions of assignment 2, compiled with the tester setting set to 0,1,2,3, and 4 respectively.* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test0_mar152014.exe a2_test0_mar152014.exe]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test1_mar152014.exe a2_test1_mar152014.exe]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test2_mar152014.exe a2_test2_mar152014.exe]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test3_mar152014.exe a2_test3_mar152014.exe]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test4_mar152014.exe a2_test4_mar152014.exe] Here are the same binaries compiled on matrix. Download them to your matrix with the wget command. Usage is wget --no-check-certificate address_of_thing_to_download. Note the --no-check-certificate flag. This is because Seneca's HTTPS certificate is out of date and we have to force wget to ignore that fact. Make sure to set the execute bit using chmod.* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test0_mar152014.out https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test0_mar152014.out]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test1_mar152014.out https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test1_mar152014.out]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test2_mar152014.out https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test2_mar152014.out]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test3_mar152014.out https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test3_mar152014.out]* [https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test4_mar152014.out https://scs.senecac.on.ca/~hasan.kamal-al-deen/public_resources/oop344/a2_test4_mar152014.out] Your assignment is ready for submission when your assignment produces behaviour that is consistent with the above binaries. However, to get 100%, ensure that your assignment meets all of the criteria in the spec/amended spec. == Test 0: A1 Test ==This test is a direct copy of the A1 tester. It is here to ensure that your display/edit functions work at a minimal level. While your A1 code will not affect your A2 mark, it will be more difficult for you to finish A2 if your A1 is in bad shape so this tester is present as a convenience to help you sort through that. == Test 1: CFrame Test ==* '''Frame Notes''':** Frame may overwrite '''but not exceed''' the top line of the screen** In turn, be sure that the move message overwrites the frame itself on the top line if the frame is currently occupying the top line while the message is displayed <br/>* '''Inner Frame Notes''':** Be sure that inner frames '''do not''' overwrite any part of their parent's frame if the parent has a frame = Spec Code Changes Amendments =
== cfg.h ==
* Instead of #defining NULL in cfg.h, you should '''#include &lt;cstdlib>''' at the top of cfg.h. eg:<br/>
== CFrame ==
=== Functions to be removed Updated ======= absrow, abscol ====Please make them '''public''' or '''protected'''. ==== width, height ====Please ensure that if the object is in fullscreen mode width returns the width of the screen and height returns the height of the screen. === Functions to be Removed ===
The following two functions should be removed from the specification completely. Let me be '''extra clear''': '''DO NOT PUT THEM IN YOUR CFrame HEADER, DO NOT CODE THEM, DO NOT USE THEM!'''
* CFrame::display
* CFrame::edit
 
=== Functions to be updated ===
The following functions should be made '''public''' or '''protected''':
* CFrame::absRow
* CFrame::absCol
== CField ==
** '''should not accept any parameters'''
** '''should return int''' (it already does)
 
=== Functions to be Removed ===
The following functions are a bit awkward. Remove them. See the '''Functions to be Added''' section for a better design.
* void** data()
* const void* pdata() const
* void display(int offset)
** Remove CField::display since it has no place as we use '''draw''' to print to screen. If you've written any code in the display function of CField, CLine, CLabel, CButton, then migrate it to the respective draw function. By the end of this fix, CField::display should '''no longer exist'''.
 
=== Functions to be Added ===
These functions act as setters/getters to CField's internal data member. Code them so that other classes can obtain or update the data member. Make these '''public'''.
* void* data() const
* void data(void*)
== CLine ==
=== Constructors ===
* Both constructors should '''cause memory to be allocated dynamically'''.<br/><br/>In the BTP300 spec, it mentions that the first constructor "passes the address of the data string directly to the CField constructor without allocating any further memory". Please '''ignore that remark''' and allocate memory dynamically anyway and '''copy''' the contents of the incoming data string '''into''' the memory that you are dynamically allocating.<br/><br/>For the rest of the spec, you can now '''assume''' that your CLine object will have dynamically allocated memory.<br/><br/> * Both constructors should accept a '''<u>bool*</u>''' and '''NOT''' a <u>bool</u> for '''insert mode'''. Updated descriptions follow:
==== Constructor 1 ====
...
= The Big Picture , Clarifications, Recommendations =
This assignment is about creating a basic console GUI system. It is meant to show the student how OOP can be used effectively to design a system. The basic setup for this system are the 6 classes iFrame, CFrame, CField, CLabel, CLine, CButton and the supplemental class CDialog provided already implemented as a part of the spec. Let's look at the role of each of these.
 
'''NOTE:''' In the assignment spec, any value in parentheses ( '''()''' ) is the '''default value''' of that particular parameter.
 
== Headers ==
In this assignment, you need to create a number of header files. You will most likely run into an issue regularly encountered by software developers which is multiple includes, chained includes, and cyclic includes (includes that end up including themselves).
 
To resolve and prevent these issues, use the following guidelines:
 
* Use header include protection. Typically this is done by using preprocessor directives to prevent a header from being included twice. For a header named '''MyHeader.h''', it looks like this:
<pre>
#ifndef __MYHEADER_H__
#define __MYHEADER_H__
 
...
// Header content
...
 
#endif
</pre>
* Try to include headers '''only''' from cpp files. While you should encounter few issues if you consistently apply the suggestion above, you can prevent even more potential problems by including headers only from cpp files.
== iFrame ==
** Width/height of the frame, including the frame/border
*** This should be the width/height of the screen if the frame is in fullscreen
 
=== Clarifications ===
==== draw ====
* The integer accepted by this function can be a value equivalent to C_NO_FRAME or any other value. If it is C_NO_FRAME, then no frame should be drawn '''even if the current widget was constructed bordered'''.
* Child classes should adjust their drawn content so as '''not to overlap the border''' if a border will be drawn.
* If a frame is in fullscreen mode (width < 0 or height < 0) then no border should be drawn.
 
==== row, col ====
The normal row and column functions (row, col) return the relative position of the widget to its parent where (0,0) indicates the most top left position on which anything can be drawn.
 
If a widget has a parent then the relative position is relative to the parent's position. If a widget has no parent <u>or if it's parent is fullscreen</u> then the position is relative to the screen in which case the position (0,0) is the most top left character on the screen.
 
==== absRow, absCol ====
The idea behind the abs functions is to return the position of the widget <u>on the screen</u>. To do this, these functions should start with the current widget's row or col value.
* If the widget has no parent or the parent is fullscreen, these functions return the same values as row/col.
* Otherwise, these functions should add their parent's '''abs'''row/'''abs'''col (note the '''abs''' version!)
** Finally, if the parent is bordered, 1 should be added to the resultant value.
 
==== Border ====
If the constructor receives a border character string that is NULL or is too short (less than 8 characters), the constructor should default to C_BORDER_CHARS.
 
==== hide ====
Hide's purpose is to hide the current object and restore whatever were the contents on the screen that it overwrote.
 
Hide accepts a CDirection value that indicates which direction that the current object is moving. Passing in C_STATIONARY indicates that the frame is not moving and that all hidden contents should be restored while any of the other values will restore only one row/column. The behaviours are:
 
* C_STATIONARY: will restore all of the screen contents hidden by the current object.
* C_MOVED_LEFT: will restore the right-most column.
* C_MOVED_RIGHT: will restore the left-most column.
* C_MOVED_UP: will restore the bottom row.
* C_MOVED_DOWN: will restore the top row.
 
This is an optimization. To explain this optimization, let's assume that hide has received the value C_MOVED_RIGHT. In this case, we only need to restore the left-most column of the contents since that column will be the only part of the contents that our object was hiding that will be shown since the rest will continue to be hidden underneath our object once it moves right by one column.
 
=== Recommendations ===
==== setLine ====
setLine is somewhat awkward in implementation. Its purpose is to fill a string that is the width of the frame with a first character, a fill character, and an end character. This however requires a string for output which typically must be dynamically allocated before use and then deallocated after use.
 
However, the same effect can be achieved through a similar function that instead of filling a string simply prints the same characters directly to console utilizing two output statements and a loop. This approach removes the need for an additional string. Obviously a function like this would not need to accept a char*.
 
You may use either of these implementations of setLine or use any third implementation that you prefer.
 
==== bool fullscreen() const ====
It may be a good idea to add a functin that returns whether a frame is currently in fullscreen mode or not. This is simple and will make code that cares about whether a frame is currently in fullscreen mode simpler to write. This function may be public or protected (not much use if it is private).
== CField ==
=== Contract ===
CField's contract consists of functions that could be used to query the capabilities of an object derived from CField and to perform the basic actions typically required from a window component. These functions are all '''pure virtual'''. The functions are as follows:
* void draw(int)
* int edit() '''[mentioned above]'''
* bool editable() const
* void set(const void*)
 
=== Responsibilities ===
CField is responsible for implementing the data setter/getter. As described above, it should implement the functions:
* void* data() const
* void data(void*)
These functions should do nothing more than get and set a private void* data member. Child classes should access the data member through the data getter and setter.
 
==== Child Class Data Storage ====
All child classes use some kind of dynamically allocated memory. CLine needs to store a pointer to a dynamically allocated string that it modifies. CLabel and CButton both need to store a pointer to a dynamically allocated string that they display. When implementing these child classes, please use the above data functions to store and retrieve the pointer. '''If you do not, you will crash the a2 tester during some tests!'''
 
== CLabel ==
A CLabel is an uneditable line of text to be displayed somewhere on the screen. It inherits from CField.
 
=== Clarifications ===
Please note that when drawing a CLabel, be sure '''not to exceed''' the parent's available width/height. If the label is to exceed the parent's width/height, be sure to '''stop drawing''' at the point at which the excess would occur.
* Eg, if we have an unframed label with the text "Hello I am a label" in a framed parent with a width of 5 and a height of 4 and the coordinates of the label are (x2,y1), it will '''incorrectly''' exceed as follows if no checking is done:
<pre>
/----\
| |
| Hello I am a label
\----/
</pre>
* The correct way to display the above would be:
<pre>
/----\
| |
| He|
\----/
</pre>
 
== CLine ==
A CLine is an editable line of text. It inherits from CField.
 
=== Recommendations ===
* CLine should use your display and edit functions that you created in A1.
* CLine should have at least two private int member that it passes to your edit function from A1 when editing is requested:
** Cursor position
** String offset
 
== CButton ==
A CButton is a text field with additional decoration displayed when the button is in its "edit" state. The edit state is exited when the user presses any key.
 
=== Recommendations ===
* When displaying the label value of a button, be sure to leave enough space for the prefix/suffix characters [ ]
* Eg, assume you have a framed button with the label value (ie the string stored in the button) "my Button":
** When draw is called, it would look like:
<pre>
/-----------\
| my Button |
\-----------/
</pre>
** When edit is called, it would look like:
<pre>
/-----------\
|[my Button]|
\-----------/
</pre>

Navigation menu