How do you read localsettings variables in default.css file in a windows store app? - windows-8

I am building a windows store app that has a default css and a default font size in that css. I am allowing the user to customize the font size from settings screen and that preference gets stored in local settings. How do I update my app to reflect the new font size? Are there any current patterns? This is a Html5/js app. Can I simply reload the css value from the change event?

When your app launches, read the font size from local settings and then set the document's font size with JavaScript:
document.body.style.fontSize = fontSizeFromSettings;
When the app is running and the user changes the font size, also call the above line. You could do this right after your code which saves the font size to local settings.
Naturally, you can also change the font size of individual elements using document.getElementById("myId").style.fontSize.

I read this as the OP having a class selector already defined, like
.myclass
{
font-size: 36px;
}
and wanting to modify all elements with the .myclass selector to be a new value, say 72px. If that's the intent, then you can dynamically modify the CSS.
Here's a simple (and fragile, not-suitable-for-production) function that looks for a specific style selector in a known CSS file and modifies it on the fly. You could probably generalize this, take a look at Changing External Stylesheets and How to change CSS Stylesheets with JavaScript for more details.
function updateFontSize(newFontSize) {
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].href.indexOf("default.css") >= 0) {
var mySheet = document.styleSheets[i];
for (var r in mySheet.cssRules) {
if (mySheet.cssRules[r].selectorText == ".myclass") {
var myRule = mySheet.cssRules[r];
myRule.style.fontSize = newFontSize;
return;
}
}
}
}
};
Then somewhere you call it like (without hardcoding the value, of course):
updateFontSize("128px");

Related

Correct GTK CSS selector to use from SWT widgets?

