OpenLayers3 - is it possible to combine modify/draw/select operations? - openlayers-3

I've started using OpenLayers3 in my app, and so far, I have succeeded in creating working versions of:
a combined draw/modify page (based on the relevant example, draw-and-modify-features.js)
a combined select/modify page (based on the relevant example, modify-features.js)
In the case of (1), the ol.interaction.Modify instance specifies that it will work on the features inside an ol.FeatureOverlay instance:
var modify = new ol.interaction.Modify({
features: featureOverlay.getFeatures()
...
...and it is that ol.FeatureOverlay that holds all the new features drawn by the user.
In the case of (2), the ol.interaction.Modify instance specifies that it will work on the features inside the ol.interaction.Select instance:
var select = new ol.interaction.Select();
var modify = new ol.interaction.Modify({
features: select.getFeatures()
});
...and unless I am mistaken, this creates a hidden ol.FeatureOverlay that holds the currently selected feature - which is then edited.
However, I can't see a way to combine all 3 - i.e. a user-friendly way to allow a user to draw, select and modify polygons.
What I'd (ideally) want is the functionality of draw/modify, but the moment I hit and keep Ctrl pressed, the cursor is no longer working in "draw" mode, but in "select" mode, allowing me to select one of the existing polygons, and subsequently hiting Delete on the keyboard to delete it, or just edit its vertices with the mouse. As soon as I click outside all polygons, I return to draw/modify mode.
I did the naive test - that of adding an ol.interaction.Select to the interactions of the draw/modify Map instance - which lead to hilarious results :-) For example, upon finishing the drawing of a polygon (i.e. when I double-click to close it) it's also getting selected... and clicking anywhere (inside or outside polygons) just starts another new polygon edge, it never selects a pre-existing one - etc.
My only thought of a solution so far is... for me to implement a "VI emulation" :-) i.e. a "command" mode (that is, the select/modify state) and an "insert" mode (i.e. the draw/modify state) - and you chose what mode you are in from a "state toggle" button inside the map (custom OL3 control) or outside the map (normal HTML button) .
I am, however, looking for a better way, like the one I suggested with holding Ctrl...
Any ideas/suggestions most welcome.

I never found a solution combining all three modes. Since no answer came up, I might as well share that in the end, having a "modal" form of working (i.e. hitting a custom control - a map-internal button - to enter "Select Mode") is not that bad. I ended up with a "Select mode", a "Draw/Modify mode", and a "Measure" mode - selectable via map-internal buttons:
In the end, it turned out fine - in hindsight, having a "combo" mode would in fact present significant usability disadvantages.

Related

SwiftUI TextField with non-default keyboard does not update the bound value

