Changeset 8523


Ignore:
Timestamp:
Feb 21, 2008, 12:37:49 AM (12 years ago)
Author:
mikel
Message:

added code to add a button to the sample window

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/examples/cocoa/ui-elements/HOWTO.html

    r8517 r8523  
    33<html xmlns="http://www.w3.org/1999/xhtml">
    44  <head>
    5     <title>Nib-Loading HOWTO</title>
     5    <title>UI Elements HOWTO</title>
    66    <link rel="stylesheet" type="text/css" href="HOWTO_files/stylesheets/styles.css" />
    77  </head>
     
    224224    specified, appears on the left lower corner of the screen.</p>
    225225
     226    <div class="title">
     227      <h2>Adding a Button</h2>
    226228    </div>
    227229
    228 
     230    <p>Once we have a window on the screen, we might like to put
     231    something in it. Let's start by adding a button.</p>
     232
     233    <p>Creating a button object is as simple as creating a window
     234    object; we simply allocate one:</p>
     235
     236    <pre>
     237(setf my-button (#/alloc ns:ns-button))
     238#&lt;NS-BUTTON &lt;NSButton: 0x13b7bec0&gt; (#x13B7BEC0)&gt;
     239    </pre>
     240
     241    <p>As with the window, most of the interesting work is in
     242    configuring the allocated button after it's allocated.</p>
     243
     244    <p>Instances of NSButton include pushbuttons with either text or
     245    image labels (or both), checkboxes, and radio buttons. In order to
     246    make a text pushbutton, we need to tell our button to use a
     247    button-type of <code>NSMomentaryPushInButton</code>, an image
     248    position of <code>NSNoImage</code>, and a border style
     249    of <code>NSRoundedBezelStyle</code>. These style options are
     250    represented by Cocoa constants.</p>
     251   
     252    <p>We also need to give the button a frame rectangle that defines
     253    its size and position. We can once again
     254    use <code>ns:with-ns-rect</code> to specify a temporary rectangle
     255    for the purpose of initializing our button:</p>
     256
     257    <pre>
     258(ns:with-ns-rect (frame 10 10 72 32)
     259  (#/initWithFrame: my-button frame)
     260  (#/setButtonType: my-button #$NSMomentaryPushInButton)
     261  (#/setImagePosition: my-button #$NSNoImage)
     262  (#/setBezelStyle: my-button #$NSRoundedBezelStyle))
     263;Compiler warnings :
     264;   Undeclared free variable MY-BUTTON (4 references), in an anonymous lambda form
     265NIL
     266    </pre>
     267
     268    <p>Now we just need to add the button to the window:</p>
     269
     270    <pre>
     271(#/addSubview: (#/contentView my-window) my-button)
     272    </pre>
     273
     274    <p>The button appears in the window with the rather uninspired
     275    label "Button". Clicking it highlights the button but, since we
     276    didn't give it any action to perform, does nothing else.</p>
     277
     278    <p>We can give the button a more interesting label and, perhaps
     279    more importantly, an action to perform, by passing a string and an
     280    action to it. First, let's set the button title:</p>
     281
     282    <pre>
     283(let ((label (%make-nsstring "Hello!")))
     284  (#/setTitle: my-button label)
     285  (#/release label))
     286;Compiler warnings :
     287;   Undeclared free variable MY-BUTTON, in an anonymous lambda form
     288NIL
     289    </pre>
     290
     291    <p>The button changes to display the text "Hello!". Notice that we
     292    are careful to save a reference to the label text and release it
     293    after changing the button title. The normal memory-management
     294    policy in Cocoa is that if we allocate an object (like the
     295    NSString "Hello!") we are responsible for releasing it. Unlike
     296    Lisp, Cocoa does not automatically garbage-collect all allocated
     297    objects by default.</p>
     298
     299    <p>Giving the button an action is slightly more
     300    complicated. Clicking a button causes the button object to send a
     301    message to a target object. We haven't given our button a message
     302    to send, nor a target object to send it to, so it doesn't do
     303    anything. In order to get it do perform some kind of action, we
     304    need to give it a target object and a message to send. Then, when
     305    we click the button, it will send the message we specify to the
     306    target we provide. Naturally, the target object had better be able
     307    to respond to the message, or else we'll just see a runtime
     308    error.</p>
     309
     310    <p>Let's define a class that knows how to respond to a greeting
     311    message, and then make an object of that class to serve as our
     312    button's target.</p>
     313
     314    <p>We can define a subclass of <code>NSObject</code> to handle
     315    our button's message:</p>
     316
     317    <pre>
     318(defclass greeter (ns:ns-object)
     319  ()
     320  (:metaclass ns:+ns-object))
     321#&lt;OBJC:OBJC-CLASS GREETER (#x13BAF810)&gt;
     322    </pre>
     323
     324    <p>We'll need to define a method to execute in response to the
     325    button's message. Action methods accept one argument (inaddition
     326    to the receiver): a sender. Normally Cocoa passes the button
     327    object itself as the sender argument; the method can do anything
     328    it likes (oor nothing at all) with the sender.</p>
     329
     330    <p>Here's a method that displays an alert dialog:</p>
     331
     332    <pre>
     333(objc:defmethod #/greet: ((self greeter) (sender :id))
     334  (declare (ignore sender))
     335  (let ((title (%make-nsstring "Hello!"))
     336        (msg (%make-nsstring "Hello, World!"))
     337        (default-button (%make-nsstring "Hi!"))
     338        (alt-button (%make-nsstring "Hello!"))
     339        (other-button (%make-nsstring "Go Away")))
     340    (#_NSRunAlertPanel title msg default-button alt-button other-button)
     341    (#/release title)
     342    (#/release msg)
     343    (#/release default-button)))
     344    </pre>
     345
     346    <p>Now we can create an instance of the Greeter class and use it
     347    as the button's target:</p>
     348
     349    <pre>
     350(setf my-greeter (#/init (#/alloc greeter)))
     351#&lt;GREETER &lt;Greeter: 0x136c58e0&gt; (#x136C58E0)&gt;
     352
     353(#/setTarget: my-button my-greeter)
     354NIL
     355
     356(#/setAction: my-button (@SELECTOR "greet:"))
     357NIL
     358    </pre>
     359
     360    <p>Now, if you click the button, an Alert panel appears.</p>
     361
     362    </div>
    229363
    230364  </body>
Note: See TracChangeset for help on using the changeset viewer.