MobileDevice
subclass: #WebDevice
category: #WebDevice !
WebDevice comment: '
Abstract Web specific device (pre CordovaDevice).
Subclasses must refine methods providing implementation.'!
! WebDevice class methodsFor: #defaults !
isInstalled
" Private - Return true if the receiver implements installed support. "
"^DOM navigator userAgent match: self installationSupport"
^false! !
! WebDevice class methodsFor: #contants !
installationSupport
" Private - Return true if the receiver implements installed support. "
^#Mozilla! !
! WebDevice class methodsFor: #defaults !
mainViewSupport
" Private - Return the support for mainView of the receiver(or nil). "
^TopPane! !
! WebDevice methodsFor: #ui !
fullScreen
" Private - Return true if the receiver display app in fullScreen mode. "
(self isMemberOf: WebDevice) ifTrue: [ ^false ].
^super fullScreen! !
! WebDevice methodsFor: #accessing !
id
" Private - Return the device ID of the receiver. "
^#WEB-DEBUG! !
! WebDevice methodsFor: #defaults !
navigationBarTop
" Private - Return the top offset for navigation bar. "
^0! !
! WebDevice methodsFor: #defaults !
navigationBarHeight
" Private - Return the height for navigation bar. "
^44! !
! WebDevice methodsFor: #defaults !
navigationBarBottom
" Private - Return the bottom offset for navigation bar. "
^self navigationBarTop + self navigationBarHeight! !
! WebDevice methodsFor: #defaults !
actionsBarHeight
" Private - Return the height for actions bar. "
^49! !
! WebDevice methodsFor: #defaults !
maxGroupHeight
" Private - Return the maximum height for groups. "
^200! !
! WebDevice methodsFor: #defaults !
screenBackground
" Private - Return the background color for screen. "
^'#F5F5F0'! !
! WebDevice methodsFor: #connection !
connectionType
" Return the type of connection active. "
^self basicAt: '$connectionType' ifAbsentPut: [
(Smalltalk includesKey: #XMLHttpRequest)
ifTrue: [#web] ifFalse: [#none]
]! !
! WebDevice methodsFor: #gui !
navigationBarFor: anApplication
" Private - Return the/a navigationBar installed on the receiver. "
^MobileNavigationBar new
application: anApplication;
when: #makeup: do: [:widget| self makeupNavigationBar: widget ];
yourself! !
! WebDevice methodsFor: #tasks !
activate: aCoordinator for: aMobileApp doing: aBlock
" Activate the coordinator as current task. "
aCoordinator aboutToActivateIn: aMobileApp.
self
basicActivate: aCoordinator for: aMobileApp
doing: [
aBlock value.
aCoordinator activatedIn: aMobileApp.
]! !
! WebDevice methodsFor: #tasks !
basicActivate: aCoordinator for: aMobileApp doing: aBlock
" Private - Activate the coordinator as active task. "
^aBlock value! !
! WebDevice methodsFor: #widgets !
text: text with: tags
" Private - Return a widget for text styled with tags. "
^HTMLWidget text: (tags inject: text into: [:total :tag|
'<',tag,'>',total,'',(tag upTo: $ ),'>'
])! !
! WebDevice methodsFor: #gui !
actionsBarFor: anApplication
" Private - Return the/an actionsBar installed on the receiver. "
^MobileActionsBar new
application: anApplication;
when: #makeup: do: [:widget| self makeupActionsBar: widget ];
yourself! !
! WebDevice methodsFor: #gui !
button: title for: imageProvider doing: aBlock
" Private - Return a button with title evaluating anAction when clicked. "
| result tool |
tool := imageProvider imageNamed: title.
tool notNil ifTrue: [
^"ImageWidget"ImageButtonMobile newDefault
src: tool;
when: #click: do: aBlock;
yourself
].
result := self text: title with: #('font size=+2' b).
result style
color: #white;
border: 'ridge 2px gray'; borderRadius: 8;
yourself.
^result
align: #center;
when: #click: do: aBlock;
yourself! !
! WebDevice methodsFor: #gui !
makeupGroupList: aList
" Private - Makeup the list of a group. "
aList
noMargins;
"overflow: #auto;
maxHeight: self maxGroupHeight asString ,self units;
"yourself! !
! WebDevice methodsFor: #list !
configure: cell title: aTitle description: aDescription detail: aDetail
" Private - Default configuration for cells in groups. "
| box line1 line2 |
line1 := '' ,aTitle ,''.
line2 := aDescription notNil ifTrue: [ '
', aDescription ] ifFalse: [
line1 :=
"'
' ," '',line1,''. '' ]. box := self text: line1 ,line2. cell addChild: box. aDetail notNil ifTrue: [ box := HTMLWidget inline. box style position: #absolute; color: #blue; right: #15pt; yourself. aDetail isString ifTrue: [ box innerHTML: aDetail ] ifFalse: [ box addChild: aDetail ]. cell addChild: box ]. ^cell ! ! ! WebDevice methodsFor: #gui ! rows: rows titled: aTitle lines: lines " Return a widget to list rows in a box. " | box index | box := HTMLWidget new. box style border: '1px solid darkgray'; borderRadius: 8; yourself. index := 0. rows do: [:each| index := index + 1. each isArray ifTrue: [ box ,(HTMLWidget with: ((HTMLWidget with: each first) align: #left; inline; yourself) with: ((HTMLWidget with: each last) align: #right; inline; yourself)). ] ifFalse: [ box ,each ]. ((lines isArray and: [ lines includes: index ]) or: [ lines = true ]) ifTrue: [ box hr ]. ]. ^HTMLWidget with: (aTitle isString ifTrue: [ (CustomWidget tag: #h1) innerHTML: aTitle; yourself ] ifFalse: [ aTitle ]) with: box! ! ! WebDevice methodsFor: #gui ! screenFor: aMobileApp " Private - Return a main screen to contain the UI elements for aMobileApp. " ^MobileScreen for: aMobileApp! ! ! WebDevice methodsFor: #gui ! screenContents " Private - Return the main screen container installed on the receiver. " | result | result := HTMLWidget new when: #makeup: do: [:widget| self makeupScreenContents: widget ]; yourself. self initializeScreenContents: result. ^result! ! ! WebDevice methodsFor: #gui ! initializeScreenContents: aWidget " Private - Initialize contents of screen aWidget. " aWidget style padding: #5 ,self units; overflow: #auto; yourself! ! ! WebDevice methodsFor: #private ! makeupScreenContents: widget " Private - Set the look&feel of the widget. " widget style position: #absolute; left: 0; right: 0; top: self navigationBarBottom asString ,self units; bottom: self actionsBarHeight asString ,self units; color: #black; background: self screenBackground; yourself.! ! ! WebDevice methodsFor: #private ! makeupNavigationBar: widget " Private - Set the look&feel of the widget. " widget style position: #absolute; left: 0; right: 0; top: self navigationBarTop asString ,self units; height: self navigationBarHeight asString ,self units; background: '#0D4E8F'; background: 'linear-gradient(#6890BA,#0D4E8F)'; yourself! ! ! WebDevice methodsFor: #private ! makeupActionsBar: widget " Private - Set the look&feel of the widget. " widget style position: #absolute; left: 0; bottom: 0; right: 0; height: self actionsBarHeight asString ,self units; background: #black; background: 'linear-gradient(gray,black,black)'; yourself! ! ! WebDevice methodsFor: #private ! wrapperForAction: anImageWidget inBar: anActionBar " Private - Return a wrapper for action button (anImageWidget). " | result | result := HTMLWidget with: anImageWidget. self centerAction: anImageWidget in: result. ^result! ! ! WebDevice methodsFor: #private ! centerAction: anImageWidget in: aHTMLWidget " Private - Set anImageWidget to be centered in anHTMLWidget. " anImageWidget style marginLeft: #auto; marginRight: #auto; verticalAlign: #middle; height: (self actionsBarHeight - 4) asString ,self units; "border: '1px dotted red';" yourself.! ! ! WebDevice methodsFor: #private ! gradient: widget color: tones " Private - Install a gradient background in the widget. " | rgb | rgb := '', tones first,',', tones second,',', tones last,', '. widget style background: '-webkit-linear-gradient(left,', 'rgba(',rgb,'0.2),', 'rgba(',rgb,'0.3) 20%,', 'rgba(',rgb,'0.3) 80%,', 'rgba(',rgb,'0.2))'! ! ! WebDevice methodsFor: #gui ! addButton: actionAssoc in: pane onClose: forceClose for: imageProvider " Private - Arrange an action button on pane. " | button | actionAssoc isNil ifTrue: [ ^nil ]. (actionAssoc isKindOf: BlockClosure) ifTrue: [ ^actionAssoc evaluateWithArguments: (Array with: pane with: forceClose) ]. actionAssoc isAssociation ifTrue: [ button := self button: actionAssoc key for: imageProvider doing: [ actionAssoc value evaluate. forceClose value. ]. self centerButton: button background: #white color: #black. pane cr; addChild: button. ^self ]. actionAssoc do: [:each| "a set of buttons" self addButton: each in: pane onClose: forceClose for: imageProvider ]! ! ! WebDevice methodsFor: #gui ! centerButton: aButton background: background color: color " Private - Center the button. " aButton style position: #relative; margin: #auto; left: 0; right: 0; height: #40pt; display: #block; opacity: 1; yourself. (aButton isKindOf: ImageWidget) ifFalse: [ aButton style background: background; color: color ]! ! ! WebDevice methodsFor: #gui ! confirm: aMobileApp text: question action: actionAssoc cancel: cancelAction close: closeAction " Prompt the user for confirmation and evaluates anAction when confirmed. " | forceClose button | forceClose := self dialog: aMobileApp text: (question isString ifTrue: [ '