1 /* 2 * Copyright 2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "PropertyItemView.h" 10 11 #include <stdio.h> 12 13 #include <Message.h> 14 #include <Window.h> 15 16 #include "support_ui.h" 17 #include "ui_defines.h" 18 19 #include "CommonPropertyIDs.h" 20 #include "Property.h" 21 #include "PropertyEditorFactory.h" 22 #include "PropertyEditorView.h" 23 #include "PropertyListView.h" 24 25 // constructor 26 PropertyItemView::PropertyItemView(Property* property) 27 : BView(BRect(0.0, 0.0, 10.0, 10.0), "property item", 28 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, 29 B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE), 30 fParent(NULL), 31 fEditorView(/*factory->*/EditorFor(property)), 32 // NOTE: can be NULL if property is NULL or unkown 33 fSelected(false), 34 fEnabled(true), 35 fLabelWidth(0.0) 36 { 37 if (fEditorView) { 38 AddChild(fEditorView); 39 fEditorView->SetItemView(this); 40 } 41 } 42 43 // destructor 44 PropertyItemView::~PropertyItemView() 45 { 46 } 47 48 // Draw 49 void 50 PropertyItemView::Draw(BRect updateRect) 51 { 52 const Property* property = GetProperty(); 53 if (property && fParent) { 54 BRect b(Bounds()); 55 56 // just draw background and label 57 rgb_color labelColor = LowColor(); 58 if (fEnabled) 59 labelColor = tint_color(labelColor, B_DARKEN_MAX_TINT); 60 else 61 labelColor = tint_color(labelColor, B_DISABLED_LABEL_TINT); 62 63 SetHighColor(labelColor); 64 BFont font; 65 GetFont(&font); 66 67 BString truncated(name_for_id(property->Identifier())); 68 font.TruncateString(&truncated, B_TRUNCATE_MIDDLE, fLabelWidth - 10.0); 69 70 font_height fh; 71 font.GetHeight(&fh); 72 73 FillRect(BRect(b.left, b.top, b.left + fLabelWidth, b.bottom), B_SOLID_LOW); 74 DrawString(truncated.String(), BPoint(b.left + 5.0, 75 floorf(b.top + b.Height() / 2.0 76 + fh.ascent / 2.0))); 77 78 // draw a "separator" line behind the label 79 SetHighColor(tint_color(LowColor(), B_DARKEN_1_TINT)); 80 StrokeLine(BPoint(b.left + fLabelWidth - 1.0, b.top), 81 BPoint(b.left + fLabelWidth - 1.0, b.bottom), B_SOLID_HIGH); 82 } 83 } 84 85 // FrameResized 86 void 87 PropertyItemView::FrameResized(float width, float height) 88 { 89 if (fEditorView) { 90 fEditorView->MoveTo(fLabelWidth, 0.0); 91 fEditorView->ResizeTo(width - fLabelWidth, height); 92 fEditorView->FrameResized(fEditorView->Bounds().Width(), 93 fEditorView->Bounds().Height()); 94 } 95 } 96 97 // MakeFocus 98 void 99 PropertyItemView::MakeFocus(bool focused) 100 { 101 if (fEditorView) 102 fEditorView->MakeFocus(focused); 103 } 104 105 // MouseDown 106 void 107 PropertyItemView::MouseDown(BPoint where) 108 { 109 if (fParent) { 110 // select ourself 111 fParent->Select(this); 112 if (fEditorView) 113 fEditorView->MakeFocus(true); 114 115 if (BMessage* message = Window()->CurrentMessage()) { 116 int32 clicks; 117 if (message->FindInt32("clicks", &clicks) >= B_OK) { 118 if (clicks >= 2) 119 fParent->DoubleClicked(this); 120 else 121 fParent->Clicked(this); 122 } 123 } 124 } 125 } 126 127 // MouseUp 128 void 129 PropertyItemView::MouseUp(BPoint where) 130 { 131 } 132 133 // MouseMoved 134 void 135 PropertyItemView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) 136 { 137 } 138 139 // PreferredHeight 140 float 141 PropertyItemView::PreferredHeight() const 142 { 143 font_height fh; 144 GetFontHeight(&fh); 145 146 float height = floorf(4.0 + fh.ascent + fh.descent); 147 if (fEditorView) 148 height = max_c(height, fEditorView->PreferredHeight()); 149 150 return height; 151 } 152 153 // PreferredLabelWidth 154 float 155 PropertyItemView::PreferredLabelWidth() const 156 { 157 float width = 0.0; 158 if (const Property* property = GetProperty()) 159 width = ceilf(StringWidth(name_for_id(property->Identifier())) + 10.0); 160 return width; 161 } 162 163 // SetLabelWidth 164 void 165 PropertyItemView::SetLabelWidth(float width) 166 { 167 if (width < 0.0) 168 width = 0.0; 169 /* if (fEditorView && width > Bounds().Width() - fEditorView->Bounds().Width()) 170 width = Bounds().Width() - fEditorView->Bounds().Width(); 171 else if (width > Bounds().Width()) 172 width = Bounds().Width();*/ 173 174 fLabelWidth = width; 175 } 176 177 // SetSelected 178 void 179 PropertyItemView::SetSelected(bool selected) 180 { 181 fSelected = selected; 182 _UpdateLowColor(); 183 } 184 185 // SetEnabled 186 void 187 PropertyItemView::SetEnabled(bool enabled) 188 { 189 if (fEnabled != enabled) { 190 fEnabled = enabled; 191 fEditorView->SetEnabled(fEnabled); 192 } 193 } 194 195 // IsFocused 196 bool 197 PropertyItemView::IsFocused() const 198 { 199 if (fEditorView) 200 return fEditorView->IsFocused(); 201 return false; 202 } 203 204 // GetProperty 205 Property* 206 PropertyItemView::GetProperty() const 207 { 208 if (fEditorView) 209 return fEditorView->GetProperty(); 210 return NULL; 211 } 212 213 // SetProperty 214 bool 215 PropertyItemView::AdoptProperty(Property* property) 216 { 217 if (fEditorView && fEditorView->AdoptProperty(property)) { 218 _UpdateLowColor(); 219 return true; 220 } 221 return false; 222 } 223 224 // SetListView 225 void 226 PropertyItemView::SetListView(PropertyListView* parent) 227 { 228 fParent = parent; 229 _UpdateLowColor(); 230 } 231 232 // UpdateObject 233 void 234 PropertyItemView::UpdateObject() 235 { 236 if (fParent && fEditorView) { 237 if (const Property* p = fEditorView->GetProperty()) 238 fParent->UpdateObject(p->Identifier()); 239 } 240 } 241 242 // #pragma mark - 243 244 // _UpdateLowColor 245 void 246 PropertyItemView::_UpdateLowColor() 247 { 248 rgb_color lowColor = fParent ? fParent->LowColor() : kWhite; 249 if (fSelected) 250 lowColor = tint_color(lowColor, B_DARKEN_2_TINT); 251 252 if (lowColor != LowColor()) { 253 SetLowColor(lowColor); 254 Invalidate(); 255 } 256 } 257 258