1 /* 2 * Copyright 2006 Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus, superstippi@gmx.de 7 */ 8 9 10 #include "InputTextView.h" 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 15 #include <String.h> 16 17 18 InputTextView::InputTextView(BRect frame, const char* name, BRect textRect, 19 uint32 resizingMode, uint32 flags) 20 : 21 BTextView(frame, name, textRect, resizingMode, flags), 22 fWasFocus(false) 23 { 24 SetWordWrap(false); 25 } 26 27 28 InputTextView::~InputTextView() 29 { 30 } 31 32 33 void 34 InputTextView::MouseDown(BPoint where) 35 { 36 // enforce the behaviour of a typical BTextControl 37 // only let the BTextView handle mouse up/down when 38 // it already had focus 39 fWasFocus = IsFocus(); 40 if (fWasFocus) { 41 BTextView::MouseDown(where); 42 } else { 43 // forward click 44 if (BView* view = Parent()) { 45 view->MouseDown(ConvertToParent(where)); 46 } 47 } 48 } 49 50 51 void 52 InputTextView::MouseUp(BPoint where) 53 { 54 // enforce the behaviour of a typical BTextControl 55 // only let the BTextView handle mouse up/down when 56 // it already had focus 57 if (fWasFocus) 58 BTextView::MouseUp(where); 59 } 60 61 62 void 63 InputTextView::KeyDown(const char* bytes, int32 numBytes) 64 { 65 bool handled = true; 66 if (numBytes > 0) { 67 switch (bytes[0]) { 68 case B_ESCAPE: 69 // revert any typing changes 70 RevertChanges(); 71 break; 72 case B_TAB: 73 // skip BTextView implementation 74 BView::KeyDown(bytes, numBytes); 75 // fall through 76 case B_RETURN: 77 ApplyChanges(); 78 break; 79 default: 80 handled = false; 81 break; 82 } 83 } 84 if (!handled) 85 BTextView::KeyDown(bytes, numBytes); 86 } 87 88 89 void 90 InputTextView::MakeFocus(bool focus) 91 { 92 if (focus != IsFocus()) { 93 if (BView* view = Parent()) 94 view->Invalidate(); 95 BTextView::MakeFocus(focus); 96 if (focus) 97 SelectAll(); 98 } 99 } 100 101 102 status_t 103 InputTextView::Invoke(BMessage* message) 104 { 105 if (!message) 106 message = Message(); 107 108 if (message) { 109 BMessage copy(*message); 110 copy.AddInt64("when", system_time()); 111 copy.AddPointer("source", (BView*)this); 112 return BInvoker::Invoke(©); 113 } 114 return B_BAD_VALUE; 115 } 116 117 118 // #pragma mark - 119 120 121 void 122 InputTextView::Select(int32 start, int32 finish) 123 { 124 BTextView::Select(start, finish); 125 126 _CheckTextRect(); 127 } 128 129 130 void 131 InputTextView::InsertText(const char* inText, int32 inLength, int32 inOffset, 132 const text_run_array* inRuns) 133 { 134 BTextView::InsertText(inText, inLength, inOffset, inRuns); 135 136 _CheckTextRect(); 137 } 138 139 140 void 141 InputTextView::DeleteText(int32 fromOffset, int32 toOffset) 142 { 143 BTextView::DeleteText(fromOffset, toOffset); 144 145 _CheckTextRect(); 146 } 147 148 149 // #pragma mark - 150 151 152 void 153 InputTextView::_CheckTextRect() 154 { 155 // update text rect and make sure 156 // the cursor/selection is in view 157 BRect textRect(TextRect()); 158 float width = ceilf(StringWidth(Text()) + 2.0); 159 if (textRect.Width() < width) { 160 textRect.right = textRect.left + width; 161 SetTextRect(textRect); 162 ScrollToSelection(); 163 } 164 } 165