UITextView in Catalyst, Input Source's character picker panel cover's characters - uitextview

I made a note app. Some user reports me a bug. When typing with Chinese Pinyin input source, character picker panel will covers characters in UITextView.
Xcode 12.4 MacOS 11.2.3
Wrong
Expectant
class ViewController: UIViewController {
let tv: UITextView = UITextView(frame: CGRect(x: 50, y: 50, width: 600, height: 200))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tv)
}
}

Related

How to set statusBar color on iPhoneX?

I use the navigationController, and i hide the navigationBar, how to set statusBar color on iPhoneX?
I do not want to set self.view.backgroundColor
iPhoneX notch color
UIView *statusBar = (UIView *)[[UIApplication sharedApplication] valueForKey:#"statusBar"];
statusBar.backgroundColor = [UIColor greenColor];
Here is a hacky trick to change/set background color for status bar during application launch or during viewDidLoad of your view controller.
extension UIApplication {
var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}
}
// Set upon application launch, if you've application based status bar
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
return true
}
}
or
// Set it from your view controller if you've view controller based statusbar
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
}
}
Here is result:
Swift 4
func setStatusBarBackgroundColor(_ color: UIColor) {
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }
statusBar.backgroundColor = color
}
In Interface Builder, I simply added a view at 0x0, 44px high and the same width as the top-level view, then set this view to the desired background color. This changed the background color of the status bar without affecting the view background color.
In my case, I needed something like this because the top half of my screen is one color and the bottom half is the other. I didn't see another way to make the status bar match the top color and the home button area match the bottom color.
This could easily be done programmatically if the extra view gets in the way on devices other than the iPhone X. In my case it doesn't cause problems on other devices.

How can set pop-up menu position in QML

I want to fix the position of pop-up menu in QML. When I click on a setting button,I want the pop-up menu will display at the fixed position. I did it by a day but can't. How can I do it in QML. Also, I want to change the size of menu item(width and Height).
Hope your help!
That depends on QtQuick.Controls version.
In 2.0 you can define size and position(and even more - you must do)
import QtQuick 2.7
import QtQuick.Controls 2.0
//import QtQuick.Controls 1.4
import QtQuick.Window 2.0
Window
{
id: window
width: 500
height: 500
visible: true
MouseArea {
anchors.fill: parent
onClicked: {
menu.x = (window.width - menu.width) / 2
menu.y = (window.height - menu.height) / 2
//menu.__popup(Qt.rect(200,200,100,100),0,0);
menu.open();
}
}
Menu {
id: menu
MenuItem { text: "item1" }
MenuItem { text: "item2"; }
MenuItem { text: "item3"; height: 100 }
}
}
In 1.4 (see commented lines) you can try Menu.__popup() but this function is private and the behavior is unpredictable.

How to add space between menus in javafx

