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 #include "InputTextView.h" 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include <String.h> 15 16 // constructor 17 InputTextView::InputTextView(BRect frame, const char* name, 18 BRect textRect, 19 uint32 resizingMode, 20 uint32 flags) 21 : BTextView(frame, name, textRect, resizingMode, flags), 22 fWasFocus(false) 23 { 24 SetWordWrap(false); 25 } 26 27 // destructor 28 InputTextView::~InputTextView() 29 { 30 } 31 32 // MouseDown 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 // MouseUp 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 // KeyDown 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 // MakeFocus 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 // Invoke 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 // #pragma mark - 118 119 // Select 120 void 121 InputTextView::Select(int32 start, int32 finish) 122 { 123 BTextView::Select(start, finish); 124 125 _CheckTextRect(); 126 } 127 128 // InsertText 129 void 130 InputTextView::InsertText(const char* inText, int32 inLength, int32 inOffset, 131 const text_run_array* inRuns) 132 { 133 BTextView::InsertText(inText, inLength, inOffset, inRuns); 134 135 _CheckTextRect(); 136 } 137 138 // DeleteText 139 void 140 InputTextView::DeleteText(int32 fromOffset, int32 toOffset) 141 { 142 BTextView::DeleteText(fromOffset, toOffset); 143 144 _CheckTextRect(); 145 } 146 147 // #pragma mark - 148 149 // _CheckTextRect 150 void 151 InputTextView::_CheckTextRect() 152 { 153 // update text rect and make sure 154 // the cursor/selection is in view 155 BRect textRect(TextRect()); 156 float width = ceilf(StringWidth(Text()) + 2.0); 157 if (textRect.Width() < width) { 158 textRect.right = textRect.left + width; 159 SetTextRect(textRect); 160 ScrollToSelection(); 161 } 162 } 163