I'm trying to apply GTK+ 3 CSS rules to widgets used in the Eclipse UI, specifically for a ComboBox right now. For example: say I want to make the background color of a selected text in a combobox to be red. The Style rule applied to the combobox widget would be
*.entry:selected { background-color: #FF0000; }
I have proven that rule using the Gtk+ CSS Inspector tool in Ubuntu and that works there but I do not find a way to apply that rule in code for ComboBoxes.
Inside SWT, there are places where CSS is used on Linux, such as this snippet to set the background color, however, adding the above rule to the CSS override does not have any apparent impact (yes, the background color does work).
#Override
void setBackgroundColor (long /*int*/ context, long /*int*/ handle, GdkRGBA rgba) {
// CSS to be parsed for various widgets within Combo
background = rgba;
String css = "* {\n";
if (rgba != null) {
String color = display.gtk_rgba_to_css_string (rgba);
css += "background: " + color + ";\n";
}
css += "}\n";
// Cache background color
cssBackground = css;
String finalCss = display.gtk_css_create_css_color_string (cssBackground, cssForeground, SWT.BACKGROUND);
//Injected code to make selected text red
finalCss += "\n.*:selected {background-color: #FF0000}";
if (entryHandle == 0 || (style & SWT.READ_ONLY) != 0) {
// For read only Combos, we can just apply the background CSS to the GtkToggleButton.
gtk_css_provider_load_from_css (OS.gtk_widget_get_style_context(buttonHandle), finalCss);
} else {
if (OS.GTK_VERSION >= OS.VERSION(3, 16, 0)) {
// For GTK3.16+, only the GtkEntry needs to be themed.
gtk_css_provider_load_from_css (OS.gtk_widget_get_style_context(entryHandle), finalCss);
} else {
// Maintain GTK3.14- functionality
setBackgroundColorGradient (OS.gtk_widget_get_style_context (entryHandle), handle, rgba);
super.setBackgroundColor (OS.gtk_widget_get_style_context (entryHandle), entryHandle, rgba);
}
}
// Set the background color of the text of the drop down menu.
OS.g_object_set (textRenderer, OS.background_rgba, rgba, 0);
}
I’ve tried various combinations of selectors and so far have not found a way to have the “selection” background color of the text to take effect.
Here is a link to the corresponding ComboBox class from SWT where it deals with CSS -- see the setBackgroundColor method.
https://github.com/eclipse/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT/gtk/org/eclipse/swt/widgets/Combo.java
I have proven that code runs and also managed to change the background for the entire combobox by changing the css rule there. However, if I inject my new rule it gets ignored.
Any help would be appreciated. Thanks!

CUBA platform how to dynamically change field color

I'm trying to dynamically change some field color when it has changed due to some processing.
CUBA documentation explains how to do it statically through web theme extension (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html), but not dynamically. Although it is possible in Vaadin (https://vaadin.com/wiki/-/wiki/Main/Dynamically%20injecting%20CSS) on which platform web gui is built upon.
I suppose that if I use the Vaadin way of injecting CSS it will work (which I will try) but I will then have Vaadin specific code, which I'm trying to avoid.
Is there a CUBA way of doing so I'm missing ?
Edit:
I'm trying to have any field of a form to change background color when it has changed from its initial value. As per CUBA documentation (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html) I need to :
- create a SCSS mixin with background color
- inject the field in the editor class in order to have access to it
- react to a field change event and then define the style name of the field
I did create the SCSS mixin, but two issues I have :
1) I would like to retrieve the field instance dynamically instead of injecting it (keep code clean and light)
2) I would like to avoid defining the background color statically so that the color could be parameterized at runtime
For 1) I tried to injected the fieldGroup and used getFieldComponent(), then applied the style with setStyleName on it when it is changed. It worked but I would prefer to define this behavior for every field that is an input field.
For 2) apart from using Vaadin specific feature of injecting CSS (and tighing my code to Vaadin (and so leading me away of generic interface) I do not see how to do
Hope it's more clear
You cannot set truly dynamic color (any RGBA) from code to field but you can create many predefined colors for your field:
#import "../halo/halo";
#mixin halo-ext {
#include halo;
.v-textfield.color-red {
background: red;
}
.v-textfield.color-blue {
background: blue;
}
.v-textfield.color-green {
background: green;
}
}
I do not recommend using styles injected from code (as Vaadin Page does) since it is a mixing of logic and presentation. Instead you can create all predefined styles (30-50 styles should be enough) and assign it depending on some conditions using setStyleName method:
public class ExtAppMainWindow extends AppMainWindow {
#Inject
private TextField textField;
private int steps = 0;
public void changeColor() {
if (steps % 2 == 0) {
textField.setStyleName("color-red");
} else {
textField.setStyleName("color-blue");
}
steps++;
}
}
If you want to apply the logic of color change for all TextFields inside of FieldGroup you can iterate FieldGroup fields in the following way:
for (FieldGroup.FieldConfig fc : fieldGroup.getFields()) {
Component fieldComponent = fieldGroup.getFieldComponent(fc);
if (fieldComponent instanceof TextField) {
TextField textField = (TextField) fieldComponent;
textField.addValueChangeListener(e ->
textField.setStyleName("color-red")
);
}
}

Printing PDF documents from Windows 8 App

