summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--views/controls/scroll_view.cc4
-rw-r--r--views/controls/scrollbar/native_scroll_bar_gtk.cc214
-rw-r--r--views/controls/scrollbar/native_scroll_bar_gtk.h79
-rw-r--r--views/examples/examples_main_base.cc2
-rw-r--r--views/examples/scroll_view_example.h121
-rw-r--r--views/views.gyp6
6 files changed, 421 insertions, 5 deletions
diff --git a/views/controls/scroll_view.cc b/views/controls/scroll_view.cc
index ecc3033..a5b5f6a 100644
--- a/views/controls/scroll_view.cc
+++ b/views/controls/scroll_view.cc
@@ -353,7 +353,7 @@ void ScrollView::ScrollToPosition(ScrollBar* source, int position) {
else if (position > max_pos)
position = max_pos;
contents_->SetX(-position);
- contents_->SchedulePaint(contents_->GetLocalBounds(true), true);
+ contents_->SchedulePaint(contents_->GetVisibleBounds(), true);
}
} else if (source == vert_sb_ && vert_sb_->IsVisible()) {
int vh = viewport_->height();
@@ -366,7 +366,7 @@ void ScrollView::ScrollToPosition(ScrollBar* source, int position) {
else if (position > max_pos)
position = max_pos;
contents_->SetY(-position);
- contents_->SchedulePaint(contents_->GetLocalBounds(true), true);
+ contents_->SchedulePaint(contents_->GetVisibleBounds(), true);
}
}
}
diff --git a/views/controls/scrollbar/native_scroll_bar_gtk.cc b/views/controls/scrollbar/native_scroll_bar_gtk.cc
new file mode 100644
index 0000000..616ff7f
--- /dev/null
+++ b/views/controls/scrollbar/native_scroll_bar_gtk.cc
@@ -0,0 +1,214 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/controls/scrollbar/native_scroll_bar_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "base/keyboard_codes_posix.h"
+#include "views/controls/scrollbar/native_scroll_bar.h"
+#include "views/controls/scrollbar/scroll_bar.h"
+
+namespace views {
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeScrollBarGtk, public:
+
+NativeScrollBarGtk::NativeScrollBarGtk(NativeScrollBar* scroll_bar)
+ : NativeControlGtk(),
+ native_scroll_bar_(scroll_bar) {
+ set_focus_view(scroll_bar);
+}
+
+NativeScrollBarGtk::~NativeScrollBarGtk() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeScrollBarGtk, View overrides:
+
+void NativeScrollBarGtk::Layout() {
+ SetBounds(native_scroll_bar_->GetLocalBounds(true));
+ NativeControlGtk::Layout();
+}
+
+gfx::Size NativeScrollBarGtk::GetPreferredSize() {
+ if (native_scroll_bar_->IsHorizontal())
+ return gfx::Size(0, GetHorizontalScrollBarHeight());
+ return gfx::Size(GetVerticalScrollBarWidth(), 0);
+}
+
+// TODO(oshima|jcampan): key/mouse events are not delievered and
+// the following code is not tested. It requires the focus manager to be fully
+// implemented.
+bool NativeScrollBarGtk::OnKeyPressed(const KeyEvent& event) {
+ if (!native_view())
+ return false;
+ switch (event.GetKeyCode()) {
+ case base::VKEY_UP:
+ if (!native_scroll_bar_->IsHorizontal())
+ MoveStep(false /* negative */);
+ break;
+ case base::VKEY_DOWN:
+ if (!native_scroll_bar_->IsHorizontal())
+ MoveStep(true /* positive */);
+ break;
+ case base::VKEY_LEFT:
+ if (native_scroll_bar_->IsHorizontal())
+ MoveStep(false /* negative */);
+ break;
+ case base::VKEY_RIGHT:
+ if (native_scroll_bar_->IsHorizontal())
+ MoveStep(true /* positive */);
+ break;
+ case base::VKEY_PRIOR:
+ MovePage(false /* negative */);
+ break;
+ case base::VKEY_NEXT:
+ MovePage(true /* positive */);
+ break;
+ case base::VKEY_HOME:
+ MoveTo(0);
+ break;
+ case base::VKEY_END:
+ MoveToBottom();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool NativeScrollBarGtk::OnMouseWheel(const MouseWheelEvent& e) {
+ if (!native_view() || native_scroll_bar_->IsHorizontal())
+ return false;
+ MoveBy(e.GetOffset());
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeScrollBarGtk, NativeControlGtk overrides:
+
+void NativeScrollBarGtk::CreateNativeControl() {
+ GtkObject* adj = gtk_adjustment_new(native_scroll_bar_->GetMinPosition(),
+ native_scroll_bar_->GetMinPosition(),
+ native_scroll_bar_->GetMaxPosition(),
+ 10, 10,
+ 0);
+ GtkWidget* widget;
+ if (native_scroll_bar_->IsHorizontal()) {
+ widget = gtk_hscrollbar_new(GTK_ADJUSTMENT(adj));
+ } else {
+ widget = gtk_vscrollbar_new(GTK_ADJUSTMENT(adj));
+ }
+
+ gtk_range_set_update_policy(GTK_RANGE(widget), GTK_UPDATE_CONTINUOUS);
+
+ g_signal_connect(G_OBJECT(adj), "value-changed",
+ G_CALLBACK(CallValueChanged), this);
+
+ NativeControlCreated(widget);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeScrollBarGtk, NativeScrollBarWrapper overrides:
+
+int NativeScrollBarGtk::GetPosition() const {
+ return static_cast<int>(gtk_range_get_value(GTK_RANGE(native_view())));
+}
+
+View* NativeScrollBarGtk::GetView() {
+ return this;
+}
+
+void NativeScrollBarGtk::Update(int viewport_size,
+ int content_size,
+ int current_pos) {
+ if (!native_view())
+ return;
+
+ if (content_size < 0)
+ content_size = 0;
+
+ if (current_pos < 0)
+ current_pos = 0;
+
+ if (current_pos > content_size)
+ current_pos = content_size;
+
+ ScrollBarController* controller = native_scroll_bar_->GetController();
+ int step = controller->GetScrollIncrement(native_scroll_bar_,
+ false /* step */,
+ true /* positive */);
+ int page = controller->GetScrollIncrement(native_scroll_bar_,
+ true /* page */, true);
+ GtkObject* adj = gtk_adjustment_new(current_pos,
+ native_scroll_bar_->GetMinPosition(),
+ content_size,
+ step, page,
+ viewport_size);
+ gtk_range_set_adjustment(GTK_RANGE(native_view()), GTK_ADJUSTMENT(adj));
+ g_signal_connect(G_OBJECT(adj), "value-changed",
+ G_CALLBACK(CallValueChanged), this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeScrollBarGtk, private:
+
+void NativeScrollBarGtk::ValueChanged() {
+ ScrollBarController* controller = native_scroll_bar_->GetController();
+ controller->ScrollToPosition(native_scroll_bar_, GetPosition());
+}
+
+// static
+void NativeScrollBarGtk::CallValueChanged(GtkWidget* widget,
+ NativeScrollBarGtk* scroll_bar) {
+ scroll_bar->ValueChanged();
+}
+
+void NativeScrollBarGtk::MoveBy(int o) {
+ MoveTo(GetPosition() + o);
+}
+
+void NativeScrollBarGtk::MovePage(bool positive) {
+ ScrollBarController* controller = native_scroll_bar_->GetController();
+ MoveBy(controller->GetScrollIncrement(native_scroll_bar_, true, positive));
+}
+
+void NativeScrollBarGtk::MoveStep(bool positive) {
+ ScrollBarController* controller = native_scroll_bar_->GetController();
+ MoveBy(controller->GetScrollIncrement(native_scroll_bar_, false, positive));
+}
+
+void NativeScrollBarGtk::MoveTo(int p) {
+ GtkAdjustment* adj = gtk_range_get_adjustment(GTK_RANGE(native_view()));
+ gtk_adjustment_set_value(adj, p);
+}
+
+void NativeScrollBarGtk::MoveToBottom() {
+ GtkAdjustment* adj = gtk_range_get_adjustment(GTK_RANGE(native_view()));
+ MoveTo(adj->upper);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativewScrollBarWrapper, public:
+
+// static
+NativeScrollBarWrapper* NativeScrollBarWrapper::CreateWrapper(
+ NativeScrollBar* scroll_bar) {
+ return new NativeScrollBarGtk(scroll_bar);
+}
+
+// static
+int NativeScrollBarWrapper::GetHorizontalScrollBarHeight() {
+ // TODO(oshima): get this from gtk's widget property "slider-width".
+ return 20;
+}
+
+// static
+int NativeScrollBarWrapper::GetVerticalScrollBarWidth() {
+ // TODO(oshima): get this from gtk's widget property "slider-width".
+ return 20;
+}
+
+} // namespace views
diff --git a/views/controls/scrollbar/native_scroll_bar_gtk.h b/views/controls/scrollbar/native_scroll_bar_gtk.h
new file mode 100644
index 0000000..ca70d1d
--- /dev/null
+++ b/views/controls/scrollbar/native_scroll_bar_gtk.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_GTK_H_
+#define VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_GTK_H_
+
+#include "views/controls/native_control_gtk.h"
+#include "views/controls/scrollbar/native_scroll_bar_wrapper.h"
+
+namespace views {
+
+class ScrollBarContainer;
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// NativeScrollBarGtk
+//
+// A View subclass that wraps a Native gtk scrollbar control.
+//
+// A scrollbar is either horizontal or vertical.
+//
+/////////////////////////////////////////////////////////////////////////////
+class NativeScrollBarGtk : public NativeControlGtk,
+ public NativeScrollBarWrapper {
+ public:
+ // Creates new scrollbar, either horizontal or vertical.
+ explicit NativeScrollBarGtk(NativeScrollBar* native_scroll_bar);
+ virtual ~NativeScrollBarGtk();
+
+ private:
+ // Overridden from View for layout purpose.
+ virtual void Layout();
+ virtual gfx::Size GetPreferredSize();
+
+ // Overridden from View for keyboard UI purpose.
+ virtual bool OnKeyPressed(const KeyEvent& event);
+ virtual bool OnMouseWheel(const MouseWheelEvent& e);
+
+ // Overridden from NativeControlGtk.
+ virtual void CreateNativeControl();
+
+ // Overridden from NativeScrollBarWrapper.
+ virtual int GetPosition() const;
+ virtual View* GetView();
+ virtual void Update(int viewport_size, int content_size, int current_pos);
+
+ // Moves the scrollbar by the given value. Negative value is allowed.
+ // (moves upward)
+ void MoveBy(int o);
+
+ // Moves the scrollbar by the page (viewport) size.
+ void MovePage(bool positive);
+
+ // Moves the scrollbar by predefined step size.
+ void MoveStep(bool positive);
+
+ // Moves the scrollbar to the given position. MoveTo(0) moves it to the top.
+ void MoveTo(int p);
+
+ // Moves the scrollbar to the end.
+ void MoveToBottom();
+
+ // Invoked when the scrollbar's position is changed.
+ void ValueChanged();
+ static void CallValueChanged(GtkWidget* widget,
+ NativeScrollBarGtk* scroll_bar);
+
+ // The NativeScrollBar we are bound to.
+ NativeScrollBar* native_scroll_bar_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NativeScrollBarGtk);
+};
+
+} // namespace views
+
+#endif // #ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_GTK_H_
+
diff --git a/views/examples/examples_main_base.cc b/views/examples/examples_main_base.cc
index cd65c2c..b407347 100644
--- a/views/examples/examples_main_base.cc
+++ b/views/examples/examples_main_base.cc
@@ -18,6 +18,7 @@
#include "views/examples/combobox_example.h"
#include "views/examples/message_box_example.h"
#include "views/examples/radio_button_example.h"
+#include "views/examples/scroll_view_example.h"
#include "views/examples/tabbed_pane_example.h"
namespace examples {
@@ -74,6 +75,7 @@ void ExamplesMainBase::Run() {
TabbedPaneExample tabbed_pane_example(tabbed_pane, message);
MessageBoxExample message_box_example(tabbed_pane, message);
RadioButtonExample radio_button_example(tabbed_pane, message);
+ ScrollViewExample scroll_view_example(tabbed_pane, message);
widget->Show();
diff --git a/views/examples/scroll_view_example.h b/views/examples/scroll_view_example.h
new file mode 100644
index 0000000..b032224
--- /dev/null
+++ b/views/examples/scroll_view_example.h
@@ -0,0 +1,121 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VIEWS_EXAMPLES_SCROLL_BAR_EXAMPLE_H_
+#define VIEWS_EXAMPLES_SCROLL_BAR_EXAMPLE_H_
+
+#include "base/string_util.h"
+#include "views/controls/button/text_button.h"
+#include "views/controls/scroll_view.h"
+#include "views/examples/example_base.h"
+
+namespace examples {
+
+class ScrollViewExample : protected ExampleBase, private views::ButtonListener {
+ public:
+ ScrollViewExample(views::TabbedPane* tabbed_pane, views::Label* message)
+ : ExampleBase(message),
+ wide_(new views::TextButton(this, L"Wide")),
+ tall_(new views::TextButton(this, L"Tall")),
+ big_square_(new views::TextButton(this, L"Big Square")),
+ small_square_(new views::TextButton(this, L"Small Square")),
+ scroll_to_(new views::TextButton(this, L"Scroll to")),
+ scrollable_(new ScrollableView()),
+ scroll_view_(new views::ScrollView()) {
+ scroll_view_->SetContents(scrollable_);
+ scrollable_->SetBounds(0, 0, 1000, 100);
+ scrollable_->SetColor(SK_ColorYELLOW, SK_ColorCYAN);
+
+ views::View* container = new views::View();
+ tabbed_pane->AddTab(L"Scroll View", container);
+
+ views::GridLayout* layout = new views::GridLayout(container);
+ container->SetLayoutManager(layout);
+
+ // Add scroll view.
+ views::ColumnSet* column_set = layout->AddColumnSet(0);
+ column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0, 0);
+ layout->StartRow(1, 0);
+ layout->AddView(scroll_view_);
+
+ // Add control buttons.
+ column_set = layout->AddColumnSet(1);
+ for (int i = 0; i < 5; i++) {
+ column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0, 0);
+ }
+ layout->StartRow(0, 1);
+ layout->AddView(wide_);
+ layout->AddView(tall_);
+ layout->AddView(big_square_);
+ layout->AddView(small_square_);
+ layout->AddView(scroll_to_);
+ }
+
+ virtual ~ScrollViewExample() {}
+
+ private:
+ // ScrollView's content, which draws gradient color on background.
+ // TODO(oshima): add child views as well.
+ class ScrollableView : public views::View {
+ public:
+ ScrollableView() {
+ SetColor(SK_ColorRED, SK_ColorCYAN);
+ }
+
+ gfx::Size GetPreferredSize() {
+ return gfx::Size(width(), height());
+ }
+
+ void SetColor(SkColor from, SkColor to) {
+ set_background(
+ views::Background::CreateVerticalGradientBackground(from, to));
+ }
+
+ virtual void Layout() {
+ SizeToPreferredSize();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScrollableView);
+ };
+
+ // ButtonListner implementation.
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
+ if (sender == wide_) {
+ scrollable_->SetBounds(0, 0, 1000, 100);
+ scrollable_->SetColor(SK_ColorYELLOW, SK_ColorCYAN);
+ } else if (sender == tall_) {
+ scrollable_->SetBounds(0, 0, 100, 1000);
+ scrollable_->SetColor(SK_ColorRED, SK_ColorCYAN);
+ } else if (sender == big_square_) {
+ scrollable_->SetBounds(0, 0, 1000, 1000);
+ scrollable_->SetColor(SK_ColorRED, SK_ColorGREEN);
+ } else if (sender == small_square_) {
+ scrollable_->SetBounds(0, 0, 100, 100);
+ scrollable_->SetColor(SK_ColorYELLOW, SK_ColorGREEN);
+ } else if (sender == scroll_to_) {
+ scroll_view_->ScrollContentsRegionToBeVisible(20, 500, 1000, 500);
+ }
+ scroll_view_->Layout();
+ }
+
+ // Control buttons to change the size of scrollable and jump to
+ // predefined position.
+ views::TextButton* wide_, *tall_, *big_square_, *small_square_, *scroll_to_;
+
+ // The content of the scroll view.
+ ScrollableView* scrollable_;
+
+ // The scroll view to test.
+ views::ScrollView* scroll_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScrollViewExample);
+};
+
+} // namespace examples
+
+#endif // VIEWS_EXAMPLES_SCROLL_BAR_EXAMPLE_H_
+
diff --git a/views/views.gyp b/views/views.gyp
index fb387e8..a16f9b2 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -159,9 +159,11 @@
'controls/scroll_view.h',
'controls/scrollbar/bitmap_scroll_bar.cc',
'controls/scrollbar/bitmap_scroll_bar.h',
- 'controls/scrollbar/native_scroll_bar_wrapper.h',
+ 'controls/scrollbar/native_scroll_bar_gtk.cc',
+ 'controls/scrollbar/native_scroll_bar_gtk.h',
'controls/scrollbar/native_scroll_bar_win.cc',
'controls/scrollbar/native_scroll_bar_win.h',
+ 'controls/scrollbar/native_scroll_bar_wrapper.h',
'controls/scrollbar/native_scroll_bar.cc',
'controls/scrollbar/native_scroll_bar.h',
'controls/scrollbar/scroll_bar.cc',
@@ -302,10 +304,8 @@
'controls/scrollbar/bitmap_scroll_bar.cc',
'controls/combo_box.cc',
'controls/hwnd_view.cc',
- 'controls/scroll_view.cc',
'controls/table/group_table_view.cc',
'controls/native_control.cc',
- 'controls/scrollbar/native_scroll_bar.cc',
'controls/separator.cc',
'controls/table/table_model.cc',
'controls/table/table_view.cc',