fix buttons behavior

This commit is contained in:
Vadim Lopatin 2014-04-17 22:48:13 +04:00
parent 1bc3a724d1
commit cd731525af
12 changed files with 101 additions and 41 deletions

View File

@ -1,4 +1,4 @@
module winmain; module main;
import dlangui.all; import dlangui.all;
import std.stdio; import std.stdio;
@ -24,13 +24,6 @@ extern (C) int UIAppMain(string[] args) {
// select translation file - for english language // select translation file - for english language
i18n.load("en.ini"); //"ru.ini", "en.ini" i18n.load("en.ini"); //"ru.ini", "en.ini"
DrawBufRef img = imageCache.get("C:\\projects\\d\\dlangui\\res\\mdpi\\btn_radio_on_holo_light.png");
ColorDrawBuf buf = cast(ColorDrawBuf)img.get;
//GrayDrawBuf gbuf = cast(GrayDrawBuf)img.get;
uint * row = buf.scanLine(0);
Log.d("btn_radio_on_holo_light pixels: ", row[0], row[1], row[2]);
// create window // create window
Window window = Platform.instance.createWindow("My Window", null); Window window = Platform.instance.createWindow("My Window", null);

View File

@ -1,25 +1,33 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" <!-- Copyright (C) 2008 The Android Open Source Project
android:constantSize="true"
android:dither="false" Licensed under the Apache License, Version 2.0 (the "License");
android:variablePadding="false" > you may not use this file except in compliance with the License.
<item You may obtain a copy of the License at
android:drawable="btn_default_small_normal_disable_focused"
android:state_enabled="false" /> http://www.apache.org/licenses/LICENSE-2.0
android:state_focused="true" />
<item Unless required by applicable law or agreed to in writing, software
android:drawable="btn_default_small_normal_disable" distributed under the License is distributed on an "AS IS" BASIS,
android:state_focused="true" /> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<item See the License for the specific language governing permissions and
android:drawable="btn_default_small_pressed" limitations under the License.
android:state_pressed="true" /> -->
<item
android:drawable="btn_default_small_selected" <selector xmlns:android="http://schemas.android.com/apk/res/android">
android:state_selected="true" /> <item android:state_window_focused="false" android:state_enabled="true"
<item android:drawable="@drawable/btn_default_small_normal" />
android:drawable="btn_default_small_normal_hover" <item android:state_window_focused="false" android:state_enabled="false"
android:state_hovered="true" /> android:drawable="@drawable/btn_default_small_normal_disable" />
<item <item android:state_pressed="true"
android:drawable="btn_default_small_normal" android:drawable="@drawable/btn_default_small_pressed" />
/> <item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_small_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_small_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_small_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_small_normal_disable" />
</selector> </selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -261,9 +261,26 @@ class RadioButton : ImageTextButton {
styleId = "TRANSPARENT_BUTTON_BACKGROUND"; styleId = "TRANSPARENT_BUTTON_BACKGROUND";
checkable = true; checkable = true;
} }
void uncheckSiblings() {
Widget p = parent;
if (!p)
return;
for (int i = 0; i < p.childCount; i++) {
Widget child = p.child(i);
if (child is this)
continue;
RadioButton rb = cast(RadioButton)child;
if (rb)
rb.checked = false;
}
}
// called to process click and notify listeners // called to process click and notify listeners
override protected bool handleClick() { override protected bool handleClick() {
uncheckSiblings();
checked = true; checked = true;
return super.handleClick(); return super.handleClick();
} }
@ -279,6 +296,7 @@ class Button : Widget {
this(string ID = null) { this(string ID = null) {
super(ID); super(ID);
styleId = "BUTTON"; styleId = "BUTTON";
clickable = true;
focusable = true; focusable = true;
trackHover = true; trackHover = true;
} }
@ -399,6 +417,7 @@ class ScrollBar : AbstractSlider, OnClickHandler {
super(ID); super(ID);
styleId = "PAGE_SCROLL"; styleId = "PAGE_SCROLL";
trackHover = true; trackHover = true;
clickable = true;
} }
} }

View File

@ -236,7 +236,7 @@ class ListWidget : WidgetGroup, OnScrollHandler {
} }
/// override to handle focus changes /// override to handle focus changes
override protected void onFocusChange(bool focused) { override protected void handleFocusChange(bool focused) {
updateSelectedItemFocus(); updateSelectedItemFocus();
} }

View File

@ -90,6 +90,7 @@ class MenuItemWidget : HorizontalLayout {
_label.text = _item.label; _label.text = _item.label;
addChild(_label); addChild(_label);
trackHover = true; trackHover = true;
clickable = true;
} }
} }

View File

