oulan / iui

Automatically exported from code.google.com/p/iui
MIT License
0 stars 0 forks source link

Enhancement: A "real" "modal" Apple dialog for iUI #294

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
So today I decided I wanted to be able to spawn Apple-esque "modal" dialog 
boxes.  You know the kind: the ones that pop up when an application requests 
permission to use your location information, or the kind that request your 
Apple ID when you're in the App Store, or JavaScript alert/confirm boxes.  This 
was a beast of a project, I spent most of my time working on the CSS to make 
this thing look as close to the original as I could, and some 36 hours later, 
here's the end result.  I'd love to see this integrated as another option in 
iUI (panel, dialog, floatDialog?), but it's going to need some tweaking; mostly 
because the CSS included with iUI doesn't behave and overlaps its class names 
to things that it shouldn't (the rules aren't specific enough).  Perhaps I'll 
get around to it, but in case I don't I wanted to donate my hard work to the 
project and let someone else run with the ball.

In the sample HTML file, click the blue button to see the dialog box pop up.  
It will (ironically) show you a full-width dialog box asking you what kind of 
dialog box you want to see.

Attachments:
fullwidth_apple.png - Apple's rendition of a full-width (!=2 buttons) dialog box
fullwidth_mine.png - My attempt to copy above
equalwidth_apple.png - Apple's version of split-width (2 buttons)
equalwidth_mine.png - My attempt to copy above
dialog.html - The source code to do all this

The screenshots are so you can compare how close I came to the original dialogs 
I was using as a test platform.  There are more options (like adding text, or 
single button dialogs), but I didn't bother to include screenshots of them.  
You can run the example code to see them in action.

At the moment, the code automatically detects whether it should make a 
full-width dialog box in the function that displays the dialog box.  The way it 
makes the decision is by counting the buttons.  A dialog box with 2 buttons 
will be displayed horizontally, anything else will be full-width.

There are two bugs I know about already:
(1) text-overflow: ellipsis isn't working on the buttons (probably just 
something I forgot somewhere).
(2) Dialog position is buggy.  It seems to display the dialog lower than it 
should the first time around.  (But if you cancel and display the same dialog 
box, it shows up in the right spot.)  I'm not sure why this is; again, probably 
something I missed.  It is rather late and I've been working on this for a 
ridiculously long time now.

Also, I didn't do a lot of testing to make sure that everything lines up as 
it's supposed to if the window is scrolled.  This applies to the DIV that 
obscures the background as well as the dialogs themselves.  Since both of these 
problems have been addressed in iUI before, I'm sure it won't be a problem to 
just borrow that code.

Another thing that would probably be good programming practice would be to 
enclose this set of (albeit few) JavaScript functions and variables in its own 
class.

One thing I'd REALLY like to see is if someone can tweak the animation to make 
it smoother.  I have the "pop" effect of the dialog replicated, but it takes 
too long and isn't smooth enough.  Maybe someone can optimize the little bit of 
JavaScript I'm using and end up with better results.

Original issue reported on code.google.com by eslind...@gmail.com on 2 Aug 2011 at 7:09

Attachments:

GoogleCodeExporter commented 9 years ago
Another thing that needs to be done is to refine the color values.  It's tricky 
nailing the same colors Apple used because of the transparency involved.  I've 
done a fair job imitating the existing buttons, but obviously it's not spot-on.

Regarding the buttons, for those interested, there are five major colors that I 
have seen used throughout Apple's UI so far (forgive me if there are official 
names that I'm not using): slate, blue, red, darkblue, and black.  Slate is the 
default "neutral" button color, with darkblue being a common alternate.  There 
seems to be little rhyme or reason to the use of these two, as evidenced by the 
Cancel button in my screenshots being slate in one and darkblue in the other.  
Meanwhile, red is consistently delete, blue is usually confirm, save, or 
submit, and black seems to be used on dark UI (when the title bar switches to 
white text on black background).  All of these are available (in some form or 
another) in the code I submitted, complete with double linear gradients, inset 
and outset box shadows, appropriate borders, and correct text color shadow.  
Now they just need tweaking to make them appear color accurate after 
transparency effects are applied.

