GTK4 Vala - show FileChooserDialog - vala

I am playing around with Vala and GTK4.
FileChooserDialog is not working for me
using Gtk;
int main (string[] argv) {
// Create a new application
var app = new Gtk.Application ("com.example.GtkApplication",
GLib.ApplicationFlags.FLAGS_NONE);
app.activate.connect (() => {
// Create a new window
var window = new Gtk.ApplicationWindow (app);
window.title = "File chooser";
window.set_default_size (350, 70);
window.resizable = false;
// Create a new button
var file_choose_button = new Gtk.Button.with_label ("...");
file_choose_button.clicked.connect (() => {
var fileChooser = new FileChooserDialog(
"Select File",
window,
FileChooserAction.OPEN,
"Cancel",
ResponseType.CANCEL,
"Open",
ResponseType.ACCEPT,
null);
fileChooser.response.connect(()=> {
stdout.printf("File selectd!");
});
// WHAT TO DO IN ORDER TO SHOW FILE CHOOSER?
});
window.set_child (file_choose_button);
// Show
window.present ();
});
return app.run (argv);
}
I am missing some important piece of code, that will cause the FileChooserDialog to "appear".
In previous Versions of GTK there is "dialog.run" - which is missing in GTK4.
The C-Example on https://docs.gtk.org/gtk4/class.FileChooserDialog.html uses makro(?) "gtk_widget_show(xxx)" for which I was not able to find an representation in Vala.
Any help appreciated!
Best Regards
Emil

After some struggle the solution was found (and is pretty simple).
As stated in the Vala Documentaion Site - File Chooser Dialog
It inherits from couple of classes one of which is GTK.Window.
So it is as simple as calling the present() method.
Thus the missing command above is:
fileChooser.present();
One should not forget to use the close() method once file was selected or selection was canceled.
Important note:
"gtk_widget_show()" representation in Vala is GTK.Widget.show() BUT
I was not clever enough to find out how to prepare the parameter.
It expects pointer (GtkWidget*) and simply passing the "fileChooser" causes all kinds of compiler exceptions.
May be someone can throw more light on this (as I am using Vala to avoid the use of C - I am clearly not the expert in this area)

Related

Fast Reports Preview - C # MVC

Good afternoon. I have reports with parameters, before forming reports, I would like to make a preview. How to use "webReport.Report.ShowPrepared ()"?
item = reportDB.SelectFirst(Convert.ToInt64(showID));
reportDB.SelectBinaryFile(ref item);
var r = new FastReport.Report();
r.LoadFromString(Encoding.UTF8.GetString(item.ReportBody));
WebReport webReport = new WebReport();
webReport.Width = Unit.Percentage(100);
webReport.Height = Unit.Percentage(100);
if (1==1)//проверка на рус язык
webReport.LocalizationFile = "~\\Translation\\Russian.frl";
SetUserInfo(ref r);
webReport.AutoWidth = true;
webReport.AutoHeight = true;
webReport.Report =r;
webReport.PrevPage();
ViewBag.WebReport = webReport.GetHtml();
As per the official documentation if Fast reports you can use like below.
First you needs to check whether the report is prepared, if prepared returns true boolean value simply you can call the showprepared() method.
webReport.Load("report1.frl");
webReport.Prepare(true);
webReport.ShowPrepared();
if you wants to use some modal window and needs to return to the privious pages then you can use it like below.
void ShowPrepared(bool modal,Form owner)
The same as the previous method. The ow ner parameter determines a
window that owns the preview window.
Please read more from here to implement it in better way.
Official Documentation Fast Reports

Ambiguous reference to member 'subscribe' Swift 3

I am new to Reactive programming, and I'm trying to observe a boolean value from my ViewModel in order to let my ViewController know when to start/stop the app's loader screen.
It's fairly simple and I want to use this method to avoid unnecessary delegates, since my ViewModel holds the business logic and my ViewController handles the UI.
My problem is this compiler error: Ambiguous reference to member 'subscribe'.
It also adds the two possible candidates, as you can see in the image below:
In my ViewModel, I've declared the observable as PublishSubject:
let done = PublishSubject<Bool>()
And I use it while observing another stream:
func subscribe() {
done.onNext(false)
anotherObservable.subscribe(
// other events observed here but not relevant to this matter
onCompleted: {
self.done.onNext(true)
}).addDisposableTo(rx_disposeBag)
}
And, finally, this is how I'm trying to handle it in the ViewController:
self.model.done.subscribe(
.onNext { isDone in
if isDone {
self.removeLoader()
}
}).addDisposableTo(rx_disposeBag)
I believe there is something simple I'm probably missing, so any help is appreciated.
In your second subscribe should be:
self.model.done.subscribe(onNext: { isDone in
if isDone {
self.removeLoader()
}
}).addDisposableTo(rx_disposeBag)

How do you pass statements through an addEventListener?

