SkiaSharp in Blazor for desktop app without WASM ( Blazor Hybrid? ) - razor

I want to use SkiaSharp in a Blazor desktop app ( Windows, Mac, Linux, etc. )
I know about Blazor Hybrid ( Blazor Desktop ) but I didn't find any way to integrate SkiaSharp.
So basically what I want is a way to use SkiaSharp in a Blazor desktop app but without WASM. Does such a thing exist?

Short Answer: No; Not Possible. (Unless I am fundamentally wrong about some detail below.)
Long Answer:
In Blazor Hybrid, the view is essentially a browser window.
For what you seek to be possible, it has to be fully compatible with web standards.
So even though this is inside a desktop app, it comes down to asking how to do SkiaSharp inside a browser.
Therefore, it has to run in WASM.
OTOH, you CAN run SkiaSharp in the NOT BLAZOR part of Maui.
But that won't be inside a Blazor Component.
If you've laid out a Maui screen (window) such that Blazor WebView is only part of what is showing, SkiaSharp could be somewhere on the screen; just not integrated into Blazor.
Its even possible to OVERLAY other Maui controls on top of the Blazor View. But the Maui controls and the Blazor content won't be aware of each other's location on the screen.
Using SkiaSharp in Maui:
Include Nuget SkiaSharp.Views.Maui.Core.
Namespace: SkiaSharp.Views.Forms
Class: SKCanvasView.
In XAML:
<ContentPage ...
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class=...>
...
<skia:SKCanvasView ... PaintSurface="OnYourPaintThisSurface" ... />
In c# code-behind:
using SkiaSharp;
using SkiaSharp.Views.Forms;
...
private void OnYourPaintThisSurface(object sender, SKPaintSurfaceEventArgs args)
{
... // your paint code here
}

Related

Is it possible to launch mobile sensor with html5 but only with android webview?

I mean without cordova or other framework. I'm pretty sure i need to write Java code and link it somehow with html5 through the android webview.
If it is possible, can get a little example how to connect to the camera or other sensor.
Some of the sensors have a JavaScript API such as geolocation, orientation (gyroscope) and the battery. To access the camera you could use MediaDevices.getUserMedia, however, this is still in an experimental stage and is not supported by all Android devices. For more information refer to this link.
Look into JavascriptInterface
https://developer.android.com/reference/android/webkit/WebView.html
https://developer.android.com/guide/webapps/webview.html
Specifically, addJavascriptInterface(java.lang.Object, java.lang.String))
#JavascriptInterface
class JsInterface {
public void startCamera() { ... }
}
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsInterface(), "androidInterface");
Basically, add the JavascriptInterface, and enable javascript on the web view. Then in your javascript you can detect if the interface exists like so:
if ("undefined" != typeof androidInterface) {
androidInterface.startCamera();
}
Now in the Java code for startCamera, you can do whatever native stuff you need done.

How to prevent AIR application from jerking around while dragging?

I've created an AIR application and it seems to be working fine but when I drag the title bar to move the native window it shakes violently and have seizures while it's dragging about.
FYI It does eventually end up where I want it to be when I stop moving the mouse.
I'm using Flex 4.6 and AIR 3.6 on Mac OSX 10.10.5. It's a s:WindowedApplication I'm also using the DragManager on a list in part of the application if that matters but it is not enabled until the user clicks into the list and moves more than a certain number of pixels.
Here is my descriptor file minus name and version info:
<application xmlns="http://ns.adobe.com/air/application/3.6">
<initialWindow>
<autoOrients>false</autoOrients>
<fullScreen>false</fullScreen>
<visible>false</visible>
</initialWindow>
</application>
On initialize I run this:
protected function initializeHandler(event:FlexEvent):void {
width = Capabilities.screenResolutionX * .96;
height = Capabilities.screenResolutionY * .9;
nativeWindow.x = (Screen.mainScreen.bounds.width - width)/2;
nativeWindow.y = (Screen.mainScreen.bounds.height - height)/2;
}
UPDATE:
I removed the main view component so it is an empty application and it drags around smoothly.
UPDATE 2:
I added the main view back in and dragged around step by step along the way. It appears to start happening when I've loaded a second Application (called a sub application) into the main application. I'm not sure though.
This happens in numerous number of my applications. It is probably because I have a component inside my application file set to size to 100% of the application. But I have not verified this on all my apps.
The solution is to resize the AIR app. After I resize it it works fine. I can drag it around and it works as expected. I think this is an AIR bug.

Adobe Air - Starling/Features | Controls and device simulator

I have few questions here, regarding creating app in Adobe Air using Starling and feathers.
I created yet a very simple app, which has Feathers list controller with static data provided to its dataProvider. According to the code it should work fine, but there are three major issues I am facing.
1: Touch/Click Positions
I am using:
list.addEventListener( Event.CHANGE, list_changeHandler );
Now the problem is, clicking coordinates are not correct. Clicking on 3rd Item triggered 4th item, to trigger 3rd, 2nd item needs to be clicked it's half way through etc.
2: Nothing, without Theme
I am using a custom theme, came along with a tutorial. If I don't use the theme, I am unable to see anything on the screen, somehow.
3: Resolution (Device Simulator) Problem
Though buggy, but it works with Theme, but my app doesn't fit with the resolution for each device simulator. Either its, iPad or iPhone 4 or any android simulator.
Also, can anyone please also explains, what is significance and use of Context3D render mode in starling class.
Any help is appreciated:
Thanks in advance
Waqar Iqbal
Starling is a Stage3D framework that displays content directly on graphic card using Context3D. Everything displayed by Starling is always under the regular display list. Feather is a component framework based on Starling.
Stage3D cannot handle any mouse operations so Starling and Feather simulate all their mouse event (those mouse event never really happen anywhere, they are created by calculation of mouse position on the stage)
not sure, never used Feather
Starling does not handle screen density and dpi calculation, if you want your app to fit any screen you'll have to handle it yourself.
I think you should see the example carefully. if u want to use any feathers component either you have to use feathers theme or custom theme.
if you use feather theme you need to provide theme path and before using any component you need to initialize that theme.Then use component any where.without theme you will not see any thing.
1: Touch/Click Positions
please provide minTouchHeight in class theme of DefaultListItemRenderer like:-
renderer.minWidth = this.gridSize;
renderer.minHeight = this.gridSize;
renderer.minTouchWidth = this.gridSize;
renderer.minTouchHeight = this.gridSize;
2: Nothing, without Theme,
3: Resolution (Device Simulator) Problem
Follow the example given in feather library
feathers-2.1.1\themes\MetalWorksMobileTheme\source\feathers\themes