I'm trying to print a PDF file from my Windows 8 app to connected printer. I'm coding with WinJS, and know that I have to create a print task to initiate printing from a Windows 8 app. So, after reviewing the documentation, I have this code:
onPrintTaskRequested: function (e) {
var self = Application.navigator.pageControl,
printTask = e.request.createPrintTask("Print Test Doc", function (args) {
args.setSource(MSApp.getHtmlPrintDocumentSource(document));
// Register the handler for print task completion event
printTask.oncompleted = self.onPrintTaskCompleted;
});
}
According to the documentation, the MSApp.getHhtmlPrintDocumentSource method accepts a specific set of data types. As stated in the documentation:
This can be the root document, the document in an IFrame, a document
fragment, or a SVG document. Be aware that htmlDoc must be a document,
not an element.
Apparently I cannot simply set the argument for getHtmlPrintDocumentSource to a .PDF or .PNG binary. So, I'm curious: does the WinJS library offer a method for printing so that I can implement the printing of a PDF file to a connected printer? Can anybody offer some tips to implement?
After trial and error, I was finally able implement the printing of a Base64 stream representing a PDF binary from a Windows 8 application.
I'm coding the app in HTML / CSS / WinJS. Essentially here is a brief explanation of how it was accomplished:
Create a new <canvas> element within the default.html file. Place it right after the open tag of the element. Like this:
<body role="application" class="app">
<canvas id="pdf-render-output"></canvas>
.
.
.
</body>
Then inside the default.css file, setup a few rules as well as a print media query. Like this:
body > canvas {
display: none;
}
.
. /* all your app's default css styles */
.
#media print {
body > * {
display:none;
max-width: 100%;
}
html {
max-width: 100%;
border-top-color: none;
border-top: 0;
}
body > canvas {
display: block;
border: none;
max-width: 100%;
width: 100%;
height: 100%;
position: relative;
}
}
Of note is the order in which the rules are declared in CSS. It's important to place the print media query after declaring default CSS rules.
After this is setup, javascript handles the rest. The basic idea is to render the PDF.js output to the "hidden" canvas in the DOM. When the document object gets sent to print, the CSS print media declaration is queried so that all elements under <body> are hidden except for the canvas element. Here is the javascript to print only the first page in the PDF:
//Define a container for the Base64 data we'll use with PDF.js
var pdfPrintData = {};
//Function to render PDF to canvas and begin printing contract with Windows 8 OS
printPrescription: function () {
var self = Application.navigator.pageControl,
printManager = Windows.Graphics.Printing.PrintManager.getForCurrentView();
self.getPDF().done(function () {
var pdfStream = pdfPrintData.base64,
pdfFile = convertDataURIToBinary(pdfStream);
PDFJS.disableWorker = true;
PDFJS.getDocument(pdfFile).then(function (pdf) {
var numPages = pdf.numPages,
renderCanvas = $('#pdf-render-output')[0];
//setup canvas
renderCanvas.height = pdf.getPage(1).data.getViewport(1).height;
renderCanvas.width = pdf.getPage(1).data.getViewport(1).width;
//Setup a render context for pdf.js to out a pdf file to the canvas.
var renderContext = {
canvasContext: renderCanvas.getContext('2d'),
viewport: pdf.getPage(1).data.getViewport(1)
};
//Bring up Windows 8 OS print after PDF is rendered to render context.
pdf.getPage(1).data.render(renderContext).then(function () {
printManager.onprinttaskrequested = self.onPrintTaskRequested;
Windows.Graphics.Printing.PrintManager.showPrintUIAsync();
});
})
});
},
onPrintTaskRequested: function (e) {
var self = Application.navigator.pageControl,
printTask = e.request.createPrintTask("Print Prescription", function (args) {
args.setSource(MSApp.getHtmlPrintDocumentSource(document));
printTask.oncompleted = self.onPrintTaskCompleted;
});
},
onPrintTaskCompleted: function (e) {
if (e.completion === Windows.Graphics.Printing.PrintTaskCompletion.failed) {
console.log("[ERX] : Failed to print!");
}
}
The self.getPDF method is just a function that retrieves the Base64 data stream, and that streams gets set on the .base64 property of the global pdfPrintData object. For some reason, I was not able to render the pdf using pdf.js to a dynamically create canvas in a dynamically created document. I had to render the output of the pdf.js render method to a canvas already present in the DOM.
As far as I know, MSApp.getHtmlPrintDocumentSource(document) is meant to be used with HTML document objects, and nothing else.
If you can assume Windows 8.1, you can try to assemble a new HTML document from your PDF file by exporting each page into a raster image using PdfPage.RenderToStreamAsync. There is a sample project in MSDN for a PDF viewer that uses this new API where you can learn how to use this method.
If you cannot assume Windows 8.1 and you need to support plain Windows 8 or Windows RT (ARM), you might need to use a third party library to create the raster images or to do the printing all together.
Amyuni PDF Creator for WinRT for example can do the printing for you. Disclaimer: I currently work for the company that develops the library

Windowless (not chromeless) Adobe AIR app

