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

View File

@@ -691,6 +691,10 @@ bool cLedGroup::isClickable(){
return true; return true;
} }
bool cLedGroup::hasChild(std::string id) {
return choices.find(id) != choices.end();
}
cLed& cLedGroup::getChild(std::string id){ cLed& cLedGroup::getChild(std::string id){
ledIter iter = choices.find(id); ledIter iter = choices.find(id);
if(iter == choices.end()) throw std::invalid_argument(id + " does not exist in the ledgroup."); 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 isClickable();
bool handleClick(location where); bool handleClick(location where);
virtual ~cLedGroup(); 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. /// @param id The unique key of the choice.
/// @return A reference to the LED object. /// @return A reference to the LED object.
/// @throw std::invalid_argument if the choice does not exist in the group. /// @throw std::invalid_argument if the choice does not exist in the group.
cLed& getChild(std::string id); cLed& getChild(std::string id);
bool hasChild(std::string id);
/// Set the currently selected LED in this group. /// Set the currently selected LED in this group.
/// @param id The unique key of the choice. /// @param id The unique key of the choice.
/// @throw std::invalid_argument if the choice does not exist in the group. /// @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 t The type of the control.
/// @param p The parent dialog. /// @param p The parent dialog.
cContainer(eControlType t, cDialog& p) : cControl(t, p) {} 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. /// Get a reference to a child control.
/// @param id The unique key of the control. /// @param id The unique key of the control.
/// @throw std::invalid_argument if the control does not exist. /// @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(); iter = controls.begin();
while(iter != controls.end()){ while(iter != controls.end()){
if(iter->second->isContainer()){ if(iter->second->isContainer()){
try{ cContainer* tmp = dynamic_cast<cContainer*>(iter->second);
cContainer* tmp = (cContainer*) (iter->second); if(tmp->hasChild(id))
return tmp->getChild(id); return tmp->getChild(id);
}catch(std::invalid_argument) {}
} }
iter++; iter++;
} }
throw std::invalid_argument(id + " does not exist in dialog " + fname); 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>"; const char*const xBadVal::CONTENT = "<content>";

View File

@@ -152,6 +152,10 @@ public:
/// Determine how the dialog exited. /// Determine how the dialog exited.
/// @return the argument passed to toast() when the dialog was closed /// @return the argument passed to toast() when the dialog was closed
bool accepted(); 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. /// Get a reference to a control.
/// @param id The unique key of the control. /// @param id The unique key of the control.
/// @throw std::invalid_argument if the control does not exist. /// @throw std::invalid_argument if the control does not exist.

View File

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

View File

@@ -21,6 +21,7 @@
/// Alternatively, it can be used as a slider control. /// Alternatively, it can be used as a slider control.
class cScrollbar : public cControl { class cScrollbar : public cControl {
int pos, max, pgsz; int pos, max, pgsz;
std::string link;
// Note: For horizontal scrollbars, up is left and down is right. // Note: For horizontal scrollbars, up is left and down is right.
enum { enum {
PART_UP, PART_UP,
@@ -70,6 +71,12 @@ public:
/// Check whether the scrollbar is vertical. /// Check whether the scrollbar is vertical.
/// @return True if it is vertical, false if it is horizontal. /// @return True if it is vertical, false if it is horizontal.
bool isVertical(); 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. /// Set the scrollbar thumb's current position.
/// @param to The new position. /// @param to The new position.
void setPosition(long to); void setPosition(long to);
@@ -85,6 +92,12 @@ public:
/// Set whether the scrollbar is vertical. /// Set whether the scrollbar is vertical.
/// @param is True to make it vertical, false to make it horizontal. /// @param is True to make it vertical, false to make it horizontal.
void setVertical(bool is); 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(); void draw();
cScrollbar& operator=(cScrollbar& other) = delete; cScrollbar& operator=(cScrollbar& other) = delete;
cScrollbar(cScrollbar& other) = delete; cScrollbar(cScrollbar& other) = delete;

View File

@@ -126,6 +126,10 @@ void cScrollPane::setPosition(long to) {
scroll.setPosition(to); scroll.setPosition(to);
} }
bool cScrollPane::hasChild(std::string id) {
return contents.find(id) != contents.end();
}
cControl& cScrollPane::getChild(std::string id) { cControl& cScrollPane::getChild(std::string id) {
auto iter = contents.find(id); auto iter = contents.find(id);
if(iter == contents.end()) throw std::invalid_argument(id + " does not exist in the scroll pane."); 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); short getFormat(eFormat prop) throw(xUnsupportedProp);
void setColour(sf::Color clr) throw(xUnsupportedProp); void setColour(sf::Color clr) throw(xUnsupportedProp);
sf::Color getColour() throw(xUnsupportedProp); sf::Color getColour() throw(xUnsupportedProp);
bool hasChild(std::string id);
cControl& getChild(std::string id); cControl& getChild(std::string id);
storage_t store(); storage_t store();
void restore(storage_t to); 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. * `max` - Specifies the maximum value of the slider. This attribute is required.
* `page-size` - Specifies how much the slider should scroll when clicking * `page-size` - Specifies how much the slider should scroll when clicking
between the thumb and the arrow button. Defaults to 10. 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 The `<stack>` tag
----------------- -----------------