I am trying to implement a menu. This is my code :
Menu menuFile1 = new Menu("ADD");
Menu menuFile2 = new Menu("EDIT");
Menu menuFile3 = new Menu("VIEW");
Menu menuFile4 = new Menu("HELP");
How can I put some space between each menu (that is between ADD,EDIT,VIEW and HELP) ?
Answer
Space around menus is controlled by padding (see the Region css guide).
For example:
menu.setStyle("-fx-padding: 5 10 8 10;");
sets the padding around the menu to 5 pixels on the top, 10 pixels on the right, 8 pixels on the bottom and 10 pixels on the left.
Sample
The following is a bit overcomplicated for a code sample to demonstrate this effect, but you could run it to see the effect of varying padding values.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringExpression;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SpacedOut extends Application {
#Override
public void start(final Stage stage) {
MenuBar menuBar = createMenuBar();
VBox controlPane = createControlPane(menuBar);
VBox layout = new VBox(10,
menuBar,
controlPane
);
VBox.setVgrow(controlPane, Priority.ALWAYS);
stage.setScene(new Scene(layout, 400, 200));
stage.show();
}
private MenuBar createMenuBar() {
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(
new Menu("ADD"),
new Menu("EDIT"),
new Menu("VIEW"),
new Menu("HELP")
);
return menuBar;
}
private VBox createControlPane(MenuBar menuBar) {
CheckBox useCustomPadding = new CheckBox("Use Custom Padding");
useCustomPadding.setSelected(false);
Slider padAmount = new Slider(0, 30, 15);
padAmount.setShowTickMarks(true);
padAmount.setShowTickLabels(true);
padAmount.setMajorTickUnit(10);
padAmount.setMaxWidth(200);
padAmount.disableProperty().bind(
useCustomPadding.selectedProperty().not()
);
VBox contentPane = new VBox(10,
useCustomPadding,
padAmount
);
contentPane.setPadding(new Insets(10));
StringExpression paddingExpression = Bindings.concat(
"-fx-padding: ", padAmount.valueProperty(), "px;"
);
menuBar.getMenus().forEach(
menu -> menu.styleProperty().bind(
Bindings
.when(useCustomPadding.selectedProperty())
.then(paddingExpression)
.otherwise("")
)
);
return contentPane;
}
public static void main(String[] args) {
launch(args);
}
}
With the setStyle() Method you can pass one or more css styles in one string.
Like menuFile1.setStyle("-fx-border-color: red; -fx-effect: dropshadow( one-pass-box , red , 10,0.5,0,0 );");
Alternatively you could put your style information inside a css file and add it to the Scene through.
Scene somescene = new Scene(root)
somescene.getStylesheets().add("your.css");
See the css reference of Java FX 2 or this tutorial.

Less CSS trickery for hover and multiple fonts on button with round edges

