tag:blogger.com,1999:blog-69100080877525135102023-06-20T06:46:02.129-07:00PresentyPharo smalltalk ui programming framework based on MVP, prototypes and continuationsDenis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-6910008087752513510.post-37252800280604272372012-09-09T13:31:00.000-07:002012-09-09T13:47:18.730-07:001$ gesture recognizer for Presenty<div dir="ltr" style="text-align: left;" trbidi="on">
Yoshiki Ohshima ported 1$ gesture recognizer to Pharo/Squeak <a href="https://github.com/yoshikiohshima/Squeak-1Dollar-Recognizer">https://github.com/yoshikiohshima/Squeak-1Dollar-Recognizer</a>.<br />
I connect it to Presenty with special user action activator. <br />
<br />
You can see it <a href="http://www.youtube.com/watch?v=8x3mY6jlvVk">here</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/8x3mY6jlvVk?feature=player_embedded' frameborder='0'></iframe></div>
</div>
Denis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.com0tag:blogger.com,1999:blog-6910008087752513510.post-70453858439333988852012-09-05T12:31:00.001-07:002012-09-05T12:31:30.499-07:00Package browser example screencast <div dir="ltr" style="text-align: left;" trbidi="on">
I create screencast about simple package browser built with Presenty.<br />
<a href="http://www.youtube.com/watch?v=f3hk3fLBcsE&feature=player_embedded">http://www.youtube.com/watch?v=ZxHJ6yJKM58&feature=player_embedded</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/ZxHJ6yJKM58?feature=player_embedded' frameborder='0'></iframe></div>
<br />
And I update prepared image for this example.<br />
<a href="http://smalltalk-presenty.googlecode.com/files/PharoPresentyBrowserExample.zip">http://smalltalk-presenty.googlecode.com/files/PharoPresentyBrowserExample.zip</a>
</div>
Denis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.com0tag:blogger.com,1999:blog-6910008087752513510.post-47199939915113232072012-08-30T02:41:00.001-07:002012-09-05T13:38:55.479-07:00New versions available<div dir="ltr" style="text-align: left;" trbidi="on">
Big hard work was done this year. Now Presenty has many new concepts and flexibility.<br />
There was presentation at ESUG 2012
<iframe src="http://www.slideshare.net/slideshow/embed_code/14152010" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="http://www.slideshare.net/esug/presenty" title="Presenty" target="_blank">Presenty</a> </strong> from <strong><a href="http://www.slideshare.net/esug" target="_blank">ESUG</a></strong> </div>
<br />
And you can try package browser example by yourself <a href="http://smalltalk-presenty.googlecode.com/files/PharoPresentyBrowserExample.zip">http://smalltalk-presenty.googlecode.com/files/PharoPresentyBrowserExample.zip</a><a href="https://code.google.com/p/smalltalk-presenty/downloads/list"></a><br />
<br />
I will prepare screencast about it very soon.</div>
Denis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.com0tag:blogger.com,1999:blog-6910008087752513510.post-23625630164018531612011-08-07T08:54:00.000-07:002011-08-07T11:56:00.388-07:00Presenter<div dir="ltr" style="text-align: left;" trbidi="on">Central component of MVP is presenter.<br />
<div style="margin-bottom: 0cm;">Presenter adds model data on view and handle it events. </div><span lang="en-US">Each presenter has view. View know nothing about presenter and model.</span><br />
<span lang="en-US">View is basic morph which show data on screen. </span><br />
<br />
<span lang="en-US">Primitive presenters change internal state of </span><span lang="en-US">morph (view)</span><span lang="en-US">. For example, </span><span lang="en-US">PtyTextLabelPesenter changes text contents of </span><span lang="en-US">PtyTextMorph (view of text label presenter) to show it string model. </span><br />
<span lang="en-US">Composite presenters (which usually implemented in applications) add </span><span lang="en-US">another morphs </span><span lang="en-US">to view from child presenters. Each presenter can show other presenters on view.</span><br />
<br />
To implement new presenter you should subclass <span lang="en-US">PtyCompositePresenter and implement method #showViewItems. Inside this method you can add child items on view:</span><br />
<br />
<div style="text-align: left;"><span lang="en-US">PtyCompositePresenter subclass: #ContactPresenter<br />
instanceVariableNames: ''<br />
classVariableNames: ''<br />
poolDictionaries: ''<br />
category: 'PresentyExamples-ContactManager'</span></div><div style="text-align: left;"><span lang="en-US"><br />
</span></div><div style="text-align: left;"><span lang="en-US">PtyContactPresenter>></span><span lang="en-US">showViewItems<br />
<br />
self showItem: (PtySimpleLabelPresenter on: model firstName).<br />
self showItem: (PtySimpleLabelPresenter on: model lastName)</span></div><br />
This is <span lang="en-US">ContactPresenter for Contact </span><span lang="en-US">instances</span><span lang="en-US">.</span><br />
Two messages can be used to show child presenters: <span lang="en-US">showItem</span>:, <span lang="en-US">showItem</span>:<span lang="en-US">on</span>:. First message show child on own presenter view. Second message show child on concrete panel.<br />
You can request subpanels (submorphs) from view by "view panelNamed: 'panelName'". It searchs morph with given name inside structure of view morph (recursively). If target morph absent it will be created and added to view morph.<br />
<br />
All presenters can be created on concrete model by #on: message.<br />
<br />
When you implement presenter you don't need to specify view for it. View of presenter is created by guide when you request guide to show presenter (method #showItems: implemented by guide). Guide search appropriate prototype for presenter and creates view based on it.<br />
When prototype is absent default view is created. Default view is unconfigurable morph with red/yellow colors. You can design it appearance (by morphic features) and save it as prototype for presenter view (in halo menu there is "apply prototype changes" item).<br />
Prototype is basic morph. Views are created by simple copy (#veryDeepCopy) of prototype.<br />
<br />
Presenter can have specific prototypes for concrete context of applcation:<br />
<ul style="text-align: left;"><li>it can be specific inside different parent presenters</li>
<li>it can be specific in context of different tasks</li>
<li>it can be specific for different styles of presenter</li>
<li>it can be specific inside different parent presenter styles</li>
</ul>Thus appearance of presenter view can be different in different parts of application. It can be configured without programming.<br />
<br />
Each presenter can have style. You can create any presenter with style by:<br />
<ul style="text-align: left;"><li>PresenterClass on: aModel withStyle: #styleName</li>
</ul>You can change presenter style at run time. For example, input field in Presenty change it style between #filled and #unfilled according to filling state of field input:<br />
<br />
<span lang="en-US">PtyFieldEditorPresenter>>valueChanged</span><span lang="en-US"><br />
| inputStyle |</span><br />
<span lang="en-US"> inputStyle := model isValid ifTrue: [#filled] ifFalse: [#unfilled].</span><br />
<span lang="en-US"> guide show: input withStyle: inputStyle</span><br />
<br />
<div style="margin-bottom: 0cm;">Last expression change style of presenter "input". It view will be replaced with new view based on new prototype. </div><div style="margin-bottom: 0cm;"><br />
</div><div style="margin-bottom: 0cm;">All presenter prototypes stored in instance of PtyPrototypeManager. You can get it by:</div><ul style="text-align: left;"><li> guide uiBuilder prototypesManager</li>
</ul><div style="margin-bottom: 0cm;">You can store this object to file and share between images:</div><ul style="text-align: left;"><li>(FileStream newFileNamed: 'yourApp.skin') fileOutClass: nil andObject: guide uiBuilder prototypesManager.</li>
<li>guide uiBuilder prototypesManager: (FileStream fileNamed: 'smallkiosk.skin') fileInObjectAndCode.</li>
</ul><br />
Next screencast show how implement presenters: <a href="http://www.youtube.com/watch?v=f3hk3fLBcsE&feature=player_embedded">http://www.youtube.com/watch?v=f3hk3fLBcsE&feature=player_embedded</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/f3hk3fLBcsE?feature=player_embedded' frameborder='0'></iframe></div><br />
<br />
<br />
</div>Denis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.com0tag:blogger.com,1999:blog-6910008087752513510.post-62793552949547849012011-08-07T08:53:00.000-07:002011-08-07T13:02:21.711-07:00Basic concepts<div dir="ltr" style="text-align: left;" trbidi="on"><span class="il">Presenty</span> is a user interface framework that makes it easy to create reusable components of user interface and user interraction logic. With <span class="il">Presenty</span> you can lively tune appearance of your application.<span class="il"> </span><br />
<div><div><div><br />
<span class="il">Presenty</span> based on Model-View-Presenter pattern, view prototypes and continuations.<br />
<br />
MVP is powerfull pattern for implementing reusable components of user interface. With MVP you can present your model by different presenters in concrete place of your application. Unfortunately existed MVP frameworks make it difficult to create multiple views for same presenter. For example, you implement ContactPresenter. And you want specific view for it in "contact dial task" and "contact sms task". With <span class="il">Presenty</span> you take it easy. Indeed you can show your presenter with styles (selected or deselected for example). And appearace of this styles can be specific in concrete application task. </div><br />
With <span class="il">Presenty</span> you can create tasks - reusable components of user interraction logic. Implementation of tasks based on continuation (like tasks in Seaside). Task programming based on simple DSL (it is usual smalltalk of course) which gives you expressions for request confirmations, show warnings, request requisities, request new tasks and others:<br />
<ul style="text-align: left;"><li>user warn: 'message'</li>
<li>user confirm: 'question?'</li>
<li>user input: requisities</li>
<li>user select: 'ItemName' from: itemsArray.</li>
<li>user execute: newTask</li>
<li>...</li>
</ul>You can extend this DSL for your application. For example, you can implement "user dialTo: aContact" which will request user for new DialContactTask. <br />
<br />
Every task know user and guide (PtyUser and PtyGuide). With "guide" you can control current view area. You can set up new area or add new items to it. You can set up modal view area and all ui actions will be placed in modal mode:<br />
<br />
guide doInModal: [user warn: 'message'].</div><div></div><div>Guide is central object which known by every application component: tasks and presenters. It is like museum guide which show you exhibits. You can ask guide to show you presenters or execute some tasks. <br />
<br />
Guide has viewport. It is instance of PtyViewportPresenter which presents main application panel with current view area. When you ask guide to show some presenter guide placed it on current view area of viewport.<br />
<br />
Each task has its own view area in which it placed ui components. Task view area inherits from caller (parent) task view area. So all components of caller tasks become parts of new task.<br />
Task can return answer to parent (caller) continuation by "parent resumeWith: #answer".<br />
Or you can stop current task by "user stopCurrentTask". And user will be return to previous request.<br />
<br />
Each presenter know about continuation in which context it has been shown. Presenter holds it in context variable. All presenters can resume it context with some value by "self answer: #value".<br />
<br />
Guide has taskNavigator object. It saves all user requests. So you always can add back button to view area which return user to previous request. "User stopCurrentTask" implemented by taskNavigator too. It removes from navigator all tasks derived from current and executes last remain task which repeats last user request.<br />
<br />
<span class="il">Presenty</span> support multilingual by default. All text and image labels are translated by guide translator object. All kind of labels has label name which is key for translator dictionary. You can easily add new languages and translations for it. When image label shown it requests image from guide resourcesManager by translated label name key. By default guide resourcesManager is PtyResourcesManager which loads images from "images" folder near VM.<br />
<br />
Guide has task settings (PtyTaskSettings). Task settings holds settings of tasks and presenters. By "guide create: aTask" you can create task instance with saved settings. New instance can be another class. For example, you can request PtyShowListTask and guide creates PtyShowListWithPagesTask or PtySimpleShowListTask. You can see hierarchy of this kind of task. Besides you can spesify settings in concrete context of current tasks chain. So in one context you will see list of items splitted by pages. In another task you will see items in scrolled panel.<br />
Task settings has userFeeling object. It provides preferred instances of tasks and presenters for current platform. Now Presenty has PtyDesktopUserFeeling and PtyStreetUserFeeling. It is possible to implement PtyMobileTouchScreenUserFeeling which gives you input fields with visual keyboard. (It is really done by PtyStreetUserFeeling, but PtyStreetUserFeeling purpose is little different than mobile touch screen devices)<br />
<br />
With Presenty you can program in terms of user interraction logic (based on tasks). Way in which this logic will be presented to user is part of design time and configuration of application. For desktop platform you can configure one "look and feel". For tablet platform "look and feel" can be very different. With Presenty you take it without code changes.<br />
<br />
In next posts I will show how create Presenty components of user interface.</div></div></div>Denis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.com0tag:blogger.com,1999:blog-6910008087752513510.post-82193108644602715712011-08-07T08:52:00.000-07:002011-08-07T11:16:33.762-07:00Overview<div dir="ltr" style="text-align: left;" trbidi="on"><br />
Presenty is framework for building applications with rich and complex user interface. It brings together several ideas, concepts and technologies including:<br />
<ul><li>Modified Model-View-Presenter pattern</li>
<li>Continuation-based tasks as elements of user interaction at application level</li>
<li>User requests as building blocks for tasks:<ul><li>Primitive user requests to invoke base interface components</li>
<li>Compound requests for calling other tasks</li>
</ul></li>
<li>Extendable DSL (pure Smalltalk) facilitating task implementation</li>
<li>Prototyping for visual components and tasks</li>
</ul><br />
Presenty provides appearance and behavior configuration for components and tasks without application code modification.<br />
<br />
Presenty license is MIT and run on Pharo.<br />
<br />
Presenty developed on Pharo 1.1.1 and not tested on latest versions yet.<br />
You can load it from <a href="http://www.squeaksource.com/Presenty.html">http://www.squeaksource.com/Presenty.html</a>. Presenty has dependence from seaside continuations. So you must load Seaside-Pharo-Continuation and Grease packages from http://www.squeaksource.com/Seaside30 repository before you install Presenty. If you want PresentyTests you should load Mocketry package from http://www.squeaksource.com/Mocketry<br />
<br />
<br />
</div>Denis Kudriashovhttp://www.blogger.com/profile/10868011339231973692noreply@blogger.com0