Adding css class names to the contents of Cells in a gwt CellTable - gwt

I want to add style classes to elements in a cell (or the td itself) that will change depending on the state of the data in the cell. For example, the cell might have color: red when the data is unsaved, color: blue while the data is being saved, and color: black once the save completes successfully. Code external to the Cell will need access to change the class names, once callbacks are fired, etc.
I have achieved something like this with a hack in my Cell that gets the Element from onBrowserEvent and adds attributes there. I can set the initial style in render and then change it as needed in onBrowserEvent, and even keep track of that element so that external code can use it. This is incomplete, because I can't get the element until onBrowserEvent is called, and annoyingly hacky because I have to set the style in two different places.
What's a better way to achieve this effect without re-rendering the entire table whenever the state of a cell changes?

I found something like
table.setRowStyles(new RowStyles() {
#Override
public String getStyleNames(Contact row, int rowIndex) {
if (row.name.startsWith("J")) {
return "bold";
}
return null;
}
});
which should work in GWT 2.4 to resolve your matter.

The disappointing answer here is that you can't have the best of both worlds - static, all-at-once-rendering, AND dynamic, change-one-element-updating. The only way to change the style of a single cell, within the methods provided by CellTable et al, is to rerender the whole table.
In my own code I've kind of formalized the hacks I made to update single cells at a time, by setting the DOM id of a div rendered to each table cell. Then I can use getElementById and proceed from there. I still avoid the overhead of a full widget. It's a little clunky, but hidden behind a nice interface it's not too bad.

Related

Flutter - best approach to create TabledToggledButtons?

I would like my toggle buttons to be layout in a table, and not as a single row.
The number of toggle buttons is not static -
that is upon init I load a resource which contains a list of all the texts that should become the toggle buttons.
Looked at a number of approaches, each has its issues:
Create a list of ToggleButtons and a list of lists of bools to store the appropriate selected state as a data structure to divide the toggle buttons into a number of rows. The problem with this approach is in the implementation of the onPressed method - how to get a reference to the appropriate element in the list of lists of bools? Or in other words - how to get a reference to ToggleButtons object from within the onPressed method?
Use key property to pass the index of the current ToggleButtons. It is not intended for this purpose, so it is a bad practice, also again, there seems to be no straightforward way to access the key property from the onPressed method.
Extend the ToggleButtons class, and specifically override its build method. This is considered an anti-pattern in Flutter in general. Specifically In this approach, as we want all the functionality to remain the same, and change only the internal Row -> Table widget generation in the build method, it looks like we would have to duplicate all the code of this method, which is a bad idea as it might brake things as it changes in future versions of this widget
Create a table of checkbox / switch widgets as an alternative, which should work easily, but I want the look & feel of toggle buttons, not checkboxes or switches :)
I must be missing something simple!
After posting this I have a new idea :)
A table of FlatButtons! Will be probably possible to achieve similar UI to ToggleButtons. Will try it in a bit.
I would still love to hear other suggestions regarding ToggleButtons.
Try using SwitchListTile.
The entire list tile is interactive: tapping anywhere in the tile toggles the switch. Tapping and dragging the Switch also triggers the onChanged callback.
To ensure that onChanged correctly triggers, the state passed into value must be properly managed. This is typically done by invoking State.setState in onChanged to toggle the state value.
The value, onChanged, activeColor, activeThumbImage, and inactiveThumbImage properties of this widget are identical to the similarly-named properties on the Switch widget.
The title, subtitle, isThreeLine, and dense properties are like those of the same name on ListTile.
The selected property on this widget is similar to the ListTile.selected property, but the color used is that described by activeColor, if any, defaulting to the accent color of the current Theme. No effort is made to coordinate the selected state and the value state; to have the list tile appear selected when the switch is on, pass the same value to both.
The switch is shown on the right by default in left-to-right languages (i.e. in the ListTile.trailing slot) which can be changed using controlAffinity. The secondary widget is placed in the ListTile.leading slot.
To show the SwitchListTile as disabled, pass null as the onChanged callback.

Passing parameters in mvp pattern

This might be a general mvp places and activities question, but the show case I'm trying to understand here is this gwtphonegap-showcase-gwt example.
How do I pass a parameter to a view from another one?
For example, let's say I want that when a user clicks on any cell on the OverviewActivity, it will take them to the same place everytime (AboutPlace), but the text should be different (let's say it contains the cell number).
I added a setText(String text) to the AboutDisplay interface with the corresponding label and setText() in the AboutDisplayGwtImpl, but I have no idea where to call it. I tried calling it in AboutActivity start() method and ClientFactoryGwtImpl getAboutDisplay() method, but they seem to be called only once when the app first loads, so I end up with the same text each time.
you should not use a view directly for that.
You can add a field on a place and set your value there and access the same value in the next activity.

