Skip to content
This repository has been archived by the owner on Aug 31, 2021. It is now read-only.

[[ AndroidButton ]] Add android native button widget #5583

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Installer/package.txt
Expand Up @@ -378,6 +378,8 @@ component Documentation
file "repo:LiveCode[[TargetEdition]]UserGuide-[[EscapedVersionTag]].pdf" as "LiveCode User Guide.pdf"

component Extensions
into [[ToolsFolder]]/Extensions place
rfolder macosx:packaged_extensions/com.livecode.widget.androidbutton
into [[ToolsFolder]]/Extensions place
rfolder macosx:packaged_extensions/com.livecode.widget.browser
into [[ToolsFolder]]/Extensions place
Expand Down
1 change: 1 addition & 0 deletions extensions/extensions.gyp
Expand Up @@ -25,6 +25,7 @@
'libraries/iconsvg/iconsvg.lcb',
'libraries/json/json.lcb',

'widgets/androidbutton/androidbutton.lcb',
'widgets/browser/browser.lcb',
#’widgets/chart/chart.lcb',
#'widgets/checkbox/checkbox.lcb',
Expand Down
314 changes: 314 additions & 0 deletions extensions/widgets/androidbutton/androidbutton.lcb
@@ -0,0 +1,314 @@
/*
Copyright (C) 2017 LiveCode Ltd.

This file is part of LiveCode.

LiveCode is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License v3 as published by the Free
Software Foundation.

LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */

/**
Name: Android Native Button

Description:
This widget is a native button on Android.

Name: enabled

Syntax:
set the enabled of <widget> to {true | false}
get the enabled of <widget>

Description:
Use the <enabled> property to enable or disable the native button. When
disabled, the button has a greyed out appearance and does not accept
clicks or touches.
*/

widget com.livecode.widget.native.android.button

use com.livecode.foreign
use com.livecode.java
use com.livecode.widget
use com.livecode.canvas
use com.livecode.engine
use com.livecode.library.widgetutils

metadata version is "1.0.0"
metadata author is "LiveCode"
metadata title is "Android Native Button"

/**
Syntax:
set the label of <widget> to <pLabel>
get the label of <widget>

Summary: The label displayed by the button.

Value (string): The string to use as the button label

Example:
set the label of widget "Android Button" to "Click me!"

Description:
The <label> property is the label displayed by the button.
*/

property "label" get mLabel set SetLabel
metadata enabled.dummy is ""

/**
Syntax:
set the labelColor of <widget> to <pLabel>
get the labelColor of <widget>

Summary: The color of the text of the button label

Value (string): A comma delimited string representing a color in RGB / RGBA format

Example:
set the labelColor of widget "Android Button" to "255,0,0,128"

Description:
Use the <labeColor> property to change the color of the label text of
the button.
*/

property labelColor get mColor set SetTextColor
metadata labelColor.label is "Text Color"
metadata labelColor.default is "0,0,0"
metadata labelColor.editor is "com.livecode.pi.colorwithalpha"
metadata labelColor.section is "Colors"

foreign handler _JNI_GetAndroidEngine() returns JObject binds to "java:com.runrev.android.Engine>getEngine()Lcom/runrev/android/Engine;!static"
foreign handler _JNI_GetEngineContext(in pEngine as JObject) returns JObject binds to "java:android.view.View>getContext()Landroid/content/Context;"

// Handlers for creating and attaching view
foreign handler _JNI_CreateButton(in pContext as JObject) returns JObject binds to "java:android.widget.Button>new(Landroid/content/Context;)"
foreign handler _JNI_AddButtonView(in pParentView as JObject, in pChildView as JObject) returns nothing binds to "java:android.view.ViewGroup>addView(Landroid/view/View;)V"

// Handlers for adding click listener
handler type ClickCallback(in pView as JObject)
foreign handler _JNI_OnClickListener(in pHandler as ClickCallback) returns JObject binds to "java:android.view.View$OnClickListener>interface()"
foreign handler _JNI_SetOnClickListener(in pButton as JObject, in pListener as JObject) returns nothing binds to "java:android.view.View>setOnClickListener(Landroid/view/View$OnClickListener;)V"

