I want to display 2 "floating buttons" a bit on top of a BottomNavigationView if one of its menu is clicked.
Here's my attempt. Basically it uses an AlertDialog supplied with a LinearLayout (full code: https://github.com/anta40/ButtonAnimTest)
bottomNav.setOnItemSelectedListener { menu ->
when (menu.itemId){
R.id.game_menu -> {
val dialogBuilder = AlertDialog.Builder(this)
val customView = layoutInflater.inflate(R.layout.custom_alert_layout, null)
dialogBuilder.setView(customView)
dialogBuilder.setCancelable(true)
val btnYes = customView.findViewById<Button>(R.id.btn_dialog_yes)
val btnNo = customView.findViewById<Button>(R.id.btn_dialog_no)
/*
taken from https://stackoverflow.com/questions/9467026/changing-position-of-the-dialog-on-screen-android
*/
val alert = dialogBuilder.create()
val dialogWindow = alert.window
val layoutParams = dialogWindow!!.attributes
layoutParams.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
layoutParams.flags = layoutParams.flags and WindowManager.LayoutParams.FLAG_DIM_BEHIND.inv()
dialogWindow.attributes = layoutParams
dialogWindow.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
btnYes.setOnClickListener {
alert.dismiss()
}
btnNo.setOnClickListener {
alert.dismiss()
}
alert.show()
true
}
}
false
}
}
There are 2 problems:
The LinearLayout is displayed too high, aligned with the TitleBar. What I want is just a little bit on top of the BottomNavigationView, like 10dp or 20dp.
The screen is dimmed a bit. I don't want the brightness to be changed when those buttons appear.
How to fix these?
Related
I get in trouble with the fact of after clicking on a button : I would like my table is set at bottom of my button but it's not that
I've managed to get it without after clicking a button but without, I've tested many things and nothing.
Here is the code :
contents = new BoxPanel(Orientation.Horizontal) {
contents += Button("Top 10 most commun runways latitude") {
val headers = Array.tabulate(10) {"Col-" + _}.toSeq
val rowData = Array.tabulate[Any](10, 10) {"" + _ + ":" + _}
contents += new ScrollPane(new Table(rowData, headers))
}
contents += Button("10 highest and lowest number of countries") {
}
contents += Button("Type of runways per country") {}
}
What I get
What I would like
Desired Result:
How do I set border(red) to my PDAnnotationTextMarkup? Just need to work with AdobePDF mainly.
def addCoordinates(cord: List[Coordinates], page) : PDPage = {
val annotations = page.getAnnotations
val borderThick = new PDBorderStyleDictionary()
borderThick.setWidth(0.8.toFloat)
borderThick.setStyle(PDBorderStyleDictionary.STYLE_SOLID)
cord.foreach {
val textM = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT)
textM.setBorderStyle(borderThick)
textM.setColor(yellow)
// Set rectange and quads
annotations.add(markup) // Need to set border to markup?
// Below code i was able to get red border with Square annotation.
// This is more kind of workaround, see two annotations in Adobe PDF (not user friendly.)
val aSquare = new PDAnnotationSquareCircle(PDAnnotationSquareCircle.SUB_TYPE_SQUARE)
aSquare.setColor(red);
// set rectange and quads
annotations.add(aSquare)
}
page
}
I want to show a list of key and values in a TreeTableView, and some of the values are a bit longer text which I want to wrap around and show completely.
I thought I use TextFieldTreeTableCell with wrapText and vgrow as follows:
val valCol = new TreeTableColumn[(String,String), String] {
text = "Header"
cellValueFactory = { p => StringProperty(p.value.value.value._2) }
cellFactory = { p => new TextFieldTreeTableCell[(String,String),String]() {
wrapText = true
vgrow = Priority.Always
} }
}
But the text is only shown in one line wiht ... at the end.
What am I missing?
When I hover on pie chart, the values are displayed in tooltip. However, I want to display values outside of pie chart. I want to make chart like this image:
How to do this?
I was able to get something similar working using chart.js v2.3.0 using both the plugin API and extending chart types API. You should be able to take this as a starting point and tweak it to your needs.
Here is how it looks after being rendered.
Note, this requires digging deep into chart.js internals and could break if they change the way tooltips are positioned or rendered in the future. I also added a new configuration option called showAllTooltips to enable selectively using the plugin on certain charts. This should work for all chart types, but I am currently only using it for pie, doughnut, bar, and line charts so far.
With that said, here is a working solution for the image above.
Chart.plugins.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create a namespace to persist plugin state (which unfortunately we have to do)
if (!chart.showAllTooltipsPlugin) {
chart.showAllTooltipsPlugin = {};
}
// turn off normal tooltips in case it was also enabled (which is the global default)
chart.options.tooltips.enabled = false;
// we can't use the chart tooltip because there is only one tooltip per chart which gets
// re-positioned via animation steps.....so let's create a place to hold our tooltips
chart.showAllTooltipsPlugin.tooltipsCollection = [];
// create a tooltip for each plot on the chart
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
// but only create one for pie and doughnut charts if the plot is large enough to even see
if (!_.contains(['doughnut', 'pie'], sector._chart.config.type) || sector._model.circumference > 0.1) {
var tooltip;
// create a new tooltip based upon configuration
if (chart.config.options.showAllTooltips.extendOut) {
// this tooltip reverses the location of the carets from the default
tooltip = new Chart.TooltipReversed({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
} else {
tooltip = new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
}
// might as well initialize this now...it would be a waste to do it once we are looping over our tooltips
tooltip.initialize();
// save the tooltips so they can be rendered later
chart.showAllTooltipsPlugin.tooltipsCollection.push(tooltip);
}
});
});
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we want to wait until everything on the chart has been rendered before showing the
// tooltips for the first time...otherwise it looks weird
if (!chart.showAllTooltipsPlugin.initialRenderComplete) {
// still animating until easing === 1
if (easing !== 1) {
return;
}
// animation is complete, let's remember that fact
chart.showAllTooltipsPlugin.initialRenderComplete = true;
}
// at this point the chart has been fully rendered for the first time so start rendering tooltips
Chart.helpers.each(chart.showAllTooltipsPlugin.tooltipsCollection, function (tooltip) {
// create a namespace to persist plugin state within this tooltip (which unfortunately we have to do)
if (!tooltip.showAllTooltipsPlugin) {
tooltip.showAllTooltipsPlugin = {};
}
// re-enable this tooltip otherise it won't be drawn (remember we disabled all tooltips in beforeRender)
tooltip._options.enabled = true;
// perform standard tooltip setup (which determines it's alignment and x, y coordinates)
tooltip.update(); // determines alignment/position and stores in _view
tooltip.pivot(); // we don't actually need this since we are not animating tooltips, but let's be consistent
tooltip.transition(easing).draw(); // render and animate the tooltip
// disable this tooltip in case something else tries to do something with it later
tooltip._options.enabled = false;
});
}
},
});
// A 'reversed' tooltip places the caret on the opposite side from the current default.
// In order to do this we just need to change the 'alignment' logic
Chart.TooltipReversed = Chart.Tooltip.extend({
// Note: tooltipSize is the size of the box (not including the caret)
determineAlignment: function(tooltipSize) {
var me = this;
var model = me._model;
var chart = me._chart;
var chartArea = me._chartInstance.chartArea;
// set caret position to top or bottom if tooltip y position will extend outsite the chart top/bottom
if (model.y < tooltipSize.height) {
model.yAlign = 'top';
} else if (model.y > (chart.height - tooltipSize.height)) {
model.yAlign = 'bottom';
}
var leftAlign, rightAlign; // functions to determine left, right alignment
var overflowLeft, overflowRight; // functions to determine if left/right alignment causes tooltip to go outside chart
var yAlign; // function to get the y alignment if the tooltip goes outside of the left or right edges
var midX = (chartArea.left + chartArea.right) / 2;
var midY = (chartArea.top + chartArea.bottom) / 2;
if (model.yAlign === 'center') {
leftAlign = function(x) {
return x >= midX;
};
rightAlign = function(x) {
return x < midX;
};
} else {
leftAlign = function(x) {
return x <= (tooltipSize.width / 2);
};
rightAlign = function(x) {
return x >= (chart.width - (tooltipSize.width / 2));
};
}
overflowLeft = function(x) {
return x - tooltipSize.width < 0;
};
overflowRight = function(x) {
return x + tooltipSize.width > chart.width;
};
yAlign = function(y) {
return y <= midY ? 'bottom' : 'top';
};
if (leftAlign(model.x)) {
model.xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (overflowLeft(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
} else if (rightAlign(model.x)) {
model.xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (overflowRight(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
}
}
});
Here is an example from Pro ScalaFX:
package proscalafx.ch02.stagecoach
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.StringProperty
import scalafx.geometry.VPos
import scalafx.scene.control.{Button, CheckBox, Label, TextField}
import scalafx.scene.input.MouseEvent
import scalafx.scene.layout.{HBox, VBox}
import scalafx.scene.paint.Color
import scalafx.scene.shape.Rectangle
import scalafx.scene.text.Text
import scalafx.scene.{Group, Scene}
import scalafx.stage.{Screen, StageStyle}
/** Stage property example.
*
* Can be run with various command line parameters to control stage style:
* decorated - a solid white background and platform decorations (default).
* transparent - transparent background and no decorations.
* undecorated - a solid white background and no decorations.
* utility - a solid white background and minimal platform decorations used for a utility window.
* #author Rafael
*/
object StageCoachMain extends JFXApp {
val titleProperty = StringProperty("")
// Process command line parameters
val stageStyle = parameters.unnamed match {
case Seq("transparent") => StageStyle.TRANSPARENT
case Seq("undecorated") => StageStyle.UNDECORATED
case Seq("utility") => StageStyle.UTILITY
case _ => StageStyle.DECORATED
}
lazy val textStageX = new Text {
textOrigin = VPos.Top
}
lazy val textStageY = new Text {
textOrigin = VPos.Top
}
lazy val textStageW = new Text {
textOrigin = VPos.Top
}
lazy val textStageH = new Text {
textOrigin = VPos.Top
}
lazy val textStageF = new Text {
textOrigin = VPos.Top
}
lazy val checkBoxResizable = new CheckBox {
text = "resizable"
// disable = stageStyle == StageStyle.TRANSPARENT || stageStyle == StageStyle.UNDECORATED
}
lazy val checkBoxFullScreen = new CheckBox {
text = "fullScreen"
}
lazy val titleTextField = new TextField {
text = "Stage Coach"
prefColumnCount = 15
}
stage = new PrimaryStage {
resizable = false
title <== titleProperty
scene = new Scene(370, 370) {
fill = Color.Transparent
root = new Group {
children = List(
new Rectangle {
width = 350
height = 350
arcWidth = 50
arcHeight = 50
fill = Color.SkyBlue
},
new VBox {
layoutX = 30
layoutY = 20
spacing = 10
children = List(
textStageX,
textStageY,
textStageW,
textStageH,
textStageF,
checkBoxResizable,
checkBoxFullScreen,
new HBox {
spacing = 10
children = List(
new Label("title:"),
titleTextField)
},
new Button {
text = "toBack()"
onAction = handle {stage.toBack()}
},
new Button {
text = "toFront()"
onAction = handle {stage.toFront()}
},
new Button {
text = "close()"
onAction = handle {stage.close()}
}
)
}
)
}
}
}
//when mouse button is pressed, save the initial position of screen
val rootGroup = stage.scene().content(0)
var dragAnchorX = 0.0
var dragAnchorY = 0.0
rootGroup.onMousePressed = (me: MouseEvent) => {
dragAnchorX = me.screenX - stage.x.value
dragAnchorY = me.screenY - stage.y.value
}
rootGroup.onMouseDragged = (me: MouseEvent) => {
stage.x = me.screenX - dragAnchorX
stage.y = me.screenY - dragAnchorY
}
textStageX.text <== new StringProperty("x: ") + stage.x.asString
textStageY.text <== new StringProperty("y: ") + stage.y.asString
textStageW.text <== new StringProperty("width: ") + stage.width.asString
textStageH.text <== new StringProperty("height: ") + stage.height.asString
textStageF.text <== new StringProperty("focused: ") + stage.focused.asString
stage.resizable = false
// NOTE: Due to a bug in JavaFX (2.2.3+) Stage.resizableProperty(), cannot directly use binding here,
// see http://javafx-jira.kenai.com/browse/RT-25942
// TODO: Revert to binding once JavaFX bug is corrected
// stage.resizable <==> checkBoxResizable.selected
checkBoxResizable.selected.onChange {
// To avoid using resizableProperty, use delegate.setResizable()
// stage.resizable = checkBoxResizable.selected.get
stage.delegate.setResizable(checkBoxResizable.selected())
}
checkBoxFullScreen.onAction = handle {
stage.fullScreen = checkBoxFullScreen.selected()
}
stage.title <== titleTextField.text
stage.initStyle(stageStyle)
stage.onCloseRequest = handle {println("Stage is closing")}
val primScreenBounds = Screen.primary.visualBounds
stage.x = (primScreenBounds.width - stage.width()) / 2
stage.y = (primScreenBounds.height - stage.height()) / 2
}
If I remove lazy before these Text objects, the app seems to works exactly the same as before. For example the textStageX object should show x-coordinate of the stage in real-time, and it still does without being lazy. So, what purpose does lazy serve here?
Another problem is that these lines of code
val primScreenBounds = Screen.primary.visualBounds
stage.x = (primScreenBounds.width - stage.width()) / 2
stage.y = (primScreenBounds.height - stage.height()) / 2
seems to intend to place the window at the center of the primary screen, but fails to do so (on OS X 10.10, with Java 1.8 and Scala 2.11.7).
lazy in unnecessary here. It is used in JFXApp if there are initialization order issues.
For the centering to work. The stage has to be shown first. I am not sure it this new in JavaFX 8 or there was a bug in original StageCoachMain code. Just add:
stage.show()
before the last three lines. You can also replace them with simply:
stage.centerOnScreen()
Thanks for pointing this out. I cleaned up the code in ProScalaFX repo.