Adding Objects to Selector (Part 1)

Adding objects to selector has been a long process. So far, there has been a list of selectors in the style dialog. Adding objects to selectors will from a hierarchical structure. So Gtk::ListStore is replaced by Gtk::TreeStore which supports hierarchical representation of elements in the treeview.

There are basically two things to be updated:

  1. Add objects to selectors in treeview of the dialog
  2. Updating the XML representation whenever any child was added to a selector

Point to be noted is that parent-child relationship has to be actually maintained in the former one only to depict the representation of treeview but no such thing has to be done in the latter case. I initially considered this relationship to be existing in both cases.

Well moving to the implementation part, if any object is selected in the drawing, clicking on ‘+’ button in any row should add it as a child in the row whose button was clicked. The button event in the first column of every row which is ‘+’ button is detected first via _handleButtonEvent(GdkEventButton *event). The selected row whose ‘+’ is obtained as:

Gtk::TreeModel::iterator iter = refTreeSelection->get_selected();
if ( iter ) {
Gtk::TreeModel::Row row = *iter;
....
}

Also I considered the objects in each selector had to be unique which I observed from Selection Sets. Style dialog is inspired from it and I followed similar steps. I worked as per this consideration but doing so had unexpected behavior. It was sort of haphazard, objects were added to selector random number of times, irrespective of the number of clicks on ‘+’.

The ultimate goal is to replace Selections sets with CSS selectors which can not only be used for selections sets but also for CSS styling. –Tavmjong Bah

So discarding the assumption I had made, I added children to rows successfully. Another Gtk::TreeModelColumn column has been added which stores the object corresponding to the selector. The other column only stores some information associated to the object like its id which can be a selector label. Having object associated is helpful.

The row obtained above is used to append children to it. The various columns of this childrow are assigned values as shown in code snippet below:

childrow = *(_store->append(row.children()));
childrow[_mColumns._selectorLabel] = obj->getId();
childrow[_mColumns._colAddRemove] = false;
childrow[_mColumns._colObj] = obj;

Screenshot from 2016-06-30 20:19:19

Looks good. 😀

This was just end of part 1 which is adding objects to selectors in treeview of the dialog. The second part which is updating XML representation will be discussed in next post.

Deletion from XML Tree Done

The previous implementation of deletion from treeview was insignificant since a selector erased from treeview was saved to document because it was not removed from XML representation of the tree too.

Modification of content in the style node of XML tree is a complicated process. Tried it but not very efficient and accurate. Instead of modifying the content, I cleared the node’s content and set its value corresponding to the selectors left in the selectorVec. The vector and content are cleared using following lines:

selVec.erase(selVec.begin()+i);
_sValue.clear();

Next I will be moving to adding and deleting objects to selectors using buttons at the beginning of every row in the treeview.

From Map to Vector

Opening an existing drawing populated the style dialog but the selectors were not added to single style element. To achieve this, I played around with the map that contained selector names mapped to selector values (style attributes) of the object.

For every element that existed in the drawing already, I iterated the map of selectors. Appending each name and value to a string, the values of the resulting string were not in the order of insertion of selectors to this map. And then I learnt that maps contain key-value pairs in an ordered manner. The ordering occurs in a lexicographic manner irrespective of order of insertion of elements to it. Remember binary tree search? Well maps operate on the basis of this search algorithm.

So instead of using this map, I created a vector since order of insertion and retrieving elements has to be same.
std::map&ltstd::string, std::string>_selectorMap; std::vector<std::pair<std::string, std::string> >_selectorVec;

Modification to move from map to vector was done at all places needed. Later I obtained nodes from XML representation of the document and added the content retrieved from the vector to a new child in the XML tree.