From 7f629a412148500f8646a8b3e3a15e2ef9b59ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 4 Apr 2009 22:22:34 +0000 Subject: [PATCH] * Tried to make the scrolling position less surprising when resizing the window. Sometimes it even seems to work :-) * FrameResized() called _UpdateSize(), although DoLayout() already did so. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29910 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/charactermap/CharacterView.cpp | 66 ++++++++++++++++++++++++- src/apps/charactermap/CharacterView.h | 6 +++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/apps/charactermap/CharacterView.cpp b/src/apps/charactermap/CharacterView.cpp index 8ca621d04e..fb85664b5b 100644 --- a/src/apps/charactermap/CharacterView.cpp +++ b/src/apps/charactermap/CharacterView.cpp @@ -214,7 +214,17 @@ CharacterView::MinSize() void CharacterView::FrameResized(float width, float height) { - _UpdateSize(); + // Scroll to character + + if (!fHasTopCharacter) + return; + + BRect frame = _FrameFor(fTopCharacter); + if (!frame.IsValid()) + return; + + BView::ScrollTo(0, frame.top - fTopOffset); + fHasTopCharacter = false; } @@ -396,6 +406,7 @@ CharacterView::Draw(BRect updateRect) void CharacterView::DoLayout() { + fHasTopCharacter = _GetTopmostCharacter(fTopCharacter, fTopOffset); _UpdateSize(); } @@ -408,7 +419,7 @@ CharacterView::_BlockAt(BPoint point) if (!IsShowingBlock(i)) continue; - if (fTitleTops[i] < point.y + if (fTitleTops[i] <= point.y && (i == kNumUnicodeBlocks - 1 || fTitleTops[i + 1] > point.y)) return i; } @@ -538,6 +549,57 @@ CharacterView::_UpdateSize() } +bool +CharacterView::_GetTopmostCharacter(uint32& character, int32& offset) +{ + int32 top = (int32)Bounds().top; + + int32 i = _BlockAt(BPoint(0, top)); + if (i == -1) + return false; + + int32 characterTop = fTitleTops[i] + fTitleHeight; + if (characterTop > top) { + character = kUnicodeBlocks[i].start; + offset = characterTop - top; + return true; + } + + int32 lines = (top - characterTop + fCharacterHeight - 1) + / fCharacterHeight; + + character = kUnicodeBlocks[i].start + lines * fCharactersPerLine; + offset = top - characterTop - lines * fCharacterHeight; + return true; +} + + +BRect +CharacterView::_FrameFor(uint32 character) +{ + // find block containing the character + + // TODO: could use binary search here + + for (uint32 i = 0; i < kNumUnicodeBlocks; i++) { + if (kUnicodeBlocks[i].end < character) + continue; + if (kUnicodeBlocks[i].start > character) { + // Character is not mapped + return BRect(); + } + + int32 diff = character - kUnicodeBlocks[i].start; + int32 y = fTitleTops[i] + fTitleHeight + diff / fCharactersPerLine; + int32 x = fGap / 2 + diff % fCharactersPerLine; + + return BRect(x, y, x + fCharacterWidth + fGap, y + fCharacterHeight); + } + + return BRect(); +} + + void CharacterView::_CopyToClipboard(const char* text) { diff --git a/src/apps/charactermap/CharacterView.h b/src/apps/charactermap/CharacterView.h index 36d91b82cc..d54650f01c 100644 --- a/src/apps/charactermap/CharacterView.h +++ b/src/apps/charactermap/CharacterView.h @@ -60,6 +60,9 @@ private: bool _GetCharacterAt(BPoint point, uint32& character, BRect* _frame = NULL); void _UpdateSize(); + bool _GetTopmostCharacter(uint32& character, + int32& offset); + BRect _FrameFor(uint32 character); void _CopyToClipboard(const char* text); private: @@ -69,6 +72,9 @@ private: bool fHasCharacter; uint32 fCurrentCharacter; BRect fCurrentCharacterFrame; + bool fHasTopCharacter; + uint32 fTopCharacter; + int32 fTopOffset; bool fShowPrivateBlocks; bool fShowContainedBlocksOnly;