1506 |
if (!_tf.is_horizontally_resizable) |
if (!_tf.is_horizontally_resizable) |
1507 |
size.width = _bounds.size.width; |
size.width = _bounds.size.width; |
1508 |
else |
else |
1509 |
{ |
size.width += 2 * _textContainerInset.width; |
|
size.width += 2 * _textContainerInset.width; |
|
|
|
|
|
/* |
|
|
The +1 is to make sure that we always have one extra point on the right |
|
|
where we can draw the insertion pointer for a character that touches |
|
|
the right edge. This is a bit of a hack, but the insertion pointer |
|
|
often disappears in field editors without this. |
|
|
*/ |
|
|
if (!_textContainerInset.width) |
|
|
size.width += 1; |
|
|
} |
|
1510 |
|
|
1511 |
if (!_tf.is_vertically_resizable) |
if (!_tf.is_vertically_resizable) |
1512 |
size.height = _bounds.size.height; |
size.height = _bounds.size.height; |
2293 |
*/ |
*/ |
2294 |
-(void) scrollRangeToVisible: (NSRange)aRange |
-(void) scrollRangeToVisible: (NSRange)aRange |
2295 |
{ |
{ |
2296 |
NSRect rect; |
NSRect rect, r; |
2297 |
|
NSView *cv; |
2298 |
|
float width; |
2299 |
|
NSPoint p0, p1; |
2300 |
|
|
2301 |
/* |
/* |
2302 |
Make sure that our size is up-to-date. If the scroll is in response to |
Make sure that our size is up-to-date. If the scroll is in response to |
2311 |
if (aRange.length > 0) |
if (aRange.length > 0) |
2312 |
{ |
{ |
2313 |
aRange.length = 1; |
aRange.length = 1; |
2314 |
[self scrollRectToVisible: |
rect = [self rectForCharacterRange: aRange]; |
2315 |
[self rectForCharacterRange: aRange]]; |
} |
2316 |
|
else |
2317 |
|
{ |
2318 |
|
rect = [_layoutManager |
2319 |
|
insertionPointRectForCharacterIndex: aRange.location |
2320 |
|
inTextContainer: _textContainer]; |
2321 |
|
rect.origin.x += _textContainerOrigin.x; |
2322 |
|
rect.origin.y += _textContainerOrigin.y; |
2323 |
|
} |
2324 |
|
|
2325 |
|
cv = [self superview]; |
2326 |
|
|
2327 |
|
/* |
2328 |
|
If we are a non-rich-text field editor in a clip view, we use some |
2329 |
|
magic to get scrolling to behave better; if not, just scroll and return. |
2330 |
|
*/ |
2331 |
|
if (!_tf.is_field_editor || _tf.is_rich_text |
2332 |
|
|| ![cv isKindOfClass: [NSClipView class]]) |
2333 |
|
{ |
2334 |
|
[self scrollRectToVisible: rect]; |
2335 |
|
return; |
2336 |
|
} |
2337 |
|
|
2338 |
|
/* |
2339 |
|
The basic principle is that we want to keep as much text as possible |
2340 |
|
visible, and we want the text to appear to keep its alignment. This is |
2341 |
|
especially important for centered text where the auto-scrolling will |
2342 |
|
scroll so it appears right- or left-aligned if we don't do anything here. |
2343 |
|
We also want to avoid spurious scrolling when the user is just moving |
2344 |
|
the insertion point. |
2345 |
|
*/ |
2346 |
|
|
2347 |
|
width = [cv frame].size.width; |
2348 |
|
|
2349 |
|
/* Get the left and right edges of the text. */ |
2350 |
|
r = [_layoutManager |
2351 |
|
insertionPointRectForCharacterIndex: 0 |
2352 |
|
inTextContainer: _textContainer]; |
2353 |
|
p0 = r.origin; |
2354 |
|
r = [_layoutManager |
2355 |
|
insertionPointRectForCharacterIndex: [_textStorage length] |
2356 |
|
inTextContainer: _textContainer]; |
2357 |
|
p1 = r.origin; |
2358 |
|
p1.x += r.size.width; |
2359 |
|
|
2360 |
|
/* We only try to be smart for single-line text. */ |
2361 |
|
if (p0.y != p1.y) |
2362 |
|
{ |
2363 |
|
[self scrollRectToVisible: rect]; |
2364 |
return; |
return; |
2365 |
} |
} |
2366 |
|
|
2367 |
rect = [_layoutManager insertionPointRectForCharacterIndex: aRange.location |
p0.x += _textContainerOrigin.x; |
2368 |
inTextContainer: _textContainer]; |
p1.x += _textContainerOrigin.x; |
2369 |
rect.origin.x += _textContainerOrigin.x; |
switch ([self alignment]) |
2370 |
rect.origin.y += _textContainerOrigin.y; |
{ |
2371 |
|
case NSLeftTextAlignment: |
2372 |
|
case NSNaturalTextAlignment: /* TODO? check default writing direction |
2373 |
|
for language? */ |
2374 |
|
case NSJustifiedTextAlignment: |
2375 |
|
/* We don't want blank space to the right of the text; scroll |
2376 |
|
further to the left if possible. */ |
2377 |
|
p1.x -= width; |
2378 |
|
if (p1.x < 0) |
2379 |
|
p1.x = 0; |
2380 |
|
|
2381 |
|
if (p1.x < rect.origin.x) |
2382 |
|
{ |
2383 |
|
rect.size.width += rect.origin.x - p1.x; |
2384 |
|
rect.origin.x = p1.x; |
2385 |
|
} |
2386 |
|
|
2387 |
|
break; |
2388 |
|
|
2389 |
|
case NSRightTextAlignment: |
2390 |
|
/* We don't want blank space to the left of the text; scroll further |
2391 |
|
to the right if possible. */ |
2392 |
|
p0.x += width; |
2393 |
|
if (p0.x > p1.x) |
2394 |
|
p0.x = p1.x; |
2395 |
|
|
2396 |
|
if (p0.x > NSMaxX(rect)) |
2397 |
|
{ |
2398 |
|
rect.size.width += p0.x - NSMaxX(rect); |
2399 |
|
} |
2400 |
|
|
2401 |
|
break; |
2402 |
|
|
2403 |
|
case NSCenterTextAlignment: |
2404 |
|
/* If all the text fits in the clip view, just center on the text. */ |
2405 |
|
if (p1.x - p0.x <= width) |
2406 |
|
{ |
2407 |
|
rect.origin.x = (p1.x + p0.x - width) / 2; |
2408 |
|
rect.size.width = width; |
2409 |
|
} |
2410 |
|
else |
2411 |
|
{ |
2412 |
|
/* Otherwise, fill the clip view with text; no blank space on |
2413 |
|
either side. */ |
2414 |
|
float x; |
2415 |
|
|
2416 |
|
x = p1.x - width; |
2417 |
|
if (x < rect.origin.x) |
2418 |
|
{ |
2419 |
|
rect.size.width += rect.origin.x - x; |
2420 |
|
rect.origin.x = x; |
2421 |
|
} |
2422 |
|
x = p0.x + width; |
2423 |
|
if (x > NSMaxX(rect)) |
2424 |
|
{ |
2425 |
|
rect.size.width += x - NSMaxX(rect); |
2426 |
|
} |
2427 |
|
} |
2428 |
|
break; |
2429 |
|
} |
2430 |
|
|
2431 |
[self scrollRectToVisible: rect]; |
[self scrollRectToVisible: rect]; |
2432 |
} |
} |
2433 |
|
|
3194 |
|
|
3195 |
new.origin.x += _textContainerOrigin.x; |
new.origin.x += _textContainerOrigin.x; |
3196 |
new.origin.y += _textContainerOrigin.y; |
new.origin.y += _textContainerOrigin.y; |
3197 |
|
|
3198 |
|
/* If the insertion would extend outside the view (e.g. because it's |
3199 |
|
just to the right of a character on the far right edge of the view, |
3200 |
|
a common case for right-aligned text), we force it back in. */ |
3201 |
|
if (NSMaxX(new) > NSMaxX(_bounds)) |
3202 |
|
{ |
3203 |
|
new.origin.x = NSMaxX(_bounds) - new.size.width; |
3204 |
|
} |
3205 |
} |
} |
3206 |
|
|
3207 |
if (!NSEqualRects(new, _insertionPointRect)) |
if (!NSEqualRects(new, _insertionPointRect)) |