This is an automated email from the ASF dual-hosted git repository. carlosrovira pushed a commit to branch feature/jewel-ui-set in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit c62176cb6819e33f1062dc05f2415d2422ffaef3 Author: Carlos Rovira <[email protected]> AuthorDate: Sun Mar 25 17:32:53 2018 +0200 radiobutton almost done but as checbox needs of #35 solved to be finished --- .../src/main/royale/RadioButtonPlayGround.mxml | 14 +- .../royale/org/apache/royale/jewel/CheckBox.as | 6 +- .../royale/org/apache/royale/jewel/RadioButton.as | 433 +++++++++++++++++++-- .../main/resources/assets/radiobutton-circle.svg | 19 + .../JewelTheme/src/main/resources/defaults.css | 57 ++- .../src/main/sass/components/_radiobutton.sass | 93 ++++- 6 files changed, 553 insertions(+), 69 deletions(-) diff --git a/examples/royale/JewelExample/src/main/royale/RadioButtonPlayGround.mxml b/examples/royale/JewelExample/src/main/royale/RadioButtonPlayGround.mxml index 14da2a1..3d34b18 100644 --- a/examples/royale/JewelExample/src/main/royale/RadioButtonPlayGround.mxml +++ b/examples/royale/JewelExample/src/main/royale/RadioButtonPlayGround.mxml @@ -29,9 +29,17 @@ limitations under the License. <html:H3 text="Jewel RadioButton"/> - <j:RadioButton text="RadioButton 1"/> - <j:RadioButton text="RadioButton 2"/> - <j:RadioButton text="RadioButton Disabled"> + <j:RadioButton text="RadioButton 1" groupName="radios" value="Test 1"/> + <j:RadioButton text="RadioButton 2" groupName="radios" value="Test 2"/> + <j:RadioButton text="RadioButton 3" groupName="radios" value="Test 3"/> + + <j:RadioButton text="Disabled"> + <j:beads> + <j:Disabled/> + </j:beads> + </j:RadioButton> + + <j:RadioButton text="Set and Disabled" selected="true"> <j:beads> <j:Disabled/> </j:beads> diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/CheckBox.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/CheckBox.as index abf8185..d69fad6 100644 --- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/CheckBox.as +++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/CheckBox.as @@ -23,7 +23,6 @@ package org.apache.royale.jewel COMPILE::JS { - import org.apache.royale.core.CSSClassList; import org.apache.royale.core.WrappedHTMLElement; import org.apache.royale.events.Event; import org.apache.royale.html.util.addElementToWrapper; @@ -114,7 +113,6 @@ package org.apache.royale.jewel return element; } - COMPILE::JS /** * override UIBase to affect positioner instead of element * @@ -123,10 +121,10 @@ package org.apache.royale.jewel * @playerversion AIR 2.6 * @productversion Royale 0.9.2 */ + COMPILE::JS override protected function setClassName(value:String):void { - //positioner.className = value; - addStyles(positioner, value); + addStyles(positioner, value); } /** diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/RadioButton.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/RadioButton.as index e77196e..19d5981 100644 --- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/RadioButton.as +++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/RadioButton.as @@ -18,96 +18,443 @@ //////////////////////////////////////////////////////////////////////////////// package org.apache.royale.jewel { - import org.apache.royale.html.RadioButton; + import org.apache.royale.events.Event; + import org.apache.royale.events.MouseEvent; COMPILE::SWF { - import flash.display.DisplayObject; + import flash.utils.Dictionary; + import org.apache.royale.core.UIButtonBase; + import org.apache.royale.core.IStrand; + import org.apache.royale.core.IValueToggleButtonModel; } COMPILE::JS { + import org.apache.royale.core.UIBase; import org.apache.royale.core.WrappedHTMLElement; - import org.apache.royale.jewel.supportClasses.RadioButtonIcon; import org.apache.royale.html.util.addElementToWrapper; + import org.apache.royale.utils.cssclasslist.addStyles; } + //-------------------------------------- + // Events + //-------------------------------------- + + /** + * Dispatched when the user clicks on RadioButton. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + [Event(name="click", type="org.apache.royale.events.MouseEvent")] + + /** + * Dispatched when RadioButton is being selected/unselected. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + [Event(name="change", type="org.apache.royale.events.Event")] + /** - * The RadioButton class is a component that displays a selectable Button. RadioButtons - * are typically used in groups, identified by the groupName property. RadioButton use - * the following beads: - * - * org.apache.royale.core.IBeadModel: the data model, which includes the groupName. - * org.apache.royale.core.IBeadView: the bead that constructs the visual parts of the RadioButton.. - * - * @toplevel - * @langversion 3.0 - * @playerversion Flash 10.2 - * @playerversion AIR 2.6 - * @productversion Royale 0.0 - */ + * The Jewel radio button component is an enhanced version of the + * standard HTML <input type="radio">, or "radio button" element. A radio button + * consists of a small circle and, typically, text that clearly communicates a + * condition that will be set when the user clicks or touches it. Radio buttons + * always appear in groups of two or more and, while they can be individually + * selected, can only be deselected by selecting a different radio button in the + * same group (which deselects all other radio buttons in the group). + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ COMPILE::SWF - public class RadioButton extends org.apache.royale.html.RadioButton - { + public class RadioButton extends UIButtonBase implements IStrand + { /** * constructor. * * @langversion 3.0 * @playerversion Flash 10.2 * @playerversion AIR 2.6 - * @productversion Royale 0.0 + * @productversion Royale 0.8 */ - public function RadioButton(upState:DisplayObject=null, overState:DisplayObject=null, downState:DisplayObject=null, hitTestState:DisplayObject=null) + public function RadioButton() { - super(upState, overState, downState, hitTestState); + super(); + + typeNames = "jewel radiobutton"; - typeNames = "jewel radiobutton" + addEventListener(org.apache.royale.events.MouseEvent.CLICK, internalMouseHandler); } - } + protected static var dict:Dictionary = new Dictionary(true); + + /** + * The name of the group. Only one RadioButton in a group is selected. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + public function get groupName() : String + { + return IValueToggleButtonModel(model).groupName; + } + public function set groupName(value:String) : void + { + IValueToggleButtonModel(model).groupName = value; + } + + /** + * The string used as a label for the RadioButton. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + public function get text():String + { + return IValueToggleButtonModel(model).text; + } + public function set text(value:String):void + { + IValueToggleButtonModel(model).text = value; + } + + /** + * Whether or not the RadioButton instance is selected. Setting this property + * causes the currently selected RadioButton in the same group to lose the + * selection. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + public function get selected():Boolean + { + return IValueToggleButtonModel(model).selected; + } + public function set selected(selValue:Boolean):void + { + IValueToggleButtonModel(model).selected = selValue; + + // if this button is being selected, its value should become + // its group's selectedValue + if( selValue ) { + for each(var rb:org.apache.royale.jewel.RadioButton in dict) + { + if( rb.groupName == groupName ) + { + rb.selectedValue = value; + } + } + } + } + + /** + * The value associated with the RadioButton. For example, RadioButtons with labels, + * "Red", "Green", and "Blue" might have the values 0, 1, and 2 respectively. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + public function get value():Object + { + return IValueToggleButtonModel(model).value; + } + public function set value(newValue:Object):void + { + IValueToggleButtonModel(model).value = newValue; + } + + /** + * The group's currently selected value. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + public function get selectedValue():Object + { + return IValueToggleButtonModel(model).selectedValue; + } + public function set selectedValue(newValue:Object):void + { + // a radio button is really selected when its value matches that of the group's value + IValueToggleButtonModel(model).selected = (newValue == value); + IValueToggleButtonModel(model).selectedValue = newValue; + } + + /** + * @private + */ + override public function addedToParent():void + { + super.addedToParent(); + + // if this instance is selected, set the local selectedValue to + // this instance's value + if( selected ) selectedValue = value; + + else { + + // make sure this button's selectedValue is set from its group's selectedValue + // to keep it in sync with the rest of the buttons in its group. + for each(var rb:org.apache.royale.jewel.RadioButton in dict) + { + if( rb.groupName == groupName ) + { + selectedValue = rb.selectedValue; + break; + } + } + } + + dict[this] = this; + } + + /** + * @private + */ + private function internalMouseHandler(event:MouseEvent) : void + { + // prevent radiobutton from being turned off by a click + if( !selected ) { + selected = !selected; + dispatchEvent(new Event(Event.CHANGE)); + } + } + } + + /** + * Dispatched when the user clicks on RadioButton. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + [Event(name="click", type="org.apache.royale.events.MouseEvent")] + + /** + * Dispatched when RadioButton is being selected/unselected. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + [Event(name="change", type="org.apache.royale.events.Event")] + COMPILE::JS - public class RadioButton extends org.apache.royale.html.RadioButton + public class RadioButton extends UIBase { - public function RadioButton() + /** + * Constructor. + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.8 + */ + public function RadioButton() { - super(); + super(); typeNames = "jewel radiobutton"; - } + } /** - * @private - * - * @royalesuppresspublicvarwarning + * Provides unique name */ - public static var radioCounter:int = 0; + protected static var radioCounter:int = 0; - private var labelFor:HTMLLabelElement; + private var radio:HTMLSpanElement; + private var icon:HTMLInputElement; + private var label:HTMLLabelElement; private var textNode:Text; - private var icon:RadioButtonIcon; + + COMPILE::JS + private var _positioner:WrappedHTMLElement; + + COMPILE::JS + override public function get positioner():WrappedHTMLElement + { + return _positioner; + } + + COMPILE::JS + override public function set positioner(value:WrappedHTMLElement):void + { + _positioner = value; + } /** * @royaleignorecoercion org.apache.royale.core.WrappedHTMLElement - * @royaleignorecoercion HTMLInputElement * @royaleignorecoercion HTMLLabelElement + * @royaleignorecoercion HTMLInputElement + * @royaleignorecoercion HTMLSpanElement * @royaleignorecoercion Text */ override protected function createElement():WrappedHTMLElement { - icon = new RadioButtonIcon() - icon.id = '_radio_' + org.apache.royale.jewel.RadioButton.radioCounter++; + var label:HTMLLabelElement = document.createElement('label') as HTMLLabelElement; + + icon = addElementToWrapper(this,'input') as HTMLInputElement; + icon.type = "radio"; + icon.className = 'input'; + icon.id = '_radio_' + + Math.random(); + label.appendChild(icon); textNode = document.createTextNode('') as Text; - labelFor = addElementToWrapper(this,'label') as HTMLLabelElement; - labelFor.appendChild(icon.element); - labelFor.appendChild(textNode); - icon.element.className = "input"; - - (textNode as WrappedHTMLElement).royale_wrapper = this; - (icon.element as WrappedHTMLElement).royale_wrapper = this; + radio = document.createElement('span') as HTMLSpanElement; + radio.className = 'span'; + radio.appendChild(textNode); + label.appendChild(radio); + //radio.addEventListener('mouseover', mouseOverHandler, false); + //radio.addEventListener('mouseout', mouseOutHandler, false); + + // (textNode as WrappedHTMLElement).royale_wrapper = this; + // (icon as WrappedHTMLElement).royale_wrapper = this; + // (radio as WrappedHTMLElement).royale_wrapper = this; + + positioner = label as WrappedHTMLElement; + _positioner.royale_wrapper = this; return element; } + + /** + * override UIBase to affect positioner instead of element + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion Royale 0.9.2 + */ + COMPILE::JS + override protected function setClassName(value:String):void + { + addStyles(positioner, value); + } + + override public function addEventListener(type:String, handler:Function, opt_capture:Boolean = false, opt_handlerScope:Object = null):void + { + if (type == MouseEvent.CLICK) + { + icon.addEventListener(type, handler, opt_capture); + } + else + { + super.addEventListener(type, handler, opt_capture, opt_handlerScope); + } + } + + public function clickHandler(event:Event):void + { + selected = !selected; + } + + public function get groupName():String + { + return icon.name as String; + } + + public function set groupName(value:String):void + { + icon.name = value; + } + + public function get text():String + { + return textNode.nodeValue; + } + + public function set text(value:String):void + { + textNode.nodeValue = value; + } + + /** @export */ + public function get selected():Boolean + { + return icon.checked; + } + + public function set selected(value:Boolean):void + { + if(icon.checked == value) + return; + var instance:Object = element['MaterialRadio']; + if(instance) + { + if(value) + instance["check"](); + else + instance["uncheck"](); + } + else + icon.checked = value; + dispatchEvent(new Event(Event.CHANGE)); + } + + public function get value():Object + { + return icon.value; + } + public function set value(v:Object):void + { + icon.value = v as String; + } + + public function get selectedValue():Object + { + var groupName:String = icon.name as String; + var buttons:NodeList = document.getElementsByName(groupName); + var n:int = buttons.length; + + for (var i:int = 0; i < n; i++) + { + if (buttons[i].checked) + { + return buttons[i].value; + } + } + return null; + } + + /** + * @royaleignorecoercion HTMLInputElement + */ + public function set selectedValue(value:Object):void + { + var groupName:String = icon.name as String; + var buttons:NodeList = document.getElementsByName(groupName); + var n:int = buttons.length; + + for (var i:int = 0; i < n; i++) + { + if (buttons[i].value === value) + { + buttons[i].checked = true; + break; + } + } + } } } \ No newline at end of file diff --git a/frameworks/themes/JewelTheme/src/main/resources/assets/radiobutton-circle.svg b/frameworks/themes/JewelTheme/src/main/resources/assets/radiobutton-circle.svg new file mode 100644 index 0000000..07beb17 --- /dev/null +++ b/frameworks/themes/JewelTheme/src/main/resources/assets/radiobutton-circle.svg @@ -0,0 +1,19 @@ +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<svg viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-616, -350)"><g transform="translate(611, 345)"><g><circle cx="11" cy="11" r="6"></circle></g></g></g></svg> \ No newline at end of file diff --git a/frameworks/themes/JewelTheme/src/main/resources/defaults.css b/frameworks/themes/JewelTheme/src/main/resources/defaults.css index 29eb2b3..d39517f 100644 --- a/frameworks/themes/JewelTheme/src/main/resources/defaults.css +++ b/frameworks/themes/JewelTheme/src/main/resources/defaults.css @@ -245,12 +245,61 @@ span { } .jewel.radiobutton { - padding-left: 5px; + display: inline-block; + margin: 0; + padding: 0; + position: relative; + vertical-align: middle; + width: 100%; + height: 22px; } .jewel.radiobutton .input { - width: 15px; - height: 15px; - border: 1px solid; + -webkit-appearance: none; + -moz-appearance: none; + -o-appearance: none; + appearance: none; + cursor: pointer; + display: inline-block; + margin: 0; + padding: 0; + width: 22px; + height: 22px; + line-height: 22px; + background: linear-gradient(white, #f3f3f3); + border: 1px solid #b3b3b3; + border-radius: 50%; +} +.jewel.radiobutton .input:checked, .jewel.radiobutton .input:checked:active { + background: url("data:image/svg+xml;utf8,<svg viewBox='0 0 12 12' version='1.1' xmlns='http://www.w3.org/2000/svg'><g transform='translate(-616, -350)'><g transform='translate(611, 345)'><g><circle fill='#3CADF1' cx='11' cy='11' r='6'></circle></g></g></g></svg>"); + background-repeat: no-repeat; + background-size: 60%; + background-position: center; + background-attachment: fixed; +} +.jewel.radiobutton .input:focus { + outline: none; + border: 1px solid #0f88d1; +} +.jewel.radiobutton .input[disabled] { + cursor: unset; + border: 1px solid #c6c6c6; + background: #F9F9F9; +} +.jewel.radiobutton .input[disabled]:checked { + border: 1px solid #c6c6c6; + background: url("data:image/svg+xml;utf8,<svg viewBox='0 0 12 12' version='1.1' xmlns='http://www.w3.org/2000/svg'><g transform='translate(-616, -350)'><g transform='translate(611, 345)'><g><circle fill='lightgray' cx='11' cy='11' r='6'></circle></g></g></g></svg>"); + background-size: 60%; + background-position: center; + background-repeat: no-repeat; + background-attachment: fixed; +} +.jewel.radiobutton .span { + cursor: pointer; + position: absolute; + margin: 0; + padding-left: 6px; + font-size: 16px; + line-height: 22px; } .jewel.slider .slider { diff --git a/frameworks/themes/JewelTheme/src/main/sass/components/_radiobutton.sass b/frameworks/themes/JewelTheme/src/main/sass/components/_radiobutton.sass index 0bba0f1..df3f1ed 100644 --- a/frameworks/themes/JewelTheme/src/main/sass/components/_radiobutton.sass +++ b/frameworks/themes/JewelTheme/src/main/sass/components/_radiobutton.sass @@ -17,20 +17,83 @@ // //////////////////////////////////////////////////////////////////////////////// +// Jewel RadioButton + +// RadioButton variables +$radiobutton-button-size: 22px +$radiobutton-border-radius: 50% +$radiobutton-label-separation: 6px +$radiobutton-label-font-size: 16px + .jewel.radiobutton - padding-left: 5px + //cursor: pointer + display: inline-block + + margin: 0 + padding: 0 + + position: relative + vertical-align: middle + + width: 100% + height: $radiobutton-button-size + + // -- INPUT .input - width: 15px - height: 15px - border: 1px solid - - // > input[type="radio"] - // width: 50px - // height: 50px - // > label - // cursor: auto - // position: relative - // display: block - // padding-left: 20px - // outline: none - //font-size: @labelFontSize \ No newline at end of file + +appear(none) + cursor: pointer + display: inline-block + + margin: 0 + padding: 0 + + width: $radiobutton-button-size + height: $radiobutton-button-size + + line-height: $radiobutton-button-size + + @if $flat + border: 0px solid + background: $default-color + @else + background: linear-gradient(lighten($default-color, 15%), lighten($default-color, 10%)) + border: 1px solid darken($default-color, 15%) + border-radius: $radiobutton-border-radius + + &:checked, &:checked:active + //background: url(assets/radiobutton-tick.svg), lighten($primary-color, 25%) + background: url("data:image/svg+xml;utf8,<svg viewBox='0 0 12 12' version='1.1' xmlns='http://www.w3.org/2000/svg'><g transform='translate(-616, -350)'><g transform='translate(611, 345)'><g><circle fill='#{$primary-color}' cx='11' cy='11' r='6'></circle></g></g></g></svg>") + background-repeat: no-repeat + background-size: 60% + background-position: center + background-attachment: fixed + + &:focus + outline: none + @if $flat + background: lighten($primary-color, 25%) + @else + border: 1px solid darken($primary-color, 15%) + + &[disabled] + cursor: unset + border: 1px solid darken($disabled-color, 20%) + background: $disabled-color + + &:checked + border: 1px solid darken($disabled-color, 20%) + //background: url(assets/radiobutton-tick.svg), $disabled-color + background: url("data:image/svg+xml;utf8,<svg viewBox='0 0 12 12' version='1.1' xmlns='http://www.w3.org/2000/svg'><g transform='translate(-616, -350)'><g transform='translate(611, 345)'><g><circle fill='#{darken($disabled-color, 15%)}' cx='11' cy='11' r='6'></circle></g></g></g></svg>") + background-size: 60% + background-position: center + background-repeat: no-repeat + background-attachment: fixed + + // -- LABEL + .span + cursor: pointer + position: absolute + margin: 0 + padding-left: $radiobutton-label-separation + font-size: $radiobutton-label-font-size + line-height: $radiobutton-button-size -- To stop receiving notification emails like this one, please contact [email protected].
