diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/simple_xp_frame.cc | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/simple_xp_frame.cc')
-rw-r--r-- | chrome/browser/simple_xp_frame.cc | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/chrome/browser/simple_xp_frame.cc b/chrome/browser/simple_xp_frame.cc new file mode 100644 index 0000000..c2038ea --- /dev/null +++ b/chrome/browser/simple_xp_frame.cc @@ -0,0 +1,423 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "chrome/browser/simple_xp_frame.h" + +#include "chrome/app/theme/theme_resources.h" +#include "base/string_util.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents.h" +#include "chrome/browser/tab_contents_container_view.h" +#include "chrome/browser/tabs/tab.h" +#include "chrome/browser/views/location_bar_view.h" +#include "chrome/browser/web_app.h" +#include "chrome/browser/web_app_icon_manager.h" +#include "chrome/browser/web_contents.h" +#include "chrome/common/win_util.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/gfx/chrome_canvas.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/common/l10n_util.h" +#include "chrome/views/focus_manager.h" +#include "chrome/views/label.h" +#include "chrome/views/text_field.h" +#include "net/base/net_util.h" +#include "SkBitmap.h" + +#include "generated_resources.h" + +// The title bar text color. +static const SkColor kTitleBarTextColor = SkColorSetRGB(255, 255, 255); + +// How thick is the top resize bar. +static const int kTopResizeBarHeight = 3; + +// Left margin on the left side of the favicon. +static const int kFavIconMargin = 2; + +// Padding between the favicon and the text. +static const int kFavIconPadding = 4; + +// Background color for the button hot state. +static const SkColor kHotColor = SkColorSetRGB(49, 106, 197); + +// distance between contents and drop arrow. +static const int kHorizMargin = 4; + +// Border all around the menu. +static const int kHorizBorderSize = 2; +static const int kVertBorderSize = 1; + +// How much wider or shorter the location bar is relative to the client area. +static const int kLocationBarOffset = 2; +// Spacing between the location bar and the content area. +static const int kLocationBarSpacing = 1; + +//////////////////////////////////////////////////////////////////////////////// +// +// TitleBarMenuButton implementation. +// +//////////////////////////////////////////////////////////////////////////////// +TitleBarMenuButton::TitleBarMenuButton(SimpleXPFrameTitleBar* title_bar) + : ChromeViews::MenuButton(L"", title_bar, false), + contents_(NULL), + title_bar_(title_bar) { + ResourceBundle &rb = ResourceBundle::GetSharedInstance(); + drop_arrow_ = rb.GetBitmapNamed(IDR_APP_DROPARROW); +} + +TitleBarMenuButton::~TitleBarMenuButton() { +} + +void TitleBarMenuButton::SetContents(ChromeViews::View* contents) { + contents_ = contents; +} + +void TitleBarMenuButton::GetPreferredSize(CSize *out) { + if (contents_) + contents_->GetPreferredSize(out); + else + out->cx = out->cy = 0; + + out->cx += drop_arrow_->width() + kHorizMargin + (2 * kHorizBorderSize); + out->cy = std::max(drop_arrow_->height(), static_cast<int>(out->cy)); + out->cy += (2 * kVertBorderSize); +} + +void TitleBarMenuButton::Paint(ChromeCanvas* canvas) { + if (GetState() == TextButton::BS_HOT || + GetState() == TextButton::BS_PUSHED || menu_visible_) { + canvas->FillRectInt(kHotColor, 0, 0, GetWidth(), GetHeight()); + } + + if (contents_) { + CSize s; + contents_->GetPreferredSize(&s); + // Note: we use a floating view in this case because we never want the + // contents to process any event. + PaintFloatingView(canvas, + contents_, + kVertBorderSize, + (GetHeight() - s.cy) / 2, + GetWidth() - kHorizMargin - drop_arrow_->width() - + (2 * kHorizBorderSize), + s.cy); + } + + // We can not use the mirroring infrastructure in ChromeViews in order to + // mirror the drop down arrow because is is drawn directly on the canvas + // (instead of using a child View). Thus, we should mirror its position + // manually. + gfx::Rect arrow_bounds(GetWidth() - drop_arrow_->width() - kHorizBorderSize, + (GetHeight() - drop_arrow_->height()) / 2, + drop_arrow_->width(), + drop_arrow_->height()); + arrow_bounds.set_x(MirroredLeftPointForRect(arrow_bounds)); + canvas->DrawBitmapInt(*drop_arrow_, arrow_bounds.x(), arrow_bounds.y()); +} + +bool TitleBarMenuButton::OnMousePressed(const ChromeViews::MouseEvent& e) { + if (e.GetFlags() & ChromeViews::MouseEvent::EF_IS_DOUBLE_CLICK) { + if (!HitTest(e.GetLocation())) + return true; + title_bar_->CloseWindow(); + return true; + } else { + return MenuButton::OnMousePressed(e); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// SimpleXPFrameTitleBar implementation. +// +//////////////////////////////////////////////////////////////////////////////// + +SimpleXPFrameTitleBar::SimpleXPFrameTitleBar(SimpleXPFrame* parent) + : parent_(parent) { + DCHECK(parent); + tab_icon_.reset(new TabIconView(this)); + tab_icon_->set_is_light(true); + menu_button_ = new TitleBarMenuButton(this); + menu_button_->SetContents(tab_icon_view()); + AddChildView(menu_button_); + + tab_icon_->Update(); + + label_ = new ChromeViews::Label(); + label_->SetColor(kTitleBarTextColor); + label_->SetHorizontalAlignment(ChromeViews::Label::ALIGN_LEFT); + AddChildView(label_); +} + +SimpleXPFrameTitleBar::~SimpleXPFrameTitleBar() { +} + +TabContents* SimpleXPFrameTitleBar::GetCurrentTabContents() { + return parent_->GetCurrentContents(); +} + +SkBitmap SimpleXPFrameTitleBar::GetFavIcon() { + // Only use the favicon if we're a web application. + TabContents* contents = GetCurrentTabContents(); + if (parent_->IsApplication()) { + TabContents* contents = GetCurrentTabContents(); + WebContents* web_contents = contents->AsWebContents(); + if (web_contents) { + // If it's a web contents, pull the favicon from the WebApp, and fallback + // to the icon. + WebApp* web_app = web_contents->web_app(); + if (web_app && !web_app->GetFavIcon().isNull()) + return web_app->GetFavIcon(); + } + if (contents) { + SkBitmap favicon = contents->GetFavIcon(); + if (!favicon.isNull()) + return favicon; + } + } + + // Otherwise, use the default icon. + return SkBitmap(); +} + +void SimpleXPFrameTitleBar::RunMenu(ChromeViews::View* source, + const CPoint& pt, HWND hwnd) { + // Make sure we calculate the menu position based on the display bounds of + // the menu button. The display bounds are different than the actual bounds + // when the UI layout is RTL and hence we use the mirroring transformation + // flag. We also adjust the menu position because RTL menus use a different + // anchor point. + CPoint p(menu_button_->GetX(APPLY_MIRRORING_TRANSFORMATION), + menu_button_->GetY() + menu_button_->GetHeight()); + + if (UILayoutIsRightToLeft()) + p.x += menu_button_->GetWidth(); + View::ConvertPointToScreen(this, &p); + parent_->RunMenu(p, hwnd); +} + +void SimpleXPFrameTitleBar::Layout() { + CSize s; + menu_button_->GetPreferredSize(&s); + menu_button_->SetBounds(kFavIconMargin, 1 + (GetHeight() - s.cy) / 2, + s.cx, s.cy); + menu_button_->Layout(); + label_->SetBounds(menu_button_->GetX() + menu_button_->GetWidth() + + kFavIconPadding, 0, + GetWidth() - (menu_button_->GetX() + + menu_button_->GetWidth() + kFavIconPadding), + GetHeight()); +} + +bool SimpleXPFrameTitleBar::WillHandleMouseEvent(int x, int y) { + // If the locale is RTL, we must query for the bounds of the menu button in + // a way that returns the mirrored position and not the position set using + // SetX()/SetBounds(). + CPoint p(x - menu_button_->GetX(APPLY_MIRRORING_TRANSFORMATION), + y - menu_button_->GetY()); + return menu_button_->HitTest(p); +} + +void SimpleXPFrameTitleBar::SetWindowTitle(std::wstring s) { + if (parent_->IsApplication()) { + std::wstring t(s); + Tab::FormatTitleForDisplay(&t); + label_->SetText(t); + } else { + label_->SetText(Browser::ComputePopupTitle( + GetCurrentTabContents()->GetURL(), s)); + } +} + +void SimpleXPFrameTitleBar::ValidateThrobber() { + tab_icon_->Update(); + menu_button_->SchedulePaint(); +} + +void SimpleXPFrameTitleBar::CloseWindow() { + parent_->Close(); +} + +void SimpleXPFrameTitleBar::Update() { + tab_icon_->Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// SimpleXPFrame implementation. +// +//////////////////////////////////////////////////////////////////////////////// + +// static +SimpleXPFrame* SimpleXPFrame::CreateFrame(const gfx::Rect& bounds, + Browser* browser) { + SimpleXPFrame* instance = new SimpleXPFrame(browser); + instance->Create(NULL, bounds.ToRECT(), + l10n_util::GetString(IDS_PRODUCT_NAME).c_str()); + instance->InitAfterHWNDCreated(); + instance->SetIsOffTheRecord(browser->profile()->IsOffTheRecord()); + ChromeViews::FocusManager::CreateFocusManager(instance->m_hWnd, + instance->GetRootView()); + return instance; +} + +SimpleXPFrame::SimpleXPFrame(Browser* browser) + : XPFrame(browser), + title_bar_(NULL), + location_bar_(NULL) { +} + +void SimpleXPFrame::InitAfterHWNDCreated() { + icon_manager_.reset(new WebAppIconManager(*this)); + XPFrame::InitAfterHWNDCreated(); +} + +SimpleXPFrame::~SimpleXPFrame() { +} + +void SimpleXPFrame::Init() { + XPFrame::Init(); + if (IsTitleBarVisible()) { + title_bar_ = new SimpleXPFrameTitleBar(this); + GetFrameView()->AddChildView(title_bar_); + } + + location_bar_ = new LocationBarView(browser_->profile(), + browser_->controller(), + browser_->toolbar_model(), + this, true); + GetFrameView()->AddChildView(location_bar_); + location_bar_->Init(); + + // Constrained popups that were unconstrained will need to set up a + // throbber. + UpdateTitleBar(); +} + +TabContents* SimpleXPFrame::GetCurrentContents() { + if (browser_) + return browser_->GetSelectedTabContents(); + else + return NULL; +} + +void SimpleXPFrame::Layout() { + XPFrame::Layout(); + if (IsTitleBarVisible()) { + TabContentsContainerView* tccv = GetTabContentsContainer(); + DCHECK(tccv); + title_bar_->SetBounds(tccv->GetX(), 0, + GetButtonXOrigin() - tccv->GetX(), + GetContentsYOrigin()); + title_bar_->Layout(); + } + + if (browser_->ShouldDisplayURLField()) { + TabContentsContainerView* container = GetTabContentsContainer(); + CSize s; + location_bar_->GetPreferredSize(&s); + location_bar_->SetBounds(container->GetX() - kLocationBarOffset, + container->GetY(), + container->GetWidth() + kLocationBarOffset * 2, + s.cy); + container->SetBounds(container->GetX(), + location_bar_->GetY() + location_bar_->GetHeight() + + kLocationBarSpacing, container->GetWidth(), + container->GetHeight() - location_bar_->GetHeight() - + 1); + location_bar_->SetVisible(true); + location_bar_->Layout(); + } else { + location_bar_->SetVisible(false); + } +} + +LRESULT SimpleXPFrame::OnNCHitTest(const CPoint& pt) { + if (IsTitleBarVisible()) { + CPoint p(pt); + ChromeViews::View::ConvertPointToView(NULL, title_bar_, &p); + if (!title_bar_->WillHandleMouseEvent(p.x, p.y) && + p.x >= 0 && p.y >= kTopResizeBarHeight && + p.x < title_bar_->GetWidth() && + p.y < title_bar_->GetHeight()) { + return HTCAPTION; + } + } + return XPFrame::OnNCHitTest(pt); +} + +void SimpleXPFrame::SetWindowTitle(const std::wstring& title) { + if (IsTitleBarVisible()) + title_bar_->SetWindowTitle(title); + XPFrame::SetWindowTitle(title); +} + +void SimpleXPFrame::UpdateTitleBar() { + if (IsTitleBarVisible()) { + title_bar_->Update(); + title_bar_->SchedulePaint(); + } + UpdateLocationBar(); +} + +void SimpleXPFrame::ValidateThrobber() { + if (IsTitleBarVisible()) + title_bar_->ValidateThrobber(); +} + +void SimpleXPFrame::RunMenu(const CPoint& pt, HWND hwnd) { + browser_->RunSimpleFrameMenu(pt, hwnd); +} + +void SimpleXPFrame::ShowTabContents(TabContents* selected_contents) { + XPFrame::ShowTabContents(selected_contents); + + icon_manager_->SetContents(selected_contents); + + UpdateLocationBar(); +} + +bool SimpleXPFrame::IsApplication() const { + return browser_->IsApplication(); +} + +void SimpleXPFrame::UpdateLocationBar() { + if (location_bar_ && location_bar_->IsVisible()) + location_bar_->Update(NULL); +} + +TabContents* SimpleXPFrame::GetTabContents() { + return GetCurrentContents(); +} + +void SimpleXPFrame::OnInputInProgress(bool in_progress) { +} |