Original comment by eslind...@gmail.com on 2 Aug 2011 at 9:58

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Updated the code.  Now using external files which are easy to include.  The 
background obscuring DIV gets created on a per-dialog basis now, since I 
realized they should obscure everything below them, including other dialogs 
(before dialogs would obscure the page but not each other).  This also has the 
added side benefit of not requiring you to remember to add a special background 
DIV to your page each time you want to use the dialog library.

Also, the JavaScript is now a singleton ("dialog" class) to avoid pollution of 
the global namespace.

To use, simply add reference to dialog.js and dialog.css, then use the 
dialog.show() and dialog.hide() functions.  Each function accepts a string (ID 
of dialog box DIV), object (dialog box DIV itself), or number (index into the 
stack of active dialogs) as its only parameter.

Normally, clicking outside the dialog box will dismiss it without action.  To 
override this behavior, specify the "modal" attribute on the dialog box:

<div class="floatDialog" modal="modal">
  <h1>Modal Example</h1>
  <p>This dialog box will not be dismissed if you click outside of it; the only way for this dialog box to disappear is for dialog.hide to be called on it.</p>
  <div class="buttons full-width">
    <button>Hard Choice #1</button>
    <button>Hard Choice #2</button>
  </div>
</div>

Note that in this example, the dialog will never disappear because dialog.hide 
is never called.  This modal functionality is intended for dialogs that need to 
force the user to choose an action, then take that action (possibly blocking 
while waiting for a response), and THEN hide the dialog box.  I'm not sure if 
this will be useful, but I've added it anyways.  It was easy enough to do while 
I was adding the auto-dismissal-by-clicking-background feature.

Original comment by eslind...@gmail.com on 2 Aug 2011 at 8:22

Attachments:

GoogleCodeExporter commented 9 years ago
Followup: I just found a great solution for the animation problem I was 
experiencing.  It turns out that there is a 'transition-timing-function' 
property which in addition to taking the default named parameters (linear, 
ease, ease-in, ease-out, etc.) can also be set to cubic-bezier with 4 
parameters specifying the x and y of P1 and P2.  By setting these to 0.5, 2.5, 
0.6, 0.5 (or thereabouts) we should be able to achieve a perfect smooth "pop" 
animation just like Apple's UI!  This is of course assuming the input AND the 
output of the cubic-bezier function aren't clamped, and several other things as 
well.  But if it works, this will provide the entire animation in one call, 
resulting in the whole sequence being smooth as well as much easier to work 
with code-wise.  In addition to this change, I also discovered 3D 
hardware-accelerated CSS transitions, which I plan on using instead of the 
previous 2D scale() function.  I'm going to switch to scale3D() (or probably 
scaleZ()) and utilize that graphics hardware!  However, I will not be posting 
these changes in this issue.  Instead, I will probably be creating a Git clone 
and committing the changes to that.  This post is informative in case I don't 
get around to the Git clone or can't get it to post to Google Code or whatever.

Original comment by eslind...@gmail.com on 21 Oct 2011 at 6:02

GoogleCodeExporter commented 9 years ago
I know, I said I wasn't going to post these here, but the tests are done and 
I'm not going to work on the Git thing just yet, so here's the candy:

Stupid cubic-bezier function is clamped to 0..1 on the input, making it pretty 
much completely useless in this instance.  (Why oh why is the input clamped? 
The output shouldn't even be clamped until it has been evaluated against the 
value, and then the value should only be clamped to the minimum and maximum for 
that particular property: 0x000000 and 0xffffff for colors for example, but 
unclamped for scale which essentially has no limits.)

Anyways, guess what I found while trying to understand why the cubic-bezier 
function was causing me so much grief?  Apple has implemented a "keyframe 
animation" technique in Safari, which works perfectly for what I need!  Check 
out the attached file for a smooth, hardware-accelerated pop-in effect.

Original comment by eslind...@gmail.com on 21 Oct 2011 at 6:50

Attachments:

GoogleCodeExporter commented 9 years ago
Hey Eric: I'd love to see the sample .html stuff checked in to Git.  Then I can 
just pull from your clone and check everything out quickly :)

Original comment by msgilli...@gmail.com on 23 Oct 2011 at 6:52

GoogleCodeExporter commented 9 years ago
Yeah I've got a clone running for it already, but it's not integrated to my 
satisfaction yet. This issue I created before our Git. 

Original comment by eslind...@gmail.com on 23 Oct 2011 at 7:00