btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / aboutsystem / HyperTextView.cpp
blobd1bc4e6e4a1da73643f31f99214980d4c210569d
1 /*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT license.
4 */
6 #include "HyperTextView.h"
8 #include <Cursor.h>
9 #include <Message.h>
10 #include <Region.h>
11 #include <Window.h>
13 #include <ObjectList.h>
16 // #pragma mark - HyperTextAction
19 HyperTextAction::HyperTextAction()
24 HyperTextAction::~HyperTextAction()
29 void
30 HyperTextAction::MouseOver(HyperTextView* view, BPoint where, BMessage* message)
32 BCursor linkCursor(B_CURSOR_ID_FOLLOW_LINK);
33 view->SetViewCursor(&linkCursor);
37 void
38 HyperTextAction::Clicked(HyperTextView* view, BPoint where, BMessage* message)
43 // #pragma mark - HyperTextView
46 struct HyperTextView::ActionInfo {
47 ActionInfo(int32 startOffset, int32 endOffset, HyperTextAction* action)
49 startOffset(startOffset),
50 endOffset(endOffset),
51 action(action)
55 ~ActionInfo()
57 delete action;
60 static int Compare(const ActionInfo* a, const ActionInfo* b)
62 return a->startOffset - b->startOffset;
65 static int CompareEqualIfIntersecting(const ActionInfo* a,
66 const ActionInfo* b)
68 if (a->startOffset < b->endOffset && b->startOffset < a->endOffset)
69 return 0;
70 return a->startOffset - b->startOffset;
73 int32 startOffset;
74 int32 endOffset;
75 HyperTextAction* action;
80 class HyperTextView::ActionInfoList
81 : public BObjectList<HyperTextView::ActionInfo> {
82 public:
83 ActionInfoList(int32 itemsPerBlock = 20, bool owning = false)
84 : BObjectList<HyperTextView::ActionInfo>(itemsPerBlock, owning)
90 HyperTextView::HyperTextView(const char* name, uint32 flags)
92 BTextView(name, flags),
93 fActionInfos(new ActionInfoList(100, true))
98 HyperTextView::HyperTextView(BRect frame, const char* name, BRect textRect,
99 uint32 resizeMask, uint32 flags)
101 BTextView(frame, name, textRect, resizeMask, flags),
102 fActionInfos(new ActionInfoList(100, true))
107 HyperTextView::~HyperTextView()
109 delete fActionInfos;
113 void
114 HyperTextView::MouseDown(BPoint where)
116 // We eat all mouse button events.
118 BTextView::MouseDown(where);
122 void
123 HyperTextView::MouseUp(BPoint where)
125 BMessage* message = Window()->CurrentMessage();
127 HyperTextAction* action = _ActionAt(where);
128 if (action != NULL)
129 action->Clicked(this, where, message);
131 BTextView::MouseUp(where);
135 void
136 HyperTextView::MouseMoved(BPoint where, uint32 transit,
137 const BMessage* dragMessage)
139 BMessage* message = Window()->CurrentMessage();
141 uint32 buttons;
142 HyperTextAction* action;
143 if (message->FindInt32("buttons", (int32*)&buttons) == B_OK
144 && buttons == 0 && (action = _ActionAt(where)) != NULL) {
145 action->MouseOver(this, where, message);
146 return;
149 BTextView::MouseMoved(where, transit, dragMessage);
153 void
154 HyperTextView::AddHyperTextAction(int32 startOffset, int32 endOffset,
155 HyperTextAction* action)
157 if (action == NULL || startOffset >= endOffset) {
158 delete action;
159 return;
162 fActionInfos->BinaryInsert(new ActionInfo(startOffset, endOffset, action),
163 ActionInfo::Compare);
165 // TODO: Of course we should check for overlaps...
169 void
170 HyperTextView::InsertHyperText(const char* inText, HyperTextAction* action,
171 const text_run_array* inRuns)
173 int32 startOffset = TextLength();
174 Insert(inText, inRuns);
175 int32 endOffset = TextLength();
177 AddHyperTextAction(startOffset, endOffset, action);
181 void
182 HyperTextView::InsertHyperText(const char* inText, int32 inLength,
183 HyperTextAction* action, const text_run_array* inRuns)
185 int32 startOffset = TextLength();
186 Insert(inText, inLength, inRuns);
187 int32 endOffset = TextLength();
189 AddHyperTextAction(startOffset, endOffset, action);
193 HyperTextAction*
194 HyperTextView::_ActionAt(const BPoint& where) const
196 int32 offset = OffsetAt(where);
198 ActionInfo pointer(offset, offset + 1, NULL);
200 const ActionInfo* action = fActionInfos->BinarySearch(pointer,
201 ActionInfo::CompareEqualIfIntersecting);
202 if (action != NULL) {
203 // verify that the text region was hit
204 BRegion textRegion;
205 GetTextRegion(action->startOffset, action->endOffset, &textRegion);
206 if (textRegion.Contains(where))
207 return action->action;
210 return NULL;