Add linked element to scrollbars

The linked element will be updated dynamically as the scrollbar's value changes.
Also: Added long-missing hasControl() method to cDialog
This commit is contained in:
2015-10-02 22:08:16 -04:00
parent f7daba4ead
commit 4aea031914
11 changed files with 72 additions and 4 deletions

View File

@@ -250,6 +250,7 @@
<xs:attribute name="initial" type="xs:integer" default="0"/>
<xs:attribute name="page-size" type="xs:integer" default="10"/>
<xs:attribute name="vertical" type="bool" default="true"/>
<xs:attribute name="link" type="xs:token"/>
<xs:attributeGroup ref="rect-size"/>
</xs:complexType>
</xs:element>
@@ -326,5 +327,9 @@
<xs:selector xpath='*'/>
<xs:field xpath='@name'/>
</xs:unique>
<xs:keyref name="sliderLink" refer="uniqueID">
<xs:selector xpath="slider"/>
<xs:field xpath="@link"/>
</xs:keyref>
</xs:element>
</xs:schema>

View File

@@ -691,6 +691,10 @@ bool cLedGroup::isClickable(){
return true;
}
bool cLedGroup::hasChild(std::string id) {
return choices.find(id) != choices.end();
}
cLed& cLedGroup::getChild(std::string id){
ledIter iter = choices.find(id);
if(iter == choices.end()) throw std::invalid_argument(id + " does not exist in the ledgroup.");

View File

@@ -215,11 +215,12 @@ public:
bool isClickable();
bool handleClick(location where);
virtual ~cLedGroup();
/// Get one of the LED's in this group.
/// Get one of the LEDs in this group.
/// @param id The unique key of the choice.
/// @return A reference to the LED object.
/// @throw std::invalid_argument if the choice does not exist in the group.
cLed& getChild(std::string id);
bool hasChild(std::string id);
/// Set the currently selected LED in this group.
/// @param id The unique key of the choice.
/// @throw std::invalid_argument if the choice does not exist in the group.

View File

@@ -286,6 +286,10 @@ public:
/// @param t The type of the control.
/// @param p The parent dialog.
cContainer(eControlType t, cDialog& p) : cControl(t, p) {}
/// Check if a control exists with a given ID.
/// @param id The unique key of the control.
/// @return true if it exists.
virtual bool hasChild(std::string id) = 0;
/// Get a reference to a child control.
/// @param id The unique key of the control.
/// @throw std::invalid_argument if the control does not exist.

View File

@@ -912,14 +912,29 @@ cControl& cDialog::getControl(std::string id) {
iter = controls.begin();
while(iter != controls.end()){
if(iter->second->isContainer()){
try{
cContainer* tmp = (cContainer*) (iter->second);
cContainer* tmp = dynamic_cast<cContainer*>(iter->second);
if(tmp->hasChild(id))
return tmp->getChild(id);
}catch(std::invalid_argument) {}
}
iter++;
}
throw std::invalid_argument(id + " does not exist in dialog " + fname);
}
bool cDialog::hasControl(std::string id) {
ctrlIter iter = controls.find(id);
if(iter != controls.end()) return true;
iter = controls.begin();
while(iter != controls.end()){
if(iter->second->isContainer()){
cContainer* tmp = dynamic_cast<cContainer*>(iter->second);
if(tmp->hasChild(id))
return true;
}
iter++;
}
return false;
}
const char*const xBadVal::CONTENT = "<content>";

View File

@@ -152,6 +152,10 @@ public:
/// Determine how the dialog exited.
/// @return the argument passed to toast() when the dialog was closed
bool accepted();
/// Check if a control exists with a given ID.
/// @param id The unique key of the control.
/// @return true if it exists.
bool hasControl(std::string id);
/// Get a reference to a control.
/// @param id The unique key of the control.
/// @throw std::invalid_argument if the control does not exist.

View File

@@ -42,6 +42,10 @@ void cScrollbar::setVertical(bool is) {
vert = is;
}
void cScrollbar::setLink(std::string l) {
link = l;
}
long cScrollbar::getPosition() {
return pos;
}
@@ -58,6 +62,10 @@ bool cScrollbar::isVertical() {
return vert;
}
std::string cScrollbar::getLink() {
return link;
}
void cScrollbar::attachClickHandler(click_callback_t f) throw(xHandlerNotSupported) {
onClick = f;
}
@@ -136,6 +144,8 @@ bool cScrollbar::handleClick(location where) {
if(pressedPart != PART_THUMB && !frame.contains(e.mouseMove.x, e.mouseMove.y)) depressed = false;
}
pos = minmax(0,max,pos);
if(parent && !link.empty())
parent->getControl(link).setTextToNum(pos);
thumbPos = bar_start;
thumbPos += btn_size + pos * (bar_size - btn_size) / max;
thumbPos = minmax(mousePos,bar_end - btn_size * 2,thumbPos);
@@ -305,6 +315,8 @@ std::string cScrollbar::parse(ticpp::Element& who, std::string fname) {
if(val == "true") vert = true;
else vert = false;
foundVertical = true;
}else if(name == "link"){
attr->GetValue(&link);
}else if(name == "initial"){
attr->GetValue(&pos);
}else if(name == "max"){
@@ -345,6 +357,8 @@ std::string cScrollbar::parse(ticpp::Element& who, std::string fname) {
else frame.height() = thickness;
}
setBounds(frame);
if(parent->hasControl(link))
parent->getControl(link).setTextToNum(pos);
return id;
}

View File

@@ -21,6 +21,7 @@
/// Alternatively, it can be used as a slider control.
class cScrollbar : public cControl {
int pos, max, pgsz;
std::string link;
// Note: For horizontal scrollbars, up is left and down is right.
enum {
PART_UP,
@@ -70,6 +71,12 @@ public:
/// Check whether the scrollbar is vertical.
/// @return True if it is vertical, false if it is horizontal.
bool isVertical();
/// Get the linked control.
///
/// A linked control is one that always reflect's the scrollbar's current
/// value as its text.
/// @return The ID of the linked control, or an empty string if none.
std::string getLink();
/// Set the scrollbar thumb's current position.
/// @param to The new position.
void setPosition(long to);
@@ -85,6 +92,12 @@ public:
/// Set whether the scrollbar is vertical.
/// @param is True to make it vertical, false to make it horizontal.
void setVertical(bool is);
/// Set the linked control.
///
/// A linked control is one that always reflect's the scrollbar's current
/// value as its text.
/// @param l The ID of the linked control, or an empty string if none.
void setLink(std::string l);
void draw();
cScrollbar& operator=(cScrollbar& other) = delete;
cScrollbar(cScrollbar& other) = delete;

View File

@@ -126,6 +126,10 @@ void cScrollPane::setPosition(long to) {
scroll.setPosition(to);
}
bool cScrollPane::hasChild(std::string id) {
return contents.find(id) != contents.end();
}
cControl& cScrollPane::getChild(std::string id) {
auto iter = contents.find(id);
if(iter == contents.end()) throw std::invalid_argument(id + " does not exist in the scroll pane.");

View File

@@ -33,6 +33,7 @@ public:
short getFormat(eFormat prop) throw(xUnsupportedProp);
void setColour(sf::Color clr) throw(xUnsupportedProp);
sf::Color getColour() throw(xUnsupportedProp);
bool hasChild(std::string id);
cControl& getChild(std::string id);
storage_t store();
void restore(storage_t to);

View File

@@ -220,6 +220,9 @@ from 0 to `max` inclusive. Defaults to 0.
* `max` - Specifies the maximum value of the slider. This attribute is required.
* `page-size` - Specifies how much the slider should scroll when clicking
between the thumb and the arrow button. Defaults to 10.
* `link` - If present, the control with this ID will have its text set
to the slider's value whenever it changes. It works best if the referenced
control appears before the slider control in the definition.
The `<stack>` tag
-----------------