refact view and groupview
This commit is contained in:
parent
3d4605c497
commit
dab3c00b4c
@ -25,9 +25,9 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import pub.doric.dev.DevPanel;
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
import pub.doric.DoricDriver;
|
import pub.doric.DoricDriver;
|
||||||
import pub.doric.dev.DevPanel;
|
|
||||||
import pub.doric.dev.LocalServer;
|
import pub.doric.dev.LocalServer;
|
||||||
import pub.doric.dev.event.EnterDebugEvent;
|
import pub.doric.dev.event.EnterDebugEvent;
|
||||||
import pub.doric.dev.event.QuitDebugEvent;
|
import pub.doric.dev.event.QuitDebugEvent;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
export * from "./src/ui/view"
|
export * from "./src/ui/view"
|
||||||
export * from "./src/ui/layout"
|
export * from "./src/ui/layout"
|
||||||
export * from "./src/ui/listview"
|
export * from "./src/ui/listview"
|
||||||
|
export * from "./src/ui/widgets"
|
||||||
export * from "./src/ui/panel"
|
export * from "./src/ui/panel"
|
||||||
export * from "./src/ui/declarative"
|
export * from "./src/ui/declarative"
|
||||||
export * from "./src/util/color"
|
export * from "./src/util/color"
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { Text, Image, LayoutConfig, View, IText, IImage } from './view'
|
import { View, } from './view'
|
||||||
import { Stack, HLayout, VLayout } from './layout'
|
import { Stack, HLayout, VLayout } from './layout'
|
||||||
|
import { IText, IImage, Text, Image } from './widgets'
|
||||||
|
|
||||||
export function text(config: IText) {
|
export function text(config: IText) {
|
||||||
const ret = new Text
|
const ret = new Text
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { View, Property, SuperView, Group, LayoutSpec } from "./view";
|
import { View, Property, LayoutSpec, Superview } from "./view";
|
||||||
import { Model } from "../util/types";
|
import { Model } from "../util/types";
|
||||||
import { O_TRUNC } from "constants";
|
import { O_TRUNC } from "constants";
|
||||||
import { Stack } from "./layout";
|
import { Stack } from "./layout";
|
||||||
@ -35,12 +35,9 @@ export class ListItem extends Stack {
|
|||||||
@Property
|
@Property
|
||||||
identifier?: string
|
identifier?: string
|
||||||
list!: List
|
list!: List
|
||||||
onChildPropertyChanged(child: View) {
|
|
||||||
super.onChildPropertyChanged(child)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class List extends View implements SuperView {
|
export class List extends Superview {
|
||||||
private cachedViews: Map<string, ListItem> = new Map
|
private cachedViews: Map<string, ListItem> = new Map
|
||||||
|
|
||||||
subviewById(id: string): ListItem | undefined {
|
subviewById(id: string): ListItem | undefined {
|
||||||
|
@ -110,7 +110,7 @@ export abstract class View implements Modeling, IView {
|
|||||||
@Property
|
@Property
|
||||||
onClick?: Function
|
onClick?: Function
|
||||||
|
|
||||||
parent?: Group
|
superview?: Superview
|
||||||
|
|
||||||
callbacks: Map<String, Function> = new Map
|
callbacks: Map<String, Function> = new Map
|
||||||
|
|
||||||
@ -188,7 +188,11 @@ export abstract class View implements Modeling, IView {
|
|||||||
}
|
}
|
||||||
/** Anchor end*/
|
/** Anchor end*/
|
||||||
|
|
||||||
__dirty_props__: { [index: string]: Model | undefined } = {}
|
private __dirty_props__: { [index: string]: Model | undefined } = {}
|
||||||
|
|
||||||
|
get dirtyProps() {
|
||||||
|
return this.__dirty_props__
|
||||||
|
}
|
||||||
|
|
||||||
nativeViewModel = {
|
nativeViewModel = {
|
||||||
id: this.viewId,
|
id: this.viewId,
|
||||||
@ -203,9 +207,6 @@ export abstract class View implements Modeling, IView {
|
|||||||
newV = obj2Model(newV)
|
newV = obj2Model(newV)
|
||||||
}
|
}
|
||||||
this.__dirty_props__[propKey] = newV
|
this.__dirty_props__[propKey] = newV
|
||||||
if (this.parent instanceof Group) {
|
|
||||||
this.parent.onChildPropertyChanged(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clean() {
|
clean() {
|
||||||
@ -236,48 +237,33 @@ export abstract class View implements Modeling, IView {
|
|||||||
toModel() {
|
toModel() {
|
||||||
return this.nativeViewModel
|
return this.nativeViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
let(block: (it: this) => void) {
|
let(block: (it: this) => void) {
|
||||||
block(this)
|
block(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
also(block: (it: this) => void) {
|
also(block: (it: this) => void) {
|
||||||
block(this)
|
block(this)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
in(group: Group) {
|
in(group: Group) {
|
||||||
group.addChild(this)
|
group.addChild(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StackConfig extends LayoutConfig {
|
export abstract class Superview extends View {
|
||||||
|
abstract subviewById(id: string): View | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LinearConfig extends LayoutConfig {
|
export abstract class Group extends Superview {
|
||||||
weight?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SuperView {
|
|
||||||
subviewById(id: string): View | undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class Group extends View implements SuperView {
|
|
||||||
@Property
|
|
||||||
readonly children: View[] = new Proxy([], {
|
readonly children: View[] = new Proxy([], {
|
||||||
set: (target, index, value) => {
|
set: (target, index, value) => {
|
||||||
if (index === 'length') {
|
const ret = Reflect.set(target, index, value)
|
||||||
this.getDirtyChildrenModel().length = value as number
|
// Let getDirty return true
|
||||||
} else if (typeof index === 'string'
|
this.dirtyProps.children = []
|
||||||
&& parseInt(index) >= 0
|
return ret
|
||||||
&& value instanceof View) {
|
|
||||||
value.parent = this
|
|
||||||
const childrenModel = this.getDirtyChildrenModel()
|
|
||||||
childrenModel[parseInt(index)] = value.nativeViewModel
|
|
||||||
}
|
|
||||||
if (this.parent) {
|
|
||||||
this.parent.onChildPropertyChanged(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Reflect.set(target, index, value)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -289,195 +275,21 @@ export abstract class Group extends View implements SuperView {
|
|||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
addChild(view: View) {
|
addChild(view: View) {
|
||||||
this.children.push(view)
|
this.children.push(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
clean() {
|
|
||||||
this.children.forEach(e => { e.clean() })
|
|
||||||
super.clean()
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirtyChildrenModel(): Model[] {
|
|
||||||
if (this.__dirty_props__.children === undefined) {
|
|
||||||
this.__dirty_props__.children = []
|
|
||||||
}
|
|
||||||
return this.__dirty_props__.children as Model[]
|
|
||||||
}
|
|
||||||
|
|
||||||
toModel() {
|
toModel() {
|
||||||
if (this.__dirty_props__.children != undefined) {
|
this.dirtyProps.children = this.children.map(e => {
|
||||||
(this.__dirty_props__.children as Model[]).length = this.children.length
|
if (e.isDirty()) {
|
||||||
|
return e.toModel()
|
||||||
|
} else {
|
||||||
|
//Dont need return model
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
return super.toModel()
|
return super.toModel()
|
||||||
}
|
}
|
||||||
|
|
||||||
onChildPropertyChanged(child: View) {
|
|
||||||
this.getDirtyChildrenModel()[this.children.indexOf(child)] = child.nativeViewModel
|
|
||||||
this.getDirtyChildrenModel().length = this.children.length
|
|
||||||
if (this.parent) {
|
|
||||||
this.parent.onChildPropertyChanged(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isDirty() {
|
|
||||||
return super.isDirty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export interface IStack extends IView {
|
|
||||||
gravity?: Gravity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Stack extends Group implements IStack {
|
|
||||||
@Property
|
|
||||||
gravity?: Gravity
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Scroller extends View implements SuperView {
|
|
||||||
@Property
|
|
||||||
contentView?: View
|
|
||||||
|
|
||||||
subviewById(id: string): View | undefined {
|
|
||||||
return this.contentView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Root extends Stack {
|
|
||||||
|
|
||||||
}
|
|
||||||
class LinearLayout extends Group {
|
|
||||||
@Property
|
|
||||||
space?: number
|
|
||||||
|
|
||||||
@Property
|
|
||||||
gravity?: Gravity
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IVLayout extends IView {
|
|
||||||
space?: number
|
|
||||||
gravity?: Gravity
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VLayout extends LinearLayout implements VLayout {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface IHLayout extends IView {
|
|
||||||
space?: number
|
|
||||||
gravity?: Gravity
|
|
||||||
}
|
|
||||||
|
|
||||||
export class HLayout extends LinearLayout implements IHLayout {
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IText extends IView {
|
|
||||||
text?: string
|
|
||||||
textColor?: Color
|
|
||||||
textSize?: number
|
|
||||||
maxLines?: number
|
|
||||||
textAlignment?: Gravity
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Text extends View implements IText {
|
|
||||||
@Property
|
|
||||||
text?: string
|
|
||||||
|
|
||||||
@Property
|
|
||||||
textColor?: Color
|
|
||||||
|
|
||||||
@Property
|
|
||||||
textSize?: number
|
|
||||||
|
|
||||||
@Property
|
|
||||||
maxLines?: number
|
|
||||||
|
|
||||||
@Property
|
|
||||||
textAlignment?: Gravity
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IImage extends IView {
|
|
||||||
imageUrl?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Image extends View implements IImage {
|
|
||||||
@Property
|
|
||||||
imageUrl?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class SectionList extends View implements SuperView {
|
|
||||||
private cachedViews: Map<string, View> = new Map
|
|
||||||
|
|
||||||
subviewById(id: string): View | undefined {
|
|
||||||
return this.cachedViews.get(id)
|
|
||||||
}
|
|
||||||
@Property
|
|
||||||
sectionRowsCount: number[] = []
|
|
||||||
|
|
||||||
@Property
|
|
||||||
renderSectionHeader!: (sectionIdx: number) => View
|
|
||||||
|
|
||||||
@Property
|
|
||||||
renderItem!: (sectionIdx: number, itemIdx: number) => View
|
|
||||||
|
|
||||||
@Property
|
|
||||||
sectionHeaderSticky = true
|
|
||||||
|
|
||||||
setupSectionRows(sectionCount: number, numberOfSection: (section: number) => number) {
|
|
||||||
this.sectionRowsCount = [...Array(sectionCount).keys()].map(e => numberOfSection(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
private getItem(sectionIdx: number, itemIdx: number) {
|
|
||||||
let view = this.cachedViews.get(`${sectionIdx}:${itemIdx}`)
|
|
||||||
if (view === undefined) {
|
|
||||||
view = this.renderItem(sectionIdx, itemIdx)
|
|
||||||
this.cachedViews.set(`${sectionIdx}:${itemIdx}`, view)
|
|
||||||
}
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
private getSectionHeader(sectionIdx: number) {
|
|
||||||
let view = this.cachedViews.get(`${sectionIdx}:`)
|
|
||||||
if (view === undefined) {
|
|
||||||
view = this.renderSectionHeader(sectionIdx)
|
|
||||||
this.cachedViews.set(`${sectionIdx}:`, view)
|
|
||||||
}
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
@Property
|
|
||||||
private renderBunchedItems(items: Array<{ itemIdx: number, sectionIdx: number }>,
|
|
||||||
headers: number[]): { items: View[], headers: View[] } {
|
|
||||||
return {
|
|
||||||
items: items.map(e => this.getItem(e.sectionIdx, e.itemIdx)),
|
|
||||||
headers: headers.map(e => this.getSectionHeader(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Slide extends View implements SuperView {
|
|
||||||
@Property
|
|
||||||
pageCount = 0
|
|
||||||
|
|
||||||
@Property
|
|
||||||
renderPage!: (pageIdx: number) => View
|
|
||||||
|
|
||||||
private cachedViews: Map<string, View> = new Map
|
|
||||||
|
|
||||||
subviewById(id: string): View | undefined {
|
|
||||||
return this.cachedViews.get(id)
|
|
||||||
}
|
|
||||||
private getPage(pageIdx: number) {
|
|
||||||
let view = this.cachedViews.get(`${pageIdx}`)
|
|
||||||
if (view === undefined) {
|
|
||||||
view = this.renderPage(pageIdx)
|
|
||||||
this.cachedViews.set(`${pageIdx}`, view)
|
|
||||||
}
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
@Property
|
|
||||||
private renderBunchedPages(pages: number[]): View[] {
|
|
||||||
return pages.map(e => this.getPage(e))
|
|
||||||
}
|
|
||||||
}
|
|
52
js-framework/src/ui/widgets.ts
Normal file
52
js-framework/src/ui/widgets.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
import { IView, View, Property } from "./view"
|
||||||
|
import { Color } from "../util/color"
|
||||||
|
import { Gravity } from "../util/gravity"
|
||||||
|
|
||||||
|
export interface IText extends IView {
|
||||||
|
text?: string
|
||||||
|
textColor?: Color
|
||||||
|
textSize?: number
|
||||||
|
maxLines?: number
|
||||||
|
textAlignment?: Gravity
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Text extends View implements IText {
|
||||||
|
@Property
|
||||||
|
text?: string
|
||||||
|
|
||||||
|
@Property
|
||||||
|
textColor?: Color
|
||||||
|
|
||||||
|
@Property
|
||||||
|
textSize?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
maxLines?: number
|
||||||
|
|
||||||
|
@Property
|
||||||
|
textAlignment?: Gravity
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IImage extends IView {
|
||||||
|
imageUrl?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Image extends View implements IImage {
|
||||||
|
@Property
|
||||||
|
imageUrl?: string
|
||||||
|
}
|
Reference in New Issue
Block a user