summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-17 22:28:22 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-17 22:28:22 +0000
commitae1a5145ea0b24a56b808b5b249c4b3910e81165 (patch)
tree8ddcae2154cc5e9a53ed19378f007426859a5e5b
parent8a7bcb02f938026aba0b7978818f7ae39688ff1a (diff)
downloadchromium_src-ae1a5145ea0b24a56b808b5b249c4b3910e81165.zip
chromium_src-ae1a5145ea0b24a56b808b5b249c4b3910e81165.tar.gz
chromium_src-ae1a5145ea0b24a56b808b5b249c4b3910e81165.tar.bz2
Lands http://codereview.chromium.org/211002 for Charlie:
Add touchpad speed factor setting to Chrome OS touchpad settings page. Created slider widget with native gtk widget. TEST=none BUG=none Review URL: http://codereview.chromium.org/209016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26511 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/chromeos/settings_contents_view.cc47
-rw-r--r--chrome/browser/chromeos/touchpad.cc20
-rw-r--r--chrome/browser/chromeos/touchpad.h11
-rw-r--r--chrome/browser/options_util.cc1
-rw-r--r--chrome/common/pref_names.cc3
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--views/controls/slider/native_slider_gtk.cc123
-rw-r--r--views/controls/slider/native_slider_gtk.h52
-rw-r--r--views/controls/slider/native_slider_wrapper.h48
-rw-r--r--views/controls/slider/slider.cc114
-rw-r--r--views/controls/slider/slider.h111
-rw-r--r--views/views.gyp10
13 files changed, 539 insertions, 5 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 6aad21b..cbec99a 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5051,6 +5051,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_OPTIONS_SETTINGS_VERT_EDGE_SCROLL_ENABLED_DESCRIPTION" desc="In the settings tab, the text next to the checkbox that enables vertical edge scrolling.">
Enable vertical edge scrolling
</message>
+ <message name="IDS_OPTIONS_SETTINGS_SPEED_FACTOR_DESCRIPTION" desc="In the settings tab, the text next to the slider for the touchpad speed factor.">
+ Speed Sensitivity:
+ </message>
</if>
</messages>
diff --git a/chrome/browser/chromeos/settings_contents_view.cc b/chrome/browser/chromeos/settings_contents_view.cc
index 467c037..7dbee18 100644
--- a/chrome/browser/chromeos/settings_contents_view.cc
+++ b/chrome/browser/chromeos/settings_contents_view.cc
@@ -20,6 +20,7 @@
#include "views/background.h"
#include "views/controls/button/checkbox.h"
#include "views/controls/combobox/combobox.h"
+#include "views/controls/slider/slider.h"
#include "views/controls/textfield/textfield.h"
#include "views/grid_layout.h"
#include "views/standard_layout.h"
@@ -354,7 +355,8 @@ void NetworkSection::InitContents() {
// TouchpadSection
class TouchpadSection : public OptionsPageView,
- public views::ButtonListener {
+ public views::ButtonListener,
+ public views::SliderListener {
public:
explicit TouchpadSection(Profile* profile);
virtual ~TouchpadSection() {}
@@ -362,6 +364,9 @@ class TouchpadSection : public OptionsPageView,
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ // Overridden from views::SliderListener:
+ virtual void SliderValueChanged(views::Slider* sender);
+
protected:
// OptionsPageView overrides:
virtual void InitControlLayout();
@@ -375,10 +380,12 @@ class TouchpadSection : public OptionsPageView,
// Controls for this section:
views::Checkbox* enable_tap_to_click_checkbox_;
views::Checkbox* enable_vert_edge_scroll_checkbox_;
+ views::Slider* speed_factor_slider_;
// Preferences for this section:
BooleanPrefMember tap_to_click_enabled_;
BooleanPrefMember vert_edge_scroll_enabled_;
+ RealPrefMember speed_factor_;
DISALLOW_COPY_AND_ASSIGN(TouchpadSection);
};
@@ -387,7 +394,8 @@ TouchpadSection::TouchpadSection(Profile* profile)
: OptionsPageView(profile),
contents_(NULL),
enable_tap_to_click_checkbox_(NULL),
- enable_vert_edge_scroll_checkbox_(NULL) {
+ enable_vert_edge_scroll_checkbox_(NULL),
+ speed_factor_slider_(NULL) {
}
void TouchpadSection::ButtonPressed(
@@ -409,6 +417,15 @@ void TouchpadSection::ButtonPressed(
}
}
+void TouchpadSection::SliderValueChanged(views::Slider* sender) {
+ if (sender == speed_factor_slider_) {
+ double value = speed_factor_slider_->value();
+ UserMetricsRecordAction(L"Options_SpeedFactorSlider_Changed",
+ profile()->GetPrefs());
+ speed_factor_.SetValue(value);
+ }
+}
+
void TouchpadSection::InitControlLayout() {
GridLayout* layout = new GridLayout(this);
SetLayoutManager(layout);
@@ -450,12 +467,32 @@ void TouchpadSection::InitContents() {
IDS_OPTIONS_SETTINGS_VERT_EDGE_SCROLL_ENABLED_DESCRIPTION));
enable_vert_edge_scroll_checkbox_->set_listener(this);
enable_vert_edge_scroll_checkbox_->SetMultiLine(true);
+ // Create speed factor slider with values between 0.1 and 1.0 step 0.1
+ speed_factor_slider_ = new views::Slider(0.1, 1.0, 0.1,
+ static_cast<views::Slider::StyleFlags>(
+ views::Slider::STYLE_DRAW_VALUE |
+ views::Slider::STYLE_ONE_DIGIT |
+ views::Slider::STYLE_UPDATE_ON_RELEASE),
+ this);
int single_column_view_set_id = 0;
ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
GridLayout::USE_PREF, 0, 0);
+ int double_column_view_set_id = 1;
+ column_set = layout->AddColumnSet(double_column_view_set_id);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, double_column_view_set_id);
+ layout->AddView(new views::Label(
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SPEED_FACTOR_DESCRIPTION)));
+ layout->AddView(speed_factor_slider_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(0, single_column_view_set_id);
layout->AddView(enable_tap_to_click_checkbox_);
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
@@ -468,6 +505,8 @@ void TouchpadSection::InitContents() {
profile()->GetPrefs(), this);
vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled,
profile()->GetPrefs(), this);
+ speed_factor_.Init(prefs::kTouchpadSpeedFactor,
+ profile()->GetPrefs(), this);
}
void TouchpadSection::NotifyPrefChanged(const std::wstring* pref_name) {
@@ -479,6 +518,10 @@ void TouchpadSection::NotifyPrefChanged(const std::wstring* pref_name) {
bool enabled = vert_edge_scroll_enabled_.GetValue();
enable_vert_edge_scroll_checkbox_->SetChecked(enabled);
}
+ if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor) {
+ double value = speed_factor_.GetValue();
+ speed_factor_slider_->SetValue(value);
+ }
}
} // namespace
diff --git a/chrome/browser/chromeos/touchpad.cc b/chrome/browser/chromeos/touchpad.cc
index f0ae97b..5c43270 100644
--- a/chrome/browser/chromeos/touchpad.cc
+++ b/chrome/browser/chromeos/touchpad.cc
@@ -30,17 +30,20 @@ void RunnableMethodTraits<Touchpad>::ReleaseCallee(
// static
void Touchpad::RegisterUserPrefs(PrefService* prefs) {
- prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, true);
+ prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, true);
+ prefs->RegisterRealPref(prefs::kTouchpadSpeedFactor, 0.5);
}
void Touchpad::Init(PrefService* prefs) {
tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
+ speed_factor_.Init(prefs::kTouchpadSpeedFactor, prefs, this);
// Initialize touchpad settings to what's saved in user preferences.
SetTapToClick();
SetVertEdgeScroll();
+ SetSpeedFactor();
}
void Touchpad::Observe(NotificationType type,
@@ -55,6 +58,8 @@ void Touchpad::NotifyPrefChanged(const std::wstring* pref_name) {
SetTapToClick();
if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled)
SetVertEdgeScroll();
+ if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor)
+ SetSpeedFactor();
}
void Touchpad::SetSynclientParam(const std::string& param,
@@ -96,3 +101,16 @@ void Touchpad::SetVertEdgeScroll() {
else
SetSynclientParam("VertEdgeScroll", "0");
}
+
+void Touchpad::SetSpeedFactor() {
+ // To set speed factor, we use MinSpeed. Both MaxSpeed and AccelFactor are 0.
+ // So MinSpeed will control the speed of the cursor with respect to the
+ // touchpad movement and there will not be any acceleration.
+ // We enforce that MinSpeed is between 0.01 and 1.00.
+ double value = speed_factor_.GetValue();
+ if (value < 0.01)
+ value = 0.01;
+ if (value > 1.0)
+ value = 1.0;
+ SetSynclientParam("MinSpeed", StringPrintf("%f", value));
+}
diff --git a/chrome/browser/chromeos/touchpad.h b/chrome/browser/chromeos/touchpad.h
index 92679d2..c4c783c 100644
--- a/chrome/browser/chromeos/touchpad.h
+++ b/chrome/browser/chromeos/touchpad.h
@@ -18,9 +18,9 @@ class PrefService;
// setting to reflect the new value.
//
// For Synaptics touchpads, we use synclient to change settings on-the-fly.
-// See "man synaptics" for a list of settings that can be changed
+// See "man synaptics" for a list of settings that can be changed.
// Since we are doing a system call to run the synclient binary, we make sure
-// that we are running on the IO thread so that we don't block the UI thread.
+// that we are running on the File thread so that we don't block the UI thread.
class Touchpad : public NotificationObserver {
public:
explicit Touchpad() {}
@@ -45,11 +45,18 @@ class Touchpad : public NotificationObserver {
// The system call will be invoked on the file thread.
void SetSynclientParam(const std::string& param, const std::string& value);
+ // Set tap-to-click to value stored in preference.
void SetTapToClick();
+
+ // Set vertical edge scrolling to value stored in preference.
void SetVertEdgeScroll();
+ // Set touchpad speed factor to value stored in preference.
+ void SetSpeedFactor();
+
BooleanPrefMember tap_to_click_enabled_;
BooleanPrefMember vert_edge_scroll_enabled_;
+ RealPrefMember speed_factor_;
DISALLOW_COPY_AND_ASSIGN(Touchpad);
};
diff --git a/chrome/browser/options_util.cc b/chrome/browser/options_util.cc
index fe588cb..94bed68 100644
--- a/chrome/browser/options_util.cc
+++ b/chrome/browser/options_util.cc
@@ -33,6 +33,7 @@ void OptionsUtil::ResetToDefaults(Profile* profile) {
#if defined(OS_CHROMEOS)
prefs::kTapToClickEnabled,
prefs::kVertEdgeScrollEnabled,
+ prefs::kTouchpadSpeedFactor,
#endif
prefs::kDownloadDefaultDirectory,
prefs::kDownloadExtensionsToOpen,
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 1fda560..ea9ebed 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -189,6 +189,9 @@ extern const wchar_t kTapToClickEnabled[] =
// A boolean pref set to true if VertEdgeScroll is being done in browser.
extern const wchar_t kVertEdgeScrollEnabled[] =
L"settings.touchpad.enable_vert_edge_scroll";
+
+// A double pref for the touchpad speed factor.
+extern const wchar_t kTouchpadSpeedFactor[] = L"settings.touchpad.speed_factor";
#endif
// The disabled messages in IPC logging.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 8502a46..75236c9 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -71,6 +71,7 @@ extern const wchar_t kTLS1Enabled[];
#if defined(OS_CHROMEOS)
extern const wchar_t kTapToClickEnabled[];
extern const wchar_t kVertEdgeScrollEnabled[];
+extern const wchar_t kTouchpadSpeedFactor[];
#endif
extern const wchar_t kIpcDisabledMessages[];
extern const wchar_t kShowHomeButton[];
diff --git a/views/controls/slider/native_slider_gtk.cc b/views/controls/slider/native_slider_gtk.cc
new file mode 100644
index 0000000..201fcda
--- /dev/null
+++ b/views/controls/slider/native_slider_gtk.cc
@@ -0,0 +1,123 @@
+// 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 <gtk/gtk.h>
+
+#include "views/controls/slider/native_slider_gtk.h"
+
+#include "base/gfx/gtk_util.h"
+#include "views/controls/slider/slider.h"
+
+namespace views {
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeSliderGtk, public:
+
+NativeSliderGtk::NativeSliderGtk(Slider* slider)
+ : slider_(slider) {
+}
+
+NativeSliderGtk::~NativeSliderGtk() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeSliderGtk, NativeSliderWrapper implementation:
+
+void NativeSliderGtk::UpdateEnabled() {
+ if (!native_view())
+ return;
+ SetEnabled(slider_->IsEnabled());
+}
+
+double NativeSliderGtk::GetValue() {
+ if (!native_view())
+ return 0;
+ return gtk_range_get_value(GTK_RANGE(native_view()));
+}
+
+void NativeSliderGtk::SetValue(double value) {
+ if (!native_view())
+ return;
+ gtk_range_set_value(GTK_RANGE(native_view()), value);
+}
+
+void NativeSliderGtk::SetFocus() {
+ Focus();
+}
+
+gfx::Size NativeSliderGtk::GetPreferredSize() {
+ if (!native_view())
+ return gfx::Size();
+
+ if (preferred_size_.IsEmpty()) {
+ GtkRequisition size_request = { 0, 0 };
+ gtk_widget_size_request(native_view(), &size_request);
+ preferred_size_.SetSize(size_request.width, size_request.height);
+ }
+ return preferred_size_;
+}
+
+View* NativeSliderGtk::GetView() {
+ return this;
+}
+
+gfx::NativeView NativeSliderGtk::GetTestingHandle() const {
+ return native_view();
+}
+
+// static
+gboolean NativeSliderGtk::OnValueChangedHandler(GtkWidget* entry,
+ NativeSliderGtk* slider) {
+ return slider->OnValueChanged();
+}
+
+gboolean NativeSliderGtk::OnValueChanged() {
+ slider_->NotifyValueChanged();
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+// NativeSliderGtk, NativeControlGtk overrides:
+
+void NativeSliderGtk::CreateNativeControl() {
+ GtkWidget* widget;
+ if (slider_->style() & Slider::STYLE_VERTICAL)
+ widget = gtk_vscale_new_with_range(slider_->min(),
+ slider_->max(),
+ slider_->step());
+ else
+ widget = gtk_hscale_new_with_range(slider_->min(),
+ slider_->max(),
+ slider_->step());
+ NativeControlCreated(widget);
+
+ bool drawvalue = slider_->style() & Slider::STYLE_DRAW_VALUE;
+ gtk_scale_set_draw_value(GTK_SCALE(native_view()), drawvalue);
+
+ int digits = 0;
+ if (slider_->style() & Slider::STYLE_ONE_DIGIT)
+ digits = 1;
+ else if (slider_->style() & Slider::STYLE_TWO_DIGITS)
+ digits = 2;
+ gtk_scale_set_digits(GTK_SCALE(native_view()), digits);
+
+ if (slider_->style() & Slider::STYLE_UPDATE_ON_RELEASE)
+ gtk_range_set_update_policy(GTK_RANGE(native_view()),
+ GTK_UPDATE_DISCONTINUOUS);
+}
+
+void NativeSliderGtk::NativeControlCreated(GtkWidget* widget) {
+ NativeControlGtk::NativeControlCreated(widget);
+ g_signal_connect(widget, "value_changed",
+ G_CALLBACK(OnValueChangedHandler), this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeSliderWrapper, public:
+
+// static
+NativeSliderWrapper* NativeSliderWrapper::CreateWrapper(Slider* field) {
+ return new NativeSliderGtk(field);
+}
+
+} // namespace views
diff --git a/views/controls/slider/native_slider_gtk.h b/views/controls/slider/native_slider_gtk.h
new file mode 100644
index 0000000..8af8c24
--- /dev/null
+++ b/views/controls/slider/native_slider_gtk.h
@@ -0,0 +1,52 @@
+// 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_SLIDER_NATIVE_SLIDER_GTK_H_
+#define VIEWS_CONTROLS_SLIDER_NATIVE_SLIDER_GTK_H_
+
+#include <gtk/gtk.h>
+
+#include "views/controls/native_control_gtk.h"
+#include "views/controls/slider/native_slider_wrapper.h"
+
+namespace views {
+
+class NativeSliderGtk : public NativeControlGtk,
+ public NativeSliderWrapper {
+ public:
+ explicit NativeSliderGtk(Slider* parent);
+ ~NativeSliderGtk();
+
+ // Overridden from NativeSliderWrapper:
+ virtual void UpdateEnabled();
+ virtual double GetValue();
+ virtual void SetValue(double value);
+ virtual void SetFocus();
+ virtual gfx::Size GetPreferredSize();
+ virtual View* GetView();
+ virtual gfx::NativeView GetTestingHandle() const;
+
+ // Overridden from NativeControlGtk:
+ virtual void CreateNativeControl();
+ virtual void NativeControlCreated(GtkWidget* widget);
+
+ private:
+ // The slider we are bound to.
+ Slider* slider_;
+
+ // The preferred size from the last size_request. See
+ // NativeButtonGtk::preferred_size_ for more detail why we need this.
+ gfx::Size preferred_size_;
+
+ // Callback when the slider value changes.
+ static gboolean OnValueChangedHandler(GtkWidget* entry,
+ NativeSliderGtk* slider);
+ gboolean OnValueChanged();
+
+ DISALLOW_COPY_AND_ASSIGN(NativeSliderGtk);
+};
+
+} // namespace views
+
+#endif // VIEWS_CONTROLS_SLIDER_NATIVE_SLIDER_GTK_H_
diff --git a/views/controls/slider/native_slider_wrapper.h b/views/controls/slider/native_slider_wrapper.h
new file mode 100644
index 0000000..100def5
--- /dev/null
+++ b/views/controls/slider/native_slider_wrapper.h
@@ -0,0 +1,48 @@
+// 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_SLIDER_NATIVE_SLIDER_WRAPPER_H_
+#define VIEWS_CONTROLS_SLIDER_NATIVE_SLIDER_WRAPPER_H_
+
+#include "base/gfx/native_widget_types.h"
+
+namespace views {
+
+class Slider;
+class View;
+
+// An interface implemented by an object that provides a platform-native slider.
+class NativeSliderWrapper {
+ public:
+ // The Slider calls this when it is destroyed to clean up the wrapper object.
+ virtual ~NativeSliderWrapper() {}
+
+ // Updates the enabled state of the native slider.
+ virtual void UpdateEnabled() = 0;
+
+ // Gets the value of the slider.
+ virtual double GetValue() = 0;
+
+ // Sets the value of the slider.
+ virtual void SetValue(double value) = 0;
+
+ // Sets the focus to the slider.
+ virtual void SetFocus() = 0;
+
+ // Returns the preferred size of the combobox.
+ virtual gfx::Size GetPreferredSize() = 0;
+
+ // Retrieves the views::View that hosts the native control.
+ virtual View* GetView() = 0;
+
+ // Returns a handle to the underlying native view for testing.
+ virtual gfx::NativeView GetTestingHandle() const = 0;
+
+ // Creates an appropriate NativeSliderWrapper for the platform.
+ static NativeSliderWrapper* CreateWrapper(Slider* slider);
+};
+
+} // namespace views
+
+#endif // VIEWS_CONTROLS_SLIDER_NATIVE_SLIDER_WRAPPER_H_
diff --git a/views/controls/slider/slider.cc b/views/controls/slider/slider.cc
new file mode 100644
index 0000000..ede29246
--- /dev/null
+++ b/views/controls/slider/slider.cc
@@ -0,0 +1,114 @@
+// 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/slider/slider.h"
+
+#include <string>
+
+#include "views/controls/slider/native_slider_wrapper.h"
+#include "views/widget/widget.h"
+
+namespace views {
+
+// static
+const char Slider::kViewClassName[] = "views/Slider";
+
+/////////////////////////////////////////////////////////////////////////////
+// Slider
+
+Slider::Slider()
+ : native_wrapper_(NULL),
+ listener_(NULL),
+ style_(STYLE_HORIZONTAL) {
+ SetFocusable(true);
+}
+
+Slider::Slider(double min, double max, double step, StyleFlags style,
+ SliderListener* listener)
+ : native_wrapper_(NULL),
+ listener_(listener),
+ style_(style),
+ min_(min),
+ max_(max),
+ step_(step) {
+ SetFocusable(true);
+}
+
+Slider::~Slider() {
+}
+
+void Slider::NotifyValueChanged() {
+ if (native_wrapper_)
+ value_ = native_wrapper_->GetValue();
+ if (listener_)
+ listener_->SliderValueChanged(this);
+}
+
+void Slider::SetValue(double value) {
+ value_ = value;
+ if (native_wrapper_)
+ native_wrapper_->SetValue(value);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Slider, View overrides:
+
+void Slider::Layout() {
+ if (native_wrapper_) {
+ native_wrapper_->GetView()->SetBounds(GetLocalBounds(true));
+ native_wrapper_->GetView()->Layout();
+ }
+}
+
+gfx::Size Slider::GetPreferredSize() {
+ if (native_wrapper_)
+ return native_wrapper_->GetPreferredSize();
+ return gfx::Size();
+}
+
+bool Slider::IsFocusable() const {
+ return IsEnabled();
+}
+
+void Slider::SetEnabled(bool enabled) {
+ View::SetEnabled(enabled);
+ if (native_wrapper_)
+ native_wrapper_->UpdateEnabled();
+}
+
+void Slider::Focus() {
+ if (native_wrapper_) {
+ // Forward the focus to the wrapper if it exists.
+ native_wrapper_->SetFocus();
+ } else {
+ // If there is no wrapper, cause the RootView to be focused so that we still
+ // get keyboard messages.
+ View::Focus();
+ }
+}
+
+void Slider::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
+ if (is_add && !native_wrapper_ && GetWidget()) {
+ // The native wrapper's lifetime will be managed by the view hierarchy after
+ // we call AddChildView.
+ native_wrapper_ = NativeSliderWrapper::CreateWrapper(this);
+ AddChildView(native_wrapper_->GetView());
+ native_wrapper_->UpdateEnabled();
+ }
+}
+
+std::string Slider::GetClassName() const {
+ return kViewClassName;
+}
+
+NativeSliderWrapper* Slider::CreateWrapper() {
+ NativeSliderWrapper* native_wrapper =
+ NativeSliderWrapper::CreateWrapper(this);
+
+ native_wrapper->UpdateEnabled();
+
+ return native_wrapper;
+}
+
+} // namespace views
diff --git a/views/controls/slider/slider.h b/views/controls/slider/slider.h
new file mode 100644
index 0000000..2e44d8a
--- /dev/null
+++ b/views/controls/slider/slider.h
@@ -0,0 +1,111 @@
+// 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_SLIDER_SLIDER_H_
+#define VIEWS_CONTROLS_SLIDER_SLIDER_H_
+
+#if defined(OS_LINUX)
+#include <gdk/gdk.h>
+#endif
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "views/view.h"
+
+namespace views {
+
+class NativeSliderWrapper;
+class Slider;
+
+// An interface implemented by an object to let it know that the slider value
+// was changed.
+class SliderListener {
+ public:
+ virtual void SliderValueChanged(Slider* sender) = 0;
+};
+
+// This class implements a ChromeView that wraps a native slider.
+class Slider : public View {
+ public:
+ // The slider's class name.
+ static const char kViewClassName[];
+
+ enum StyleFlags {
+ STYLE_HORIZONTAL = 0, // Horizontal is default type.
+ STYLE_VERTICAL = 1<<0,
+ STYLE_DRAW_VALUE = 1<<1, // Display current value next to the slider.
+ STYLE_ONE_DIGIT = 1<<2, // 1 decimal place of precision for value.
+ STYLE_TWO_DIGITS = 1<<3, // 2 decimal places of precision for value.
+ STYLE_UPDATE_ON_RELEASE = 1<<4, // The slider will only notify value
+ // changed on release of mouse
+ };
+
+ Slider();
+ Slider(double min, double max, double step, StyleFlags style,
+ SliderListener* listener);
+ virtual ~Slider();
+
+ // Cause the slider to notify the listener that the value has changed.
+ virtual void NotifyValueChanged();
+
+ // Gets/Sets the value in the slider.
+ const double value() const { return value_; }
+ void SetValue(double value);
+
+ // Accessor for |style_|.
+ StyleFlags style() const { return style_; }
+
+ // Accessor for |min_|.
+ const double min() const { return min_; }
+
+ // Accessor for |max_|.
+ const double max() const { return max_; }
+
+ // Accessor for |step_|.
+ const double step() const { return step_; }
+
+ // Overridden from View:
+ virtual void Layout();
+ virtual gfx::Size GetPreferredSize();
+ virtual bool IsFocusable() const;
+ virtual void SetEnabled(bool enabled);
+
+ protected:
+ virtual void Focus();
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+ virtual std::string GetClassName() const;
+
+ // Creates a new native wrapper properly initialized and returns it. Ownership
+ // is passed to the caller.
+ NativeSliderWrapper* CreateWrapper();
+
+ private:
+ // The object that actually implements the native slider.
+ NativeSliderWrapper* native_wrapper_;
+
+ // The slider's listener. Notified when slider value changed.
+ SliderListener* listener_;
+
+ // The mask of style options for this Slider.
+ StyleFlags style_;
+
+ // The minimum value of the slider.
+ double min_;
+
+ // The maximum value of the slider.
+ double max_;
+
+ // The step increment of the slider.
+ double step_;
+
+ // The value displayed in the slider.
+ double value_;
+
+ DISALLOW_COPY_AND_ASSIGN(Slider);
+};
+
+} // namespace views
+
+#endif // VIEWS_CONTROLS_SLIDER_SLIDER_H_
diff --git a/views/views.gyp b/views/views.gyp
index aa36238..a242b82 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -167,6 +167,11 @@
'controls/separator.h',
'controls/single_split_view.cc',
'controls/single_split_view.h',
+ 'controls/slider/slider.cc',
+ 'controls/slider/slider.h',
+ 'controls/slider/native_slider_gtk.cc',
+ 'controls/slider/native_slider_gtk.h',
+ 'controls/slider/native_slider_wrapper.h',
'controls/tabbed_pane/tabbed_pane.cc',
'controls/tabbed_pane/tabbed_pane.h',
'controls/tabbed_pane/native_tabbed_pane_gtk.cc',
@@ -318,6 +323,11 @@
'_CRT_SECURE_NO_DEPRECATE',
'_SCL_SECURE_NO_DEPRECATE',
],
+ 'sources!': [
+ 'controls/slider/slider.cc',
+ 'controls/slider/slider.h',
+ 'controls/slider/native_slider_wrapper.h',
+ ],
'include_dirs': [
# TODO(beng): move wtl to src/third_party
'../chrome/third_party/wtl/include',