I am using a TextField to update a numeric value in my app model. The page editing the values is triggered from a NavigationView. Everything works fine when I use a default keyboard, ie:
TextField("Enter a number", value: $userData.chosenNumber, formatter: NumberFormatter())
.keyboardType(.default)
will update the value of userData.chosenNumber when hitting the Return key and this change is reflected on the main navigation screen (userData is an EnvironmentObject).
However, the same code using .keyboardType(.numberPad) instead won't show a Return key, and userData.chosenNumber won't be updated when navigating back to the main view. This happens both in the simulator and live on device (but things work as expected using SwiftUI live preview, or in the simulator when hitting the physical keyboard Return key).
Is there a way to get the new value picked up please without having to use a default keyboard?
--Edit--
Based on pawello2222's suggestion in the comments, I tried the solution in this other SO's question but that didn't fully work in my case.
What the other question suggests: introducing a Binding<String> (via a computed property) that acts as intermediate between the value I want to modify and the string displayed in the UI.
This works to modify the value inside my view.
However the runtime fails to detect that the EnvironmentObject injected by the parent view is modified, so after leaving the view the app UI is not refreshed and the other views do not get updated.
(For some context, my app computes a diver's bottom time based on an air tank site and the diver's air consumption. The detail view is used to edit the diver's air consumption value while another view displays the resulting bottom time. So in my case the diver's consumption gets updated, but the bottom time doesn't receive an update, unlike what happens with a standard keyboard.)

How to remove map Places and annotations from MKMapKit in Objective c

Hi i have an MapView in My Project i need to remove all the labels Annotations, places from MapView. Looks like Plain mapView
i tried the Following Code its working fine but still i getting some building details, Street names and all i want that also to be removed only User Location Can be Visible
here is the code:
[mapView setShowsPointsOfInterest:NO];
the above code working fine and removed default location icons from mapKit but not removing all Icons and Label, how to remove all default icons and label names from MapKit
starting with iOS 11, you can set
mapView.mapType = .mutedStandard
This removes distracting details from the map.
Apple uses this type of map, when they want to emphasise a transit route and everything else should be in the background without distracting.
Starting with iOS 13 you have even more fine grained control:
Using MKMapKit.pointOfInterestFilter you can include or exclude specific categories of points of interest.
So if you're making an App 'Best restaurants in my city', your app has its own restaurant annotations, you remove the restaurant category from Apple's point of interests, but all other POI categories are just fine for you.
https://developer.apple.com/documentation/mapkit/mkmapview/3143417-pointofinterestfilter?language=objc
Starting with iOS 16 most APIs described above are deprecated, but the ideas remain the same.
Now you set MKMapView.preferredConfiguration to a subclass of class MKMapConfiguration. These subclasses are
MKStandardMapConfiguration
MKHybridMapConfiguration
MKImageryMapConfiguration
Each of these classes have exactly those parameters that make sense for the type of map.
For example, MKImageryMapConfiguration shows no POIS and no roads, so it makes no sense that this class has parameters like pointOfInterestFilter or showsTraffic.
Classes MKStandardMapConfiguration and MKHybridMapConfiguration now have a parameter pointOfInterestFilter that has been in MKMapKit.pointOfInterestFilter in earlier iOS versions.
Old deprecated mapView.mapType = .mutedStandard is now init parameter emphasisStyle of class MKStandardMapConfiguration
P.S.
Please also have a look at the other answer of #Grimxn. Bringing your own overlay is much effort but a valid alternative.
It seems to be a bit of a kludge.
Firstly, you replace the map with an overlay of your own...
self.mapView.insertOverlay(underlay, at: 0, level: MKOverlayLevel.aboveLabels)
This can be anything. If you want to use Google Maps, or Open Street Map, you can, like this:
let url = "http://mt0.google.com/vt/x={x}&y={y}&z={z}"
//let url = "http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
let underlay = MKTileOverlay(urlTemplate: url)
underlay.canReplaceMapContent = true
alternatively, if you just want blank, give it a default layer:
let underlay = MKTileOverlay()
underlay.canReplaceMapContent = true
The parameter level: allows you to specify whether your background obscures just their background map, or the background & roads or the background & labels, but NOT above everything. The documentation says:
MKOverlayLevel.aboveLabels
case aboveLabels = 1
Place the overlay above map labels, shields, or point-of-interest
icons but below annotations and 3D projections of buildings.
I can't get that to work for the default MKTileOverlay() - it seems to do the same as the alternative .aboveRoads - i.e. it hides all of the map including roads, but not labels. When you specify one of the external overlays (e.g. google) - they DO replace the labels. Probably a bug, so the final step, to completely obliterate the labels is
self.mapView.mapType = .satellite
This removes the labels, and your overlay is hiding the satellite map. Not neat, but not difficult, either.
In case anyone is coming back to this, as of writing this, if you want literally just a map and road names, no points of interest, just use
mapView.pointOfInterestFilter = .excludingAll

Xcode/Objective-C implementing a players turn toggle

I'm new to the whole VCM programming structure and more specifically to objective-c.
Right now i'm working on an iOS app that is like the game "connect 4." This Xcode project is my practice project that i've been using to play around/learn how to make iOS apps so there are several files and lots of commented out code, so Ill try my best to provide the necessary content from my project.
App State:
Right now I have a 10x10 grid of blue square/buttons. I'm still in the early stages of implementing the functionality of the game. Rather than making each square its own button, I created 10 frames and 10 buttons. Each row is a single button, which is broken up into 10 squares.
I currently have the squares change their color to red and become disabled once clicked. If I click multiple times.. the squares turn red when pressed. Heres a screenshot example run:
What Im wanting to do:
I want to build off of what I have, but not exactly sure how to keep track of which "players turn" it is. For example.. I want the first clicked square to turn red, representing player1's move. I want the second click to turn the button, say green, representing player2's move.. then the next move will be player 1's move.
I know Ill have to make sure the button is/was ENABLED and valid before switching which players turn it is.
How should I go about doing this? This is more of a general question, but I'll provide needed code snippets if necessary. Thanks!
In your .h file add an integer (variable)
int Turn = 1;
In your .m file you can do:
if(Turn == 1)
{
// Player one is playing
Turn = 2;
}
else if(Turn == 2)
{
// Player two is playing
Turn = 1;
}

Change found text highlight in a Firefox extension

I'm developing an extension for Firefox which searches terms in a page. And I'd like to change found text highlight color and background. For example, I search for a letter "s" and by default it's selected with a blue rectangle with white text color. So I want to change the blue to the red.
How could I do this via JS?
Edit0:
To select a found text I use document.createRange() and selection.addRange() methods.
I don't know how the default finder selects a found term and applies background to it.
So maybe the 'range' method is not the best.
But I think I'm searching a way to highlight this created range...
Edit1:
Now I've partially resolved the color-changing preoblem. Just add a CSS rule with ::-moz-selection and red background when a text is found and selected. Then for document 'onmousedown' I remove this rule not to leave the default selection as red.
But a new problem is when I find say a digit and it gets a selection the background of that selection is gray (so it looks like a text selection of an inactive window). Then when I click with my mouse somewhere in the document text and press F3 the extension finds the next digit and selects it with the red background. And next findings work right (with red background).
So my purpose is change that initial gray background to red.
Maybe I should change the inactive selection color...
Edit2:
Now I updated my JS code:
var selection=w.getSelection()
var range=w.document.createRange()
range.setStart(foundNode,foundOffset)
range.setEnd(foundNode,foundOffset+foundLength)
selection.removeAllRanges()
selection.addRange(range)
var controller=gBrowser.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
controller.setDisplaySelection(controller.SELECTION_ATTENTION)
controller.repaintSelection(controller.SELECTION_NORMAL)
Thanks to Noitidart's answer I found some information on how to use nsISelectionController XPCOM interface to select found text with background. Still I can't set a custom color for this background so that it be different from the default color of found text in Firefox. But setting the ui.textSelectBackgroundAttention preference in about:config to desired color will work with both my extension and default find engine.
I've found that SELECTION_ATTENTION constant is responsible for that background color and the setDisplaySelection method links the color to the selected text. But I couldn't find any implementation of this method. I saw only nsISelectionController idl file with its structure but no correspondent .cpp or .js file implementing this .idl. So I don't have information on how the color is set.
Edit3:
Recently I added the "Highlight All" functionality to my extension. And a new question about color of this highlight has rised. Using the above tecnique will show all the matches with green find color (by default). But it's more comfortable to use a different color to distinguish the current match and others.
So I couldn't find another helpful nsISelectionController constant for the "Highlight All" selection. I simply set this selection to 'DISABLED' type and changed the ui.textSelectBackgroundDisabled about:config pref. This pref is obviously for the selected text background of an inactive window. And it worked for me.
controller.setDisplaySelection(controller.SELECTION_DISABLED)
Another thing is that I'm not sure that the controller.repaintSelection() in the previous Edit is necessary. I guess the selection didn't work without it when I started my experiments with this stuff. But now I removed that line and all still work.
Plus:
And some additional links if somebody will need:
nsISelectionController Reference
Selection Reference
Forum question about highlight
about:config prefs for highlight
An Add-on using a similar tecnique
Finder.jsm and other sources
Also I used some files from Firefox source archive: Firefox 33 Source:
- nsISelectionController.idl [\content\base\public\]
- nsTypeAheadFind.cpp [\toolkit\components\typeaheadfind\]
- Finder.jsm [\toolkit\modules\]
- findbar.xml [\toolkit\content\widgets\]
I asked this question to quicksilver via email and this is what he told me:
You might find this one helpful: https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsISelectionController
I'm hardly the master you think I am, actually. :) To change those colors I just change the values for preferences:
ui.textHighlightBackground
ui.textHighlightForeground
ui.textSelectBackgroundAttention -> SELECTION_ATTENTION, it's not a highlight, it's a normal selection (as you would select some text with your mouse and it would turn the regular blue blackground, in windows at least) but it's given "attention", so it has the green background that the find operation reports. Basically it's a way of showing the user "Here I am!!" after firefox automatically selecs the text he searched for.
And I really don't know most of those contants, SELECTION_NORMAL is for normal text selection, like it would be when you select text with your mouse, SELECTION_FIND is for the highlights, and I only know the ON/HIDDEN/OFF/DISABLED ones which are self-explanatory. SELECTION_SPELLCHECK is probably for the auto-correct when you are typing in an editable content node, but I'm just guessing that one from the name.
Also, as far as I know, it's not possible to just create custom selection ranges/contants, as the code simply won't recognize them without editing the C++ code as well. Which is actually one of the reasons I haven't implemented https://github.com/Quicksaver/FindBar-Tweak/issues/76 yet.

ISQL 7.3 Perform screens with 132-columns

If I change SuSE's terminfo to 132-column (co#132) and in my Perform .per code specify
SCREEN SIZE 24 BY 132, would I be able to fit more field tags past the 80-column mark and it display them properly?.. I want to cram more stuff into one screen without having to split it up into separate screens. Has anyone done this before?
Assuming you have set INFORMIXTERM=terminfo so Perform uses Terminfo, then yes, what you suggest should work. It is a long while since I last did this, but it worked back in the early '90s on real green (or orange) screens - like Wyse 60 terminals.

Resources