2 * Copyright 2002-2012, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
11 #include "StatusView.h"
18 #include <CharacterSet.h>
19 #include <CharacterSetRoster.h>
20 #include <ControlLook.h>
23 #include <PopUpMenu.h>
24 #include <ScrollView.h>
25 #include <StringView.h>
28 #include <tracker_private.h>
31 #include "Constants.h"
34 const float kHorzSpacing
= 5.f
;
35 #define UTF8_EXPAND_ARROW "\xe2\x96\xbe"
37 using namespace BPrivate
;
40 #undef B_TRANSLATION_CONTEXT
41 #define B_TRANSLATION_CONTEXT "StatusView"
44 StatusView::StatusView(BScrollView
* scrollView
)
46 BView(BRect(), "statusview",
47 B_FOLLOW_BOTTOM
| B_FOLLOW_LEFT
, B_WILL_DRAW
),
48 fScrollView(scrollView
),
49 fPreferredSize(0., 0.),
53 memset(fCellWidth
, 0, sizeof(fCellWidth
));
57 StatusView::~StatusView()
63 StatusView::AttachedToWindow()
65 SetFont(be_plain_font
);
68 BMessage
message(UPDATE_STATUS
);
69 message
.AddInt32("line", 1);
70 message
.AddInt32("column", 1);
71 message
.AddString("encoding", "");
74 BScrollBar
* scrollBar
= fScrollView
->ScrollBar(B_HORIZONTAL
);
75 MoveTo(0., scrollBar
->Frame().top
);
77 rgb_color color
= B_TRANSPARENT_COLOR
;
78 BView
* parent
= Parent();
80 color
= parent
->ViewColor();
82 if (color
== B_TRANSPARENT_COLOR
)
83 color
= ui_color(B_PANEL_BACKGROUND_COLOR
);
92 StatusView::GetPreferredSize(float* _width
, float* _height
)
94 _ValidatePreferredSize();
97 *_width
= fPreferredSize
.width
;
100 *_height
= fPreferredSize
.height
;
105 StatusView::ResizeToPreferred()
108 GetPreferredSize(&width
, &height
);
110 if (Bounds().Width() > width
)
111 width
= Bounds().Width();
113 BView::ResizeTo(width
, height
);
118 StatusView::Draw(BRect updateRect
)
120 if (fPreferredSize
.width
<= 0)
123 if (be_control_look
!= NULL
) {
124 BRect
bounds(Bounds());
125 be_control_look
->DrawMenuBarBackground(this,
126 bounds
, updateRect
, ViewColor());
129 BRect
bounds(Bounds());
130 rgb_color highColor
= HighColor();
131 SetHighColor(tint_color(ViewColor(), B_DARKEN_2_TINT
));
132 StrokeLine(bounds
.LeftTop(), bounds
.RightTop());
134 float x
= bounds
.left
;
135 for (size_t i
= 0; i
< kStatusCellCount
- 1; i
++) {
137 StrokeLine(BPoint(x
, bounds
.top
+ 3), BPoint(x
, bounds
.bottom
- 3));
140 SetLowColor(ViewColor());
141 SetHighColor(highColor
);
143 font_height fontHeight
;
144 GetFontHeight(&fontHeight
);
147 float y
= (bounds
.bottom
+ bounds
.top
148 + ceilf(fontHeight
.ascent
) - ceilf(fontHeight
.descent
)) / 2;
150 for (size_t i
= 0; i
< kStatusCellCount
; i
++) {
151 if (fCellText
[i
].Length() == 0)
153 DrawString(fCellText
[i
], BPoint(x
+ kHorzSpacing
, y
));
160 StatusView::MouseDown(BPoint where
)
162 if (where
.x
< fCellWidth
[kPositionCell
]) {
167 if (!fReadOnly
|| !fCanUnlock
)
170 float left
= fCellWidth
[kPositionCell
] + fCellWidth
[kEncodingCell
];
175 BMessage
* message
= Window()->CurrentMessage();
177 && message
->FindInt32("clicks", &clicks
) == B_OK
&& clicks
> 1)
180 BPopUpMenu
*menu
= new BPopUpMenu(B_EMPTY_STRING
, false, false);
181 menu
->AddItem(new BMenuItem(B_TRANSLATE("Unlock file"),
182 new BMessage(UNLOCK_FILE
)));
184 where
.y
= Bounds().bottom
;
186 ConvertToScreen(&where
);
187 menu
->SetTargetForItems(this);
188 menu
->Go(where
, true, true, true);
193 StatusView::SetStatus(BMessage
* message
)
195 int32 line
= 0, column
= 0;
196 if (B_OK
== message
->FindInt32("line", &line
)
197 && B_OK
== message
->FindInt32("column", &column
))
200 snprintf(info
, sizeof(info
),
201 B_TRANSLATE("line %d, column %d"), line
, column
);
202 fCellText
[kPositionCell
].SetTo(info
);
205 if (B_OK
== message
->FindString("encoding", &fEncoding
)) {
206 // sometime corresponding Int-32 "encoding" attrib is read as string :(
207 if (fEncoding
.Length() == 0
208 || fEncoding
.Compare("\xff\xff") == 0
209 || fEncoding
.Compare("UTF-8") == 0)
211 // do not display default UTF-8 encoding
212 fCellText
[kEncodingCell
].Truncate(0);
213 fEncoding
.Truncate(0);
215 const BCharacterSet
* charset
216 = BCharacterSetRoster::FindCharacterSetByName(fEncoding
);
217 fCellText
[kEncodingCell
]
218 = charset
!= NULL
? charset
->GetPrintName() : "";
222 bool modified
= false;
225 if (B_OK
== message
->FindBool("modified", &modified
) && modified
) {
226 fCellText
[kFileStateCell
] = B_TRANSLATE("Modified");
227 } else if (B_OK
== message
->FindBool("readOnly", &fReadOnly
) && fReadOnly
) {
228 fCellText
[kFileStateCell
] = B_TRANSLATE("Read-only");
229 if (B_OK
== message
->FindBool("canUnlock", &fCanUnlock
) && fCanUnlock
)
230 fCellText
[kFileStateCell
] << " " UTF8_EXPAND_ARROW
;
232 fCellText
[kFileStateCell
].Truncate(0);
234 _ValidatePreferredSize();
240 StatusView::SetRef(const entry_ref
& ref
)
247 StatusView::_ValidatePreferredSize()
249 float orgWidth
= fPreferredSize
.width
;
251 fPreferredSize
.width
= 0.f
;
252 for (size_t i
= 0; i
< kStatusCellCount
; i
++) {
253 if (fCellText
[i
].Length() == 0) {
257 float width
= ceilf(StringWidth(fCellText
[i
]));
259 width
+= kHorzSpacing
* 2;
260 if (width
> fCellWidth
[i
] || i
!= kPositionCell
)
261 fCellWidth
[i
] = width
;
262 fPreferredSize
.width
+= fCellWidth
[i
];
266 font_height fontHeight
;
267 GetFontHeight(&fontHeight
);
269 fPreferredSize
.height
= ceilf(fontHeight
.ascent
+ fontHeight
.descent
270 + fontHeight
.leading
);
272 if (fPreferredSize
.height
< B_H_SCROLL_BAR_HEIGHT
)
273 fPreferredSize
.height
= B_H_SCROLL_BAR_HEIGHT
;
275 float delta
= fPreferredSize
.width
- orgWidth
;
277 BScrollBar
* scrollBar
= fScrollView
->ScrollBar(B_HORIZONTAL
);
278 scrollBar
->ResizeBy(-delta
, 0);
279 scrollBar
->MoveBy(delta
, 0);
284 StatusView::_ShowDirMenu()
287 status_t status
= entry
.SetTo(&fRef
);
289 if (status
!= B_OK
|| !entry
.Exists())
292 BPrivate::BDirMenu
* menu
= new BDirMenu(NULL
,
293 BMessenger(kTrackerSignature
), B_REFS_RECEIVED
);
295 menu
->Populate(&entry
, Window(), false, false, true, false, true);
297 BPoint point
= Bounds().LeftBottom();
299 ConvertToScreen(&point
);
300 BRect
clickToOpenRect(Bounds());
301 ConvertToScreen(&clickToOpenRect
);
302 menu
->Go(point
, true, true, clickToOpenRect
);