<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<div id="divtagdefaultwrapper" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p>Hi all,</p>
<p><br>
</p>
<p>as you're talking about UI notifications, I would like to add my 2 cents:</p>
<p><br>
</p>
<p>I have always found the <span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;">
UIManagers' </span>implementations of #inform:, #request:, #chooseFrom:, etc. a bit strange. They first signal a ProvideAnswerNotification, and then, if it was not handled and resumed, display a UI element to the user.</p>
<p>Why is this not rather implemented as a UserNotification, similar to the implementation of ParserNotifications? Pseudocode:</p>
<p><br>
</p>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif;"><b>"Client code"</b></span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<p style="text-decoration-line: line-through;"><strike><span style="font-family: Candara, Optima, sans-serif;">UIManager default inform: 'Carpe Squeak'.</span></strike></p>
<p></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<p style=""><span style="font-family: Candara, Optima, sans-serif;">UserNotification signal: 'Carpe Squeak'. "of course, we could also move this to Object >> #inform: again"</span></p>
<p></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><strike><span style="font-family: Candara, Optima, sans-serif;">UIManager default chooseFrom: (1 to: 10).</span></strike></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif;">UserNotification signalChoiceFrom: (1 to: 10).</span></p>
<p><span style="font-family: Candara, Optima, sans-serif;">UserNotification signalRequest: 'What's your name?' initialAnswer: Utilites authorName.</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><br>
</p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif;"><b>"Implementation"</b></span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif;">UserNotification >> defaultAction</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="white-space: pre; font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif;">Project current uiManager inform: self messageText</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><br>
</p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif; color: rgb(117, 123, 128);">UserNotification >> signalChoiceFrom: values "optional, for convenience"</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre; color: rgb(117, 123, 128);"></span><span style="font-family: Candara, Optima, sans-serif; color: rgb(117, 123, 128);">^ UserChoiceNotification signalFrom: values</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><br>
</p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif;">UserChoiceNotification >> signalFrom: values</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px;">^ self new</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;"><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">values:
 values;</span></span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;"><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">signal</span></span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;"><br>
</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Candara, Optima, sans-serif; font-size: 16px;">UserChoiceNotification >> defaultAction</span></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;"><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">^
 Project current uiManager chooseFrom: self values<br>
</span></span></p>
<p><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;"><span style="font-family: Candara, Optima, sans-serif;"><br>
</span></span></p>
<p><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px;"><span style="font-family: Candara, Optima, sans-serif;">MorphicUIManager
 >> inform: aString<br>
</span></span></p>
<div><strike><span style="white-space: pre; font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif;">self askForProvidedAnswerTo: aString ifSupplied: [:answer | </span><br>
</strike></div>
<div><strike><span style="white-space: pre; font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif;">^ answer].</span></strike></div>
<div><span style="white-space: pre; font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif;">^ UserDialogBoxMorph inform: aString</span></div>
<p></p>
</div>
</blockquote>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<p><br>
</p>
<p><b>Advantages:</b></p>
<p></p>
<ul style="margin-bottom: 0px; margin-top: 0px;">
<li>Each notification is completely represented by a full-fledged first-class object - whereas a ProvideAnswerNotification maps the actual notification quite badly: it does not even store the values to choose from, an initial answer, etc...<span></span></li><li><span style="font-size: 12pt;">Not only, but particularly in tests: You could do amazing things such as</span><br>
</li><li><span><span style="font-family: Candara, Optima, sans-serif;">self</span><br>
<span style="font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">should: [ modelUnderTest doSomeOperation ]</span><br>
<span style="font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">raise: UserChoiceNotification</span><br>
<span style="font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">withExceptionDo: [ :notification |</span><br>
<span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">self</span><br>
<span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Candara, Optima, sans-serif;">should:
 [ '*file*exists*' match: notification messageText ];</span><br>
<span style="font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols; font-size: 16px; white-space: pre;"><span style="font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif; font-size: 16px; white-space: pre;"></span></span><span style="font-family: Candara, Optima, sans-serif;">should:
 [ <b>notification values includes: 'overwrite that file'</b> ] ].<br>
