Changes

Jump to: navigation, search

Console UI Core Classes - OOP344 20121

47,758 bytes added, 13:52, 1 April 2012
CLineEdit
{{OOP344 Index | 20121}}
 
=Objective=
Your objective at this stage is to create series of core classes designed to interact with the user. These '''Core Classes''' then can be used in development of any interactive application.
* Use includes only in files in which the actual header file code is used.
* '''Avoid "just in case" includes.'''
=File Names=
Use the following rules to create filenames for your class.
*Each class MUST have its own header file and cpp file for implementation
*Use the class name for the name of the file but make sure it is all lowercase.
*:For example '''CFrame''' class should have '''cframe.h''' and '''cframe.cpp''' files for its implementation.
=Hierarchy=
<big><pre>
CFrame
|
|---CDialog
|
|
|---CField
|
|-------- CLabel
|
|
|-------- CButton
|
|
|-------- CLineEdit
| |
| |-------CValEdit
|
|-------- CText
|
|
|-------- CCheckMark
|
|
|-------- CCheckList
|
|
|-------- CMenuItem
|
|
|-------- CMenu
</pre></big>
=Student Resources=
===Help/Question===
*N/AIf anyone need help on this R0.2 please let me know. I can help you. MSN: thevakaran@live.com --[[User:Tvirutthasalam|Deva]] 20:56, 1 March 2012 (EST)
=Releases and Due Dates=
this tester is already in your trunk:<br />
[svn://zenit.senecac.on.ca/oop344/trunk/cioTesters/Test1Frame.cpp Test1Frame.cpp]
==R0.2==
Dialog and Labels
===To Do===
Complete the coding of CField, CLabel and CDialog and then test the project using Test2DialogAndLabel.cpp.<br/>
Workload estimate out of 100:
* CLabel 20%
* CDialog 80%
# First start with creating mockup classes (create the classes with empty methods that do nothing but compiles), you should have 6 files for headers and cpp code, and add them to trunk.
# considering the percentage of the workload, assign tasks to each team member.
# Each team member branch the trunk to start their work.
# communicate with your team members and keep updating your code with their additions, (remember that you have access to their branches)
# keep regular IRC meetings ( you can invite me to your meetings too for advice and help)
# When all done, merge back the additions to trunk.
# Do final test and tag it to R0.2
 
===Due Date===
Friday Mar 09, 23:59
 
===Tester===
*[svn://zenit.senecac.on.ca/oop344/trunk/cioTesters/Test2DialogAndLabel.cpp Test2DialogAndLabel.cpp ]
*: on OSX, you can emulate XTerm keyboard settings using [http://iterm.sourceforge.net/ iTerm]/[http://www.iterm2.com/#/section/home ITerm 2]
*: on Matrix, $~fardad.soleimanloo/t2 runs the demo for the test
====Makefile for test 2 on matrix====
*create a file in the root of cio call it '''"makefile"''' and copy the content below:
*: make sure the lines starting with c++ are tabbed once.
*: then at command line issue the command '''"make"''' to complie; the name of the executable will be '''prjexe'''
<big><pre>
t2: bconsole.o console.o cframe.o cfield.o cdialog.o clabel.o Test2DialogAndLabel.o
c++ bconsole.o console.o cframe.o cfield.o cdialog.o clabel.o \
Test2DialogAndLabel.o -lncurses -o prjexe
 
bconsole.o: bconsole.h bconsole.cpp
c++ -c bconsole.cpp
 
console.o: console.cpp console.h bconsole.h
c++ -c console.cpp
 
cframe.o: cframe.cpp cframe.h cuigh.h console.h bconsole.h
c++ -c cframe.cpp
 
cfield.o: cfield.cpp cfield.h cuigh.h cframe.h console.h bconsole.h
c++ -c cfield.cpp
 
cdialog.o: cdialog.cpp cdialog.h cfield.h cuigh.h cframe.h console.h bconsole.h
c++ -c cdialog.cpp
 
clabel.o: clabel.cpp clabel.h cfield.h cframe.h cuigh.h console.h bconsole.h
c++ -c clabel.cpp
 
Test2DialogAndLabel.o: Test2DialogAndLabel.cpp clabel.h cdialog.h cframe.h cuigh.h cfield.h console.h bconsole.h
c++ -c Test2DialogAndLabel.cpp
</pre></big>
==R0.3 - R0.7==
 
===To Do===
* 0.3 CLineEdit
* 0.4 CButton
* 0.5 CCheckMark
* 0.6 CMenuItem
* 0.7 CValEdit
 
===Due Date===
* Mon, Apr 2nd, 2012 11:59:59
 
===Tester===
* The testers are in [svn://zenit.senecac.on.ca/oop344/trunk/cioTesters Lecture Repository]
 
==CFrame==
The code for this class is provided. You must understand and use it to develop your core classes.
 
CFrame class is responsible to create a frame or structure in which all user interface classes contain themselves in. It can draw a border around it self or be border-less.
CFrame also, before displaying itself on the screen, will save the area it is about to cover, so it can redisplay them to hide itself.
 
CFrame is base of all objects in our user interface system.
 
<big><syntaxhighlight lang="cpp">
#pragma once
#include "cuigh.h"
 
class CFrame{
int _row; // relative row of left top corner to the container frame or the screen if _frame is null
int _col; // relative col of left top corner to the container frame or the screen if _frame is null
int _height;
int _width;
char _border[9]; // border characters
bool _visible; // is bordered or not
CFrame* _frame; // pointer to the container of the frame (the frame, surrounding this frame)
char* _covered; // pointer to the characters of the screen which are covered by this frame, when displayed
void capture(); // captures and saves the characters in the area covered by this frame when displayed and sets
// _covered to point to it
protected:
int absRow()const;
int absCol()const;
public:
CFrame(int Row=-1, int Col=-1, int Width=-1,int Height=-1,
bool Visible = false,
const char* Border=C_BORDER_CHARS,
CFrame* Frame = (CFrame*)0);
virtual void draw(int fn=C_FULL_FRAME);
virtual void move(CDirection dir);
virtual void move();
virtual void hide();
 
virtual ~CFrame();
/* setters and getters: */
 
bool fullscreen()const;
 
void visible(bool val);
bool visible()const;
 
void frame(CFrame* theContainer);
CFrame* frame();
void row(int val);
int row()const;
 
void col(int val);
int col()const;
 
void height(int val);
int height()const;
 
void width(int val);
int width()const;
 
void refresh();
};
</syntaxhighlight></big>
===Properties===
int _row, holds the relative coordinate of top row of this border with respect to its container.<br />
int _col, same as _row, but for _col. <br />
int _height, height of the entity. <br />
int _width, width of the entity. <br />
char _border[9], characters used to draw the border: <br />
: _border[0], left top
: _border[1], top side
: _border[2], right top
: _border[3], right side
: _border[4], right bottom
: _border[5], bottom side
: _border[6], bottom left
: _border[7], left side
bool _visible; Indicates if the border surrounding the entity is to be drawn or not. <br />
CFrame* _frame; holds the container (another CFrame) which has opened this one (owner or container of the current CFrame). '''_frame''' will be NULL if this CFrame does not have a container, in which case, it will be full screen and no matter what the values of row, col, width and height are, CFrame will be '''Full Screen''' (no border will be drawn)<br />
char* _covered; is a pointer to a character array that hold what was under this frame before being drawn. When the CFrame wants to hide itself, it simple copies the content of this array back on the screen on its own coordinates.
 
===Methods and Constructors===
====Private Methods====
<big><syntaxhighlight lang="cpp">
void capture();
</syntaxhighlight></big>
:if _covered pointer is not pointing to any allocated memory, it will call the iol_capture function to capture the area that is going to be covered by this frame and keeps its address in _covered.
 
====Protected Methods====
*int absRow()const; calculates the absolute row (relative to the left top corner of the screen) and returns it.
*:it returns the sum of '''row()''' of this border plus all the '''row()'''s of the '''_frame'''s
*int absCol()const; calculates the absolute column(relative to the left top corner of the screen) and returns it.
*:it returns the sum of '''col()''' of this border plus all the '''col()'''s of the '''_frame'''s
 
====Public Methods====
 
<big><syntaxhighlight lang="cpp">
CFrame(int Row=-1, int Col=-1, int Width=-1,int Height=-1,
bool Visible = false,
const char* Border=C_BORDER_CHARS,
CFrame* Frame = (CFrame*)0);
</syntaxhighlight></big>
:Sets the corresponding attributes to the incoming values in the argument list and set _covered to null
 
<big><syntaxhighlight lang="cpp">
virtual void draw(int fn=C_FULL_FRAME);
</syntaxhighlight></big>
* First it will '''capture()''' the coordinates it is supposed to cover
* If frame is '''fullscreen()''' then it just clears the screen and exits. <br />
 
Otherwise:<br />
*If the _visible flag is true, it will draw a box at _row and _col, with size of _width and _height using the _border characters and fills it with spaces. Otherwise it will just draw a box using spaces at the same location and same size.
 
 
<big><syntaxhighlight lang="cpp">
virtual void move(CDirection dir);
</syntaxhighlight></big>
First it will hide the Frame, then adjust the row and col to more to the "dir" direction and then draws the Frame back on screen.
<big><syntaxhighlight lang="cpp">
virtual void hide();
</syntaxhighlight></big>
using iol_restore()it restores the characters behind the Frame back on screen. It will also free the memory pointed by _covered;
 
<big><syntaxhighlight lang="cpp">
virtual ~CFrame();
</syntaxhighlight></big>
It will make sure allocated memories are freed.
 
<big><syntaxhighlight lang="cpp">
bool fullscreen()const;
void visible(bool val);
bool visible()const;
void frame(CFrame* theContainer);
CFrame* frame();
void row(int val);
int row()const;
void col(int val);
int col()const;
void height(int val);
int height()const;
void width(int val);
int width()const;
</syntaxhighlight></big>
 
These functions set and get the attributes of the CFrame.
 
==CField==
Note: The code for this class is provided. You must understand and use it to develop your core classes.
</syntaxhighlight></big>
Sets and Gets the _frame attribute of CFrame by calling CFrame::frame() method. Make sure to cast The CDialog to CFrame when setting and cast CFrame to CDialog when getting!
 
==CLabel==
A readonly Field that encapsulates console.display() function. (i.e it is responsible to display a short character string on the display) CLable CLabel although, by inheritance is Frame, but it is never '''bordered'''.
<big><syntaxhighlight lang="cpp">
#include "cfield.h"
void set(const void* str);
</syntaxhighlight></big>
if _length width() is greater than zero, it will copy the string pointed by str into the string pointed by _data upto _length width characters.if _length width() is zero,<br /> It will delete the memory pointed by _data and reallocates enough memory for str and copies the string pointed by str into the newly allocated memory pointed by _data. 
==CDialog==
Organizes CField objects on the screen, displays them and then lets the user edit them one by one.
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
The constructor, passes all the incoming arguments to the corresponding arguments of the apparent constructor '''CFrame'''.<br />Then it will set all called a attributes to their default values and then sets all the field pointers (_fld) to NULL.
It also sets all the dynamic (_dyn) flags to false.
<big><syntaxhighlight lang="cpp">
virtual ~CDialog();
</syntaxhighlight></big>
The destructor, will loop through all the field pointers and if the corresponding dynamic flag is true then it will delete the field pointed to by the field pointer.
===Methods===
</syntaxhighlight></big>
Returns the reference of the Field that was just being edited.
==CLineEdit==
'''ClineEdit''' encapsulates the console.edit() function of Console class.
<big><syntaxhighlight lang="cpp">
#include "cfield.h"
namespace cio{
class CLineEdit: public CField{
bool _dyn;
int _maxdatalen;
bool* _insertmode;
int _curpos;
int _offset;
public:
CLineEdit(char* Str, int Row, int Col, int Width,
int Maxdatalen, bool* Insertmode,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
CLineEdit(int Row, int Col, int Width,
int Maxdatalen, bool* Insertmode,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
~CLineEdit();
void draw(int Refresh = C_FULL_FRAME);
int edit();
bool editable()const;
 
void set(const void* Str);
};
}
</syntaxhighlight></big>
 
===Attributes===
<big><syntaxhighlight lang="cpp">
bool _dyn;
</syntaxhighlight></big>
_dyn is set to true if the object dynamically allocated memory and is responsible to free it at destruction time.
<big><syntaxhighlight lang="cpp">
int _maxdatalen;
</syntaxhighlight></big>
no comment!
<big><syntaxhighlight lang="cpp">
bool* _insertmode;
</syntaxhighlight></big>
points to the location of input method (insert or overstrike)
<big><syntaxhighlight lang="cpp">
int _curpos;
</syntaxhighlight></big>
current position of cursor
<big><syntaxhighlight lang="cpp">
int _offset;
</syntaxhighlight></big>
current offset
 
===Constructors / Destructor===
<big><syntaxhighlight lang="cpp">
CLineEdit(char* Str, int Row, int Col, int Width,
int Maxdatalen, int* Insertmode,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
 
LineEdit, sets the Field's _data to the value of str. If LineEdit is instantiated with this constructor then it will edit an external string provided by the caller function of LineEdit. LineEdit in this case is not creating any dynamic memory, therefore _dyn is set to false (therefore the destructor will not attempt to deallocate the memory pointed by _data).<br />
The location (row and col) and Bordered are directly passed to the parent (CField) and str is passed as data to the parent constructor. Unlike Label, LineEdit could have border or not so depending on this (Bordered being true or false) the Height is set to 3 or 1 respectfully. <br />
(hint: use '''? :''' operator to pass the proper Height value to CField's constructor)
 
<big><syntaxhighlight lang="cpp">
CLineEdit(int Row, int Col, int Width,
int Maxdatalen, int* Insertmode,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
Works exactly like the previous constructor with one difference; since no external data is passed to be edited here, this constructor must allocate enough dynamic memory to accommodate editing of '''Maxdatalen''' characters. Then make it an empty string and set Fields's _data to point to it. Make sure _dyn is set to true in this case, so the destructor knows that it has to deallocate the memory at the end.
<big><syntaxhighlight lang="cpp">
~CLineEdit();
</syntaxhighlight></big>
If '''_dyn''' is true, it will deallocate the character array pointed by Fields's '''_data'''
 
===Methods===
 
<big><syntaxhighlight lang="cpp">
void draw(int Refresh = C_FULL_FRAME);
</syntaxhighlight></big>
It will first call Frame's draw passing '''Refresh''' as an argument to it.<br />
Then it will make a direct call to console.display() to show the data kept in Field's '''_data'''.<br />
The values used for the arguments of console.display() are:
*str: address of string pointed by _data + the value of _offset
*row: absRow() (''add one if border is visible'')
*col: absCol() (''add one if border is visible'')
*len: width() (''reduce by two if border is visible''')
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
Makes a direct call to, and returns '''console.edit()'''.
For the coordinates and width arguments follow the same rules as the draw function.
For the rest of the arguments of console.edit(), use the attributes of '''CLineEdit'''.
<big><syntaxhighlight lang="cpp">
bool editable()const;
</syntaxhighlight></big>
Always return true;
 
<big><syntaxhighlight lang="cpp">
void set(const void* Str);
</syntaxhighlight></big>
Copies the characters pointed by '''Str''' into the memory pointed by Field's '''_data''' up to '''_maxdatalen''' characters.
 
==CButton==
Button is a child of CField.
It displays a small piece of text (usually one word or two) and accepts one key hit entry.
When in edit mode, to indicate the editing mode, it will surround the text with squared brackets.
<big><syntaxhighlight lang="cpp">
#pragma once
#include "cfield.h"
namespace cio{
class CButton: public CField{
 
public:
CButton(const char *Str, int Row, int Col,
bool Bordered = true,
const char* Border=C_BORDER_CHARS);
virtual ~CButton();
void draw(int rn=C_FULL_FRAME);
int edit();
bool editable()const;
void set(const void* str);
};
}
</syntaxhighlight></big>
 
===Attributes===
This class does not have any attributes of its own!
===Constructor / Destructor===
<big><syntaxhighlight lang="cpp">
CButton(const char *Str, int Row, int Col,
bool Bordered = true,
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
When creating a Button, allocate enough memory to hold the contents of the '''Str''' and set Field's _data to point to it. Then copy the content of '''Str''' into the newly allocated memory.<br />
Pass all the arguments directly to Field's constructor.<br />
For Field size (width and hight) do the following:<br />
For width: Set width to the length of '''Str''' + 2 (adding 2 for surrounding brackets) or if the Button is bordered set width to the length of '''Str''' + 4 (adding 2 for surrounding brackets and 2 for the borders).
For height: Set the height to 1 or if the Button is bordered, set the height to 3.
<big><syntaxhighlight lang="cpp">
virtual ~CButton();
</syntaxhighlight></big>
Deallocates the allocated memory pointed by Field's '''_data'''.
 
===Methods===
<big><syntaxhighlight lang="cpp">
void draw(int fn=C_FULL_FRAME);
</syntaxhighlight></big>
Draws the Button with border around it if it is Bordered. Note that there should be a space before and after of the text that will be used to surround the text with "[" and "]"<br />
hint:<br />
:*First calls Frame's draw(fn) (passing the fn argument to the parents draw)
 
:Use console.display() to display the Button's text (pointed by Field's _data)
:*If not bordered
:*:display the text at absRow() and absCol()
:*If bordered
:*:display the text at absRow()+1 and absCol()+2
 
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
First draw() the Button, then surround it by squared brackets, place the cursor under the first character of Button's text and wait for user entry.<br />
When user hits a key, if the key is ENTER_KEY or SPACE, return C_BUTTON_HIT (defined in cuigh.h) otherwise return the entered key.<br />
 
<big><syntaxhighlight lang="cpp">
void set(const void* str);
</syntaxhighlight></big>
First deallocated what is pointed by Field's _data.
Then allocate new memory to the size of content of str and copy the content into it and make
Field's _data point to it.
 
<big><syntaxhighlight lang="cpp">
bool editable()const;
</syntaxhighlight></big>
Always returns true
 
==CValEdit==
<big><syntaxhighlight lang="cpp">
#include "clineedit.h"
 
namespace cio{
class CValEdit: public CLineEdit{
void (*_help)(MessageStatus, CDialog&);
bool (*_validate)(const char*, CDialog&);
public:
CValEdit(char* Str, int Row, int Col, int Width,
int Maxdatalen, bool* Insertmode,
bool (*Validate)(const char* , CDialog&) = NO_VALDFUNC,
void (*Help)(MessageStatus, CDialog&) = NO_HELPFUNC,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
CValEdit(int Row, int Col, int Width,
int Maxdatalen, bool* Insertmode,
bool (*Validate)(const char* , CDialog&) = NO_VALDFUNC,
void (*Help)(MessageStatus, CDialog&) = NO_HELPFUNC,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
int edit();
};
}
</syntaxhighlight></big>
===Attributes===
<big><syntaxhighlight lang="cpp">
void (*_help)(MessageStatus, CDialog&);
bool (*_validate)(const char*, CDialog&);
</syntaxhighlight></big>
*_help, holds the address of the help logic (function) or NULL if there is no help function is assigned
*_validate, holds the address of the validation logic (function) or NULL if there is no validation function is assgned
 
===Constructors===
<big><syntaxhighlight lang="cpp">
CValEdit(char* Str, int Row, int Col, int Width,
int Maxdatalen, bool* Insertmode,
bool (*Validate)(const char* , CDialog&) = NO_VALDFUNC,
void (*Help)(MessageStatus, CDialog&) = NO_HELPFUNC,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
CValEdit(int Row, int Col, int Width,
int Maxdatalen, bool* Insertmode,
bool (*Validate)(const char* , CDialog&) = NO_VALDFUNC,
void (*Help)(MessageStatus, CDialog&) = NO_HELPFUNC,
bool Bordered = false,
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
These constructors pass all their arguments to corresponding arguments of CLineEdit constructor and then set '''_help''' and '''_validate''' attributes to the corresponding incoming arguments
 
===Method===
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
If the container() is NULL then this function works exactly like LineEdit::edit().<br />
If the container() is not NULL:
#If _help function exist, it calls the function passing MessageStatus::SetMessage and container()'s reference as arguments.
#Calls CLineEdit's edit()
#If validation function exists, and the terminating key of CLineEdit's edit() is a navigation key(see below)
#:It will call the validation function on the Field's _data, if the data is valid, it goes to next step, otherwise it will repeat calling CLineEdit's edit().
#After validation is done, if _help function exists, it will recall the help function using MessageStatus::ClearMessage and contianer()'s reference as arguments.
#It will return the terminating key
 
''Navigation keys are Up key, Down key, Tab key or Enter key.''<br />
''MessageStatus is enumerated in '''cuigh.h'''''
 
==CCheckMark==
<big><syntaxhighlight lang="cpp">
#include "cfield.h"
#include "clabel.h"
namespace cio{
class CCheckMark : public CField{
bool _flag;
bool _radio;
char _format[4];
CLabel _Label;
public:
CCheckMark(bool Checked,const char* Format, const char* Text, int Row, int Col, int Width, bool IsRadio = false);
CCheckMark(const CCheckMark& C);
void draw(int fn = C_NO_FRAME) ;
int edit();
bool editable()const;
void set(const void* flag);
bool checked()const;
void checked(bool val);
bool radio(); // addition for R0.6
void radio(bool isRadio); // addition for R0.6
operator bool(); // addtion for R0.6
operator char*(); // addition for R0.6
bool operator=(bool flag);
};
}
 
 
</syntaxhighlight></big>
===Attributes===
<big><syntaxhighlight lang="cpp">
int _flag;
bool _radio;
char _format[4];
CLabel _Label;
</syntaxhighlight></big>
*'''_flag''' holds the status of the Checkbox (0: unchecked or 1: checked ) and is pointed by _data pointer .
*'''_radio''' dictates the behavior of the Checkbox as a radio-button, or a check-mark.
*'''_format''' holds the characters, the Checkbox is drawn with (i.e. "[X]", "(O)", "<*>", etc...).
*'''_Label''' holds the Label attached to the this Checkbox
 
===Constructor / Destructor===
<big><syntaxhighlight lang="cpp">
CCheckMark(bool Checked,const char* Format, const char* Text, int Row, int Col, int Width, bool IsRadio = false);
</syntaxhighlight></big>
*Passes the ''Row, Col, Width and "1"'' to ''row, col, width and height'' arguments of CField and directly initializes _Label with ''Text, 0, 4, and (Width-4)'' for ''Str, Row, Col and Len'', arguments of CLabel's Constructor.<br />
 
*Sets the frame of _Label to its owner (Checkmark i.e. 'this');
*Sets _flag to Checked
*Sets _radio to IsRadio
*Copies Format to _format
*Sets _data to the address of _flag
<big><syntaxhighlight lang="cpp">
CCheckMark(const CCheckMark& C);
</syntaxhighlight></big>
*Passes incoming CCheckMark reference ("C") to CField's copy constructor, and directly initializes the _Label with the _Label of C
*Sets all the attributes of this object to the attributes of incoming CCheckMark reference ("C")
*Sets _data to the address of _flag
 
===Methods===
<big><syntaxhighlight lang="cpp">
void draw(int fn = C_NO_FRAME) ;
</syntaxhighlight></big>
Using Console methods:<br />
#displays the _format string at absRow() and absCol()
#if _flag is false, it will overwrite the second character printed above, with a space (removes the check mark on console)
#draw()s the _Label
#sets the position of the cursor at the checkmark (second character of printed _format)
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
#draw()s the checkmark
#gets a key
#: the key must be either SPACE or any non-printable character (all printable character are ignored)
#if the entered key is space
##if _radio is true, it will set the _flag to true
##if _radio is false, it will flip the value of _flag.
##draw()s the checkmark again
<big><syntaxhighlight lang="cpp">
bool editable()const;
</syntaxhighlight></big>
*Always return true;
<big><syntaxhighlight lang="cpp">
void set(const void* flag);
</syntaxhighlight></big>
*Casts the incoming flag pointer to an (bool*) and sets the content of '''_flag''' to where '''flag''' is pointing to.
<big><syntaxhighlight lang="cpp">
bool checked()const;
void checked(bool val);
</syntaxhighlight></big>
*These methods set and get _flag.
<big><syntaxhighlight lang="cpp">
bool radio(); // addition for R0.6
void radio(bool isRadio); // addition for R0.6
</syntaxhighlight></big>
* These to methods, get and set the '''_radio''' attribute.
<big><syntaxhighlight lang="cpp">
operator bool(); // addtion for R0.6
</syntaxhighlight></big>
* Overload the '''bool''' cast to return the value of '''_flag'''
<big><syntaxhighlight lang="cpp">
operator char*(); // addtion for R0.6
</syntaxhighlight></big>
* Overload the '''char*''' cast to return the value of '''_Label.data()'''
<big><syntaxhighlight lang="cpp">
bool operator=(bool flag);; // addtion for R0.6
</syntaxhighlight></big>
* Overload the operator= and set the _flag to flag
 
==CMenuItem==
CMenuItem provides a Label that is can be marked as selected by pressing the space bar.
<big><syntaxhighlight lang="cpp">
#include "clabel.h"
#include "cfield.h"
namespace cio{
class CMenuItem:public CField{
bool _selected;
char _format[3];
CLabel Label;
public:
CMenuItem(bool Selected,const char* Format, const char* Text, int Row, int Col, int Width);
CMenuItem(const CMenuItem &CM);
void draw(int fn = C_NO_FRAME) ;
int edit();
bool editable()const;
void set(const void* Selected);
bool selected()const;
void selected(bool val);
const char* Text();
};
}
</syntaxhighlight></big>
===Attributes===
<big><syntaxhighlight lang="cpp">
bool _selected;
</syntaxhighlight></big>
Holds the status of the MenuItem, being selected or not;
<big><syntaxhighlight lang="cpp">
char _format[3];
</syntaxhighlight></big>
Holds the surrounding characters with which a selected MenuItem is shown:<br />
If _format holds "[]", then a selected MenuItem will be like [MenuText]
<big><syntaxhighlight lang="cpp">
CLabel Label;
</syntaxhighlight></big>
Hold the Text of the MenuItem.
 
===Constructors / Destructor===
<big><syntaxhighlight lang="cpp">
CMenuItem(bool Selected,const char* Format, const char* Text, int Row, int Col, int Width);
</syntaxhighlight></big>
#Initializes the CField with Row, Col, Width and 1 for Height
#Initializes the Label with (Text, 0, 1 and Width-2) for (Str, Row, Col, and Len)
#Sets the attributes to corresponding arguments
#Sets CFields::_data to the address of _format
#Sets the Label's frame to this object.
<big><syntaxhighlight lang="cpp">
CMenuItem(const CMenuItem &CM);
</syntaxhighlight></big>
#Passes CM to CField and Initializes the Label with CM
#Sets the _selected to _selected of CM
#Sets CFields::_data to the address of _format
#Sets the Label's frame to this object.
 
===Methods===
<big><syntaxhighlight lang="cpp">
void draw(int fn = C_NO_FRAME) ;
</syntaxhighlight></big>
#Draws the Label with fn
#If _selected is true, it surrounds the Label Text the _format[0] and _format[1]
#If _selected if false, it surrounds the Label with SPACEs (overwrites _format[0] and _format[1])
#Positions the cursor at the first character of the Label
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
#draw()s the MenuItem
#gets a key
#: the key must be either SPACE or any non-printable character (all printable character are ignored)
#if the entered key is space
##it will set the _selected to true
##draw()s the MenuItem again
#returns the key
<big><syntaxhighlight lang="cpp">
bool editable()const;
</syntaxhighlight></big>
Returns true.
<big><syntaxhighlight lang="cpp">
void set(const void* Selected);
</syntaxhighlight></big>
Sets _selected to where Selected is pointing to
<big><syntaxhighlight lang="cpp">
bool selected()const;
</syntaxhighlight></big>
Returns Selected
<big><syntaxhighlight lang="cpp">
void selected(bool val);
</syntaxhighlight></big>
Sets _selected to val
<big><syntaxhighlight lang="cpp">
const char* Text();
</syntaxhighlight></big>
Returns the text of Label
 
==CText==
CText is a CField to edit a multiline text.<br />
To do this, it will use the [svn://zenit.senecac.on.ca/oop344/trunk/textClass Text class] to convert a character string containing a text into a (simulated) two dimensional array.
<big><syntaxhighlight lang="cpp">
 
#pragma once
#include "cfield.h"
#include "text.h"
 
using namespace cio;
 
 
class CText:public CField{
Text _T;
bool _displayOnly;
int _curpos;
bool* _insertmode;
int _offset;
int _lcurpos;
int _loffset;
public:
CText(int Row, int Col, int Width, int Height, bool* Insertmode,
bool displayOnly = false, const char* Border=C_BORDER_CHARS);
CText(const char* Str, int Row, int Col, int Width, int Height,
bool* Insertmode, bool displayOnly = false,
const char* Border=C_BORDER_CHARS);
void draw(int fn = C_FULL_FRAME);
 
void set(const void *Str);
void *data()const;
 
int edit();
bool editable()const;
bool displayOnly();
void displayOnly(bool val);
};
 
 
</syntaxhighlight></big>
===Attributes===
<big><syntaxhighlight lang="cpp">
Text _T;
</syntaxhighlight></big>
An instance of the [svn://zenit.senecac.on.ca/oop344/trunk/textClass Text class]
<big><syntaxhighlight lang="cpp">
bool _displayOnly;
</syntaxhighlight></big>
If it is set to true, then the Text can only be viewed but not edited; All scrolling, page UP, DOWN, etc... is enabled but any attempt to change the text, is ignored quietly. This attribute is passed to ReadOnly argument of Console::edit(......).
<big><syntaxhighlight lang="cpp">
int _curpos;
bool* _insertmode;
int _offset;
</syntaxhighlight></big>
Values used by Console::edit(......)
<big><syntaxhighlight lang="cpp">
int _lcurpos;
int _loffset;
</syntaxhighlight></big>
Vertical cursor position in text.
Vertical offset of the text relative to the frame of CText. This value indicates, how many line are hidden above the frame when text is scrolled down.
 
===Constructors/Destructor===
<big><syntaxhighlight lang="cpp">
CText(int Row, int Col, int Width, int Height, bool* Insertmode,
bool displayOnly = false, const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
Initialized the CField with the corresponding incoming arguments and then sets all the attributes to their corresponding arguments.
<big><syntaxhighlight lang="cpp">
CText(const char* Str, int Row, int Col, int Width, int Height,
bool* Insertmode, bool displayOnly = false,
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
Works exactly like the previous constructor but it also '''set()'''s the class to '''Str'''.
 
===Methods===
'''Under Construction'''
<big><syntaxhighlight lang="cpp">
void draw(int fn = C_FULL_FRAME);
</syntaxhighlight></big>
First it will draw the CField using the fn arguement.<br />
Then it will use console.display to display all the Lines of _T that are positioned inside the frame of the CText. (i.e. from _loffset to _loffset + Height() - 2).<br />
Two Important things to note:
# you should note that '''Lines''' are '''console.display()'''ed from _offset character. (i.e. &_T[theLineNumber][_offset]).
# Also you should '''console.display()''' the Lines only if the length of the line is more than the _offset(i.e. _T[theLineNumver].strlen() > _offset)
<big><syntaxhighlight lang="cpp">
void set(const void *Str);
</syntaxhighlight></big>
Sets the '''_T''' attribute to the incoming string.
<big><syntaxhighlight lang="cpp">
void *data()const;
</syntaxhighlight></big>
Exports the string out of _T and returns its address after casting it to '''void*'''.
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
# Create local variables to hold the following attributes in case ESCAPE is hit to undo:
## _T
## _curpos
## _offset
## _lcurpos
## _loffset
# Create the usual '''while(!done)''' structure for interfacing with user
# '''draw()''' the text
# '''console.edit()''' the Line at where vertical cursor is after _loffset.
## use absRow() and _lcurpos to calculate the row on which the editing should happen
## use absCol() to calculate the column on which editing to happen.
## use width() to calculate the fieldLen for '''console.edit()'''
## use the '''size()''' of the current '''Line''' in '''_T''' to determine the maximum data length of the string to '''console.edit()'''
## the isTextEditor is always true
## the ReadOnly depends on the value of '''_displayOnly'''
<big><syntaxhighlight lang="cpp">
bool editable()const;
</syntaxhighlight></big>
Always return true;
<big><syntaxhighlight lang="cpp">
bool displayOnly();
void displayOnly(bool val);
</syntaxhighlight></big>
These methods Get and Set the '''_displayOnly''' attribute.
 
===The Text Helper Class===
[svn://zenit.senecac.on.ca/oop344/trunk/textClass Text class]
==CCheckList==
<big><syntaxhighlight lang="cpp">
#pragma once
#include "cfield.h"
#include "ccheckmark.h"
namespace cio{
 
class CCheckList : public CField{
CCheckMark* _checkmarks[32];
bool _radio;
char _format[4];
unsigned int _cnt;
unsigned int _flags;
unsigned int _cur;
public:
CCheckList(const char* Format, int Row, int Col, int Width,bool radio, bool Bordered = true,const char* Border=C_BORDER_CHARS);
~CCheckList(void);
CCheckList& add(const char* Text, bool selected = false);
CCheckList& operator<<(const char* Text);
void draw(int fn = C_FULL_FRAME);
int edit();
void* data();
void set(const void* data);
CCheckMark& operator[](unsigned int index);
bool editable()const;
bool radio()const;
void radio(bool val);
unsigned int flags()const;
void flags(unsigned int theFlags);
int selectedIndex()const;
void selectedIndex(int index);
unsigned int length();
};
}
</syntaxhighlight></big>
===Attributes===
<big><syntaxhighlight lang="cpp">
CCheckMark* _checkmarks[32];
</syntaxhighlight></big>
An array of 32 CCheckmark pointers that will point to _cnt dynamically allocated CCheckMarks.
<big><syntaxhighlight lang="cpp">
bool _radio;
</syntaxhighlight></big>
Holds the behaviour of the CCheckList to be like a Radio Button List or Check Mark List
<big><syntaxhighlight lang="cpp">
char _format[4];
</syntaxhighlight></big>
Holds the format with which a check mark is displayed (i.e. "[X]" or "(o)" etc...)
<big><syntaxhighlight lang="cpp">
unsigned int _cnt;
</syntaxhighlight></big>
Holds the number of CCheckMarks currently in CCheckList
<big><syntaxhighlight lang="cpp">
unsigned int _flags;
</syntaxhighlight></big>
Always holds the bit pattern corresponding to the status of the CCheckMarks in the List. Note that bit 0 (right most) will correspond to the first CCheckMark.
<big><syntaxhighlight lang="cpp">
unsigned int _cur;
</syntaxhighlight></big>
Holds the index of the CCheckMark in the "_checkmarks" array which is currently being edited. (focused)
 
===Constructors/Destructor===
<big><syntaxhighlight lang="cpp">
CCheckList(const char* Format, int Row, int Col, int Width,bool radio, bool Bordered = true,const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
Passes corresponding values to the Base class (CField) then
#sets the _data attribute to the address of _flags
#copies '''Format''' and '''radio''' into '''_format''' and '''_radio''' respectively
#sets '''_cnt, _cur''' and '''_flags''' to zero
<big><syntaxhighlight lang="cpp">
~CCheckList(void);
</syntaxhighlight></big>
Goes through '''_checkmarks''' up to '''_cnt''' and if deletes them one by one.
 
===Methods===
<big><syntaxhighlight lang="cpp">
CCheckList& add(const char* Text, bool selected = false);
</syntaxhighlight></big>
* Only adds a new CCheckMark if '''_cnt''' does not exceed the maximum amount of '''_checkmarks''' (32)
* Creates a new CCheckMark with the row being '''_cnt'''+1, the height being 1 and the length being the length of '''Text'''+4
* Sets the newly created CCheckMarks' frame to '''this'''
* Automatically expands the width of the CCheckList if the width of the newly created CCheckMark is bigger than the current width of the CCheckList
* Sets the height of the CCheckList to '''_cnt'''+3
* Updates the bit pattern of '''_flags'''
* Increments '''_cnt'''
<big><syntaxhighlight lang="cpp">
CCheckList& operator<<(const char* Text);
</syntaxhighlight></big>
returns add(Text).
<big><syntaxhighlight lang="cpp">
void draw(int fn = C_FULL_FRAME);
</syntaxhighlight></big>
Draws the frame and then draws all the '''_checkmarks''', making sure the cursor is standing under the first checked checkmark.
<big><syntaxhighlight lang="cpp">
int edit();
</syntaxhighlight></big>
*Draws the '''CCheckList''' then starts editing the '''_checkmarks''' form '''_cur''' and according to the return key of CCheckMark::edit():
**If Down or Right key is hit it goes to the next '''_checkmark''', if '''_cur''' is the last one, then it exits the edit, returning the last key entered.
**UP and Left key works in opposite direction of Down and Right, if '''_cur''' is already zero, then it exits the edit, returning the last key entered.
**If Space is hit, then if '''_radio''' is true, it will uncheck all the '''_checkmarks''' other than the '''_cur'''rent one.
<big><syntaxhighlight lang="cpp">
void* data();
</syntaxhighlight></big>
returns the bit pattern held in _flags. <br />
''make sure _flags are updated to the status of the '''_checkmarks'''''
<big><syntaxhighlight lang="cpp">
void set(const void* data);
</syntaxhighlight></big>
sets the '''_flags''' and updates the '''_checkmarks''' to the bitpattern of '''_flags'''
<big><syntaxhighlight lang="cpp">
CCheckMark& operator[](unsigned int index);
</syntaxhighlight></big>
returns the CCheckMark corresponding the '''index''' value.
<big><syntaxhighlight lang="cpp">
bool editable()const;
</syntaxhighlight></big>
always returns true;
<big><syntaxhighlight lang="cpp">
bool radio()const;
</syntaxhighlight></big>
returns '''_radio'''
<big><syntaxhighlight lang="cpp">
void radio(bool val);
</syntaxhighlight></big>
sets the _radio and updates all _checkMarks radio value.
<big><syntaxhighlight lang="cpp">
unsigned int flags()const;
</syntaxhighlight></big>
returns the '''_flags''' attribute
<big><syntaxhighlight lang="cpp">
void flags(unsigned int theFlags);
</syntaxhighlight></big>
sets the '''_flags''' attribute
<big><syntaxhighlight lang="cpp">
int selectedIndex()const;
</syntaxhighlight></big>
returns the index of the first CCheckMark that is selected, and -1 if nothing is selected.
<big><syntaxhighlight lang="cpp">
void selectedIndex(int index);
</syntaxhighlight></big>
sets the selectedindex. (only un-selects the rest if object is in radio mode)<br />
if index is less than zero, then it will un-selects all
<big><syntaxhighlight lang="cpp">
unsigned int length();
</syntaxhighlight></big>
returns '''_cnt'''
 
==CMenu and MNode==
CMenu is a linked list of MNodes. Providing menu selection for the user in two formats; Drop Down List, or a simple menu.
 
<big><syntaxhighlight lang="cpp">
#ifndef __CIO__CMENU_H__
#define __CIO__CMENU_H__
#include "cuigh.h"
#include "cfield.h"
#include "cmenuitem.h"
#include "cbutton.h"
namespace cio{
class Cmenu;
 
class MNode{
CMenuItem* _item;
MNode* _next;
MNode* _prev;
unsigned int _index;
MNode(CMenuItem* item,unsigned int index, MNode* prev, MNode* next = ((MNode*)0));
~MNode(void);
friend class CMenu;
};
 
class CMenu : public CField{
MNode* _first;
MNode* _head;
MNode* _tail;
MNode* _cur;
char _format[3];
unsigned int _cnt;
int _selectedIndex;
bool _dropdown;
bool _dropped;
bool goNext();
bool goPrev();
CButton _Title;
public:
static const bool Select;
CMenu(const char* Title, const char* Format, int Row, int Col,
int Width, int Height,bool dropdown,
const char* Border=C_BORDER_CHARS);
CMenu& add(const char* Text, bool selected = false);
CMenu& operator<<(const char* Text);
CMenu& operator<<(bool select);
void draw(int fn = C_FULL_FRAME);
int edit();
void set(const void* data);
int selectedIndex() const;
int selectedIndex(int index);
const char* selectedText();
bool editable()const;
~CMenu(void);
};
extern const bool Select;
}
 
#endif
</syntaxhighlight></big>
===MNode===
MNode holds to main about an Item in the menut:
# The CMenuItem object
# The index of this Item
MNode is a fully private class and is only accessible by CMenu.
====Attributes====
<big><syntaxhighlight lang="cpp">
CMenuItem* _item;
</syntaxhighlight></big>
Holds the address of a dynamically allocated CMenuItem
<big><syntaxhighlight lang="cpp">
unsigned int _index;
</syntaxhighlight></big>
Holds the index (sequence -1) number of the '''CMenuItem''' in the '''CMenu'''.
<big><syntaxhighlight lang="cpp">
MNode* _next;
MNode* _prev;
</syntaxhighlight></big>
Standard next and previous pointer for a linked list node.
 
====Constructor/Destructor====
<big><syntaxhighlight lang="cpp">
MNode(CMenuItem* item,unsigned int index, MNode* prev, MNode* next = ((MNode*)0));
</syntaxhighlight></big>
Sets the corresponding attributes to the values of the arguments.
<big><syntaxhighlight lang="cpp">
~MNode(void);
</syntaxhighlight></big>
deletes the '''_item'''
 
===CMenu===
CMenu is a linked list of MNodes and also contains a CButton for a Title (only used on if in '''_dropdown''' mode). <br />
Assuming that a CMenu is created with a title as "FILE" and menu-items as "Save, Load, Print, Quit":
*When in '''_dropdown''' mode:
When drawing, Only the _Title(CButton) is drawn (and not the menu itself)
<big><pre>
FILE
</pre></big>
When edited (in '''_dropdown''' mode) the CButton gets activated and if it is hit, then the Menu will be dropped down (drawn) under the CButton and user can browse through the options and select one of them. selecting the option in this case will close the menu and CButton gets activated again:<br />
when active, CMenu looks like this:
<big><pre>
[FILE]
</pre></big>
User hits enter: (since nothing is selected all menu items are unselected)
<big><pre>
FILE
/-------\
| Save |
| Load |
| Print |
| Quit |
\-------/
</pre></big>
Now the cursor is standing under '''S'''ave.
User hits down arrow twice to select '''P'''rint and then hits Space:
<big><pre>
[FILE]
</pre></big>
The Print is selected and The menu is closed and FILE is active again.
If the user hits Enter again:
<big><pre>
FILE
/-------\
| Save |
| Load |
|[Print]|
| Quit |
\-------/
</pre></big>
We will see the Print is selected and the cursor in under P.
If user hits Enter instead of space, the selection wont change and whatever was selected before will remain the same:
<big><pre>
[FILE]
</pre></big>
User hits navigation keys and moves out of the CMenu Field.
''Note that if '''left''' or '''right''' navigation keys are hit when the title is active, then they are translated to '''up''' or '''down''' respectively.
*When NOT in '''_dropdown''' mode:
*:The CButton will not be displayed at all, and when user starts to edit, he enters the menu browsing the items and if he gets to the end of the menu, the control goes to the next field in the dialog. If user goes up and passes the first them, then the control will go to the previous field in the dalog.
<big><pre>
/-------\
| Save |
| Load |
|[Print]|
| Quit |
\-------/
</pre></big>
''Note that if the number of menu items are more than the space provided by the CField's frame, then the menu items should scroll up and down to accommodate the selection''
====Attributes====
<big><syntaxhighlight lang = "cpp">
MNode* _first;
</syntaxhighlight></big>
points to the first CMenuItem visible on the menu.
<big><syntaxhighlight lang = "cpp">
MNode* _head;
MNode* _tail;
MNode* _cur;
</syntaxhighlight></big>
standard Link list pointers
<big><syntaxhighlight lang = "cpp">
char _format[3];
</syntaxhighlight></big>
The two characters used to surround the selected menu item
<big><syntaxhighlight lang = "cpp">
unsigned int _cnt;
</syntaxhighlight></big>
The number of CMenuItems in CMenu
<big><syntaxhighlight lang = "cpp">
int _selectedIndex;
</syntaxhighlight></big>
The index of the selected CMenuItem (saved in MNode::index), if there is no selected menu, then this value is -1.
<big><syntaxhighlight lang = "cpp">
bool _dropdown;
</syntaxhighlight></big>
True if the Menu is a Drop Down Menu.
<big><syntaxhighlight lang = "cpp">
bool _dropped;
</syntaxhighlight></big>
Flag used to hold the status of a Drop Down Menu, (_dropped or not)
<big><syntaxhighlight lang = "cpp">
bool goNext();
bool goPrev();
</syntaxhighlight></big>
standard gonext() and goprev() in linked lists
<big><syntaxhighlight lang = "cpp">
CButton _Title;
</syntaxhighlight></big>
CButton holding the Title of this menu
====Constructor/Destructor====
<big><syntaxhighlight lang = "cpp">
CMenu(const char* Title, const char* Format, int Row, int Col,
int Width, int Height,bool dropdown,
const char* Border=C_BORDER_CHARS);
</syntaxhighlight></big>
#Initializes CField as follows:
#* Row: Passes Row, if this menu is not a dropdown, otherwise it will pass Row+1.
#* Col, Width, Height are passed directly
#* Data: a void null pointer is passed for data
#* Bordered: since CMenu is always bordered, true is passed here
#* Border is directly passed.
#Initializes _Title (the CButton) as follows:
#* Str, Title is passed here
#* Row, -1
#* Col, 1
#* Bordered, since the title of the dorpdown is alway NOT bordered, then false is passed here.
#Constructor Settings:
#* Link list attributes are set as standard linked list contructor
#* Format is copied into _format
#* _cnt is set to zero
#* _selectedIndex is set to -1
#* _data is set to address of _selectedIndex
#* _dropdown is set to dropdown
#* _dropped is set to false
#* _Title's frame is set to the CMenu object (this)
<big><syntaxhighlight lang = "cpp">
~CMenu();
</syntaxhighlight></big>
Standard Linked list destructor
 
====Methods====
<big><syntaxhighlight lang = "cpp">
CMenu& add(const char* Text, bool selected = false);
</syntaxhighlight></big>
Standard append for a linked list:
#creates an MNode with
#* a new CMenutItem with
#*:selected, _format, Text for first three arguments
#*:1, 1, and (width of the menu) -2, for Row col and width
#* the rest are what is needed for a standard append procedure for a linked list
#appends the new MNode to the end of the list
#if the new added CMenuItem is selected, it will update the selected index
'''''Note that if the added CMenuItem is the first CMenuItem in the list, then the _first pointer should be pointing to it'''''
<big><syntaxhighlight lang = "cpp">
CMenu& operator<<(const char* Text);
</syntaxhighlight></big>
returns add(Text)
<big><syntaxhighlight lang = "cpp">
CMenu& operator<<(bool select);
</syntaxhighlight></big>
if select is true, it will select the last CMenuItem added to the CMenu
<big><syntaxhighlight lang = "cpp">
void draw(int fn = C_FULL_FRAME);
</syntaxhighlight></big>
#if this is a '''_dropdown''', then it will draw the _Title
#: and then if '''_dropped''' is true, it will draw the CField and then draw the CMenuItems starting form what _first is pointing to, up to (CField's hieght -2) times.
#if this not a '''_dropdown''' then the _Title will never be drawn and the CMenuItems should be drawn as above.
<big><syntaxhighlight lang = "cpp">
int edit();
</syntaxhighlight></big>
Edits the menu the way it is explains in [[#CMenu|CMenu]] description.<br />
If it is too confusing, this [[CMenu pseudo code - OOP344 20113|pseudo code]] may help.
<big><syntaxhighlight lang = "cpp">
void set(const void* data);
</syntaxhighlight></big>
Sets the selected index to the integer pointed by data;
<big><syntaxhighlight lang = "cpp">
int selectedIndex() const;
</syntaxhighlight></big>
returns the selected index or -1 if nothing is selected
<big><syntaxhighlight lang = "cpp">
int selectedIndex(int index);
</syntaxhighlight></big>
sets the selected index.
<big><syntaxhighlight lang = "cpp">
const char* selectedText();
</syntaxhighlight></big>
returns the text of the selected menu, if nothing is selected, and empty string is returned.
<big><syntaxhighlight lang = "cpp">
bool editable()const;
</syntaxhighlight></big>
returns true if '''_cnt''' is greater than zero
1
edit

Navigation menu