// Property setters
foreign handler _JNI_SetTextViewText(in pView as JObject, in pValue as JString) returns nothing binds to "java:android.widget.TextView>setText(Ljava/lang/CharSequence;)V"
foreign handler _JNI_SetTextViewTextColor(in pView as JObject, in pValue as JInt) returns nothing binds to "java:android.widget.TextView>setTextColor(I)V"
foreign handler _JNI_GetColorFromARGB(in pA as JInt, in pR as JInt, in pG as JInt, in pB as JInt) returns JInt binds to "java:android.graphics.Color>argb(IIII)I!static"
foreign handler _JNI_SetTextViewEnabled(in pView as JObject, in pValue as JBoolean) returns nothing binds to "java:android.view.View>setEnabled(Z)V"

private variable mLabel as String
private variable mColor as String
private variable mButton as optional JObject
private variable mOpen as Boolean

private handler IsAndroid() returns Boolean
return the operating system is "android"
end handler

public handler OnCreate()
put false into mOpen
put "" into mLabel
put "0,0,0" into mColor
end handler

public handler OnSave(out rProperties as Array)
put mLabel into rProperties["label"]
put mColor into rProperties["color"]
end handler

public handler OnLoad(in pProperties as Array)
put pProperties["label"] into mLabel
put pProperties["color"] into mColor
end handler

private unsafe handler InitButtonView()
// Create an android button using the Engine Context
variable tEngine as JObject
put _JNI_GetAndroidEngine() into tEngine

variable tContext as JObject
put _JNI_GetEngineContext(tEngine) into tContext
put _JNI_CreateButton(tContext) into mButton

// put my native window into tParent
variable tParent as Pointer
MCWidgetGetMyStackNativeView(tParent)

// wrap the parent pointer
variable tParentObj as JObject
put PointerToJObject(tParent) into tParentObj

// add the view
_JNI_AddButtonView(tParentObj, mButton)

// get the pointer from the view and set the native layer
variable tButtonPointer as Pointer
put PointerFromJObject(mButton) into tButtonPointer
set my native layer to tButtonPointer

// add an OnClick listener
variable tListener as JObject
put _JNI_OnClickListener(ButtonClicked) into tListener
_JNI_SetOnClickListener(mButton, tListener)

// Update label, text size and color, and enabled state
updateProperties()
end handler

private unsafe handler FinalizeButtonView()
set my native layer to nothing
put nothing into mButton
end handler

private handler updateProperties()
SetEnabled(my enabled)
SetLabel(mLabel)
SetTextColor(mColor)
end handler

public handler OnOpen()
put true into mOpen
if IsAndroid() then
unsafe
InitButtonView()
end unsafe
end if
end handler

public handler OnClose()
if IsAndroid() then
unsafe
FinalizeButtonView()
end unsafe
end if
put false into mOpen
end handler

public handler ButtonClicked(in pView as JObject)
post "mouseUp"
end handler

public handler OnClick()
post "mouseUp"
end handler

constant kSvgIcon is "M493 615Q509 615 520.5 603.5 532 592 532 576 532 560 520.5 548.5 509 537 493 537 477 537 466 548.5 455 560 455 576 455 592 466 603.5 477 615 493 615ZM915 615Q931 615 942 603.5 953 592 953 576 953 560 942 548.5 931 537 915 537 899 537 887.5 548.5 876 560 876 576 876 592 887.5 603.5 899 615 915 615ZM103 799Q145 799 175 829 205 859 205 901L205 1331Q205 1374 175.5 1404 146 1434 103 1434 60 1434 30 1404 0 1374 0 1331L0 901Q0 859 30 829 60 799 103 799ZM1163 818L1163 1484Q1163 1530 1131 1562 1099 1594 1054 1594L979 1594 979 1821Q979 1864 949 1894 919 1924 876 1924 833 1924 803 1894 773 1864 773 1821L773 1594 635 1594 635 1821Q635 1864 605 1894 575 1924 532 1924 490 1924 460 1894 430 1864 430 1821L429 1594 355 1594Q309 1594 277 1562 245 1530 245 1484L245 818 1163 818ZM931 413Q1038 468 1102 566.5 1166 665 1166 782L241 782Q241 665 305 566.5 369 468 477 413L406 282Q399 269 411 262 424 256 431 268L503 400Q598 358 704 358 810 358 905 400L977 268Q984 256 997 262 1009 269 1002 282ZM1408 901L1408 1331Q1408 1374 1378 1404 1348 1434 1305 1434 1263 1434 1233 1404 1203 1374 1203 1331L1203 901Q1203 858 1233 828.5 1263 799 1305 799 1348 799 1378 828.5 1408 858 1408 901Z"
constant kBorderWidth is 5
private handler expandRectangle(in pRect as Rectangle, in pExp as Number) returns Rectangle
return rectangle [ the left of pRect - pExp, the top of pRect - pExp, the right of pRect + pExp, the bottom of pRect + pExp]
end handler

