How can one write a WatchOS widget for accessoryCorner family that renders appropriately? - watchos

I'm trying to build a widget that has a gauge like in the image attached. It does not seem like there are any APIs to render the gauge (or any other view for that matter) on an arc, depending on which corner is used.
Is there any such support, or are such widgets only available to Apple? E.g. can one tell which corner the widget is being rendered in, so that the correct transformations be computed?
Thank you!

You can get close to an Apple style corner widget, but there are currently some limitations. As far as I know you have to use the .widgetLabel modifier which restricts you to an "Image, Text, Gauge, ProgressView, or a container with multiple subviews".
The styling for the Gauge and ProgressView seem to be predefined as well - for example styling the gauge with .gaugeStyle(LinearCapacityGaugeStyle()) doesn't change the appearance.
var body: some View {
switch widgetFamily {
case .accessoryCorner: // WatchOS only
Text("50%") // Watch out for clipping
.font(.system(size: 20))
.foregroundColor(.blue)
.widgetLabel {
ProgressView(value: 0.5)
.tint(.blue)
}
}
}
or
var body: some View {
switch widgetFamily {
case .accessoryCorner: // WatchOS only
Text("50%") // Watch out for clipping
.font(.system(size: 20))
.foregroundColor(.blue)
.widgetLabel {
Gauge(value: 50.0, in: 0...100) {
Text("Not shown")
} currentValueLabel: {
Text("Not shown")
} minimumValueLabel: {
Text("0") // Watch out for clipping
} maximumValueLabel: {
Text("100") // Watch out for clipping
}
.tint(.blue)
.gaugeStyle(LinearCapacityGaugeStyle()) // Doesn't do anything
}
Gives you:
You can rotate the text manually to try and make it line up with corner, but as you say then there doesn't seem to be a way to identify which corner the widget is in so you don't know which way to rotate it...

Related

Does pdf.js allow rendering of a selected (rectangular) part of a page instead of rendering an entire page to a canvas?

Does pdf.js allow to render a PDF page only partially? More specifically, is it possible to tell pdf.js to render a selected "rectangle of pixels" out of an entire PDF page?
Assuming a resolution of 144 dpi, a typical page (DIN A4) would have approx. 684 (width) by 1190 (height) pixels. I would like to render (for example) a rectangle like [100, 100] (top left coordinate in pixels) and [400, 400] (bottom right coordinate in pixels).
A typical use case could be a scanned document with several handwritten notes that I would like to display and further process individually.
I do understand that a "workaround" could be to save the entire page as jpg (or any other suitable bitmap format) and apply some clipping function. But this would for sure be a less performant approach than selected rendering.
pdfs.js uses a viewport object (presumably containing parameters) for rendering. This object contains
height
width
offsetX
offsetY
rotation
scale
transform
viewBox (by default [0, 0, width / scale, height / scale])
One might think that manipulating the viewBox inside it might lead to the desired outcome, but I have found that changing the viewBox parameters does not do anything at all. The entire page is rendered every time that I apply the render method.
What might I have done wrong? Does pdf.js offer the desired functionality? And if so, how can I get it to work? Thank you very much!
Here is a very simple React component demonstrating my approach (that does not work):
import React, { useRef } from 'react';
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.js';
function PdfTest() {
// useRef hooks
const myCanvas: React.RefObject<HTMLCanvasElement> = useRef(null);
const test = () => {
const loadDocument = pdfjs.getDocument('...');
loadDocument.promise
.then((pdf) => {
return pdf.getPage(1);
})
.then((page) => {
const viewport = page.getViewport({ scale: 2 });
// Here I modify the viewport object on purpose
viewport.viewBox = [100, 100, 400, 400];
if (myCanvas.current) {
const context = myCanvas.current.getContext('2d');
if (context) {
page.render({ canvasContext: context, viewport: viewport });
myCanvas.current.height = viewport.height;
myCanvas.current.width = viewport.width;
}
}
});
};
// Render function
return (
<div>
<button onClick={test}>Test!</button>
<canvas ref={myCanvas} />
</div>
);
}
export default PdfTest;
My initial thought was also to modify a viewBox of page Viewport. This was not the right guess (I hope that you already figured it out).
What do you need really to do to project only a part of a page to canvas is to prepare correctly the transformation of Viewport.
So it will look more or less like following:
const scale = 2
const viewport = page.getViewport({
scale,
offsetX: -100 * scale,
offsetY: - 100 * scale
})
This will move your your box section to the beginning of the canvas coordinates.
What probably you would like to do next is to make a canvas equal to the selected rectangle size (in your case is 300x300 scaled by your scale) and this solved the issue in my case.

PDF view - view not showing unless zoom is out

I'm working on a swiftUI app where I have to display multiple PDF files in one screen.
I've created a PDFView:
struct PDFKitRepresentedView: UIViewRepresentable {
let url: URL
init(_ url: URL) {
self.url = url
}
func makeUIView(context: UIViewRepresentableContext<PDFKitRepresentedView>) -> PDFKitRepresentedView.UIViewType {
let pdfView = PDFView()
let pdfDocument = PDFDocument(url: self.url)
pdfView.document = pdfDocument
return pdfView
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PDFKitRepresentedView>) {
// Update the view.
}
}
struct PDFKitView: View {
var url: URL
var body: some View {
PDFKitRepresentedView(url)
}
}
The PDF is created here:
if let url = attachment.path {
PDFKitView(url: url)
.frame(width: UIScreen.screenWidth - 40, height: UIScreen.screenHeight - 40, alignment: .center)
.padding()
}
The problem I'm having is that, whenever the first document is multipage, in order to see the other documents the user has first to pinch to zoom out completely and the other PDF's are shown in sequence.
I've tried to add this values, but that just makes the content of the PDF to disappear
I was wondering if setting the frame on the PDFKitView directly could be causing the issue, but no.
Anyone has any suggestions on how to make this work? I assume that if I could make the pdf to show already with a min zoom it would display the view correctly.
I finally found the answer on this post How to detect where NaN is passing to CoreGraphics API on Mac OS X 10.9

Bootstrap affix smooth scroll

I have been working on bootstrap scrollspy (affix) and it worked fine. I added a script for a smooth movement whenever you click sections.
But it doesn't seem to be working properly.
When you click "section3", it's not move section3.
When you double click, it goes wrong section.
fix nav is not fixed and not showing on responsive.
This is an example page, with the following code:
$(document).ready(function() {
// Add scrollspy to <body>. changed to half-right-wrap
$('div.half-right-wrap').scrollspy({
target: ".navbar",
offset: 50
});
// Add smooth scrolling on all links inside the navbar
$("#myNavbar a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$('div.half-right-content').animate({
scrollTop: $(hash).offset().top
}, 600, function() {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
});
** Please have a look at PC size to see "affix nav"
How can we make it properly? I guess I added wrong selector in js. It was "body" and add my own selector.

Use Dojo boxConstrainedMoveable to constrain movable div to window

I have a div, to which I applied Dojo dojo/dnd/Moveable. But, I'd like to prevent the user from dragging the div offscreen. So, I think I need to implement dojo/dnd/move/boxConstrainedMoveable.
I'm starting with this:
var dnd = new Moveable(this.domNode, {
'handle': this.titleNode
});
There's a similar SO question here:
Constrain a moveable object in Dojo. Applying that answer, I get something like this:
var dnd = new move.boxConstrainedMoveable(
'handle': this.titleNode
constraints: {
l: 0,
t: 20,
w: 500,
h: 500
},
within: true
);
But, I just can't understand how the bounding box works. I simply want the div to stay inside the window. I've tried implementing a few things with the window box, the div's margin box. Nothing's worked, and all I've made is a big mess.
I read the docs here:
http://dojotoolkit.org/api/?qs=1.9/dojo/dnd/move.boxConstrainedMoveable
Has anyone done this with Dojo? I'd be very appreciate of an example.
I looked up some old code I have and I did implement this type of movable once. This was written against Dojo 1.7, so things may have changed in 1.9. Fiddle demonstration: https://jsfiddle.net/4ev1daqr/26/
The main difference between your attempted solution and this is that the constraints property in the moveable needs to be a function rather than a static bounding box. When using the boxConstrainedMoveable module, the static bounding box should be assigned to a box property, rather than the constraints property.
This is actually a nice design, IMHO, because it allows the constraints to react to changes in application state, e.g. hiding a sidebar or moving a splitter, but it does make the simple case a bit more difficult to get working.
define(["dojo/_base/declare",
"dojo/dnd/move",
"dojo/dom",
"dojo/_base/window",
"dojo/dom-style",
"dojo/dom-geometry",
],
function (declare, move, dom, win, domStyle, domGeom) {
return declare( "my/dnd/move/BodyConstrainedMoveable", [move.constrainedMoveable], {
markupFactory: function(params, node){
return new this(node, params);
},
constructor: function(node, params) {
// Constrain the node to be within the body
this.constraints = function() {
var n = win.body(),
s = domStyle.getComputedStyle(n),
mb = domGeom.getMarginBox(n, s);
if ( this.node ) {
var menubox = domGeom.getMarginBox(this.node);
mb.w -= menubox.w;
mb.h -= menubox.h;
}
return mb;
};
}
})});

QML application launcher similar to iOS

I'm trying to write an application launcher using QtQuick\QML, and I'd like the user experience to be similar to iOS, in terms of having a grid of icons that can be rearranged with icons that "move out of the way" via animated transitions and a "snap to grid" effect if the icon is dropped in an intermediate position. I've tried using GridView and the drag properties, but I can't seem to get the layout do what I want. What would be the best way to implement this type of app using QML? I'm fairly new to QtQuick, and I feel like maybe I'm missing something fundamental that would make this fairly easy\obvious to write.
For putting icons in a grid, you can use the grid view:
http://developer.qt.nokia.com/doc/qt-4.8/qml-gridview.html
Go through the Qt Quick documentation, you will find out how to do this.
This is not directly relevant to implementing the grid of icons, but I recently came across the QML component Loader. This lets you load QML components on demand, and could be useful for the code that launches an app after the icon is selected.
http://doc-snapshot.qt-project.org/5.0/qml-qtquick2-loader.html
I have made Nokia N9 launched look and feel (Maemo 6, or also known as MeeGo).
It is similar, I just scroll from up to down with icons, while you change "pages" from left to right (and vice versa).
I don't know is it best way, but this is how I did icon manager (its shrinked, this is only to give you idea - in reality it is considerably larger):
Item
{
id: root
function getChildAt(x, y) {}
function getIndexOfChild(child) {}
function moveChild(child, x, y)
{
//moving around icons
}
function setIndexToChild(child)
{
//index of child in Grid element (where to drop)
}
Flickable
{
id: scroller
clip: true
//you most likely want HorizontalFlick ("paging" effect you can add on onBeginingXChanged)
flickableDirection: Flickable.VerticalFlick
contentHeight: iconTable.height
contentWidth: iconTable.width
Grid
{
id: iconTable
width: root.width
anchors.top: parent.top
flow: Grid.LeftToRight
spacing: 10
add: Transition
{
NumberAnimation
{
properties: "x,y"
//make desired transition
}
}
move: Transition
{
NumberAnimation
{
properties: "x,y"
//make desired transition
}
}
}
}
}
You could also write down your own implementation of manager in C++ and later on use it in QML.
This is how it looks like:
I created something distantly connected to this recently, the idea is: create a ListView with snapping. Its delegate should contain a GridView. Separate all of the apps into n-element chunks. Then (it's only the idea)
ListModel
{
ListElement { apps: [app1, app2, ..., appn] }
ListElement { apps: [app1, app2, ..., appn] }
....
ListElement { apps: [app1, app2, ..., appk] }
}
Then populate the ListView with this model and the GridView with the apps property.
I don't know whether you can provide drag and drop here, though