modify idgen.py,make id's value more stable than evenr.2,modify uidemo

This commit is contained in:
侯歌 2022-02-11 14:54:04 +08:00
parent 25c73c5cb7
commit 0f9d33fc7c
27 changed files with 1072 additions and 255 deletions

View File

@ -7,12 +7,27 @@ namespace uidemo{
class R{
public:
enum id {
idno = 0x00002710 ,
filename = 0x00002711 ,
filesize = 0x00002712 ,
exitbutton = 0x00002713 ,
tablayout = 0x00002714 ,
viewpager = 0x00002715
idno = 0x00002710 /* 10000*/ ,
filename = 0x00002711 /* 10001*/ ,
filesize = 0x00002712 /* 10002*/ ,
exitbutton = 0x00002713 /* 10003*/ ,
tablayout = 0x00002714 /* 10004*/ ,
viewpager = 0x00002715 /* 10005*/ ,
tv1 = 0x00002716 /* 10006*/ ,
et1 = 0x00002717 /* 10007*/ ,
tv2 = 0x00002718 /* 10008*/ ,
et2 = 0x00002719 /* 10009*/ ,
btnadd = 0x0000271A /* 10010*/ ,
table = 0x0000271B /* 10011*/ ,
address = 0x0000271C /* 10012*/ ,
BtnGo = 0x0000271D /* 10013*/ ,
TextUrl = 0x0000271E /* 10014*/ ,
WebView01 = 0x0000271F /* 10015*/ ,
icon = 0x00002720 /* 10016*/ ,
editText1 = 0x00002721 /* 10017*/ ,
editText2 = 0x00002722 /* 10018*/ ,
button1 = 0x00002723 /* 10019*/ ,
table1 = 0x00002724 /* 10020*/
};//endof enum id
};//endof class R

View File

@ -1,28 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="0x23"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_height="wrap_content"
android:background="#FF12151C">
<TextView
android:id="@id/idno"
android:id="@+id/idno"
android:layout_width="80dp"
android:layout_alignParentLeft="true"
android:layout_height="match_parent"
android:scaleType="center"
android:background="#0"
android:textColor="#00FF00"
android:layout_centerVertical="true"
android:background="#ff0000"
android:text="NONO"
>
</TextView>
<TextView
android:id="@id/filename"
android:id="@+id/filename"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#333333"
android:layout_toEndOf="@id/idno"
android:layout_toLeftOf="@id/filesize"
android:background="#00FF00"
android:layout_centerVertical="true"
android:textSize="24sp"
android:textColor="#888888"
android:text="Text Lines(FileName)"
android:layout_weight="1">
</TextView>
<TextView
android:id="@if/filesize"
android:id="@+id/filesize"
android:layout_width="120dp"
android:layout_height="match_parent"
android:background="#111111">
android:layout_alignParentRight="true"
android:background="#0000ff"
android:layout_centerVertical="true"
android:text="12.3K"
android:textColor="#FFFFFF"
android:textSize="32sp">
</TextView>
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,37 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="0x23"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF12151C">
<ImageView
android:id="@+id/icon"
android:src="@mipmap/dev_sync"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:scalrType="centerCrop"
/>
<TextView
android:id="@+id/filename"
android:layout_width="maptch_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/icon"
android:background="#008800"
android:text="FileName"
android:layout_marginBottom="2dp"
android:textColor="#ffffff"
/>
<TextView
android:id="@+id/filesize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/icon"
android:layout_below="@id/filename"
android:background="#004400"
android:text="12.5k"
android:textColor="#ffff88"
/>
</RelativeLayout>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:background="#00FF00">
<Button android:id="@+id/BtnGo"
android:layout_width="80dpwrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:text="Go"/>
<EditText android:id="@+id/TextUrl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="请输入网址"
android:layout_alignTop="@id/BtnGo"
android:layout_toLeftOf="@id/BtnGo"/>
</RelativeLayout>
<TextView android:id="@+id/WebView01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/address"
android:text="Text view ..."/>
</LinearLayout>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:background="#aa0000"
android:text="@string/red" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:background="#00aa00"
android:text="@string/green" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:background="#0000aa"
android:text="@string/blue" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:background="#aaaa00"
android:text="@string/yellow" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/row1"
android:textSize="15pt" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/row2"
android:textSize="15pt" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/row3"
android:textSize="15pt" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/row4"
android:textSize="15pt" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,92 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:gravity="center_vertical"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:textSize="20sp"
android:text="请输入行:"
/>
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="请输入数字!"
android:numeric="decimal" />
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:gravity="center_vertical"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:textSize="20sp"
android:text="请输入列:"
/>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="请输入数字!"
android:numeric="decimal">
<!--requestFocus/-->
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button1"
android:text="一键自动生成表格"
/>
</LinearLayout>
</LinearLayout>
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/table1">
</TableLayout>
</LinearLayout>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="6">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请输入要生成表格的行号列"
android:textSize="15sp"/>
<TableRow
android:gravity="center"
android:layout_marginTop="5dp"
>
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="行"
android:textSize="15sp"/>
<EditText
android:id="@+id/et1"
android:layout_width="100dp"
android:layout_height="wrap_content"/>
</TableRow>
<TableRow
android:gravity="center"
android:layout_marginTop="5dp"
>
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="列"
android:textSize="15sp" />
<EditText
android:id="@+id/et2"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:numeric="decimal"/>
<!-- decimal 只能输入数字大于0的数字-->
</TableRow>
<TableRow
android:gravity="center"
>
<Button
android:id="@+id/btnadd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="确定"
/>
</TableRow>
</TableLayout>
</LinearLayout>
<TableLayout
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:stretchColumns="*"
android:shrinkColumns="*">
</TableLayout>
</LinearLayout>

View File

@ -23,6 +23,24 @@
android:layout_height="match_parent"
android:background="transparent"
android:layout_weight="1">
<!--TabItem
android:id="101"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Tab2"
android:icon="@mipmap/dev_sync"/>
<TabItem
android:id="102"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Tab3"
android:icon="@mipmap/dev_sync"/>
<TabItem
android:id="103"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Tab1"
android:icon="@mipmap/dev_sync"/-->
</TabLayout>
<ImageButton
android:id="300"

15
apps/uidemo/assets/values/ID.xml Normal file → Executable file
View File

@ -6,5 +6,20 @@
<id name="exitbutton">0x00002713</id>
<id name="tablayout">0x00002714</id>
<id name="viewpager">0x00002715</id>
<id name="tv1">0x00002716</id>
<id name="et1">0x00002717</id>
<id name="tv2">0x00002718</id>
<id name="et2">0x00002719</id>
<id name="btnadd">0x0000271a</id>
<id name="table">0x0000271b</id>
<id name="address">0x0000271c</id>
<id name="BtnGo">0x0000271d</id>
<id name="TextUrl">0x0000271e</id>
<id name="WebView01">0x0000271f</id>
<id name="icon">0x00002720</id>
<id name="editText1">0x00002721</id>
<id name="editText2">0x00002722</id>
<id name="button1">0x00002723</id>
<id name="table1">0x00002724</id>
</resources>

View File

@ -2,6 +2,9 @@
#include <dirent.h>
#include <cdroid.h>
#include <R.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
namespace cdroid{
std::string SimplifyPath(const std::string & path) {
char rpath[1024];
@ -18,14 +21,20 @@ View*FileAdapter::getView(int position, View* convertView, ViewGroup* parent){
ViewGroup*vp=(ViewGroup*)convertView;
TextView*tv;
if(convertView==nullptr){
vp=(ViewGroup*)LayoutInflater::from(&App::getInstance())->inflate("layout/fileitem.xml",nullptr);
vp=(ViewGroup*)LayoutInflater::from(&App::getInstance())->inflate(mResource,nullptr);
}
tv=(TextView*)vp->findViewById(uidemo::R::id::idno);
if(tv)tv->setText(std::to_string(position));
tv=(TextView*)vp->findViewById(uidemo::R::id::filename);
tv->setText(mi.fileName);
tv->setTextColor(mi.isDir?0xFFFFFFFF:0xFF88FF00);
tv->setTextSize(28);
tv=(TextView*)vp->findViewById(uidemo::R::id::filesize);
if(tv&&mi.isDir==false){
struct stat st;
int rc=stat(mi.fullpath.c_str(),&st);
if(rc==0)
tv->setText(std::to_string(st.st_size/1024)+"K");
else tv->setText("stat Error");
}
return vp;
}

View File

@ -13,8 +13,10 @@ public:
};
class FileAdapter:public ArrayAdapter<FileItem>{
private:
std::string mResource;
public:
FileAdapter(const std::string&res):mResource(res){}
View*getView(int position, View* convertView, ViewGroup* parent)override;
int loadFiles(const std::string&path);
static std::string SimplifyPath(const std::string & path);

View File

@ -13,33 +13,58 @@
#include <R.h>
class FileTypeAdapter:public PagerAdapter{
public:
int getCount()override{return 3;}
int getCount()override{return 5;}
bool isViewFromObject(View* view, void*object)override{ return view==object;}
void* instantiateItem(ViewGroup* container, int position)override{
ListView*lv=new ListView(480,400);
lv->setDivider(new ColorDrawable(0x80224422));
lv->setDividerHeight(1);
lv->setSelector(new ColorDrawable(0x8800FF00));
lv->setVerticalScrollBarEnabled(true);
lv->setOverScrollMode(View::OVER_SCROLL_ALWAYS);
FileAdapter*adapter=new FileAdapter();
adapter->loadFiles("/");
lv->setAdapter(adapter);
lv->setBackgroundColor(0xFF000000|(0xFF<<position*8));
container->addView(lv);
lv->setOnItemClickListener([](AdapterView&lv,View&v,int pos,long id){
FileAdapter*adp=(FileAdapter*)lv.getAdapter();
FileItem&f=adp->getItemAt(pos);
LOG(DEBUG)<<"clicked "<<pos<<" "<<f.fileName;
if(f.isDir){
adp->clear();
adp->loadFiles(f.fullpath);
adp->notifyDataSetChanged();
std::string res[]={"@layout/layout1.xml","@layout/layout2.xml","@layout/layout3.xml"};
switch(position){
case 2:
case 3:
case 4:
{View*v=LayoutInflater::from(container->getContext())->inflate(res[position-2],nullptr,false);
container->addView(v);
v->requestLayout();
return v;
}break;
case 0:
{
ListView*lv=new ListView(800,480);
lv->setDivider(new ColorDrawable(0x80224422));
lv->setDividerHeight(1);
lv->setSelector(new ColorDrawable(0x8800FF00));
lv->setVerticalScrollBarEnabled(true);
lv->setOverScrollMode(View::OVER_SCROLL_ALWAYS);
FileAdapter*adapter=new FileAdapter("@layout/fileitem.xml");
adapter->loadFiles("/");
lv->setAdapter(adapter);
lv->setBackgroundColor(0xFF000000|(0xFF<<position*8));
container->addView(lv);
lv->setOnItemClickListener([](AdapterView&lv,View&v,int pos,long id){
FileAdapter*adp=(FileAdapter*)lv.getAdapter();
FileItem&f=adp->getItemAt(pos);
LOG(DEBUG)<<"clicked "<<pos<<" "<<f.fileName;
if(f.isDir){
adp->clear();
adp->loadFiles(f.fullpath);
adp->notifyDataSetChanged();
}
});
LOGV("instantiateItem %d to %p",position,lv);
return lv;
}
case 1:{LOGD("===========1111");
GridView*gv=new GridView(800,480);
FileAdapter*adapter=new FileAdapter("@layout/fileitem2.xml");
gv->setNumColumns(3);
gv->setAdapter(adapter);
gv->setHorizontalSpacing(2);
gv->setVerticalSpacing(2);
container->addView(gv);
adapter->loadFiles("/");
adapter->notifyDataSetChanged();
return gv;
}
});
LOGV("instantiateItem %d to %p",position,lv);
return lv;
}
}
void destroyItem(ViewGroup* container, int position,void* object)override{
container->removeView((View*)object);
@ -69,6 +94,7 @@ public:
};
MediaWindow::MediaWindow(int x,int y,int w,int h):Window(x,y,w,h){
#if 10
ViewGroup*vg=(ViewGroup*)LayoutInflater::from(getContext())->inflate("layout/main.xml",this);
mAdapter=new FileTypeAdapter();
mTabLayout=(TabLayout*)vg->findViewById(uidemo::R::id::tablayout);
@ -82,13 +108,17 @@ MediaWindow::MediaWindow(int x,int y,int w,int h):Window(x,y,w,h){
mPager = (ViewPager*)vg->findViewById(uidemo::R::id::viewpager);
#endif
mTabLayout->setSelectedTabIndicatorColor(0x8000FF00);
mTabLayout->setSelectedTabIndicatorHeight(4);
mTabLayout->setSelectedTabIndicatorHeight(5);
mTabLayout->setTabTextColors(0xFFFF0000,0xFF00FF00);
mTabLayout->setTabIndicatorGravity(Gravity::BOTTOM);//TOP/BOTTOM/CENTER_VERTICAL/FILL_VERTICAL
LOGD("pager=%p tab=%p this=%p:%p",mPager,mTabLayout,this,vg);
mPager->setAdapter(mAdapter);
mTabLayout->setupWithViewPager(mPager);
mTabLayout->requestLayout();
#else
LayoutInflater::from(getContext())->inflate("@layout/fileitem",this);
requestLayout();
#endif
}
Window*CreateMultiMedia(){

View File

@ -81,6 +81,7 @@ class IDGenerater(object):
def scanxml(self,scanPath):
lastmodifytime=0
for top, dirs, nondirs in os.walk(scanPath):
dirs.sort()
for item in nondirs:
fname=os.path.join(top, item)
if (not item.endswith('.xml')) or (self.dirHasId(fname)<0):

View File

@ -1,33 +0,0 @@
<LinearLayout xmlns:cdroid="http://schemas.android.com/apk/res/android"
cdroid:layout_width="fill_parent"
cdroid:layout_height="wrap_content"
cdroid:orientation="horizontal">
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity= "center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#aa0000"
cdroid:text="@string/red" />
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#00aa00"
cdroid:text="@string/green" />
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#0000aa"
cdroid:text="@string/blue" />
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#aaaa00"
cdroid:text="@string/yellow" />
</LinearLayout>

View File

@ -1,33 +0,0 @@
<LinearLayout xmlns:cdroid="http://schemas.android.com/apk/res/android"
cdroid:layout_width="fill_parent"
cdroid:layout_height="fill_parent"
cdroid:orientation="vertical">
<TextView
cdroid:layout_width="fill_parent"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center"
cdroid:layout_weight="1"
cdroid:background="#aa0000"
cdroid:text="@string/red" />
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#00aa00"
cdroid:text="@string/green" />
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#0000aa"
cdroid:text="@string/blue" />
<TextView
cdroid:layout_width="wrap_content"
cdroid:layout_height="fill_parent"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
cdroid:background="#aaaa00"
cdroid:text="@string/yellow" />
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:cdroid="http://schemas.android.com/apk/res/android"
cdroid:layout_width="match_parent"
cdroid:layout_height="match_parent"
cdroid:orientation="vertical"
cdroid:background="?cdroid:attr/toastFrameBackground">
<TextView
cdroid:id="@cdroid:id/message"
cdroid:layout_width="wrap_content"
cdroid:layout_height="wrap_content"
cdroid:layout_weight="1"
cdroid:layout_gravity="center_horizontal"
cdroid:textAppearance="@cdroid:style/TextAppearance.Toast"
cdroid:textColor="@cdroid:color/bright_foreground_dark"
cdroid:shadowColor="#BB000000"
cdroid:shadowRadius="2.75"
/>
</LinearLayout>

58
src/gui/res/values/ID.xml Executable file → Normal file
View File

@ -1,33 +1,33 @@
<?xml version="1.0" encoding="utf-8"?><!--Generated by CDdroid's machine,Do not edit !!!-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<id name="parentPanel">0x000003e8</id>
<id name="topPanel">0x000003e9</id>
<id name="titleDividerTop">0x000003ea</id>
<id name="title_template">0x000003eb</id>
<id name="icon">0x000003ec</id>
<id name="alertTitle">0x000003ed</id>
<id name="titleDivider">0x000003ee</id>
<id name="contentPanel">0x000003ef</id>
<id name="scrollView">0x000003f0</id>
<id name="message">0x000003f1</id>
<id name="customPanel">0x000003f2</id>
<id name="custom">0x000003f3</id>
<id name="buttonPanel">0x000003f4</id>
<id name="button2">0x000003f5</id>
<id name="button3">0x000003f6</id>
<id name="button1">0x000003f7</id>
<id name="text1">0x000003f8</id>
<id name="titleDividerNoCustom">0x000003f9</id>
<id name="textSpacerNoTitle">0x000003fa</id>
<id name="textSpacerNoButtons">0x000003fb</id>
<id name="increment">0x000003fc</id>
<id name="numberpicker_input">0x000003fd</id>
<id name="decrement">0x000003fe</id>
<id name="leftSpacer">0x000003ff</id>
<id name="rightSpacer">0x00000400</id>
<id name="select_dialog_listview">0x00000401</id>
<id name="background">0x00000402</id>
<id name="progress">0x00000403</id>
<id name="secondaryProgress">0x00000404</id>
<id name="background">0x000003e8</id>
<id name="progress">0x000003e9</id>
<id name="secondaryProgress">0x000003ea</id>
<id name="parentPanel">0x000003eb</id>
<id name="topPanel">0x000003ec</id>
<id name="title_template">0x000003ed</id>
<id name="icon">0x000003ee</id>
<id name="alertTitle">0x000003ef</id>
<id name="titleDivider">0x000003f0</id>
<id name="contentPanel">0x000003f1</id>
<id name="scrollView">0x000003f2</id>
<id name="message">0x000003f3</id>
<id name="customPanel">0x000003f4</id>
<id name="custom">0x000003f5</id>
<id name="buttonPanel">0x000003f6</id>
<id name="leftSpacer">0x000003f7</id>
<id name="button1">0x000003f8</id>
<id name="button3">0x000003f9</id>
<id name="button2">0x000003fa</id>
<id name="rightSpacer">0x000003fb</id>
<id name="titleDividerNoCustom">0x000003fc</id>
<id name="text1">0x000003fd</id>
<id name="select_dialog_listview">0x000003fe</id>
<id name="increment">0x000003ff</id>
<id name="numberpicker_input">0x00000400</id>
<id name="decrement">0x00000401</id>
<id name="textSpacerNoTitle">0x00000402</id>
<id name="textSpacerNoButtons">0x00000403</id>
<id name="titleDividerTop">0x00000404</id>
</resources>

58
src/gui/widget/R.h Executable file → Normal file
View File

@ -7,35 +7,35 @@ namespace cdroid{
class R{
public:
enum id {
parentPanel = 0x000003E8 /* 1000*/ ,
topPanel = 0x000003E9 /* 1001*/ ,
titleDividerTop = 0x000003EA /* 1002*/ ,
title_template = 0x000003EB /* 1003*/ ,
icon = 0x000003EC /* 1004*/ ,
alertTitle = 0x000003ED /* 1005*/ ,
titleDivider = 0x000003EE /* 1006*/ ,
contentPanel = 0x000003EF /* 1007*/ ,
scrollView = 0x000003F0 /* 1008*/ ,
message = 0x000003F1 /* 1009*/ ,
customPanel = 0x000003F2 /* 1010*/ ,
custom = 0x000003F3 /* 1011*/ ,
buttonPanel = 0x000003F4 /* 1012*/ ,
button2 = 0x000003F5 /* 1013*/ ,
button3 = 0x000003F6 /* 1014*/ ,
button1 = 0x000003F7 /* 1015*/ ,
text1 = 0x000003F8 /* 1016*/ ,
titleDividerNoCustom = 0x000003F9 /* 1017*/ ,
textSpacerNoTitle = 0x000003FA /* 1018*/ ,
textSpacerNoButtons = 0x000003FB /* 1019*/ ,
increment = 0x000003FC /* 1020*/ ,
numberpicker_input = 0x000003FD /* 1021*/ ,
decrement = 0x000003FE /* 1022*/ ,
leftSpacer = 0x000003FF /* 1023*/ ,
rightSpacer = 0x00000400 /* 1024*/ ,
select_dialog_listview = 0x00000401 /* 1025*/ ,
background = 0x00000402 /* 1026*/ ,
progress = 0x00000403 /* 1027*/ ,
secondaryProgress = 0x00000404 /* 1028*/
background = 0x000003E8 /* 1000*/ ,
progress = 0x000003E9 /* 1001*/ ,
secondaryProgress = 0x000003EA /* 1002*/ ,
parentPanel = 0x000003EB /* 1003*/ ,
topPanel = 0x000003EC /* 1004*/ ,
title_template = 0x000003ED /* 1005*/ ,
icon = 0x000003EE /* 1006*/ ,
alertTitle = 0x000003EF /* 1007*/ ,
titleDivider = 0x000003F0 /* 1008*/ ,
contentPanel = 0x000003F1 /* 1009*/ ,
scrollView = 0x000003F2 /* 1010*/ ,
message = 0x000003F3 /* 1011*/ ,
customPanel = 0x000003F4 /* 1012*/ ,
custom = 0x000003F5 /* 1013*/ ,
buttonPanel = 0x000003F6 /* 1014*/ ,
leftSpacer = 0x000003F7 /* 1015*/ ,
button1 = 0x000003F8 /* 1016*/ ,
button3 = 0x000003F9 /* 1017*/ ,
button2 = 0x000003FA /* 1018*/ ,
rightSpacer = 0x000003FB /* 1019*/ ,
titleDividerNoCustom = 0x000003FC /* 1020*/ ,
text1 = 0x000003FD /* 1021*/ ,
select_dialog_listview = 0x000003FE /* 1022*/ ,
increment = 0x000003FF /* 1023*/ ,
numberpicker_input = 0x00000400 /* 1024*/ ,
decrement = 0x00000401 /* 1025*/ ,
textSpacerNoTitle = 0x00000402 /* 1026*/ ,
textSpacerNoButtons = 0x00000403 /* 1027*/ ,
titleDividerTop = 0x00000404 /* 1028*/
};//endof enum id
};//endof class R

View File

@ -251,7 +251,9 @@ void AbsListView::initAbsListView() {
mOnScrollListener.onScrollStateChanged = nullptr;
mScroller = new OverScroller(getContext());
mEdgeGlowTop = mEdgeGlowBottom =nullptr;
mEdgeGlowBottom = new EdgeEffect(mContext);
mEdgeGlowTop = new EdgeEffect(mContext);
mFlingRunnable = std::bind(&AbsListView::FLY_Proc,this);
mCheckFlywheel = std::bind(&AbsListView::FLY_CheckFlyWheelProc,this);
mWidthMeasureSpec=0;
@ -304,20 +306,6 @@ void AbsListView::setScrollIndicatorViews(View* up, View* down){
mScrollDown = down;
}
void AbsListView::setOverScrollMode(int mode) {
if (mode != OVER_SCROLL_NEVER) {
if (mEdgeGlowTop == nullptr) {
Context* context = getContext();
mEdgeGlowTop = new EdgeEffect(context);
mEdgeGlowBottom = new EdgeEffect(context);
}
} else {
mEdgeGlowTop = nullptr;
mEdgeGlowBottom = nullptr;
}
AdapterView::setOverScrollMode(mode);
}
void AbsListView::setAdapter(Adapter*adapter) {
if (adapter != nullptr) {
mAdapterHasStableIds =adapter->hasStableIds();
@ -1554,7 +1542,7 @@ View*AbsListView::obtainView(int position, bool*outMetadata) {
void AbsListView::draw(Canvas& canvas) {
AdapterView::draw(canvas);
if (mEdgeGlowTop != nullptr) {
if (shouldDisplayEdgeEffects()) {
int scrollY = mScrollY;
bool clipToPadding = getClipToPadding();
int width;
@ -2374,23 +2362,21 @@ bool AbsListView::startScrollIfNeeded(int x, int y, MotionEvent* vtev) {
void AbsListView::scrollIfNeeded(int x, int y, MotionEvent* vtev) {
int rawDeltaY = y - mMotionY;
int scrollOffsetCorrection = 0;
int scrollConsumedCorrection = 0;
if (mLastY == INT_MIN) {
rawDeltaY -= mMotionCorrection;
}
if (dispatchNestedPreScroll(0, mLastY != INT_MIN ? mLastY - y : -rawDeltaY,
mScrollConsumed, mScrollOffset)) {
int incrementalDeltaY = mLastY != INT_MIN ? y - mLastY : rawDeltaY;
incrementalDeltaY = releaseGlow(incrementalDeltaY,x);
if (dispatchNestedPreScroll(0,-incrementalDeltaY, mScrollConsumed, mScrollOffset)) {
rawDeltaY += mScrollConsumed[1];
scrollOffsetCorrection = -mScrollOffset[1];
scrollConsumedCorrection = mScrollConsumed[1];
incrementalDeltaY += mScrollConsumed[1];
if (vtev != nullptr) {
vtev->offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
}
int deltaY = rawDeltaY;
int incrementalDeltaY = mLastY != INT_MIN ? y - mLastY + scrollConsumedCorrection : deltaY;
int lastYCorrection = 0;
if (mTouchMode == TOUCH_MODE_SCROLL/*3*/) {
@ -2468,13 +2454,13 @@ void AbsListView::scrollIfNeeded(int x, int y, MotionEvent* vtev) {
mTouchMode = TOUCH_MODE_OVERSCROLL;
}
if (incrementalDeltaY > 0) {
mEdgeGlowTop->onPull((float) -overscroll / getHeight(), (float) x / getWidth());
mEdgeGlowTop->onPullDistance((float) -overscroll / getHeight(), (float) x / getWidth());
if (!mEdgeGlowBottom->isFinished()) {
mEdgeGlowBottom->onRelease();
}
invalidateTopGlow();
} else if (incrementalDeltaY < 0) {
mEdgeGlowBottom->onPull((float) overscroll / getHeight(), 1.f - (float) x / getWidth());
mEdgeGlowBottom->onPullDistance((float) overscroll / getHeight(), 1.f - (float) x / getWidth());
if (!mEdgeGlowTop->isFinished()) {
mEdgeGlowTop->onRelease();
}
@ -2513,14 +2499,14 @@ void AbsListView::scrollIfNeeded(int x, int y, MotionEvent* vtev) {
(overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS &&
!contentFits())) {
if (rawDeltaY > 0) {
mEdgeGlowTop->onPull((float) overScrollDistance / getHeight(),
mEdgeGlowTop->onPullDistance((float) overScrollDistance / getHeight(),
(float) x / getWidth());
if (!mEdgeGlowBottom->isFinished()) {
mEdgeGlowBottom->onRelease();
}
invalidateTopGlow();
} else if (rawDeltaY < 0) {
mEdgeGlowBottom->onPull((float) overScrollDistance / getHeight(),
mEdgeGlowBottom->onPullDistance((float) overScrollDistance / getHeight(),
1.f - (float) x / getWidth());
if (!mEdgeGlowTop->isFinished()) {
mEdgeGlowTop->onRelease();
@ -2556,6 +2542,34 @@ void AbsListView::scrollIfNeeded(int x, int y, MotionEvent* vtev) {
}//if (y != mLastY)
}
}
int AbsListView::releaseGlow(int deltaY, int x) {
// First allow releasing existing overscroll effect:
float consumed = .0f;
if (mEdgeGlowTop->getDistance() != .0f) {
consumed = mEdgeGlowTop->onPullDistance((float) deltaY / getHeight(),
(float) x / getWidth());
if (consumed != .0f) {
invalidateTopGlow();
}
} else if (mEdgeGlowBottom->getDistance() != .0f) {
consumed = -mEdgeGlowBottom->onPullDistance((float) -deltaY / getHeight(),
1.f - (float) x / getWidth());
if (consumed != .0f) {
invalidateBottomGlow();
}
}
int pixelsConsumed = round(consumed * getHeight());
return deltaY - pixelsConsumed;
}
/**
* @return <code>true</code> if either the top or bottom edge glow is currently active or
* <code>false</code> if it has no value to release.
*/
bool AbsListView::isGlowActive()const{
return mEdgeGlowBottom->getDistance() != 0 || mEdgeGlowTop->getDistance() != 0;
}
void AbsListView::invalidateTopGlow() {
if (mEdgeGlowTop == nullptr) return;
@ -2579,7 +2593,7 @@ void AbsListView::invalidateBottomGlow() {
}
void AbsListView::finishGlows() {
if (mEdgeGlowTop != nullptr) {
if (shouldDisplayEdgeEffects()) {
mEdgeGlowTop->finish();
mEdgeGlowBottom->finish();
}
@ -2700,6 +2714,42 @@ void AbsListView::setVisibleRangeHint(int start,int end) {
//nothing,for android's remote view
}
//Sets the edge effect color for both top and bottom edge effects.
void AbsListView::setEdgeEffectColor(int color) {
setTopEdgeEffectColor(color);
setBottomEdgeEffectColor(color);
}
/**
* Sets the bottom edge effect color.
*/
void AbsListView::setBottomEdgeEffectColor( int color) {
mEdgeGlowBottom->setColor(color);
invalidateBottomGlow();
}
/**
* Sets the top edge effect color.
*/
void AbsListView::setTopEdgeEffectColor(int color) {
mEdgeGlowTop->setColor(color);
invalidateTopGlow();
}
/**
* Returns the top edge effect color.
*/
int AbsListView::getTopEdgeEffectColor()const{
return mEdgeGlowTop->getColor();
}
/**
* @return The bottom edge effect color.
*/
int AbsListView::getBottomEdgeEffectColor()const{
return mEdgeGlowBottom->getColor();
}
void AbsListView::onTouchUp(MotionEvent&ev) {
View*child;
int childCount;
@ -2829,7 +2879,7 @@ void AbsListView::onTouchUp(MotionEvent&ev) {
setPressed(false);
if (mEdgeGlowTop != nullptr) {
if (shouldDisplayEdgeEffects()) {
mEdgeGlowTop->onRelease();
mEdgeGlowBottom->onRelease();
}
@ -2853,6 +2903,10 @@ void AbsListView::onTouchUp(MotionEvent&ev) {
}*/
}
bool AbsListView::shouldDisplayEdgeEffects()const{
return getOverScrollMode() != OVER_SCROLL_NEVER;
}
void AbsListView::onTouchCancel() {
switch (mTouchMode) {
case TOUCH_MODE_OVERSCROLL:
@ -2873,7 +2927,7 @@ void AbsListView::onTouchCancel() {
removeCallbacks(mPendingCheckForLongPress);
recycleVelocityTracker();
}
if (mEdgeGlowTop != nullptr) {
if (shouldDisplayEdgeEffects()) {
mEdgeGlowTop->onRelease();
mEdgeGlowBottom->onRelease();
}

View File

@ -161,12 +161,15 @@ private:
void onTouchUp(MotionEvent& ev);
void onTouchDown(MotionEvent& ev);
void onTouchMove(MotionEvent&,MotionEvent&);
bool shouldDisplayEdgeEffects()const;
void onTouchCancel();
void onSecondaryPointerUp(MotionEvent&);
bool contentFits();
void positionSelector(int position, View* sel, bool manageHotspot, float x, float y);
bool startScrollIfNeeded(int x, int y, MotionEvent* vtev);
void scrollIfNeeded(int x, int y, MotionEvent* vtev);
int releaseGlow(int deltaY, int x);
bool isGlowActive()const;
void invalidateTopGlow();
void invalidateBottomGlow();
void finishGlows();
@ -259,7 +262,12 @@ protected:
void hideSelector();
void reportScrollStateChange(int newState);
void setVisibleRangeHint(int start,int end);
int reconcileSelectedPosition();
void setEdgeEffectColor(int color);
void setBottomEdgeEffectColor( int color);
void setTopEdgeEffectColor(int color);
int getTopEdgeEffectColor()const;
int getBottomEdgeEffectColor()const;
int reconcileSelectedPosition();
void requestLayoutIfNecessary();
bool resurrectSelection();
@ -294,7 +302,6 @@ public:
AbsListView(int w,int h);
AbsListView(Context*,const AttributeSet&atts);
~AbsListView();
void setOverScrollMode(int mode)override;
void setAdapter(Adapter*adapter)override;
int getCheckedItemCount()const;
int getCheckedItemPositions(SparseBooleanArray&array);

View File

@ -2,7 +2,8 @@
#include <systemclock.h>
#include <cdtypes.h>
#include <cdlog.h>
#include <animation/valueanimator.h>
#include <animation/animationutils.h>
namespace cdroid{
@ -38,16 +39,29 @@ void EdgeEffect::setSize(int width, int height){
float oR = height * RADIUS_FACTOR / SIN;
float oy = COS * oR;
float oh = oR - oy;
mWidth = width;
mHeight = height;
mRadius = r;
mBaseGlowScale = h > 0 ? std::min(oh / h, 1.f) : 1.f;
mBounds.set(mBounds.left, mBounds.top, width, (int) std::min((float)height, h));
}
int EdgeEffect::getCurrentEdgeEffectBehavior() {
if (0/*!ValueAnimator::areAnimatorsEnabled()*/) {
return TYPE_NONE;
} else {
return mEdgeEffectType;
}
}
bool EdgeEffect::isFinished()const{
return mState == STATE_IDLE;
}
void EdgeEffect::finish(){
mState = STATE_IDLE;
mDistance = 0;
mVelocity = 0;
}
void EdgeEffect::onPull(float deltaDistance){
@ -55,13 +69,21 @@ void EdgeEffect::onPull(float deltaDistance){
}
void EdgeEffect::onPull(float deltaDistance, float displacement){
int edgeEffectBehavior = getCurrentEdgeEffectBehavior();
if (edgeEffectBehavior == TYPE_NONE) {
finish();
return;
}
long now = SystemClock::uptimeMillis();
mTargetDisplacement = displacement;
if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration) {
if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration && edgeEffectBehavior == TYPE_GLOW) {
return;
}
if (mState != STATE_PULL) {
mGlowScaleY = std::max(PULL_GLOW_BEGIN, mGlowScaleY);
if (edgeEffectBehavior == TYPE_STRETCH)
mPullDistance = mDistance;
else
mGlowScaleY = std::max(PULL_GLOW_BEGIN, mGlowScaleY);
}
mState = STATE_PULL;
@ -69,14 +91,21 @@ void EdgeEffect::onPull(float deltaDistance, float displacement){
mDuration = PULL_TIME;
mPullDistance += deltaDistance;
float absdd = std::abs(deltaDistance);
mGlowAlpha = mGlowAlphaStart = std::min(MAX_ALPHA,
mGlowAlpha + (absdd * PULL_DISTANCE_ALPHA_GLOW_FACTOR));
if (edgeEffectBehavior == TYPE_STRETCH) {
// Don't allow stretch beyond 1
mPullDistance = std::min(1.f, mPullDistance);
}
mDistance = std::max(.0f, mPullDistance);
mVelocity = 0;
if (mPullDistance == 0) {
mGlowScaleY = mGlowScaleYStart = 0;
mGlowAlpha = mGlowAlphaStart = 0;
} else {
float absdd = std::abs(deltaDistance);
mGlowAlpha = mGlowAlphaStart = std::min(MAX_ALPHA,
mGlowAlpha + (absdd * PULL_DISTANCE_ALPHA_GLOW_FACTOR));
float scale = (float) (std::max(0.f, 1.f - 1.f /
(float)std::sqrt(std::abs(mPullDistance) * mBounds.height) - 0.3f) / 0.7f);
@ -85,6 +114,32 @@ void EdgeEffect::onPull(float deltaDistance, float displacement){
mGlowAlphaFinish = mGlowAlpha;
mGlowScaleYFinish = mGlowScaleY;
if(edgeEffectBehavior ==TYPE_STRETCH && mDistance ==0)
mState = STATE_IDLE;
}
float EdgeEffect::onPullDistance(float deltaDistance, float displacement) {
int edgeEffectBehavior = getCurrentEdgeEffectBehavior();
if (edgeEffectBehavior == TYPE_NONE) {
return .0f;
}
float finalDistance = std::max(.0f, deltaDistance + mDistance);
float delta = finalDistance - mDistance;
if (delta == .0f && mDistance == .0f) {
return .0f; // No pull, don't do anything.
}
if (mState != STATE_PULL && mState != STATE_PULL_DECAY && edgeEffectBehavior == TYPE_GLOW) {
// Catch the edge glow in the middle of an animation.
mPullDistance = mDistance;
mState = STATE_PULL;
}
onPull(delta, displacement);
return delta;
}
float EdgeEffect::getDistance()const{
return mDistance;
}
void EdgeEffect::onRelease(){
@ -100,33 +155,43 @@ void EdgeEffect::onRelease(){
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
mVelocity = 0.f;
mStartTime = SystemClock::uptimeMillis();
mDuration = RECEDE_TIME;
}
void EdgeEffect::onAbsorb(int velocity){
mState = STATE_ABSORB;
velocity = std::min(std::max(MIN_VELOCITY, std::abs(velocity)), MAX_VELOCITY);
int edgeEffectBehavior = getCurrentEdgeEffectBehavior();
if (edgeEffectBehavior == TYPE_STRETCH) {
mState = STATE_RECEDE;
mVelocity = velocity * ON_ABSORB_VELOCITY_ADJUSTMENT;
mStartTime = AnimationUtils::currentAnimationTimeMillis();
} else if (edgeEffectBehavior == TYPE_GLOW){
mState = STATE_ABSORB;
mVelocity= 0;
velocity = std::min(std::max(MIN_VELOCITY, std::abs(velocity)), MAX_VELOCITY);
mStartTime = SystemClock::uptimeMillis();
mDuration = 0.15f + (velocity * 0.02f);
mStartTime = SystemClock::uptimeMillis();
mDuration = 0.15f + (velocity * 0.02f);
// The glow depends more on the velocity, and therefore starts out
// nearly invisible.
mGlowAlphaStart = GLOW_ALPHA_START;
mGlowScaleYStart = std::max(mGlowScaleY, 0.f);
// The glow depends more on the velocity, and therefore starts out
// nearly invisible.
mGlowAlphaStart = GLOW_ALPHA_START;
mGlowScaleYStart = std::max(mGlowScaleY, 0.f);
// Growth for the size of the glow should be quadratic to properly
// respond
// to a user's scrolling speed. The faster the scrolling speed, the more
// intense the effect should be for both the size and the saturation.
mGlowScaleYFinish = std::min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2, 1.f);
// Alpha should change for the glow as well as size.
mGlowAlphaFinish = std::max(
// Growth for the size of the glow should be quadratic to properly
// respond to a user's scrolling speed. The faster the scrolling speed, the more
// intense the effect should be for both the size and the saturation.
mGlowScaleYFinish = std::min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2, 1.f);
// Alpha should change for the glow as well as size.
mGlowAlphaFinish = std::max(
mGlowAlphaStart, std::min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA));
mTargetDisplacement = 0.5f;
mTargetDisplacement = 0.5f;
}else {
finish();
}
}
void EdgeEffect::setColor(int color){
@ -138,24 +203,31 @@ int EdgeEffect::getColor()const{
}
bool EdgeEffect::draw(Canvas& canvas){
update();
float centerX = mBounds.centerX();
float centerY = mBounds.height - mRadius;
canvas.save();
const int edgeEffectBehavior = getCurrentEdgeEffectBehavior();
if (edgeEffectBehavior == TYPE_GLOW){
update();
float centerX = mBounds.centerX();
float centerY = mBounds.height - mRadius;
canvas.save();
float displacement = std::max(0.f, std::min(mDisplacement, 1.f)) - 0.5f;
float translateX = mBounds.width * displacement / 2;
float displacement = std::max(0.f, std::min(mDisplacement, 1.f)) - 0.5f;
float translateX = mBounds.width * displacement / 2;
canvas.rectangle(mBounds);
canvas.clip();
canvas.set_color(mColor);
canvas.curve_to(mBounds.left,mBounds.top,mBounds.width/2+translateX,mBounds.height*mGlowScaleY,mBounds.width,0);
canvas.fill();
canvas.restore();
canvas.rectangle(mBounds);
canvas.clip();
canvas.set_color(mColor);
canvas.curve_to(mBounds.left,mBounds.top,mBounds.width/2+translateX,mBounds.height*mGlowScaleY,mBounds.width,0);
canvas.fill();
canvas.restore();
}else if(edgeEffectBehavior == TYPE_STRETCH /*&& canvas instanceof RecordingCanvas*/){
}else{
mState = STATE_IDLE;
mDistance = 0;
mVelocity = 0;
}
bool oneLastFrame = false;
if (mState == STATE_RECEDE && mGlowScaleY == 0) {
if (mState == STATE_RECEDE && mDistance ==0 && mVelocity == 0) {
mState = STATE_IDLE;
oneLastFrame = true;
}
@ -174,6 +246,9 @@ void EdgeEffect::update() {
mGlowAlpha = mGlowAlphaStart + (mGlowAlphaFinish - mGlowAlphaStart) * interp;
mGlowScaleY = mGlowScaleYStart + (mGlowScaleYFinish - mGlowScaleYStart) * interp;
if (mState != STATE_PULL) {
mDistance = calculateDistanceFromGlowValues(mGlowScaleY, mGlowAlpha);
}
mDisplacement = (mDisplacement + mTargetDisplacement) / 2;
if (t >= 1.f - EPSILON) {
@ -212,4 +287,92 @@ void EdgeEffect::update() {
}
}
template <typename T> int signum(T val) {
return (T(0) < val) - (val < T(0));
}
void EdgeEffect::updateSpring() {
long time = AnimationUtils::currentAnimationTimeMillis();
float deltaT = (time - mStartTime) / 1000.f; // Convert from millis to seconds
if (deltaT < 0.001f) {
return; // Must have at least 1 ms difference
}
mStartTime = time;
if (abs(mVelocity) <= LINEAR_VELOCITY_TAKE_OVER
&& abs(mDistance * mHeight) < LINEAR_DISTANCE_TAKE_OVER
&& signum(mVelocity) == -signum(mDistance)
) {
// This is close. The spring will slowly reach the destination. Instead, we
// will interpolate linearly so that it arrives at its destination quicker.
mVelocity = signum(mVelocity) * LINEAR_VELOCITY_TAKE_OVER;
float targetDistance = mDistance + (mVelocity * deltaT / mHeight);
if (signum(targetDistance) != signum(mDistance)) {
// We have arrived
mDistance = 0;
mVelocity = 0;
} else {
mDistance = targetDistance;
}
return;
}
double mDampedFreq = NATURAL_FREQUENCY * sqrt(1 - DAMPING_RATIO * DAMPING_RATIO);
// We're always underdamped, so we can use only those equations:
double cosCoeff = mDistance * mHeight;
double sinCoeff = (1 / mDampedFreq) * (DAMPING_RATIO * NATURAL_FREQUENCY
* mDistance * mHeight + mVelocity);
double distance = pow(M_E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT)
* (cosCoeff * cos(mDampedFreq * deltaT)
+ sinCoeff * sin(mDampedFreq * deltaT));
double velocity = distance * (-NATURAL_FREQUENCY) * DAMPING_RATIO
+ pow(M_E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT)
* (-mDampedFreq * cosCoeff * sin(mDampedFreq * deltaT)
+ mDampedFreq * sinCoeff * cos(mDampedFreq * deltaT));
mDistance = (float) distance / mHeight;
mVelocity = (float) velocity;
if (mDistance > 1.f) {
mDistance = 1.f;
mVelocity = .0f;
}
if (isAtEquilibrium()) {
mDistance = 0;
mVelocity = 0;
}
}
float EdgeEffect::calculateDistanceFromGlowValues(float scale, float alpha) {
if (scale >= 1.f) {
// It should asymptotically approach 1, but not reach there.
// Here, we're just choosing a value that is large.
return 1.f;
}
if (scale > .0f) {
float v = 1.f / 0.7f / (mGlowScaleY - 1.f);
return v * v / mBounds.height;
}
return alpha / PULL_DISTANCE_ALPHA_GLOW_FACTOR;
}
bool EdgeEffect::isAtEquilibrium()const{
double displacement = mDistance * mHeight; // in pixels
double velocity = mVelocity;
// Don't allow displacement to drop below 0. We don't want it stretching the opposite
// direction if it is flung that way. We also want to stop the animation as soon as
// it gets very close to its destination.
return displacement < 0 || (abs(velocity) < VELOCITY_THRESHOLD
&& displacement < VALUE_THRESHOLD);
}
float EdgeEffect::dampStretchVector(float normalizedVec)const{
float sign = normalizedVec > .0f ? 1.f : -1.f;
float overscroll = abs(normalizedVec);
float linearIntensity = LINEAR_STRETCH_INTENSITY * overscroll;
double scalar = M_E / SCROLL_DIST_AFFECTED_BY_EXP_STRETCH;
double expIntensity = EXP_STRETCH_INTENSITY * (1.f - exp(-overscroll * scalar));
return sign * (float) (linearIntensity + expIntensity);
}
}//namespace

View File

@ -8,6 +8,63 @@ namespace cdroid{
class EdgeEffect{
private:
/*Completely disable edge effect*/
static constexpr int TYPE_NONE = -1;
/*Use a color edge glow for the edge effect.*/
static constexpr int TYPE_GLOW = 0;
/*Use a stretch for the edge effect. */
static constexpr int TYPE_STRETCH = 1;
/**
* The velocity threshold before the spring animation is considered settled.
* The idea here is that velocity should be less than 0.1 pixel per second.
*/
static constexpr double VELOCITY_THRESHOLD = 0.01;
/**
* The speed at which we should start linearly interpolating to the destination.
* When using a spring, as it gets closer to the destination, the speed drops off exponentially.
* Instead of landing very slowly, a better experience is achieved if the constexpr
* destination is arrived at quicker.
*/
static constexpr float LINEAR_VELOCITY_TAKE_OVER = 200.f;
/**
* The value threshold before the spring animation is considered close enough to
* the destination to be settled. This should be around 0.01 pixel.
*/
static constexpr double VALUE_THRESHOLD = 0.001;
/**
* The maximum distance at which we should start linearly interpolating to the destination.
* When using a spring, as it gets closer to the destination, the speed drops off exponentially.
* Instead of landing very slowly, a better experience is achieved if the constexpr
* destination is arrived at quicker.
*/
static constexpr double LINEAR_DISTANCE_TAKE_OVER = 8.0;
/**
* The natural frequency of the stretch spring.
*/
static constexpr double NATURAL_FREQUENCY = 24.657;
/**
* The damping ratio of the stretch spring.
*/
static constexpr double DAMPING_RATIO = 0.98;
/**
* The variation of the velocity for the stretch effect when it meets the bound.
* if value is > 1, it will accentuate the absorption of the movement.
*/
static constexpr float ON_ABSORB_VELOCITY_ADJUSTMENT = 13.f;
static constexpr float LINEAR_STRETCH_INTENSITY = 0.016f;
static constexpr float EXP_STRETCH_INTENSITY = 0.016f;
static constexpr float SCROLL_DIST_AFFECTED_BY_EXP_STRETCH = 0.33f;
// Time it will take the effect to fully recede in ms
static constexpr int RECEDE_TIME = 600;
// Time it will take before a pulled glow begins receding in ms
@ -34,6 +91,8 @@ private:
static constexpr float RADIUS_FACTOR = 0.6f;
float mGlowAlpha;
float mGlowScaleY;
float mDistance;
float mVelocity; // only for stretch animations
float mGlowAlphaStart;
float mGlowAlphaFinish;
@ -59,13 +118,21 @@ private:
float mPullDistance;
Rect mBounds;
float mWidth;
float mHeight;
int mColor;
float mRadius;
float mBaseGlowScale;
float mDisplacement = 0.5f;
float mTargetDisplacement = 0.5f;
int mEdgeEffectType = TYPE_GLOW;
private:
void update();
void updateSpring();
int getCurrentEdgeEffectBehavior();
float calculateDistanceFromGlowValues(float scale, float alpha);
bool isAtEquilibrium()const;
float dampStretchVector(float normalizedVec)const;
public:
EdgeEffect(Context* context);
~EdgeEffect();
@ -74,6 +141,8 @@ public:
void finish();
void onPull(float deltaDistance);
void onPull(float deltaDistance, float displacement);
float onPullDistance(float deltaDistance, float displacement);
float getDistance()const;
void onRelease();
void onAbsorb(int velocity);
void setColor(int color);

View File

@ -24,11 +24,14 @@ static constexpr int RULES_HORIZONTAL[] = {
DECLARE_WIDGET(RelativeLayout)
RelativeLayout::RelativeLayout(int w,int h):ViewGroup(w,h){
mIgnoreGravity=NO_ID;
mIgnoreGravity = NO_ID;
mDirtyHierarchy = true;
}
RelativeLayout::RelativeLayout(Context* context,const AttributeSet& attrs)
:ViewGroup(context,attrs){
mIgnoreGravity = NO_ID;
mDirtyHierarchy = true;
}
bool RelativeLayout::shouldDelayChildPressedState(){
@ -740,7 +743,7 @@ bool RelativeLayout::checkLayoutParams(const ViewGroup::LayoutParams* p)const{
ViewGroup::LayoutParams* RelativeLayout::generateLayoutParams(const ViewGroup::LayoutParams* lp)const{
if (true){//sPreserveMarginParamsInLayoutParamConversion) {
if (dynamic_cast<const LayoutParams*>(lp)) {
return new LayoutParams((const LayoutParams)*lp);
return new LayoutParams((const LayoutParams&)*lp);
} else if (dynamic_cast<const MarginLayoutParams*>(lp)) {
return new LayoutParams((const MarginLayoutParams&)*lp);
}
@ -752,23 +755,35 @@ ViewGroup::LayoutParams* RelativeLayout::generateLayoutParams(const ViewGroup::L
/////////////////////////////////////////////////////////////////////////////////
RelativeLayout::LayoutParams::LayoutParams(int w, int h)
:MarginLayoutParams(w,h){
alignWithParent=false;
mRulesChanged=false;
mIsRtlCompatibilityMode=false;
alignWithParent= false;
mRulesChanged = false;
mIsRtlCompatibilityMode= false;
memset(mRules,0,sizeof(mRules));
memset(mInitialRules,0,sizeof(mInitialRules));
mLeft = mTop = mRight = mBottom = VALUE_NOT_SET;
mNeedsLayoutResolution = false;
}
RelativeLayout::LayoutParams::LayoutParams(const ViewGroup::LayoutParams& source)
:MarginLayoutParams(source){
mRulesChanged = false;
alignWithParent= false;
memset(mRules,0,sizeof(mRules));
memset(mInitialRules,0,sizeof(mInitialRules));
mLeft = mTop = mRight = mBottom = 0;//VALUE_NOT_SET;
mIsRtlCompatibilityMode= false;
mNeedsLayoutResolution = false;
}
RelativeLayout::LayoutParams::LayoutParams(const ViewGroup::MarginLayoutParams& source)
:MarginLayoutParams(source){
mRulesChanged = false;
alignWithParent= false;
mIsRtlCompatibilityMode=false;
memset(mRules,0,sizeof(mRules));
memset(mInitialRules,0,sizeof(mInitialRules));
mLeft = mTop = mRight = mBottom = VALUE_NOT_SET;
mNeedsLayoutResolution = false;
}
RelativeLayout::LayoutParams::LayoutParams(const RelativeLayout::LayoutParams& source)
@ -778,12 +793,17 @@ RelativeLayout::LayoutParams::LayoutParams(const RelativeLayout::LayoutParams& s
alignWithParent= source.alignWithParent;
memcpy(mRules,source.mRules,sizeof(mRules));
memcpy(mInitialRules,source.mInitialRules,sizeof(mInitialRules));
mLeft = source.mLeft;
mTop = source.mTop;
mRight = source.mRight;
mBottom = source.mBottom;;
mNeedsLayoutResolution = false;
}
RelativeLayout::LayoutParams::LayoutParams(Context*ctx,const AttributeSet&atts):MarginLayoutParams(ctx,atts){
#define GETID(res) ctx->getId(atts.getString(res))
alignWithParent = atts.getBoolean("alignWithParentIfMissing",false);
mLeft = mTop = mRight = mBottom = VALUE_NOT_SET;
mRules[LEFT_OF] = GETID("layout_toLeftOf");
mRules[RIGHT_OF]= GETID("layout_toRightOf");
mRules[ABOVE] = GETID("layout_above");

86
src/gui/widget/toast.cc Executable file
View File

@ -0,0 +1,86 @@
#include <widget/toast.h>
#include <widget/textview.h>
#include <widget/R.h>
namespace cdroid{
Toast::Toast(Context*context){
mContext = context;
mX = mY = 0;
mGravity = Gravity::NO_GRAVITY;
mWindow = nullptr;
}
void Toast::show(){
}
void Toast::cancel(){
}
void Toast::setView(View*view){
mNextView = view;
}
View*Toast::getView()const{
return mNextView;
}
void Toast::setDuration(int duration){
mDuration = duration;
}
int Toast::getDuration()const{
return mDuration;
}
void Toast::setMargin(int horizontalMargin,int verticalMargin){
}
int Toast::getHorizontalMargin()const{
return mHorizontalMargin;
}
int Toast::getVerticalMargin()const{
return mVerticalMargin;
}
void Toast::setGravity(int gravity,int xoffset,int yoffset){
mGravity =gravity;
mX = xoffset;
mY = yoffset;
}
int Toast::getGravity()const{
return mGravity;
}
int Toast::getXOffset()const{
return mX;
}
int Toast::getYOffset()const{
return mY;
}
Toast*Toast::makeText(Context*context,const std::string&text,int duration){
Toast*result = new Toast(context);
LayoutInflater*inflater=LayoutInflater::from(context);
View*v = inflater->inflate("cdroid:layout/transient_notification",nullptr);
TextView*tv= (TextView*)v->findViewById(cdroid::R::id::message);
tv->setText(text);
result->mNextView=v;
result->mDuration =duration;
return result;
}
void Toast::setText(const std::string&text){
TextView*tv=nullptr;
if(mNextView)
tv=(TextView*)mNextView->findViewById(cdroid::R::id::message);
if(tv==nullptr)
throw("This Toast was not created by Toast::makeText");
tv->setText(text);
}
}

44
src/gui/widget/toast.h Executable file
View File

@ -0,0 +1,44 @@
#ifndef __TOAST_H__
#define __TOAST_H__
#include <widget/view.h>
#include <widget/cdwindow.h>
namespace cdroid{
class Toast{
private:
int mGravity;
int mX,mY;
int mHorizontalMargin;
int mVerticalMargin;
Window*mWindow;
protected:
Context*mContext;
int mDuration;
View*mNextView;
public:
enum{
LENGTH_SHORT,
LENGTH_LONG
};
public:
Toast(Context*context);
void show();
void cancel();
void setView(View*);
View*getView()const;
void setDuration(int duration);
int getDuration()const;
void setMargin(int horizontalMargin,int verticalMargin);
int getHorizontalMargin()const;
int getVerticalMargin()const;
void setGravity(int gravity,int xoffset,int yoffset);
int getGravity()const;
int getXOffset()const;
int getYOffset()const;
static Toast*makeText(Context*,const std::string&text,int duration);
void setText(const std::string&);
};
}//endof namespace
#endif

View File

@ -1048,12 +1048,12 @@ void View::setOverScrollMode(int overScrollMode){
bool View::overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
int scrollRangeY, int maxOverScrollX, int maxOverScrollY, bool isTouchEvent){
int overScrollMode = mOverScrollMode;
bool canScrollHorizontal= computeHorizontalScrollRange() > computeHorizontalScrollExtent();
bool canScrollVertical = computeVerticalScrollRange() > computeVerticalScrollExtent();
bool overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
const int overScrollMode = mOverScrollMode;
const bool canScrollHorizontal= computeHorizontalScrollRange() > computeHorizontalScrollExtent();
const bool canScrollVertical = computeVerticalScrollRange() > computeVerticalScrollExtent();
const bool overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
(overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);
bool overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
const bool overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
(overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);
int newScrollX = scrollX + deltaX;
@ -1063,10 +1063,10 @@ bool View::overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int sc
if (!overScrollVertical) maxOverScrollY = 0;
// Clamp values if at the limits and record
int left = -maxOverScrollX;
int right = maxOverScrollX + scrollRangeX;
int top = -maxOverScrollY;
int bottom = maxOverScrollY + scrollRangeY;
const int left = -maxOverScrollX;
const int right = maxOverScrollX + scrollRangeX;
const int top = -maxOverScrollY;
const int bottom = maxOverScrollY + scrollRangeY;
bool clampedX = false;
if (newScrollX > right) {

View File

@ -495,7 +495,7 @@ bool ViewGroup::addViewInLayout(View* child, int index,LayoutParams* params){
bool ViewGroup::addViewInLayout(View* child, int index,LayoutParams* params,bool preventRequestLayout){
if (child == nullptr) {
LOGE("Cannot add a null child view to a ViewGroup");
return false;
return false;
}
child->mParent = nullptr;
addViewInner(child, index, params, preventRequestLayout);