Dynamic CSS class names in GWT - css

I am in the process of porting a simple CSS grid system to GWT. My CSS file currently has classes like .size1, .size2 etc., and I have a CSS resource that looks like -
interface MyResource extends CSSResource {
#ClassName("size1")
String size1();
#ClassName("size2")
String size2();
// And so on
}
However what I really want, is to have a single function like the following -
String size(int size);
which will generate the appropriate class when passed the size as an integer at runtime. This is needed as I perform some calculations to determine the actual space available/needed for a widget in javascript and then attach the appropriate class name.
Is this something that is even possible with GWT?
Edit: To clarify, I can easily write such a method myself like so -
String size(int size) {
switch(size) {
case 1: return size1();
case 2: return size2();
... and so on
}
}
However MyResource is an interface and its implementation is generated at runtime by GWT. This means I cannot add my size method to the MyResource type. So I guess I am asking for a way to add custom methods to the MyResource class.

I think you should not try to solve this via css files, but if you want to have dynamic values in your style you should set those values in code via myWidget.getElement().getStyle().setSomeCssMethod(). Or in this case you seem to want to set size, as in height and width. For most widgets those values can be set directly. Unless I'm missing something, why do you want to use css classes and not set it directly in code?

You can't pass method names to the CSSResource.
Remember that CSSResource's purpose is to minify and obfuscate the CSS class names.
However, just because CSS Resource can do this, doesn't mean you have to use it for all you code.
For example you already know that the CSS Resource methods return a string, so just create your own method that returns a string (your dynamic class names) and to load your CSS use the #CssResource.NotStrict annotation when adding it to your resource.

Related

Looking to avoid ViewBag usage in MVC 5 - suggestions?