What would be the best way to go about building an Adobe AIR app that doesn't have any windows (i.e. exists only in the system tray / dock)? I noticed that the default base tag in Flash Builder is <s:WindowedApplication> which seems to imply there'll be a window.
Should I just use <s:WindowedApplication> and call window.hide()? I saw there's another base class, <s:Application>, but I got the sense that was more for files that run in the browser. It seems like using window.hide() would briefly flash a window when the application starts which could confuse users. However I'd also ideally like to retain the ability to have the app open a window later if needed, or also to change the application from tray-only to windowed through an update.
You need to edit the app-config file to enable transparent chrome and visible = false. Then you need to change the WindowedApplication tag to and app your custom skin. You need to add control buttons for close etc, since that functionality isn't present in a web-app (since you have changed the tag). Also you need to add drag functionality. If you like to make your application re-sizable you need to add that too, manually.
In your manifest (-app.xml) file set systemChrome to none and transparent to true. The visible property is irrelevant, and the default is false anyway so ignore it.
you'll have to tweak this, import whatever classes are missing, etc... you could also do it as an mxml component and just set visible and enabled to false on the root tag. Fill up the trayImages array with the icons you want in the dock.
p
ackage{
import spark.components.WindowedApplication;
public class HiddenApplication extends WindowedApplication{
public function HiddenApplication(){
super();
enabled=false;
visible=false;
var trayImages:Array;
if(NativeApplication.supportsDockIcon||NativeApplication.supportsSystemTrayIcon){
NativeApplication.nativeApplication.activate();
var sep:NativeMenuItem = new NativeMenuItem(null,true);
var exitMenu:NativeMenuItem = new NativeMenuItem('Exit',false);
exitMenu.addEventListener(Event.SELECT,shutdown);
var updateMenu:NativeMenuItem = new NativeMenuItem('Check for Updates',false);
updateMenu.addEventListener(Event.SELECT,upDcheck);
var prefsMenu:NativeMenuItem = new NativeMenuItem('Preferences',false);
prefsMenu.addEventListener(Event.SELECT,Controller.showSettings);
NativeApplication.nativeApplication.icon.addEventListener(ScreenMouseEvent.CLICK,showToolBar);
if(NativeApplication.supportsSystemTrayIcon){
trayIcon = SystemTrayIcon(NativeApplication.nativeApplication.icon);
setTrayIcons();
trayIcon.tooltip = "Some random tooltip text";
trayIcon.menu = new NativeMenu();
trayIcon.menu.addItem(prefsMenu);
trayIcon.menu.addItem(sep);
trayIcon.menu.addItem(updateMenu);
trayIcon.menu.addItem(exitMenu);
}
else{
dockIcon = DockIcon(NativeApplication.nativeApplication.icon);
setTrayIcons();
dockIcon.menu = new NativeMenu();
dockIcon.menu.addItem(prefsMenu);
dockIcon.menu.addItem(sep);
dockIcon.menu.addItem(updateMenu);
dockIcon.menu.addItem(exitMenu);
}
}
function setTrayIcons(n:Number=0):void{
if(showTrayIcon&&(trayIcon||dockIcon)){
Controller.debug('Updating tray icon');
if(NativeApplication.supportsSystemTrayIcon){
trayIcon.bitmaps = trayImages;
}
else if(NativeApplication.supportsDockIcon){
dockIcon.bitmaps = trayImages;
}
}
else if(trayIcon||dockIcon) trayIcon.bitmaps = new Array();
}
}
}

Flex: Embedding fonts at runtime only works locally?

I'm trying to change the text format in a TextField I get from a .swf. I'm embedding my font in a myFont.swf:
public class TemplateFont extends Sprite
{
[Embed(source='../fontFiles/geogrotesque/Geogrotesque-Regular.ttf', fontName='theFontName')]
public static var FONT_TEXT:Class;
}
Then I'm loading it where I need it and registering it:
var FontLibrary:Class = e.target.applicationDomain.getDefinition("TemplateFont") as Class;
Font.registerFont(FontLibrary.FONT_TEXT);
And then I'm trying to set the format to my Textfield:
txtTitle.embedFonts = true;
txtTitle.antiAliasType = AntiAliasType.ADVANCED;
var titleFormat:TextFormat = txtTitle.getTextFormat(); //TextFormat is set in swf, just wanna change font at runtime.
titleFormat.font = "theFontName;
txtTitle.htmlText = title; //coming from xml sorrunded with CDATA
txtTitle.defaultTextFormat = titleFormat;
txtTitle.setTextFormat(titleFormat);
This all works fine when I'm running it on my computer, but as soon as I place my files on a server nothing shows. When I'm tracing the htmlText for the TextField it looks fine, but no text is showing up. I'm also tracing the registered fonts to see that they are there, and they are.
Anybody knows?
Two things:
The EULA of this font don't allowed to upload the font to a server.
Have you a legal copy of Geogrotesque? We only sell Open Type format (OT), but not True Type (TTF).
If you have doubts about this, please contact with Emtype.