Add gtk.TreeView columns to a size group - user-interface

I want to stack two treeviews on each other and have the columns be aligned. I figured the way to do this would be to use a gtk.SizeGroup somehow. However, gtk.TreeViewColumn is not a widget... how can I do this?

I have two suggestions:
Look at how gtk.SizeGroup is implemented and see if you can write your own TreeViewColumnSizeGroup.
Connect to notify::width of each column and in the callback set the width of the corresponding column in the other treeview.

UPDATE: This is the final code that worked. In a loop I'm building both view columns at the same time, so this line is sufficient:
col1.connect("notify::width", lambda col1,_,col2:col2.set_fixed_width(
col1.get_width()), col2)
I think the reason there is no "column widget" is that the main area is just a gtk.gdk.Drawable where each of the cell renderers draw their stuff. However, each column has headers that are widgets, so we can use those to do what we want.
Pick one view to be the 'main' one, and set the other to have gtk.TREE_VIEW_COLUMN_FIXED sizing. Use .forall() to go through the internal child widgets of the 'main' view. These will be gtk.Buttons representing the column headers. Connect to their size-allocate event. On that event handler, get the requested width, and .set_fixed_width of the corresponding column on the slave view.
self._svcols = []
def sizealloc(wid, alloc):
ci = self._svcols.index(wid)
cl = self.slaveView.get_column(ci)
cl.set_fixed_width(alloc.width)
def resizes(child):
child.connect('size-allocate', sizealloc)
self._svcols.append(child)
self.mainView.forall(resizes)
This works even if the column headers are not being shown.

Related

How to get KendoUI Grid to work with custom cell renderer and selection

It seems that the selection events are not being passed through custom cell renderers. My goal is I want to change the background color of every cell in my grid (based on the values), and also be able to handle selection events. I've modified the example in the docs here:
https://www.telerik.com/kendo-react-ui/components/grid/selection/
To include a background color on the Units on Order column. You'll notice that that column does not participate in selections. I created a stackblitz example here:
https://stackblitz.com/edit/react-o4ycqi?file=app/main.jsx
All I changed was I added a cellWithBackground function and assigned it to the column UnitsInStock. Here is that function
const cellWithBackGround = props => {
const examplePrice = true;
const style = {
backgroundColor: "rgb(243, 23, 0, 0.32)"
};
const field = props.field || '';
return <td style={style}>
{props.dataItem[field]}
</td>;
};
I did find an example that was close but it I couldn't get it to work with functional components. It just worked with classes which I don't use. So, please provide examples or references on that support Functional Components.
H Peter,
Thank you for sharing the code. By completely replacing the entire cell's infrastructure, it will no longer respond to anything from the Grid.
Specifically, I'm referring to this line in the function. It only returns a <td> with the field's name, it abandons the rest of the properties of the element.
//cell returned form the function
return <td style={style}>
{props.dataItem[field]}
</td>;
At that point, it's basically a dead cell. It will not respond to events, data actions, etc because it is missing all the parts that the Grid requires to interact with it.
Further Guidance
As I mentioned in my Twitter reply, you can get guidance for the Kendo Engineers to help you from here.
I think there's a better way to handle this by using styling instead of manually handling the DOM elements directly. At the very least, you need to return the complete infrastructure of the cell and they can assist with that.

adding row manualy into DataGrid using VB6

i want to display the data into DataGrid manually in VB6, source of data is not from database or other source. I have created the column, like this:
For i = 2 To 4
DataGrid1.Columns.Add i
Next i
DataGrid1.Columns(0).Caption = "No"
DataGrid1.Columns(1).Caption = "Subdataset"
DataGrid1.Columns(2).Caption = "Dimension"
DataGrid1.Columns(3).Caption = "Check"
DataGrid1.Columns(3).Caption = "Detail"
but i can't add row and add value into it, i have tried like this:
Me.DataGrid1.AllowUserToAddRows = True
DataGrid1.Row = DataGrid1.Row + 1
then i got error
Please tell me if anybody can help me, thank you
Not only is DataGrid designed to be a bound control, it doesn't support unbound use. Says so right in the doc. So, the short answer is that you can't do what you are trying to do, because it's designed to display values from a database.
Instead, you'll want to use the MSFlexGrid control (Not the MSHFlexGrid control, although some of the doc confuses them), which you can read about here. Suppose you play around with that (the AddItem method is the fundamental piece you need to work with) and post back with specifics if you have problems.
Once you have added the table (DataGrid) right click select edit then you can insert columns:

How to tell if an element is a Widget? (CKEditor)