How does one implement pull-to-refresh with a LongListSelector in Windows Phone 8?

I am writing a new WP8 app using the off-the-shelf LongListSelector that is shipped in the Microsoft.Phone.Controls assembly. Can anyone provide a code example that implements pull-to-refresh, originally made popular by Tweetie for iPhone and now common on iOS and Android? The existing examples use non-standard controls and I'd like to maintain my use of LongListSelector in WP8.
EDIT
I have found a good answer on StackOverflow describing the Twitter sample and how to do this in more detail:
Continuous Pagination with LongListSelector
You do not.
Pull-to-refresh is not a standard Windows Phone interaction, and you therefore should not implement it.
No native/first-party Windows Phone application use this functionality, and almost no third-party application does either. There is a reason for that.
To refresh the content of a page (or in your case, a LongListSelector), you should use a refresh ApplicationBacIconButton, just like in the Mail app. That's the standard and preferred way to manage refreshes.
Windows Phone is not Android, nor is it iOS. Keep that in mind when designing an application for it.
It is not a zoo, there are rules.
Actually, I just discovered a project uploaded to the Windows Phone Dev Center on November 30, 2012 that implements "infinite scrolling" using Twitter Search and Windows Phone 8 LongListSelector.
Download this project at: http://code.msdn.microsoft.com/wpapps/TwitterSearch-Windows-b7fc4e5e
If you really must do this (see answer by Miguel Rochefort) then details can be found at http://blogs.msdn.com/b/jasongin/archive/2011/04/13/pull-down-to-refresh-a-wp7-listbox-or-scrollviewer.aspx
Basically, the ScrollViewer has hidden/undocumented states that allow for detecting "compression" at the top or bottom of the list and you can use this to trigger the loading.
This is not completely trivial, but one way of doing it is to use GestureService
this.gestureListener = GestureService.GetGestureListener(containerPage);
this.gestureListener.DragStarted += gestureListener_DragStarted;
this.gestureListener.DragCompleted += gestureListener_DragCompleted;
this.gestureListener.DragDelta += gestureListener_DragDelta;
However, it has some bugs. For example, DragCompleted is not always raised, so you need to double-check for that using ManipulationCompleted event, which seems to be more reliable.
containerPage.ManipulationStarted += delegate { this.manipulationInProgress = true; };
containerPage.ManipulationCompleted += delegate
{
this.manipulationInProgress = false;
PerformDragComplete();
};
Another issue is that DragDelta occasionally reports bad coordinates. So you would need a fix like this:
Point refPosition = e.GetPosition(null);
if (refPosition.X == 0 && refPosition.Y == 0)
{
Tracer.WriteLine("Skipping buggy event");
return;
}
Finally, you can find if list is all the way at the top:
public double VerticalOffset
{
get
{
ViewportControl viewportControl = this.FindChildByName("ViewportControl") as ViewportControl;
if (viewportControl != null)
{
Tracer.WriteLine("ViewPort.Bounds.Top=" + viewportControl.Bounds.Top + " ViewPort.Top=" + viewportControl.Viewport.Top.ToString() + " State=" + this.ManipulationState);
return viewportControl.Bounds.Top - viewportControl.Viewport.Top;
}
return double.NaN;
}
}
You can check out the samples in
https://github.com/Kinnara/WPToolkit
it has an excellent implementation something called a ListView extension of the longllistselector control, that will really help you out.
and remember with longlistselector always try to load 20 items atleast. =)
As the WP8 LLS doesn't use a scrollviewer, I guess you will have to inspect the UI tree to get a hold on the viewport control and see what you can do with ViewportControl.Viewport property ...
Oh ... the twitter application is now using the pull to refresh interaction. I like the UI guidelines of the WP platform but rules, once mastered, are made to be broken ;)
This post here can give you hints on how to get the viewport control and retreive the scrolling offset. this scrolling offset must be of a particular value when the list is bouncing

Handling JavaScript calls to window.open()- not using Native Windows - Adobe AIR

I am developing an Adobe AIR application which uses both native windows and floating panels. Is is possible to enable the creation of a floating window instead of a native window when a JavaScript window.open() function is called?
It is required that all of the floating windows are contained within one native window, therefore the creation of more native windows is not suitable.
I have used a Custom HTMLHost class in order to enable the creation of a native window but I can’t work out a way of creating a MDI window instead. I am using the flexMDI framework for my floating panel interface.
Any help on this would be much appreciated.
You can try hijacking the HTML's window object via code:
htmlContent.addEventListener(Event.COMPLETE, htmlLoaded);
private function myOpenFunction(...args) {
// Do stuff with args
}
private function htmlLoaded(event:Event):void
{
htmlContent.domWindow.open = myOpenFunction;
}
I'm not sure if that (or something very similar) will work, but it's probably the only way to do it if it can be done at all.