2 * Copyright (c) 1999-2000, Eric Moon.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // +++++ cortex integration 23aug99:
34 // - way too many protected members
36 // - implement GetPreferredSize() (should work before the view is attached
37 // to a window -- doable?)
38 // - keyboard entry (pop-up text field)
39 // - 'spin' mode: value changes based on vertical distance of pointer
40 // (configurable; set buttons/modifiers to activate either mode?)
42 // - should parameter binding happen at this level?
43 // +++++ how about a ValControlFactory? give it a BParameter, get back a
44 // ValControl subclass... +++++
48 // ABSTRACT CLASS: ValControl
49 // An abstract base class for 'value controls' -- interface
50 // components that display a value that may be modified via
51 // click-drag. Other editing methods (such as 'click, then
52 // type') may be supported by subclasses.
55 // getValue() and setValue(), for raw (BParameter-style) value access
56 // MessageReceived(), to handle:
59 // M_OFFSET_VALUE (May be sent by segments during mouse action,
60 // +++++ is a faster method needed?)
63 // The control view consists of:
65 // - One or more segments. Each segment is individually
66 // draggable. Subclasses may mix segment types, or Add
67 // and remove segments dynamically.
69 // - A manipulator region, to which subcontrols (such as 'spin
70 // arrows') may be added.
72 // Views/segments may be aligned flush left or flush right. The
73 // side towards which views are aligned may be referred to as
76 // Quickie interface guidelines:
78 // - Value controls are always underlined, indicating that the
79 // value is editable. (+++++ possible extension: dotted-underline
80 // for continuous variation, and solid for discrete/step variation)
82 // - When a value control's 'click action' is to pop down a menu of
83 // available choices (or pop up any sort of non-typable display)
84 // this should be indicated by a small right triangle in the
86 // +++++ this may need some clarification; pop-down sliders, for example?
89 // e.moon 19sep99 Cleanup
90 // e.moon 23aug99 begun Cortex integration
91 // e.moon 17jan99 started
96 #include "cortex_defs.h"
98 #include "ValCtrlLayoutEntry.h"
108 __BEGIN_CORTEX_NAMESPACE
110 class ValControlSegment
;
114 class ValControl
: public BControl
{
116 typedef BControl _Inherited
;
118 public: // types & constants
119 // child-view alignment options:
125 // alignment flags +++++ 23aug99: not implemented -- should they be?
131 // should value update messages be sent asynchronously (during
132 // a mouse operation) or synchronously (after the mouse is
139 enum entry_location
{
146 // layout system state +++++
150 public: // messages (all ValControl-related messages go here!)
153 // Set value of a control or segment:
154 // [your value field(s)] or "_value" (string)
155 M_SET_VALUE
= ValControl_message_base
,
157 // Request for value of control/segment:
158 // [your value field(s)]
161 // ... reply to M_GET_VALUE with this:
162 // [your value field(s)]
168 // * parameter-mode value access
170 // called to set the control's value from raw BParameter data
171 virtual void setValue(const void* data
, size_t size
) = 0;
173 // called to request the control's value in raw form
174 virtual void getValue(void* data
, size_t* ioSize
) = 0;
176 // * string value access
178 virtual status_t
setValueFrom(const char* text
) = 0;
180 virtual status_t
getString(BString
& buffer
) = 0;
182 // called when a child view's preferred size has changed;
183 // it's up to the ValControl to grant the resize request.
184 // Return true to notify the child that the request has
185 // been granted, or false if denied (the default.)
187 virtual bool childResizeRequest(BView
* child
) { return false; }
189 public: // ctor/dtor/accessors
190 virtual ~ValControl();
192 // value-access methods are left up to the subclasses,
193 // since they'll take varying types of arguments.
194 // (M_SET_VALUE and M_GET_VALUE should always behave
195 // as you'd expect, with a 'value' field of the appropriate
196 // type replacing or returning the current value.) +++++ decrepit
198 // Note that all implementations offering pop-up keyboard entry
199 // must accept an M_SET_VALUE with a value of B_STRING_TYPE.
201 // get/set update mode (determines whether value updates are
202 // sent to the target during mouse operations, or only on
204 update_mode
updateMode() const;
205 void setUpdateMode(update_mode mode
);
207 // +++++ get/set font used by segments
208 // (would separate 'value' and 'label' fonts be a good move?)
209 // const BFont* font() const;
211 const BFont
* labelFont() const; //nyi
212 void setLabelFont(const BFont
* labelFont
); //nyi
214 const BFont
* valueFont() const; //nyi
215 void setValueFont(const BFont
* valueFont
); //nyi
217 // get baseline y offset: this is measured relative to the top of the
219 float baselineOffset() const;
221 // segment padding: this amount of padding is added to the
222 // right of each segment bounds-rectangle
223 float segmentPadding() const;
225 // fast drag rate: returns ratio of pixels:units for fast
226 // (left-button) dragging
227 float fastDragRate() const; //nyi
229 // slow drag rate: returns ratio for precise (both/middle-button)
231 float slowDragRate() const; //nyi
234 BView
* backBufferView() const; //nyi
235 BBitmap
* backBuffer() const; //nyi
237 // pop up keyboard input field
238 // +++++ should this turn into a message?
239 virtual void showEditField();
241 public: // debugging [23aug99]
244 public: // BControl impl.
245 // SetValue(), Value() aren't defined, since they only support
246 // 32-bit integer values. TextControl provides a precedent for
247 // this kind of naughtiness.
249 // empty implementation (hands off to BControl)
250 virtual void SetEnabled(bool enabled
);
252 public: // BView impl.
254 // handle initial layout stuff:
255 virtual void AttachedToWindow();
256 virtual void AllAttached();
258 // paint decorations (& decimal point)
259 virtual void Draw(BRect updateRect
);
261 virtual void drawDecimalPoint(ValCtrlLayoutEntry
& entry
);
263 // handle frame resize (grow backbuffer if need be)
264 virtual void FrameResized(float width
, float height
);
266 // calculate minimum size
267 virtual void GetPreferredSize(float* outWidth
, float* outHeight
);
269 virtual void MakeFocus(bool focused
= true);
271 virtual void MouseDown(BPoint where
);
274 virtual void MessageReceived(BMessage
* message
);
276 public: // archiving/instantiation
277 ValControl(BMessage
* archive
);
279 status_t
Archive(BMessage
* archive
, bool deep
= true) const;
281 protected: // internal ctor/operations
282 ValControl(BRect frame
, const char* name
, const char* label
,
283 BMessage
* message
, align_mode alignMode
, align_flags alignFlags
,
284 update_mode updateMode
= UPDATE_ASYNC
, bool backBuffer
= true);
286 // Add segment view (which is responsible for generating its
287 // own ValCtrlLayoutEntry)
288 void _Add(ValControlSegment
* segment
, entry_location from
,
289 uint16 distance
= 0);
291 // Add general view (manipulator, label, etc.)
292 // (the entry's frame rectangle will be filled in)
293 // covers ValCtrlLayoutEntry ctor:
294 void _Add(ValCtrlLayoutEntry
& entry
, entry_location from
);
296 // access child-view ValCtrlLayoutEntry
297 // (_IndexOf returns index from left)
298 const ValCtrlLayoutEntry
& _EntryAt(uint16 offset
) const;
300 const ValCtrlLayoutEntry
& _EntryAt(entry_location from
,
301 uint16 distance
= 0) const;
303 uint16
_IndexOf(BView
* child
) const;
305 uint16
CountEntries() const;
307 private: // steaming entrails
308 // (re-)initialize the backbuffer
309 void _AllocBackBuffer(float width
, float height
);
311 // insert a layout entry in ordered position (doesn't call
313 void _InsertEntry(ValCtrlLayoutEntry
& entry
, uint16 index
);
315 // move given entry horizontally (update child view's position
316 // and size as well, if any)
317 void _SlideEntry(int index
, float delta
);
319 // turn entry_location/offset into an index:
320 uint16
_LocationToIndex(entry_location from
, uint16 distance
= 0) const;
322 void _GetDefaultEntrySize(ValCtrlLayoutEntry::entry_type type
,
323 float* outWidth
, float* outHeight
);
325 void _InvalidateAll();
328 // the set of visible segments and other child views,
329 // in left-to-right. top-to-bottom order
330 typedef std::vector
<ValCtrlLayoutEntry
> layout_set
;
331 layout_set fLayoutSet
;
333 // true if value has been changed since last request
334 // (allows caching of value)
337 // when should messages be sent to the target?
338 update_mode fUpdateMode
;
343 align_mode fAlignMode
;
344 align_flags fAlignFlags
;
346 // the bounds rectangle requested upon construction.
347 // if the ALIGN_GROW flag is set, the real bounds
348 // rectangle may be wider
351 // backbuffer (made available to segments for flicker-free
353 bool fHaveBackBuffer
;
354 BBitmap
* fBackBuffer
;
355 BView
* fBackBufferView
;
357 static const float fSegmentPadding
;
359 static const float fDecimalPointWidth
;
360 static const float fDecimalPointHeight
;
366 __END_CORTEX_NAMESPACE
367 #endif // VAL_CONTROL_H