So I have been googling how to remove any and all usage of ViewBags in favour of something more elegant and effective. Unfortunately virtually all of the information I have come across is for prior versions of MVC, and I have yet to find something that both works and is really effective.
One of my primary objective is to be able to populate both the page and the layout at the same time, so that I can add a page title to both the <h2> as well as the <title>. I also want to be able to, if needed, to supply the first paragraph of the body content, which is drawn from the database as a separate column, to the meta-description (this is a special case where all first paragraphs are their own separate entry in the row in the db, purely for the purpose of also acting as the meta-description).
I have run across something that I believe will meet my needs, but I cannot seem to properly implement the fifth code block:
Now create the view base class. You need to create two versions to
have support for typed views.
public class ViewBaseWithLayoutModel : WebViewPage{
public LayoutViewModel LayoutModel {
get { return (LayoutViewModel)ViewBag.LayoutModel; }
}
}
public class ViewBaseWithLayoutModel<T> : WebViewPage<T>{
public LayoutViewModel LayoutModel {
get { return (LayoutViewModel)ViewBag.LayoutModel; }
}
}
Specifically, it is the “create the view base class” that has me tied up in knots -- are they talking about an entirely new section in the project, similar to the Views, Controllers, Models, Extensions, Validators, etc., such that the namespace would be namespace Project.ViewBase {?
And if I can put the fifth code block straight beside another controller like BaseController (inside the Project.Controllers namespace but below the BaseController class in that file), why do both classes throw the errors,
'ViewBaseWithLayoutModel' does not implement inherited abstract member 'WebPageExecutingBase.Execute()'
As well, the sixth code block references
<pages pageBaseType="Namespace.To.ViewBaseWithLayoutModel">
So in the above case would it be 'Project.Controllers.ViewBaseWithLayout'?
Any help would be greatly appreciated.

How to use Resource bundle(Client Bundle) in JSNI?

I am trying to use client bundle of css resource in JSNI but couldn't find any helpful code.
I want to know how to call css resource in JSNI and how exaclty to use client bundle in JSNI.
My Normal code:--
Resource.INSTANCE.button().ensureInjected();
Resource res = GWT.create(Resource.class);
button.setStyleName(res.button().gwtbutton());
How to write in jsni?
Here Resource----> is interface extend clientbundle.
gwtbutton ---> is css.
I have read in this link https://groups.google.com/forum/#!topic/google-web-toolkit/94v4tjCZiBo that we can use the CssResource through jsni. But I'm unclear about his usage its syntax.
There's no magic here (OK, there is a bit, but behind the scenes). Your Resource interface's implementation is automatically generated by GWT, so when you call res.button().gwtbutton(), it will return a proper name for the style you are referencing from a CSS file. This name could be obfuscated, with a prefix, etc. It doesn't matter to you - in the end it's just a string, a style's name. Just pass it as a String to your JSNI method:
public native void addStyle(String style) /*-{
// Add style to a DOM element
}-*/;
// Invoke like so:
addStyle(res.button().gwtbutton());
If you want to use your ClientBundle directly in JSNI code:
// First, get Resource instance from a static field
var resource = #package.Resource::INSTANCE;
// Then, get the CssResource with the style
var button = resource.#package.Resource::button()();
// Finally, get the style's name
var gwtButton = button.#package.Button::gwtButton()();
Substitute package.Resource for the proper qualified name (package + class name) of the Resource interface. Use the code completion offered by Google Plugin for Eclipse if needed. Do the same for the type returned by the button method (it's probably some interface extending CssResource).
If you are troubled by the syntax, please dig through the documentation or look into some tutorials on Java Native Interface - it shares a lot of similarities with JSNI and might be better documented.

Best Way to Handle System-Wide QSettings in Multiple Classes

I have multiple classes that all need to access QSettings. It would be nice to have some standardized keys should they not exist. It also needs to be system wide, which requires creating an instance of QSettings. My current implementation is a class that all the other classes include.
int Settings::serverRefreshRate() {
return settings->value("server/refreshRate", 10000 /* default value*/).toInt();
}
Though this does mean including this class everywhere, which I believe will add overhead.
Would making this class external be a good idea? What about static?
Thanks!
As you're likely to only have one instance of this class, I'd personally make it static and use the singleton design pattern

JJTree add methods to node classes

So, I'd like to add methods to subclasses of SimpleNode. For example, I have a Position Node. After running jjt and javacc, a Position.java will be generated. It's expected to look like
class Position extends SimpleNode {
private int line, column; // I'll add private members here
...
public int getLine() {
return this.line;
} // add some methods here
...
}
Now, I'm making changes in the generated java files. However, it's not a good idea to do so, as generated java files are frequently removed and jjt file is re-made. Is it possible to add these declarations in jjt file (I didn't find something like this in the manual)? I'm also thinking about deriving subclasses of them. It doesn't work cleanly either.
You can modify the node implementations all you like. JJTree will only generate them if they are missing. From the manual
If you don't provide implementations for the node classes JJTree will generate sample implementations based on SimpleNode for you. You can then modify the implementations to suit.

ActionScript Interfaces with custom namespaces

Is there any way to get interface to play along with custom namespace? Example follows.
IHeaderRenderer.as:
public interface IHeaderRenderer{
function set header(value:IHeader):void;
function get header():IHeader;
}
HeaderRenderer.as
import fi.test.internalNamespace;
public class HeaderRenderer implements IHeaderRenderer{
internalNamespace function set header(value:IHeader):void{
// do something
}
internalNamespace function get header():IHeader{
// do something
}
}
This gives you the basic compiler error:
1044: Interface method get header in namespace fi.gridutils.headerrenderers:IHeaderRenderer not implemented by class fi.gridutils.headerrenderers.implementation:HeaderRenderer.
Why is this needed, you might ask. I'm developing a component, where the header accessors should not be directly visible to the components end user (developer), but if the developer wants to create his own Renderer he should know that they are needed. This is because the parent component will use these accessors to give the custom renderer the data it needs to render the header correctly.
Now to my mind there seems to be only three choices:
1) use public access control. This has the setback that the end developer will see accessors, which should not be directly accessed by him. Plus they add unnecessary clutter as they appear in auto-complete.
2) do not use interface. This means the end user has pretty poor options of developing the component further.
3) use the interface, but omit the accessors that use internalNamespace. Now the end developer will not know that he should add also header accessors to his custom headerrenderer class, which ends up in Flash Player giving following error to the developer in runtime:
Cannot create property internalNamespace/::header on fi.gridutils.headerrenderers.implementation.HeaderRenderer.
Sorry for all the blabbing. Any cunning ideas how this kind of situation could be handled?
In ActionScript, the interface methods need to be public. What good is an interface, if you can't guarantee the component using it can access the relevant interface methods?
that said, you can use the exclude metadata to prevent properties from showing up in code hinting.
Something like this:
[Exclude(name="header", kind="property")]
More info

Resources