Goal: Create a round button that has multiple text fonts.
Example: See RoundButtonWithMultipleFonts.java and RoundButtonWithMultipleFonts.css
RoundButtonWithMultipleFonts.java:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class RoundButtonWithMultipleFonts extends Application {
public static void main(String... args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Button with multiple fonts?");
stage.setScene(new Scene(getRoot(), 400, 400));
stage.getScene().getStylesheets().addAll(getClass().getResource("RoundButtonWithMultipleFonts.css").toExternalForm());
stage.sizeToScene();
stage.show();
}
private Parent getRoot() {
Button button = new Button(""); // The labels should be the buttons text
button.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
System.out.println("Button clicked");
}
});
Label header = new Label("A Prideful Header"); // Label for big font on button
header.getStyleClass().addAll("header");
Label footer = new Label("a humble footer"); // Label for small font on button
footer.getStyleClass().addAll("footer");
// Since the labels are on top of the button, pass any events they capture to the button
configurePassThroughEvents(button, header, footer);
StackPane stack = new StackPane();
stack.getChildren().addAll(button, header, footer);
return stack;
}
private void configurePassThroughEvents(Control targetControl, Control... sourceControls) {
MouseEventPassThrough passThroughEvent = new MouseEventPassThrough(targetControl);
for(Control sourceControl : sourceControls) {
sourceControl.setOnMouseClicked(passThroughEvent);
sourceControl.setOnMouseDragged(passThroughEvent);
sourceControl.setOnMouseDragEntered(passThroughEvent);
sourceControl.setOnMouseDragExited(passThroughEvent);
sourceControl.setOnMouseDragOver(passThroughEvent);
sourceControl.setOnMouseDragReleased(passThroughEvent);
sourceControl.setOnMouseEntered(passThroughEvent);
sourceControl.setOnMouseExited(passThroughEvent);
sourceControl.setOnMouseMoved(passThroughEvent);
sourceControl.setOnMousePressed(passThroughEvent);
sourceControl.setOnMouseReleased(passThroughEvent);
}
}
private static class MouseEventPassThrough implements EventHandler<MouseEvent> {
private final Control targetControl;
private MouseEventPassThrough(Control targetControl) { this.targetControl = targetControl; }
#Override public void handle(MouseEvent mouseEvent) { targetControl.fireEvent(mouseEvent); }
}
}
RoundButtonWithMultipleFonts.css:
.button {
-fx-border-width: 1px;
-fx-border-color: #000000;
-fx-border-radius: 45;
-fx-background-color: linear-gradient(#ffffff 0%, #cccccc 100%);
-fx-background-radius: 45;
-fx-padding: 50 100;
}
.button:hover {
-fx-background-color: linear-gradient(#ffffff 0%, coral 100%);
}
.label {
-fx-padding: 10;
-fx-background-color: cornflowerblue;
}
.header {
-fx-font-size: 110%;
-fx-font-weight: bold;
-fx-translate-y: -20;
}
.footer {
-fx-font-size: 80%;
-fx-translate-y: 20;
}
Runtime Results:
Problem:
When the mouse scrolls over one of the button's corners, the button enters the hovered state, but the mouse is still outside the visual bounds of the button indicated by the button's border and background. (See image.)
This example uses a stack pane, multiple labels, an event pass through mechanism, and css trickery to give the appearance of a button containing text with multiple fonts.
Questions:
How can I specify that the button should enter the hovered state only if the mouse collides with the buttons visual boundary as specified in the css with the border or background properties?
Is there a simpler way to specify multiple fonts (with general text layout) for a button than what is done in this example? Ideally I would want to just use a Button with a nested Node as the text. That would allow me to put anything I wanted inside the buttons textual area without needing the event pass through mechanism, the StackPane, and the css trickery.
You can use setGraphic(Node node); method of Button class to set your custom labels on button. Here is an example,
Label header = new Label("A Prideful Header");
header.getStyleClass().addAll("header");
Label footer = new Label("a humble footer");
footer.getStyleClass().addAll("footer");
VBox box = new VBox();
box.getChildren().addAll(header,footer);
Button button = new Button();
button.setGraphic(box);

How to implement a transparent Pane with non-transparent children?

How can i implement a transparent panel with non-transparent children in JavaFX 2?
The effect i want to achieve is for example applied to menus in Blender:
The menu-panel / window is transparent, but the text items are not transparent which leads to a pretty effect.
Set the background of your pane to a color with an alpha component. You can use a stylesheet or an inline style for this.
For example, if your pane was named glass, then the following will give it a rounded, translucent cyan background:
glass.setStyle("-fx-background-color: rgba(0, 100, 100, 0.5); -fx-background-radius: 10;");
You could also accomplish similar effects using blends, stackpanes or groups of items with the opacity set for items at the back of the stackpane or group.
Here is an executable example using the css background method.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class TranslucentPane extends Application {
#Override public void start(final Stage stage) throws Exception {
final ImageView imageView = new ImageView(
new Image("https://upload.wikimedia.org/wikipedia/commons/b/b7/Idylls_of_the_King_3.jpg")
);
imageView.setFitHeight(300);
imageView.setFitWidth(228);
final Label label = new Label("The Once\nand\nFuture King");
label.setStyle("-fx-text-fill: goldenrod; -fx-font: italic 20 \"serif\"; -fx-padding: 0 0 20 0; -fx-text-alignment: center");
StackPane glass = new StackPane();
StackPane.setAlignment(label, Pos.BOTTOM_CENTER);
glass.getChildren().addAll(label);
glass.setStyle("-fx-background-color: rgba(0, 100, 100, 0.5); -fx-background-radius: 10;");
glass.setMaxWidth(imageView.getFitWidth() - 40);
glass.setMaxHeight(imageView.getFitHeight() - 40);
final StackPane layout = new StackPane();
layout.getChildren().addAll(imageView, glass);
layout.setStyle("-fx-background-color: silver; -fx-padding: 10;");
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) { launch(args); }
}
Sample program output:

Resources