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 // MouseUp 127 void 128 PropertyItemView::MouseUp(BPoint where) 129 { 130 } 131 132 // MouseMoved 133 void 134 PropertyItemView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) 135 { 136 } 137 138 // PreferredHeight 139 float 140 PropertyItemView::PreferredHeight() const 141 { 142 font_height fh; 143 GetFontHeight(&fh); 144 145 float height = floorf(4.0 + fh.ascent + fh.descent); 146 if (fEditorView) 147 height = max_c(height, fEditorView->PreferredHeight()); 148 149 return height; 150 } 151 152 // PreferredLabelWidth 153 float 154 PropertyItemView::PreferredLabelWidth() const 155 { 156 float width = 0.0; 157 if (const Property* property = GetProperty()) 158 width = ceilf(StringWidth(name_for_id(property->Identifier())) + 10.0); 159 return width; 160 } 161 162 // SetLabelWidth 163 void 164 PropertyItemView::SetLabelWidth(float width) 165 { 166 if (width < 0.0) 167 width = 0.0; 168 /* if (fEditorView && width > Bounds().Width() - fEditorView->Bounds().Width()) 169 width = Bounds().Width() - fEditorView->Bounds().Width(); 170 else if (width > Bounds().Width()) 171 width = Bounds().Width();*/ 172 173 fLabelWidth = width; 174 } 175 176 // SetSelected 177 void 178 PropertyItemView::SetSelected(bool selected) 179 { 180 fSelected = selected; 181 _UpdateLowColor(); 182 } 183 184 // SetEnabled 185 void 186 PropertyItemView::SetEnabled(bool enabled) 187 { 188 if (fEnabled != enabled) { 189 fEnabled = enabled; 190 fEditorView->SetEnabled(fEnabled); 191 } 192 } 193 194 // IsFocused 195 bool 196 PropertyItemView::IsFocused() const 197 { 198 if (fEditorView) 199 return fEditorView->IsFocused(); 200 return false; 201 } 202 203 // GetProperty 204 Property* 205 PropertyItemView::GetProperty() const 206 { 207 if (fEditorView) 208 return fEditorView->GetProperty(); 209 return NULL; 210 } 211 212 // SetProperty 213 bool 214 PropertyItemView::AdoptProperty(Property* property) 215 { 216 if (fEditorView && fEditorView->AdoptProperty(property)) { 217 _UpdateLowColor(); 218 return true; 219 } 220 return false; 221 } 222 223 // SetListView 224 void 225 PropertyItemView::SetListView(PropertyListView* parent) 226 { 227 fParent = parent; 228 _UpdateLowColor(); 229 } 230 231 // UpdateObject 232 void 233 PropertyItemView::UpdateObject() 234 { 235 if (fParent && fEditorView) { 236 if (const Property* p = fEditorView->GetProperty()) 237 fParent->UpdateObject(p->Identifier()); 238 } 239 } 240 241 // #pragma mark - 242 243 // _UpdateLowColor 244 void 245 PropertyItemView::_UpdateLowColor() 246 { 247 rgb_color lowColor = fParent ? fParent->LowColor() : kWhite; 248 if (fSelected) 249 lowColor = tint_color(lowColor, B_DARKEN_2_TINT); 250 251 if (lowColor != LowColor()) { 252 SetLowColor(lowColor); 253 Invalidate(); 254 } 255 } 256 257