@ -20,6 +20,7 @@ Authors: $(WEB coolreader.org, Vadim Lopatin)
*/ */
module dlangui.widgets.tabs; module dlangui.widgets.tabs;
import dlangui.core.signals;
import dlangui.widgets.layouts; import dlangui.widgets.layouts;
import dlangui.widgets.controls; import dlangui.widgets.controls;
@ -82,6 +83,7 @@ class TabItemWidget : HorizontalLayout {
addChild(_label); addChild(_label);
addChild(_closeButton); addChild(_closeButton);
setItem(item); setItem(item);
clickable = true;
trackHover = true; trackHover = true;
} }
protected bool onClick(Widget source) { protected bool onClick(Widget source) {

View File

@ -52,10 +52,21 @@ enum Orientation : ubyte {
Horizontal Horizontal
} }
/// interface - slot for onClick
interface OnClickHandler { interface OnClickHandler {
bool onClick(Widget source); bool onClick(Widget source);
} }
/// interface - slot for onCheckChanged
interface OnCheckHandler {
bool onCheckChanged(Widget source, bool checked);
}
/// interface - slot for onFocusChanged
interface OnFocusHandler {
bool onFocusChanged(Widget source, bool focused);
}
class Widget { class Widget {
/// widget id /// widget id
protected string _id; protected string _id;
@ -152,10 +163,15 @@ class Widget {
@property uint state() const { @property uint state() const {
if ((_state & State.Parent) != 0 && _parent !is null) if ((_state & State.Parent) != 0 && _parent !is null)
return _parent.state; return _parent.state;
return _state; return _state | State.WindowFocused; // TODO:
} }
/// override to handle focus changes /// override to handle focus changes
protected void onFocusChange(bool focused) { protected void handleFocusChange(bool focused) {
onFocusChangeListener(this, checked);
}
/// override to handle check changes
protected void handleCheckChange(bool checked) {
onCheckChangeListener(this, checked);
} }
/// set new widget state (set of flags from State enum) /// set new widget state (set of flags from State enum)
@property Widget state(uint newState) { @property Widget state(uint newState) {
@ -166,9 +182,14 @@ class Widget {
invalidate(); invalidate();
// notify focus changes // notify focus changes
if ((oldState & State.Focused) && !(newState & State.Focused)) if ((oldState & State.Focused) && !(newState & State.Focused))
onFocusChange(false); handleFocusChange(false);
else if (!(oldState & State.Focused) && (newState & State.Focused)) else if (!(oldState & State.Focused) && (newState & State.Focused))
onFocusChange(true); handleFocusChange(true);
// notify checked changes
if ((oldState & State.Checked) && !(newState & State.Checked))
handleCheckChange(false);
else if (!(oldState & State.Checked) && (newState & State.Checked))
handleCheckChange(true);
} }
return this; return this;
} }
@ -337,13 +358,23 @@ class Widget {
return _pos.isPointInside(x, y); return _pos.isPointInside(x, y);
} }
/// return true if state has State.Enabled flag set
@property bool enabled() { return (state & State.Enabled) != 0; }
/// change enabled state
@property Widget enabled(bool flg) { flg ? setState(State.Enabled) : resetState(State.Enabled); return this; }
protected bool _clickable; protected bool _clickable;
/// when true, user can click this control, and get onClick listeners called
@property bool clickable() { return _clickable; } @property bool clickable() { return _clickable; }
@property Widget clickable(bool flg) { _clickable = flg; return this; } @property Widget clickable(bool flg) { _clickable = flg; return this; }
@property bool canClick() { return _clickable && enabled && visible; }
protected bool _checkable; protected bool _checkable;
/// when true, control supports Checked state
@property bool checkable() { return _checkable; } @property bool checkable() { return _checkable; }
@property Widget checkable(bool flg) { _checkable = flg; return this; } @property Widget checkable(bool flg) { _checkable = flg; return this; }
@property bool canCheck() { return _checkable && enabled && visible; }
protected bool _checked; protected bool _checked;
/// get checked state /// get checked state
@ -425,7 +456,7 @@ class Widget {
/// process key event, return true if event is processed. /// process key event, return true if event is processed.
bool onKeyEvent(KeyEvent event) { bool onKeyEvent(KeyEvent event) {
if (clickable) { if (canClick) {
// support onClick event initiated by Space or Return keys // support onClick event initiated by Space or Return keys
if (event.action == KeyAction.KeyDown) { if (event.action == KeyAction.KeyDown) {
if (event.keyCode == KeyCode.SPACE || event.keyCode == KeyCode.RETURN) { if (event.keyCode == KeyCode.SPACE || event.keyCode == KeyCode.RETURN) {
@ -448,7 +479,7 @@ class Widget {
bool onMouseEvent(MouseEvent event) { bool onMouseEvent(MouseEvent event) {
//Log.d("onMouseEvent ", id, " ", event.action, " (", event.x, ",", event.y, ")"); //Log.d("onMouseEvent ", id, " ", event.action, " (", event.x, ",", event.y, ")");
// support onClick // support onClick
if (clickable) { if (canClick) {
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) { if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
setState(State.Pressed); setState(State.Pressed);
if (focusable) if (focusable)
@ -497,9 +528,15 @@ class Widget {
return false; return false;
} }
// =======================================================
// Signals
/// on click event listener (bool delegate(Widget)) /// on click event listener (bool delegate(Widget))
Signal!OnClickHandler onClickListener; Signal!OnClickHandler onClickListener;
/// checked state change event listener (bool delegate(Widget, bool))
Signal!OnCheckHandler onCheckChangeListener;
/// focus state change event listener (bool delegate(Widget, bool))
Signal!OnFocusHandler onFocusChangeListener;
// ======================================================= // =======================================================
// Layout and measurement methods // Layout and measurement methods