</span></span></li><li>Instead of the hardcoded resumption values for canceling (#cancel and true), you could just implement #cancel on UserNotification and say:<br>
<span style="font-family: Candara, Optima, sans-serif;">[ self chooseFrom: #(one two three) ]
<b>on: UserNotification do: #cancel</b></span><br>
<ul>
<li>(By the way, these hardcoded values currently lead to a strange behavior of the following snippet:<br>
<div><span style="font-family: Candara, Optima, sans-serif;">[ </span><span style="font-family: Candara, Optima, sans-serif;">UIManager default chooseFrom: #(true false) </span><span style="font-family: Candara, Optima, sans-serif;">]</span></div>
<div><span style="white-space: pre; font-family: Candara, Optima, sans-serif;"></span><span style="font-family: Candara, Optima, sans-serif;">valueSuppressingMessages: #('*') "returns 1 instead of 0"<span style="font-family: Calibri, Helvetica, sans-serif;">)</span></span></div>
</li></ul>
</li><li><span><b><span style="font-family: Candara, Optima, sans-serif;"></span></b></span>Currently, we have massive duplication of calls to #askForProvidedAnswerTo:ifSupplied: in each UIManager. If we inversed the call chain as proposed, UIManagers could refocus
 on their task to display UI elements.</li><li>Maybe this change would allow us to move all the convenience methods with default parameters from UIManager into the special UserNotification classes, to tidy up the things a bit :)</li></ul>
<div><br>
</div>
<div><b>Disadvantages:</b></div>
<div>
<ul style="margin-bottom: 0px; margin-top: 0px;">
<li>Compatibility issues: (How) could we preserve the behavior of all current clients that directly call UIManager?<br>
</li><li>Add yours here :-)</li></ul>
</div>
<p></p>
<p><br>
</p>
<p>Best,</p>
<p>Christoph</p>
<br>
<div style="color: rgb(0, 0, 0);">
<hr style="display:inline-block; width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Jakob Reschke <forums.jakob@resfarm.de><br>
<b>Gesendet:</b> Samstag, 2. November 2019 17:36 Uhr<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] [Discussion] Warning vs. Halt (or: "Why is a warning a notification?")</font>
<div> </div>
</div>
<div>
<div dir="auto">
<div>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">Marcel Taeumel <<a href="mailto:marcel.taeumel@hpi.de">marcel.taeumel@hpi.de</a>> schrieb am Sa., 2. Nov. 2019, 13:54:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex; border-left:1px #ccc solid; padding-left:1ex">
<div>
<div id="m_-1915767081189451620__MailbirdStyleContent" style="font-size:10pt; font-family:Arial; color:#000000">
<div>Hmmm..... Notifcations that claim to be resumable but require user input in #defaultAction feel kind of awkwardly designed...</div>
</div>
</div>
</blockquote>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">Yes they are. After all they don't really have a default value that should be automatically determined. Or in other words they must be handled and if they are not they force you to handle them manually. In that regard they behave more like Errors,
 which are manually handled in the debugger. They are not errors from a functional perspective though.</div>
<div dir="auto"><br>
</div>
<div dir="auto">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex; border-left:1px #ccc solid; padding-left:1ex">
<div>
<div id="m_-1915767081189451620__MailbirdStyleContent" style="font-size:10pt; font-family:Arial; color:#000000">
<div>In that sense, I can also resume any error with "nil" (or "false") if I want to....</div>
</div>
</div>
</blockquote>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">...which is what you get when you press "proceed", right? But you are not allowed to send #resume or #resume: to them.</div>
<div dir="auto"><br>
</div>
<div dir="auto">#resume with default value does not make much sense for those request exceptions either.</div>
<div dir="auto"><br>
</div>
<div dir="auto">A more sensible pattern might be:</div>
<div dir="auto"><br>
</div>
<div dir="auto">    value := RequestNotification signal.</div>
<div dir="auto">    value ifNil: [self showUiRequest].</div>
<div dir="auto"><br>
</div>
<div dir="auto">But you cannot enforce it anyway.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Also these requests are mostly UI situations which want to be unit-testable and therefore use these exceptions, aren't they? So they might not be amenable or relevant for catch-all exception handling for server purposes anyway.</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>