GWT Editable Grid : How to replace cell widgets dynamically?

I have created editable grid in which I am adding all the cell widgets. Now I want to check for some condition and replace a cell or column with another cell widget. For example if I have defined a column of EditTextCell, based on a boolean condition I have to change that column to have selectioncells(combo box). How to achieve this?
There are three ways to do that:
Use a CompositeCell with an EditTextCell and a SelectionCell and override the render method of the CompositeCell to render either the EditTextCell or the SelectionCell based on a boolean flag that you store in your DTOthat is bound to the Cell.
Create a custom cell extending AbstractEditableCell for example (see this tutorial) and implement the functionality yourself. You can check out the code for SelectionCell and EditTextCell and copy most of it. In the render method you have to either display a dropdownlist or just a text based on the boolean flag.
Extend either EditTextCell or SelectionCell and implement the missing functionality. The advantage is that you can probably re-use some of the render methods and you don't have to write the complete render code yourself.

how to keep view "humble" -using SuggestBox with special Oracle and Suggestion

i learned how to implement my own SuggestionOracle("AuSuggestOracle") and own
Suggestions("AuMultiWordSuggestion"). In my case the suggestion object
is constructed with a DTO. On a selection event i need this dto (or
some fields of it) to react appropriate.
I implemented a widget containing 3 suggest boxes with this special
oracle and some logic between them. Now i want to apply MVP pattern -
split this widget in presenter and view.
At the moment the presenters display interface look like that:
public interface Display {
HasSelectionHandlers<Suggestion> getFedLand();
HasSelectionHandlers<Suggestion> getCounty();
HasSelectionHandlers<Suggestion> getCommunity();
AuSuggestOracle getFedLandOracle();
AuSuggestOracle getCountyOracle();
AuSuggestOracle getCommunityOracle();
void clearCounty();
void clearCommunity();
void activateForm();
Widget asWidget();
}
the problem is the implicit knowledge about my model in methods
returning "AuSuggestOracle". so my question is how to get the view/
interface "humble". in my case the displayed suggestion-strings are
ambiguous and i need at least the "id" of a selected item to know what
DTObject is selected.
The way I got around this is by leaving out the getters for the Oracle since once my presenter sets it my view doesn't need any information about it. So, my interface looked like this:
public interface Display {
...
void setSuggestionOracle(SuggestOracle oracle);
HasSelectionHandlers<SuggestOracle.Suggestion> getSelectionListener();
}
The problem I encountered was being able to add the suggestion to the SuggestBox after it was instantiated. To get around this, I initialized with a blank SuggestBox and then removed it from the view, updated in, and inserted it back into position.
After that, you can write your handler (in the presenter) to check if the suggestion is an instance of your custom suggestion and your presenter can handle the selection and push the relevant information back down to your view.
By doing this, all your view knows is that it will be taking generic suggestions for something, and that at some later time it will be updating with information (which will be as a result of the suggestion, but the view is to 'humble' to know that).

How do I add ScrolledWindow support to a custom Widget in GtkMM?

I am writing a custom widget for Gtkmm that is supposed to display a huge dataset (imagine something like a 4096x256 character datasheet).
Mostly for reasons of elegance, but also for a possible usage in a Glade/Gtk-Builder editor, I want this widget to support ScrolledWindow natively, that is, once it is set as the child of ScrolledWindow, it is recognized as a scrollable widget, allowing to set horizontal and vertical Adjustment objects on it, which it can subsequently tamper with.
It appears to do so, I need to do something like this in the constructor of my widget:
// get Gtk C type from wrapper class
GtkWidget* gwidget = this->gobj();
// imagine code here that magically creates a gobject signal,
// that we can catch in C++.
// this is actually the part which I don't know how to do.
guint my_signal = magic_way_to_create_this_signal(
&MyClass::rainbow_unicorn_signal_handler);
// make ScrolledWindow recognize this window as scrollable
GTK_WIDGET_GET_CLASS(gwidget)->set_scroll_adjustments_signal = my_signal;
Later on, the signal emitted by ScrolledWindow when the widget is added needs to be caught by my Widget through a signal proxy method or something? I have no idea.
How can I do this?
The 'magic_way_to_create_this_signal' is g_signal_new(). You call it in your widget's my_widget_class_init() function which is part of the GObject way of defining a class. I'm not exactly sure what the equivalent is in Gtkmm.
See also the footnote in the GTK docs, where it is explained why making a widget natively scrollable is such a hassle.
You could also put your widget into a Gtk::Viewport which adds scrolling capabilities to its child widget.