Iv been trying to pass arguments through an addEventListener event in actionscript such as...
target.addEventListener("pComp", rakeSoil(target));
but i get errors.
Iv tried to google but no luck :/
Thanks for replying if you do :)
The target is already passed as part of the event, either event.currentTarget or event.target will be what you want.
If you want something else passed, create a custom event. Add the property to the custom event.
Try adding an additional method as your event listener:
target.addEventListener ("pComp", targetListener);
...
private function targetListener (event:Event):void {
rakeSoil (event.currentTarget);
}
How this is what you want:
{
var target:EventDispatcher = ...;
Function rakeSoil = function (e:Event):void
{
// handle target
}
target.addEventListener("pComp", rakeSoil);
}
rakeSoil is a first class function(or closure), when event is dispatched, it will be invoked, and you can access 'target' in it.
EDIT:
Have a look at Closure (computer science)
I have always found anonymous functions to be more trouble than they are worth. I would simply follow the standard event handler code layout. It's more formal and takes a little more effort up front, but there is no ambiguity and it is far more readable when you return to it a year from now (reduces head-scratching duration):
// Target extends EventDispatcher
private var target:Target;
public function listenToTarget();
{
target = new Target();
target.addEventListener("pComp", pCompHandler);
}
private function pCompHandler(event:Event):void
{
target.rakeSoil();
}
Although, now that I look at it more closely, why are you having this object do something that Target should be capable of handling internally on its own?

Very basic AChartEngine XY

I've been trying for hours to get something as simple as displaying a line chart based on 2 dots that I supply manually and all I get is a crash. I've tried to understand how everything works based on the demo code but it's too complex. I'm not even concerned about writing nice code with onResume() etc, I just want something to display the first time I open the activity. Once I know how to do that I'll be able to adapt and learn what I need. Here's the code I came up with:
public class StatsActivity extends Activity {
private XYMultipleSeriesDataset StatsDataset = new XYMultipleSeriesDataset();
private XYMultipleSeriesRenderer StatsRenderer = new XYMultipleSeriesRenderer();
private XYSeries StatsCurrentSeries;
private GraphicalView StatsChartView;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.stats);
LinearLayout layout = (LinearLayout) findViewById(R.id.Statschart);
StatsRenderer.setAxesColor(Color.YELLOW);
String seriesTitle = "Rank";
XYSeries series = new XYSeries(seriesTitle);
series.add(5, 7); //1st series I want to add
StatsDataset.addSeries(series);
series.add(9, 1); //the 2nd one
StatsDataset.addSeries(series);
StatsCurrentSeries = series;
System.out.println(series);
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.RED);
StatsRenderer.addSeriesRenderer(renderer);
StatsChartView = ChartFactory.getLineChartView(this, StatsDataset,StatsRenderer);
layout.addView(StatsChartView);
}
}
I've been reading the docs to determine what each function does but in the end I still can't get anything to display.
Thanks!
The big thing that I struggled with is that you need a renderer for each XYSeries. You have two series here, but just one renderer - I just create/add renderers when I input data. Also, Android is mostly pass-by-reference, so you've passed the same data set in twice (i.e. your second update to the data will be mirrored "in" the MultipleSeriesDataset).

How to invoke an ActionScript method from JavaScript (HTMLLoader) object in AIR?

So I have an Application Sandbox HTMLLoader object which I create in AIR and simply want to call ActionScript methods from JavaScript. In Flash, this is accomplished through our trusty ExternalInterface.addCallback() function. However in AIR, things are quite a bit different, and I just can't seem to get it to work.
Here is a simplified overview of my project:
My AIR (ActionScript) main:
public class Main extends Sprite {
public var _as3Var:String = "testing";
public function as3Function():void
{
trace("as3Function called from Javascript");
}
public function Main() {
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);
}
protected function onInvoke(e:InvokeEvent):void {
NativeApplication.nativeApplication.removeEventListener(InvokeEvent.INVOKE, onInvoke );
var app = new App();
addChild(app);
app.init(new ExternalContainer(), e.currentDirectory, e.arguments);
}
}
And this is how I create my HTMLLoader object:
{
_html = new HTMLLoader();
_html.useCache = false;
_html.runtimeApplicationDomain = ApplicationDomain.currentDomain;
_html.load(new URLRequest("sandbox/AirRoot.html"));
_html.width = 800;
_html.height = 600;
App.ref.addChild(_html);
}
And at last, here is my snippet of JavaScript in my AirRoot.html file which is trying to call the public method as3Function() declared in my Main class:
Exposed.testAs3 = function()
{
air.trace("Exposed.testAs3 called"); /* This works fine. */
air.trace("runtimeVersion:"); /* This works fine. */
air.trace(air.NativeApplication.nativeApplication.runtimeVersion); /* This works fine. */
air.trace("seeing if I can get to AS3 params..."); /* This works fine. */
/* This doesn't work - get the following error: TypeError: Value undefined does not allow function calls. */
air.NativeApplication.nativeApplication.as3Function();
}
What am I missing?
OK, I am going to answer my own question. I promise this was not a ploy to gain more reputation points, but I was seriously confused today but have now found the appropriate answers and documentation - which is usually the main problem to many an engineer's question...
Anyway, the answer:
The AIR HTMLLoader object contains a magical property, HTMLLoader.window, which is a proxy to the JavaScript window object. So setting HTMLLoader.window = AS3Function; is one way - or in relation to my previously included example (assuming I setup a static property called Main which pointed to the Main class):
_html.window.as3Function = Main.as3Function;
And now in JavaScript I can just call as3Function as:
<script>
window.as3Function();
</script>
Another interesting property is the JavaScript "window.htmlLoader" object. It is a proxy to the AS3 HTMLLoader parent object, in my case, the _html object. From this you can access things in relation to the _html object from JavaScript.
I'm not sure if this is a change in the new version of AIR, but you no longer need to reference the window in the javascript call, you can just do this:
<script>
as3Function();
</script>

Resources