public handler OnPaint()
variable tIsAndroid as Boolean
put IsAndroid() into tIsAndroid
if tIsAndroid then
updateProperties()
return
end if

// Draw placeholder image - the icon
variable tFillPaint as Paint
variable tStrokePaint as Paint
put solid paint with color [0.875, 0.875, 0.875] into tFillPaint
put solid paint with color [0.75, 0.75, 0.75] into tStrokePaint
variable tBounds as Rectangle
put my bounds into tBounds
set the paint of this canvas to tFillPaint
fill rectangle path of tBounds on this canvas
set the paint of this canvas to tStrokePaint
set the stroke width of this canvas to kBorderWidth
set the join style of this canvas to "bevel"
stroke rectangle path of expandRectangle(tBounds, -kBorderWidth / 2) on this canvas
variable tPath as Path
put path kSvgIcon into tPath
constrainPathToRect(expandRectangle(tBounds, -2 * kBorderWidth), tPath)
fill tPath on this canvas
// Draw the control name
put solid paint with color [1, 1, 1, 0.1] into tFillPaint
put solid paint with color [0.25, 0.25, 0.25] into tStrokePaint
variable tNameString as String
if mLabel is empty then
put my name into tNameString
else
put mLabel into tNameString
end if
set the font of this canvas to my font

variable tTextBounds as Rectangle
put the image bounds of text tNameString on this canvas into tTextBounds
translate this canvas by [ the width of tBounds / 2, the height of tBounds / 2]
translate this canvas by [ -(the width of tTextBounds / 2), the height of tTextBounds / 2]
set the paint of this canvas to tFillPaint

variable tRect as Rectangle
put expandRectangle(tTextBounds, kBorderWidth) into tRect
fill rounded rectangle path of tRect with radius 5 on this canvas
set the paint of this canvas to solid paint with stringToColor(mColor)
fill text tNameString at center of tRect on this canvas
end handler

public handler SetEnabled(in pValue as Boolean)
if mOpen and mButton is not nothing then
unsafe
_JNI_SetTextViewEnabled(mButton, pValue)
end unsafe
redraw all
end if
end handler

public handler SetLabel(in pLabel as String)
put pLabel into mLabel
if mOpen and mButton is not nothing then
unsafe
_JNI_SetTextViewText(mButton, StringToJString(mLabel))
end unsafe
redraw all
end if
end handler

public handler SetTextColor(in pColor as String)
put pColor into mColor
if mOpen and mButton is not nothing then
unsafe
SetStringAndroidColor(pColor)
end unsafe
redraw all
end if
end handler

private handler ColorComponentToInt(in pComponent as Real) returns Integer
multiply pComponent by 255
round pComponent
return pComponent
end handler

private unsafe handler SetStringAndroidColor(in pString as String)
variable tColor as Color
put stringToColor(pString) into tColor

variable tA as Integer
variable tR as Integer
variable tG as Integer
variable tB as Integer
put ColorComponentToInt(the alpha of tColor) into tA
put ColorComponentToInt(the red of tColor) into tR
put ColorComponentToInt(the green of tColor) into tG
put ColorComponentToInt(the blue of tColor) into tB

variable tColorInt as Integer
put _JNI_GetColorFromARGB(tA,tR,tG,tB) into tColorInt

_JNI_SetTextViewTextColor(mButton, tColorInt)
end handler

end widget
@@ -0,0 +1,16 @@
# Android Native Button

A new widget has been added which is a native button view on Android. On
all other platforms it presents a placeholder image with the Android
logo.

## Properties

* **enabled** - The enabled state of the button
* **label** - The label to display
* **labelColor** - The color of the button label text
* **textSize** - The size of the button label text

## Messages

* **mouseUp** - sent when the button is clicked