Per CKEditor, initialize widget added with insertElement, we are doing an insertElement() and then initializing with initOn(). The problem is that some of the elements we are inserting are not supposed to be widgets and initOn() makes them widgets and the context menu doesn't work right. I am having trouble finding any properties inside the item/element to tell if something is/is not a widget so I can then call initOn().
Cross-posted downstream on Drupal.org here https://www.drupal.org/node/2466297
First of all - which element do you mean?
(Note: In this section I am assuming that a widget was correctly and fully initialised.)
Widget element
A widget can obviously consists of many elements. One of them is called the "widget element" and this is the element which you "upcasted" and which you can later access through widget.element.
Since CKEditor 4.5.0 there will be such method available:
Widget.isDomWidgetElement = function( node ) {
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-widget' );
};
You can of course already use this code to check if a given node is a widget element.
Widget wrapper
Second important element is the widget's wrapper. It is created during data processing if a widget element was marked to be upcasted or when initOn() is called if the widget element wasn't wrapped yet. You can access this element through the widget.wrapper property.
Since CKEditor 4.5.0 there will be a following method available:
Widget.isDomWidgetWrapper = function( node ) {
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-wrapper' );
};
And again - you can use this code already.
Important note here - since you mention insertElemet() in your question. As I explained in CKEditor, initialize widget added with insertElement editor#insertElement() does not trigger data processing. Therefore, element that you insert is inserted as is. This means that the widget wrapper is not created during insertion and will be created once you call initOn().
Finding widgets by any element
Many times you want to find a widget instance by some element that you have (any element that can be inside a widget). There's a useful method for that: getByElement().
What should become a widget? Aka - how to deal with editor.insertElement()?
You mentioned that you use editor.insertElement() and that you don't know which elements are supposed to be widgets. This should never happen. editor.insertElement() is a quite low level method which will not do all the data processing and upcasting magic which editor.insertHtml() does. It means that it is supposed to be used in a different case - when you want to insert exactly the element that you have.
For instance, your table plugin is building a table structure to be inserted into editor. You know that the table is empty, so you control every bit of it (other plugins should not interfere here). It is also important that it's the table's plugin decision, not e.g. a template's plugin decision. The table's plugin control the table feature, while the template plugin only uses tables. So in such case, when you have a full control, you can use editor.insertElement(). Then you always know what you insert and what is supposed to become a widget.
In all other scenarios you should use editor.insertHtml(), so the whole data processing layer is triggered. Thanks to it other features like the widgets system, the link plugin (which turns empty anchors into fake objects), etc. can prepare the data that you insert to be fully editable and integrated.
Tl;dr
If your plugin knows what it does, it can use editor.insertElement(), but since it knows what it does it will know which inserted element must become a widget.
If your plugin does not fully control the situation, then you should use the editor.isertHtml() method which is far more automated and will turn proper elements into widgets based on the upcast callbacks.

Handsontable Dynamically Set Settings

I have a very big handsontable. I have dropdown columns defined, but, the values for the sources are retrieved with AJAX.
How can I set the "source" property of a "column" of type "dropdown" dynamically?
Regards!
You can, and should, use:
hotInstance.updateSettings({
columns: getNewColumns()
})
Where getNewColumns() would return an array of columns with the data and new source (or make the AJAX call from in here). That should do it!
Thank you for the answer ZekeDroid.
I was able to solve my issue.
First lets talk about a problem in the angular directive:
I am using the handsontable's angular directive. Two things happen: 1. If I associated the datarows attribute to a nested variale in the model, for example $scope.hot.data, then when I change the value of the model ( $scope.hot.data ) the grid ui is not refreshed. I am pretty sure this is an issue with the directive. Now: 2. Assume I use $scope.data and I update its value (this is the model right), then the grid ui is not refreshed either. I have to do something like hotInstance.updateSettings({data: newData}) as well.
I have to do both things; that is, update the model and call the update settings method. This is the only way I could get it work properly.
Note: if I do $scope.$apply() instead the updateSettings, I get an error in the console.

Trying to dynamically change width of hidden column leads to error "to many recursions"

unfortunately I can't find any help concerning to my specific problem.
I try to simplify it:
My grid consists of a shown column (A) and a hidden column (B) and other shown columns as well (C,D). With a custom button I can switch between these two columns, so that A is hidden and B is shown and vice versa.
My aim is as follows:
If the width of (shown) A has been changed, the width of (hidden) B should also be changed.
My current way to realize this this:
resizeStop: function () {
var $self = $(this);
shrinkToFit = $self.jqGrid("getGridParam", "shrinkToFit");
$self.jqGrid("setGridWidth", this.grid.newWidth, shrinkToFit);
var a = $self.jqGrid("getGridParam","colModel");
$self.jqGrid("setColWidth", "customers.name_short",a[2].width);
},
I works, but I have to wait for a wile and in addition to that I get the following log: "too much recursion". It seems that the function setColWidth is called more than 300 times.
I analyzed the code of setColWidth but I could not find any hint where it would call itself.
Can anybody help me?
Thanks in advance!
I suppose that you use my method setColWidth from here and the answer. It's wrong to use it inside of resizeStop callback.
You wrote: "With a custom button I can switch between these two columns, so that A is hidden and B is shown and vice versa." It seems to me that you need place one call of setColWidth method directly after you makes the column A or the column B visible (in the click event handle of your custom button). It should solve the problem.
UPDATED: The following demo http://jsfiddle.net/OlegKi/m7f9ghwq/18/ demonstrates the approach.

Resources