diff --git a/apps/w9/R.h b/apps/w9/R.h
index 7897a4b5..d566822b 100644
--- a/apps/w9/R.h
+++ b/apps/w9/R.h
@@ -14,11 +14,12 @@ namespace R{
static constexpr int often = 0x00002715 ;/*10005*/
static constexpr int care = 0x00002716 ;/*10006*/
static constexpr int favorite = 0x00002717 ;/*10007*/
- static constexpr int options = 0x00002718 ;/*10008*/
+ static constexpr int numpicker = 0x00002718 ;/*10008*/
static constexpr int text1 = 0x00002719 ;/*10009*/
static constexpr int text2 = 0x0000271A ;/*10010*/
- static constexpr int content = 0x0000271B ;/*10011*/
- static constexpr int optionsContainer = 0x0000271C ;/*10012*/
+ static constexpr int option1 = 0x0000271B ;/*10011*/
+ static constexpr int option2 = 0x0000271C ;/*10012*/
+ static constexpr int option3 = 0x0000271D ;/*10013*/
};/*namespace id*/
namespace strings{
diff --git a/apps/w9/assets/layout/optionitem.xml b/apps/w9/assets/layout/optionitem.xml
index 8d811809..69591877 100755
--- a/apps/w9/assets/layout/optionitem.xml
+++ b/apps/w9/assets/layout/optionitem.xml
@@ -1,29 +1,30 @@
-
-
+
+
+ android:id="@+id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="1dp"
+ android:layout_above="@id/text2"
+ android:gravity="center"
+ android:textSize="32dp"
+ android:textColor="white"
+ android:paddingVertical="5dp"
+ android:background="#121212"/>
-
+ android:id="@+id/text2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_marginTop="1dp"
+ android:paddingVertical="5dp"
+ android:gravity="center"
+ android:textSize="32dp"
+ android:background="#181818"/>
+
diff --git a/apps/w9/assets/layout/options.xml b/apps/w9/assets/layout/options.xml
index c867ab1d..db6b1887 100755
--- a/apps/w9/assets/layout/options.xml
+++ b/apps/w9/assets/layout/options.xml
@@ -3,34 +3,31 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
-
-
-
-
-
-
-
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:background="#112233"
+ android:text2="温度"
+ />
+
+
diff --git a/apps/w9/assets/values/ID.xml b/apps/w9/assets/values/ID.xml
index a7f5ac82..6334fd20 100644
--- a/apps/w9/assets/values/ID.xml
+++ b/apps/w9/assets/values/ID.xml
@@ -8,10 +8,11 @@
0x00002715
0x00002716
0x00002717
- 0x00002718
+ 0x00002718
0x00002719
0x0000271a
- 0x0000271b
- 0x0000271c
+ 0x0000271b
+ 0x0000271c
+ 0x0000271d
diff --git a/apps/w9/optionpicker.cc b/apps/w9/optionpicker.cc
new file mode 100644
index 00000000..d760210a
--- /dev/null
+++ b/apps/w9/optionpicker.cc
@@ -0,0 +1,110 @@
+#include
+#include
+#include
+#include
+
+DECLARE_WIDGET(OptionPicker)
+OptionPicker::OptionPicker(int w,int h):RelativeLayout(w,h){
+
+}
+
+OptionPicker::OptionPicker(Context*ctx,const AttributeSet&attr):RelativeLayout(ctx,attr){
+ LayoutInflater::from(ctx)->inflate("@layout/optionitem",this);
+ mNumberPicker = (NumberPicker*)findViewById(w9::R::id::numpicker);
+ mNumberPicker->setVisibility(View::GONE);
+ mText1=(TextView*)findViewById(w9::R::id::text1);
+ mText2=(TextView*)findViewById(w9::R::id::text2);
+ mText1->setText(attr.getString("text1"));
+ mText2->setText(attr.getString("text2"));
+ LOGD("mNumberPicker=%p text=%p/%p",mNumberPicker,mText1,mText2);
+ mNumberPicker->setOnValueChangedListener([this](NumberPicker&v,int ov,int nv){
+ mText1->setText(std::to_string(nv));
+ if(ov=0) ov=mValues.at(ov);
+ if(nv=0) nv=mValues.at(nv);
+ if(mOnValueChangedListener)
+ mOnValueChangedListener(v,ov,nv);
+ });
+}
+
+NumberPicker&OptionPicker::getPicker(){
+ return *mNumberPicker;
+}
+
+void OptionPicker::setText(const std::string&text){
+ mText1->setText(text);
+}
+
+void OptionPicker::setText(const std::string&text1,const std::string&text2){
+ mText1->setText(text1);
+ mText2->setText(text2);
+}
+
+void OptionPicker::setOnValueChangedListener(NumberPicker::OnValueChangeListener onValueChangedListener){
+ mOnValueChangedListener=onValueChangedListener;
+}
+
+void OptionPicker::setValuedName(const std::vector&values,const std::vector&names){
+ mValues=values;
+ mNumberPicker->setMinValue(0);
+ mNumberPicker->setMaxValue(values.size());
+ mNumberPicker->setDisplayedValues(names);
+}
+
+void OptionPicker::showOptions(bool on){
+ mNumberPicker->setVisibility(on?View::VISIBLE:View::GONE);
+ LOGV("%p:%d visible=%d",this,mID,on);
+}
+
+static int makeMeasureSpec(int measureSpec, int maxSize){
+ if (maxSize == -1/*SIZE_UNSPECIFIED*/) {
+ return measureSpec;
+ }
+ int size = MeasureSpec::getSize(measureSpec);
+ int mode = MeasureSpec::getMode(measureSpec);
+ switch (mode) {
+ case MeasureSpec::EXACTLY: return measureSpec;
+ case MeasureSpec::AT_MOST: return MeasureSpec::makeMeasureSpec(std::min(size, maxSize), MeasureSpec::EXACTLY);
+ case MeasureSpec::UNSPECIFIED: return MeasureSpec::makeMeasureSpec(maxSize, MeasureSpec::EXACTLY);
+ default: throw std::string("Unknown measure mode: ")+std::to_string(mode);
+ }
+}
+
+int OptionPicker::resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize, int measureSpec) {
+ if (minSize != -1/*SIZE_UNSPECIFIED*/) {
+ int desiredWidth = std::max(minSize, measuredSize);
+ return resolveSizeAndState(desiredWidth, measureSpec, 0);
+ } else {
+ return measuredSize;
+ }
+}
+
+void OptionPicker::onMeasure(int widthMeasureSpec, int heightMeasureSpec){
+ RelativeLayout::onMeasure(widthMeasureSpec,heightMeasureSpec);
+ return;
+ // Try greedily to fit the max width and height.
+ const int mMaxWidth=-1, mMaxHeight=-1;
+ const int mMinWidth=-1, mMinHeight=-1;
+ int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMaxWidth);
+ int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight);
+ RelativeLayout::onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
+ // Flag if we are measured with width or height less than the respective min.
+ int widthSize = resolveSizeAndStateRespectingMinSize(mMinWidth, getMeasuredWidth(),
+ widthMeasureSpec);
+ int heightSize = resolveSizeAndStateRespectingMinSize(mMinHeight, getMeasuredHeight(),
+ heightMeasureSpec);
+ LOGD("%p:%d setMeasuredDimension(%x/%d,%x/%d)",this,mID,widthSize,widthSize,heightSize,heightSize);
+ setMeasuredDimension(widthSize, heightSize);
+}
+
+void OptionPicker::onLayout(bool changed, int left, int top, int width, int height){
+ RelativeLayout::onLayout(changed,left,top,width,height);
+ return ;
+ const int inptTxtMsrdWdth = mText2->getMeasuredWidth();
+ const int inptTxtMsrdHght = mText2->getMeasuredHeight();
+ const int msrdWdth = getMeasuredWidth();
+ const int msrdHght = getMeasuredHeight();
+ mText2->layout(0, msrdHght-inptTxtMsrdHght, inptTxtMsrdWdth, inptTxtMsrdHght);
+ mText1->layout(0,msrdHght-inptTxtMsrdHght*2,inptTxtMsrdWdth, inptTxtMsrdHght);
+ LOGD("%p:%d textSize=(%d,%d) measuredsize=%dx%d",this,mID,inptTxtMsrdWdth,inptTxtMsrdHght,msrdWdth,msrdHght);
+ mNumberPicker->layout(0,0,inptTxtMsrdWdth,msrdHght-inptTxtMsrdHght*2);
+}
diff --git a/apps/w9/optionpicker.h b/apps/w9/optionpicker.h
new file mode 100644
index 00000000..7e0ebb06
--- /dev/null
+++ b/apps/w9/optionpicker.h
@@ -0,0 +1,27 @@
+#pragma once
+#include
+#include
+#include
+
+class OptionPicker:public RelativeLayout{
+protected:
+ NumberPicker*mNumberPicker;
+ TextView* mText1,*mText2;
+ std::vectormValues;
+ NumberPicker::OnValueChangeListener mOnValueChangedListener;
+protected:
+ int resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize, int measureSpec);
+ void onMeasure(int widthMeasureSpec, int heightMeasureSpec)override;
+ void onLayout(bool changed, int left, int top, int width, int height)override;
+public:
+ OptionPicker(int,int);
+ OptionPicker(Context*,const AttributeSet&attr);
+ NumberPicker&getPicker();
+ void setText(const std::string&text);
+ void setText(const std::string&,const std::string&);
+ void setOnValueChangedListener(NumberPicker::OnValueChangeListener onValueChangedListener);
+ /*values used for uart commandid,names used for display,values.size==names.size*/
+ void setValuedName(const std::vector&values,const std::vector&names);
+ void showOptions(bool on);
+};
+
diff --git a/apps/w9/washoptions.cc b/apps/w9/washoptions.cc
index bbaed117..506b9245 100644
--- a/apps/w9/washoptions.cc
+++ b/apps/w9/washoptions.cc
@@ -1,47 +1,21 @@
#include
#include
#include
+#include
-WashOptionsWindow::WashOptionsWindow(int options):Window(0,0,1280,800){
+WashOptionsWindow::WashOptionsWindow(int options):Window(0,0,-1,-1){
LayoutInflater::from(getContext())->inflate("@layout/options",this);
- NumberPicker*np=(NumberPicker*)findViewById(w9::R::id::options);
- np->setMinValue(0);
- np->setMaxValue(4);
- np->setSelector(5,-1);
- LinearLayout*ll=(LinearLayout*)findViewById(w9::R::id::optionsContainer);
- const char*labels[]={
- "Button0",
- "Button1",
- "Button2",
- "Button3",
- "Button4",
- "Button5"
- };
- const int count=sizeof(labels)/sizeof(labels[0]);
- for(int i=0;iaddView(opt,new LinearLayout::LayoutParams(-1,32,1.f/count)).setId(100+i).setClickable(true);
- opt->setText(labels[i]);
- opt->setBackgroundResource("@drawable/optionbackground");
- opt->setOnClickListener(std::bind(&WashOptionsWindow::onOptionClick,this,std::placeholders::_1));
+ ViewGroup*vg=dynamic_cast(getChildAt(0));
+ for(int i=0;igetChildCount();i++){
+ vg->getChildAt(i)->setOnClickListener(std::bind(&WashOptionsWindow::onOptionClick,this,std::placeholders::_1));
}
- dynamic_cast(np->getLayoutParams())->setMarginStart(600);
- FrameLayout*frame=(FrameLayout*)findViewById(w9::R::id::content);
- frame->requestLayout();
}
void WashOptionsWindow::onOptionClick(View&v){
- ViewGroup*parent=v.getParent();
- const int count=parent->getChildCount();
- const bool checked=dynamic_cast(v).isChecked();
- for(int i=0;igetChildAt(i);
- dynamic_cast(v)->setChecked(false);
+ ViewGroup*vg=v.getParent();
+ for(int i=0;igetChildCount();i++){
+ OptionPicker*op=dynamic_cast(vg->getChildAt(i));
+ op->showOptions(op==&v);
}
- dynamic_cast(v).setChecked(checked);
- NumberPicker*np=(NumberPicker*)findViewById(w9::R::id::options);
- dynamic_cast(np->getLayoutParams())->setMarginStart(v.getLeft());
- FrameLayout*frame=(FrameLayout*)findViewById(w9::R::id::content);
- LOGD("set numberpicker to %d",v.getLeft());
- frame->requestLayout();
+ invalidate();
}