2 * Copyright 2010 Stephan Aßmus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include "URLInputGroup.h"
11 #include <ControlLook.h>
12 #include <Clipboard.h>
13 #include <GroupLayout.h>
14 #include <GroupLayoutBuilder.h>
16 #include <LayoutUtils.h>
18 #include <PopUpMenu.h>
19 #include <SeparatorView.h>
27 #include "BitmapButton.h"
28 #include "BrowsingHistory.h"
29 #include "IconButton.h"
30 #include "IconUtils.h"
31 #include "TextViewCompleter.h"
34 #undef B_TRANSLATION_CONTEXT
35 #define B_TRANSLATION_CONTEXT "URL Bar"
38 class URLChoice
: public BAutoCompleter::Choice
{
40 URLChoice(const BString
& choiceText
, const BString
& displayText
,
41 int32 matchPos
, int32 matchLen
, int32 priority
)
43 BAutoCompleter::Choice(choiceText
, displayText
, matchPos
, matchLen
),
48 bool operator<(const URLChoice
& other
) const
50 if (fPriority
> other
.fPriority
)
52 return DisplayText() < other
.DisplayText();
55 bool operator==(const URLChoice
& other
) const
57 return fPriority
== other
.fPriority
58 && DisplayText() < other
.DisplayText();
66 class BrowsingHistoryChoiceModel
: public BAutoCompleter::ChoiceModel
{
67 virtual void FetchChoicesFor(const BString
& pattern
)
69 int32 count
= CountChoices();
70 for (int32 i
= 0; i
< count
; i
++) {
71 delete reinterpret_cast<BAutoCompleter::Choice
*>(
72 fChoices
.ItemAtFast(i
));
76 // Search through BrowsingHistory for any matches.
77 BrowsingHistory
* history
= BrowsingHistory::DefaultInstance();
82 int32 priority
= INT_MAX
;
84 count
= history
->CountItems();
85 for (int32 i
= 0; i
< count
; i
++) {
86 BrowsingHistoryItem item
= history
->HistoryItemAt(i
);
87 const BString
& choiceText
= item
.URL();
88 int32 matchPos
= choiceText
.IFindFirst(pattern
);
91 if (lastBaseURL
.Length() > 0
92 && choiceText
.FindFirst(lastBaseURL
) >= 0) {
96 lastBaseURL
= baseURL(choiceText
);
97 fChoices
.AddItem(new URLChoice(choiceText
,
98 choiceText
, matchPos
, pattern
.Length(), priority
));
103 fChoices
.SortItems(_CompareChoices
);
106 virtual int32
CountChoices() const
108 return fChoices
.CountItems();
111 virtual const BAutoCompleter::Choice
* ChoiceAt(int32 index
) const
113 return reinterpret_cast<BAutoCompleter::Choice
*>(
114 fChoices
.ItemAt(index
));
117 static int _CompareChoices(const void* a
, const void* b
)
119 const URLChoice
* aChoice
120 = *reinterpret_cast<const URLChoice
* const *>(a
);
121 const URLChoice
* bChoice
122 = *reinterpret_cast<const URLChoice
* const *>(b
);
123 if (*aChoice
< *bChoice
)
125 else if (*aChoice
== *bChoice
)
135 // #pragma mark - URLTextView
138 static const float kHorizontalTextRectInset
= 4.0;
141 class URLInputGroup::URLTextView
: public BTextView
{
143 static const uint32 MSG_CLEAR
= 'cler';
146 URLTextView(URLInputGroup
* parent
);
147 virtual ~URLTextView();
149 virtual void MessageReceived(BMessage
* message
);
150 virtual void FrameResized(float width
, float height
);
151 virtual void MouseDown(BPoint where
);
152 virtual void KeyDown(const char* bytes
, int32 numBytes
);
153 virtual void MakeFocus(bool focused
= true);
155 virtual BSize
MinSize();
156 virtual BSize
MaxSize();
158 void SetUpdateAutoCompleterChoices(bool update
);
161 virtual void InsertText(const char* inText
, int32 inLength
,
163 const text_run_array
* inRuns
);
164 virtual void DeleteText(int32 fromOffset
, int32 toOffset
);
167 void _AlignTextRect();
170 URLInputGroup
* fURLInputGroup
;
171 TextViewCompleter
* fURLAutoCompleter
;
172 bool fUpdateAutoCompleterChoices
;
176 URLInputGroup::URLTextView::URLTextView(URLInputGroup
* parent
)
179 fURLInputGroup(parent
),
180 fURLAutoCompleter(new TextViewCompleter(this,
181 new BrowsingHistoryChoiceModel())),
182 fUpdateAutoCompleterChoices(true)
186 fURLAutoCompleter
->SetModificationsReported(true);
190 URLInputGroup::URLTextView::~URLTextView()
192 delete fURLAutoCompleter
;
197 URLInputGroup::URLTextView::MessageReceived(BMessage
* message
)
199 switch (message
->what
) {
205 BTextView::MessageReceived(message
);
212 URLInputGroup::URLTextView::FrameResized(float width
, float height
)
214 BTextView::FrameResized(width
, height
);
220 URLInputGroup::URLTextView::MouseDown(BPoint where
)
222 bool wasFocus
= IsFocus();
227 if (Window()->CurrentMessage()->FindInt32("buttons", &buttons
) != B_OK
)
228 buttons
= B_PRIMARY_MOUSE_BUTTON
;
230 if ((buttons
& B_SECONDARY_MOUSE_BUTTON
) != 0) {
231 // Display context menu
232 int32 selectionStart
;
234 GetSelection(&selectionStart
, &selectionEnd
);
235 bool canCutOrCopy
= selectionEnd
> selectionStart
;
237 bool canPaste
= false;
238 if (be_clipboard
->Lock()) {
239 if (BMessage
* data
= be_clipboard
->Data())
240 canPaste
= data
->HasData("text/plain", B_MIME_TYPE
);
241 be_clipboard
->Unlock();
244 BMenuItem
* cutItem
= new BMenuItem(B_TRANSLATE("Cut"),
245 new BMessage(B_CUT
));
246 BMenuItem
* copyItem
= new BMenuItem(B_TRANSLATE("Copy"),
247 new BMessage(B_COPY
));
248 BMenuItem
* pasteItem
= new BMenuItem(B_TRANSLATE("Paste"),
249 new BMessage(B_PASTE
));
250 BMenuItem
* clearItem
= new BMenuItem(B_TRANSLATE("Clear"),
251 new BMessage(MSG_CLEAR
));
252 cutItem
->SetEnabled(canCutOrCopy
);
253 copyItem
->SetEnabled(canCutOrCopy
);
254 pasteItem
->SetEnabled(canPaste
);
255 clearItem
->SetEnabled(strlen(Text()) > 0);
257 BPopUpMenu
* menu
= new BPopUpMenu("url context");
258 menu
->AddItem(cutItem
);
259 menu
->AddItem(copyItem
);
260 menu
->AddItem(pasteItem
);
261 menu
->AddItem(clearItem
);
263 menu
->SetTargetForItems(this);
264 menu
->Go(ConvertToScreen(where
), true, true, true);
268 // Only pass through to base class if we already have focus.
272 BTextView::MouseDown(where
);
277 URLInputGroup::URLTextView::KeyDown(const char* bytes
, int32 numBytes
)
281 BView::KeyDown(bytes
, numBytes
);
285 // Text already unlocked && replaced in BrowserWindow,
291 // Don't let this through to the text view.
296 BString currentText
= Text();
297 BTextView::KeyDown(bytes
, numBytes
);
298 // Lock the URL input if it was modified
299 if (!fURLInputGroup
->IsURLInputLocked()
300 && Text() != currentText
)
301 fURLInputGroup
->LockURLInput();
308 URLInputGroup::URLTextView::MakeFocus(bool focus
)
310 // Unlock the URL input if focus was lost.
312 fURLInputGroup
->LockURLInput(false);
314 if (focus
== IsFocus())
317 BTextView::MakeFocus(focus
);
322 fURLInputGroup
->Invalidate();
327 URLInputGroup::URLTextView::MinSize()
330 min
.height
= ceilf(LineHeight(0) + kHorizontalTextRectInset
);
331 // we always add at least one pixel vertical inset top/bottom for
333 min
.width
= min
.height
* 3;
334 return BLayoutUtils::ComposeSize(ExplicitMinSize(), min
);
339 URLInputGroup::URLTextView::MaxSize()
341 BSize
max(MinSize());
342 max
.width
= B_SIZE_UNLIMITED
;
343 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), max
);
348 URLInputGroup::URLTextView::SetUpdateAutoCompleterChoices(bool update
)
350 fUpdateAutoCompleterChoices
= update
;
355 URLInputGroup::URLTextView::InsertText(const char* inText
, int32 inLength
,
356 int32 inOffset
, const text_run_array
* inRuns
)
358 // Filter all line breaks, note that inText is not terminated.
360 if (*inText
== '\n' || *inText
== '\r')
361 BTextView::InsertText(" ", 1, inOffset
, inRuns
);
363 BTextView::InsertText(inText
, 1, inOffset
, inRuns
);
365 BString
filteredText(inText
, inLength
);
366 filteredText
.ReplaceAll('\n', ' ');
367 filteredText
.ReplaceAll('\r', ' ');
368 BTextView::InsertText(filteredText
.String(), inLength
, inOffset
,
372 // Make the base URL part bold.
373 BString
text(Text(), TextLength());
374 int32 baseUrlStart
= text
.FindFirst("://");
375 if (baseUrlStart
>= 0)
379 int32 baseUrlEnd
= text
.FindFirst("/", baseUrlStart
);
381 baseUrlEnd
= TextLength();
385 const rgb_color black
= (rgb_color
) { 0, 0, 0, 255 };
386 const rgb_color gray
= (rgb_color
) { 60, 60, 60, 255 };
387 if (baseUrlStart
> 0)
388 SetFontAndColor(0, baseUrlStart
, &font
, B_FONT_ALL
, &gray
);
389 if (baseUrlEnd
> baseUrlStart
) {
390 font
.SetFace(B_BOLD_FACE
);
391 SetFontAndColor(baseUrlStart
, baseUrlEnd
, &font
, B_FONT_ALL
, &black
);
393 if (baseUrlEnd
< TextLength()) {
394 font
.SetFace(B_REGULAR_FACE
);
395 SetFontAndColor(baseUrlEnd
, TextLength(), &font
, B_FONT_ALL
, &gray
);
398 fURLAutoCompleter
->TextModified(fUpdateAutoCompleterChoices
);
403 URLInputGroup::URLTextView::DeleteText(int32 fromOffset
, int32 toOffset
)
405 BTextView::DeleteText(fromOffset
, toOffset
);
407 fURLAutoCompleter
->TextModified(fUpdateAutoCompleterChoices
);
412 URLInputGroup::URLTextView::_AlignTextRect()
414 // Layout the text rect to be in the middle, normally this means there
415 // is one pixel spacing on each side.
416 BRect
textRect(Bounds());
418 float vInset
= max_c(1,
419 floorf((textRect
.Height() - LineHeight(0)) / 2.0 + 0.5));
420 float hInset
= kHorizontalTextRectInset
;
423 hInset
= be_control_look
->DefaultLabelSpacing();
425 textRect
.InsetBy(hInset
, vInset
);
426 SetTextRect(textRect
);
430 const uint32 kGoBitmapWidth
= 14;
431 const uint32 kGoBitmapHeight
= 14;
432 const color_space kGoBitmapFormat
= B_RGBA32
;
434 const unsigned char kGoBitmapBits
[] = {
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff,
445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x17, 0x17, 0x17, 0x21, 0x49, 0x49, 0x49, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff,
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21, 0x49, 0x49, 0x49, 0xe0, 0x50, 0x50, 0x50, 0xff,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21, 0x49, 0x49, 0x49, 0xe0,
457 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x2f, 0x56, 0x50, 0x50, 0x50, 0xff, 0x4d, 0x4d, 0x4d, 0xed,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21,
460 0x49, 0x49, 0x49, 0xe0, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff,
461 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff,
462 0x50, 0x50, 0x50, 0xff, 0x37, 0x37, 0x37, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21, 0x49, 0x49, 0x49, 0xe0, 0x50, 0x50, 0x50, 0xff,
464 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff,
465 0x50, 0x50, 0x50, 0xff, 0x4b, 0x4b, 0x4b, 0xec, 0x37, 0x37, 0x37, 0x77, 0x00, 0x00, 0x00, 0x02,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x17, 0x17, 0x17, 0x21, 0x49, 0x49, 0x49, 0xe1, 0x50, 0x50, 0x50, 0xff, 0x50, 0x50, 0x50, 0xff,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21,
471 0x49, 0x49, 0x49, 0xe1, 0x50, 0x50, 0x50, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21, 0x49, 0x49, 0x49, 0xe1,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
487 const unsigned char kPlaceholderIcon
[] = {
488 0x6e, 0x63, 0x69, 0x66, 0x04, 0x04, 0x00, 0x66, 0x03, 0x00, 0x3f, 0x80,
489 0x02, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x3d, 0xa6, 0x64, 0xc2, 0x19,
490 0x98, 0x00, 0x00, 0x00, 0x4d, 0xce, 0x64, 0x49, 0xac, 0xcc, 0x00, 0xab,
491 0xd5, 0xff, 0xff, 0x00, 0x6c, 0xd9, 0x02, 0x00, 0x06, 0x02, 0x00, 0x00,
492 0x00, 0x3d, 0x26, 0x64, 0xc2, 0x19, 0x98, 0x00, 0x00, 0x00, 0x4d, 0xce,
493 0x64, 0x49, 0xac, 0xcc, 0x00, 0x80, 0xff, 0x80, 0xff, 0x00, 0xb2, 0x00,
494 0x04, 0x02, 0x04, 0x34, 0x22, 0xbd, 0x9b, 0x22, 0xb8, 0x53, 0x22, 0x28,
495 0x2e, 0x28, 0xb5, 0xef, 0x28, 0xbb, 0x37, 0x34, 0x3a, 0xb8, 0x53, 0x3a,
496 0xbd, 0x9b, 0x3a, 0x40, 0x2e, 0x40, 0xbb, 0x37, 0x40, 0xb5, 0xef, 0x02,
497 0x08, 0xbe, 0xb6, 0xb4, 0xac, 0xc1, 0x46, 0xb4, 0xac, 0xbc, 0x25, 0xb4,
498 0xac, 0xb8, 0x09, 0xb7, 0x35, 0xb9, 0xcf, 0xb5, 0xa0, 0xb8, 0x05, 0xbe,
499 0xb6, 0x35, 0xc2, 0xe5, 0x35, 0xbe, 0xb6, 0x35, 0xc5, 0x68, 0xb8, 0x09,
500 0xc6, 0x36, 0xb8, 0x09, 0xc6, 0x36, 0xb9, 0xcf, 0xc7, 0xca, 0xbe, 0xb6,
501 0xc8, 0xc1, 0xbc, 0x25, 0xc8, 0xc1, 0xc1, 0xb3, 0xc8, 0xc1, 0xc6, 0x3c,
502 0xc5, 0x5b, 0xc4, 0x65, 0xc7, 0x70, 0xc6, 0x3e, 0xbe, 0xb6, 0xc2, 0x0f,
503 0xba, 0x87, 0xc2, 0x0f, 0xbe, 0xb6, 0xc2, 0x0f, 0xb8, 0x05, 0xc5, 0x64,
504 0xb7, 0x37, 0xc5, 0x64, 0xb7, 0x37, 0xc3, 0x9e, 0xb5, 0xa2, 0x02, 0x04,
505 0xb8, 0x09, 0xb7, 0x35, 0xb8, 0x05, 0xbe, 0xb6, 0xb5, 0xf8, 0xb9, 0x0c,
506 0xb4, 0xac, 0xbe, 0xb6, 0xb4, 0xac, 0xbb, 0xba, 0xb4, 0xac, 0xc1, 0xb1,
507 0xb8, 0x09, 0xc6, 0x36, 0xb5, 0xf8, 0xc4, 0x5e, 0xb9, 0xcf, 0xc7, 0xca,
508 0x35, 0xc2, 0xe5, 0x35, 0xc5, 0x68, 0x35, 0xbe, 0xb6, 0x02, 0x04, 0x4d,
509 0x51, 0xc4, 0xf2, 0xbf, 0x04, 0x53, 0x4e, 0xc8, 0xc1, 0xbe, 0x58, 0xc8,
510 0xc1, 0xc1, 0x55, 0xc8, 0xc1, 0xbb, 0x5d, 0xc5, 0x64, 0xb6, 0xd9, 0xc7,
511 0x75, 0xb8, 0xb0, 0xc3, 0x9e, 0xb5, 0x44, 0xc2, 0x0f, 0xba, 0x29, 0xc2,
512 0x0f, 0xb7, 0xa6, 0xc2, 0x0f, 0xbe, 0x58, 0x04, 0x0a, 0x00, 0x01, 0x00,
513 0x12, 0x42, 0x19, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x19,
514 0x98, 0xc6, 0x19, 0x93, 0x44, 0x19, 0xa2, 0x01, 0x17, 0x84, 0x00, 0x04,
515 0x0a, 0x01, 0x01, 0x00, 0x12, 0x42, 0x19, 0x98, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x42, 0x19, 0x98, 0xc7, 0x26, 0x5f, 0x28, 0x96, 0xf9, 0x01,
517 0x17, 0x83, 0x00, 0x04, 0x0a, 0x02, 0x01, 0x01, 0x00, 0x0a, 0x03, 0x02,
521 // #pragma mark - PageIconView
524 class URLInputGroup::PageIconView
: public BView
{
528 BView("page icon view", B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
),
531 SetDrawingMode(B_OP_ALPHA
);
532 SetBlendingMode(B_PIXEL_ALPHA
, B_ALPHA_OVERLAY
);
533 SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR
);
541 virtual void Draw(BRect updateRect
)
543 BRect
bounds(Bounds());
544 BRect
iconBounds(0, 0, 15, 15);
546 floorf((bounds
.left
+ bounds
.right
547 - (iconBounds
.left
+ iconBounds
.right
)) / 2 + 0.5f
),
548 floorf((bounds
.top
+ bounds
.bottom
549 - (iconBounds
.top
+ iconBounds
.bottom
)) / 2 + 0.5f
));
550 DrawBitmap(fIcon
, fIcon
->Bounds(), iconBounds
,
551 B_FILTER_BITMAP_BILINEAR
);
554 virtual BSize
MinSize()
556 return BSize(18, 18);
559 virtual BSize
MaxSize()
561 return BSize(B_SIZE_UNLIMITED
, B_SIZE_UNLIMITED
);
564 virtual BSize
PreferredSize()
569 void SetIcon(const BBitmap
* icon
)
573 fIcon
= new BBitmap(icon
);
575 fIcon
= new BBitmap(BRect(0, 0, 15, 15), B_RGB32
);
576 BIconUtils::GetVectorIcon(kPlaceholderIcon
,
577 sizeof(kPlaceholderIcon
), fIcon
);
587 // #pragma mark - URLInputGroup
590 URLInputGroup::URLInputGroup(BMessage
* goMessage
)
592 BGroupView(B_HORIZONTAL
, 0.0),
593 fWindowActive(false),
596 GroupLayout()->SetInsets(2, 2, 2, 2);
598 fIconView
= new PageIconView();
599 GroupLayout()->AddView(fIconView
, 0.0f
);
601 fTextView
= new URLTextView(this);
604 AddChild(new BSeparatorView(B_VERTICAL
, B_PLAIN_BORDER
));
606 // TODO: Fix in Haiku, no in-built support for archived BBitmaps from
608 // fGoButton = new BitmapButton("kActionGo", NULL);
609 fGoButton
= new BitmapButton(kGoBitmapBits
, kGoBitmapWidth
,
610 kGoBitmapHeight
, kGoBitmapFormat
, goMessage
);
611 GroupLayout()->AddView(fGoButton
, 0.0f
);
613 SetFlags(Flags() | B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
);
614 SetLowColor(ViewColor());
615 SetViewColor(fTextView
->ViewColor());
617 SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH
,
618 B_ALIGN_VERTICAL_CENTER
));
623 URLInputGroup::~URLInputGroup()
629 URLInputGroup::AttachedToWindow()
631 BGroupView::AttachedToWindow();
632 fWindowActive
= Window()->IsActive();
637 URLInputGroup::WindowActivated(bool active
)
639 BGroupView::WindowActivated(active
);
640 if (fWindowActive
!= active
) {
641 fWindowActive
= active
;
648 URLInputGroup::Draw(BRect updateRect
)
650 BRect
bounds(Bounds());
651 rgb_color
base(LowColor());
653 if (fWindowActive
&& fTextView
->IsFocus())
654 flags
|= BControlLook::B_FOCUSED
;
655 be_control_look
->DrawTextControlBorder(this, bounds
, updateRect
, base
,
661 URLInputGroup::MakeFocus(bool focus
)
663 // Forward this to the text view, we never accept focus ourselves.
664 fTextView
->MakeFocus(focus
);
669 URLInputGroup::TextView() const
676 URLInputGroup::SetText(const char* text
)
678 // Ignore setting the text, if the input is locked.
682 if (!text
|| !Text() || strcmp(Text(), text
) != 0) {
683 fTextView
->SetUpdateAutoCompleterChoices(false);
684 fTextView
->SetText(text
);
685 fTextView
->SetUpdateAutoCompleterChoices(true);
691 URLInputGroup::Text() const
693 return fTextView
->Text();
698 URLInputGroup::GoButton() const
705 URLInputGroup::SetPageIcon(const BBitmap
* icon
)
707 fIconView
->SetIcon(icon
);
712 URLInputGroup::IsURLInputLocked() const
719 URLInputGroup::LockURLInput(bool lock
)