diff options
-rw-r--r-- | chrome/app/theme/filebrowse_fullscreen.png | bin | 0 -> 1347 bytes | |||
-rw-r--r-- | chrome/app/theme/theme_resources.grd | 1 | ||||
-rw-r--r-- | chrome/browser/browser_resources.grd | 2 | ||||
-rw-r--r-- | chrome/browser/dom_ui/filebrowse_ui.cc | 86 | ||||
-rw-r--r-- | chrome/browser/resources/filebrowse.html | 327 |
5 files changed, 382 insertions, 34 deletions
diff --git a/chrome/app/theme/filebrowse_fullscreen.png b/chrome/app/theme/filebrowse_fullscreen.png Binary files differnew file mode 100644 index 0000000..6f8ff12 --- /dev/null +++ b/chrome/app/theme/filebrowse_fullscreen.png diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 1e7cd38..bf7187d 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -420,6 +420,7 @@ <include name="IDR_ICON_PHOTO" file="icon_photo.png" type="BINDATA" /> <include name="IDR_ICON_WEBPAGE" file="icon_webpage.png" type="BINDATA" /> <include name="IDR_FILEBROWSER_UPLOAD" file="filebrowse_upload.png" type="BINDATA" /> + <include name="IDR_FILEBROWSER_FULLSCREEN" file="filebrowse_fullscreen.png" type="BINDATA" /> </if> <if expr="(pp_ifdef('chromeos') or pp_ifdef('toolkit_views')) and pp_ifdef('_google_chrome')"> diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 2940bef..fd17ea6 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This comment is only here because changes to resources are not picked up -without changes to the corresponding grd file. dhg testing --> +without changes to the corresponding grd file. dhg teammmmiiqsing --> <grit latest_public_release="0" current_release="1"> <outputs> <output filename="grit/browser_resources.h" type="rc_header"> diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc index 6e67a6f..68dbd21 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -8,6 +8,7 @@ #include "app/resource_bundle.h" #include "base/logging.h" #include "base/message_loop.h" +#include "base/path_service.h" #include "base/singleton.h" #include "base/string_piece.h" #include "base/string_util.h" @@ -24,6 +25,7 @@ #include "chrome/browser/net/url_fetcher.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/profile.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/time_format.h" #include "chrome/common/url_constants.h" @@ -34,6 +36,10 @@ #include "grit/generated_resources.h" #include "grit/locale_settings.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/mount_library.h" +#endif + // Maximum number of search results to return in a given search. We should // eventually remove this. static const int kMaxSearchResults = 100; @@ -70,6 +76,9 @@ class TaskProxy; // The handler for Javascript messages related to the "filebrowse" view. class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, public DOMMessageHandler, +#if defined(OS_CHROMEOS) + public chromeos::MountLibrary::Observer, +#endif public base::SupportsWeakPtr<FilebrowseHandler>, public URLFetcher::Delegate { public: @@ -84,6 +93,12 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, virtual DOMMessageHandler* Attach(DOMUI* dom_ui); virtual void RegisterMessages(); +#if defined(OS_CHROMEOS) + void MountChanged(chromeos::MountLibrary* obj, + chromeos::MountEventType evt, + const std::string& path); +#endif + // Callback for the "getRoots" message. void HandleGetRoots(const Value* value); @@ -128,7 +143,7 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { public: - TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler) + explicit TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler) : handler_(handler) {} void ReadInFileProxy() { if (handler_) { @@ -187,11 +202,18 @@ void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path, FilebrowseHandler::FilebrowseHandler() : profile_(NULL) { // TODO(dhg): Check to see if this is really necessary +#if defined(OS_CHROMEOS) + chromeos::MountLibrary* lib = chromeos::MountLibrary::Get(); + lib->AddObserver(this); +#endif lister_ = NULL; } FilebrowseHandler::~FilebrowseHandler() { - // TODO(dhg): Cancel any pending listings that are currently in flight. +#if defined(OS_CHROMEOS) + chromeos::MountLibrary* lib = chromeos::MountLibrary::Get(); + lib->RemoveObserver(this); +#endif if (lister_.get()) { lister_->Cancel(); lister_->set_delegate(NULL); @@ -251,6 +273,17 @@ void FilebrowseHandler::FireUploadComplete() { dom_ui_->CallJavascriptFunction(L"uploadComplete", info_value); } +#if defined(OS_CHROMEOS) +void FilebrowseHandler::MountChanged(chromeos::MountLibrary* obj, + chromeos::MountEventType evt, + const std::string& path) { + if (evt == chromeos::DISK_REMOVED || + evt == chromeos::DISK_CHANGED) { + dom_ui_->CallJavascriptFunction(L"rootsChanged"); + } +} +#endif + void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source, const GURL& url, const URLRequestStatus& status, @@ -267,16 +300,47 @@ void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source, void FilebrowseHandler::HandleGetRoots(const Value* value) { ListValue results_value; DictionaryValue info_value; - DictionaryValue* page_value = new DictionaryValue(); // TODO(dhg): add other entries, make this more general - page_value->SetString(kPropertyPath, "/home/chronos"); - page_value->SetString(kPropertyTitle, "home"); +#if defined(OS_CHROMEOS) + chromeos::MountLibrary* lib = chromeos::MountLibrary::Get(); + const chromeos::MountLibrary::DiskVector& disks = lib->disks(); + + for (size_t i = 0; i < disks.size(); ++i) { + if (!disks[i].mount_path.empty()) { + DictionaryValue* page_value = new DictionaryValue(); + page_value->SetString(kPropertyPath, disks[i].mount_path); + FilePath currentpath; + currentpath = FilePath(disks[i].mount_path); + std::string filename; + filename = currentpath.BaseName().value(); + page_value->SetString(kPropertyTitle, filename); + page_value->SetBoolean(kPropertyDirectory, true); + results_value.Append(page_value); + } + } +#else + DictionaryValue* page_value = new DictionaryValue(); + page_value->SetString(kPropertyPath, "/media"); + page_value->SetString(kPropertyTitle, "Removeable"); page_value->SetBoolean(kPropertyDirectory, true); results_value.Append(page_value); +#endif + FilePath default_download_path; + if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, + &default_download_path)) { + NOTREACHED(); + } - info_value.SetString(L"functionCall", "getRoots"); + DictionaryValue* download_value = new DictionaryValue(); + download_value->SetString(kPropertyPath, default_download_path.value()); + download_value->SetString(kPropertyTitle, "File Shelf"); + download_value->SetBoolean(kPropertyDirectory, true); + + results_value.Append(download_value); + info_value.SetString(L"functionCall", "getRoots"); + info_value.SetString(kPropertyPath, ""); dom_ui_->CallJavascriptFunction(L"browseFileResult", info_value, results_value); } @@ -443,6 +507,16 @@ void FilebrowseHandler::HandleGetChildren(const Value* value) { void FilebrowseHandler::OnListFile( const file_util::FileEnumerator::FindInfo& data) { +#if defined(OS_WIN) + if (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + return; + } +#elif defined(OS_POSIX) + if (data.filename[0] == '.') { + return; + } +#endif + DictionaryValue* file_value = new DictionaryValue(); #if defined(OS_WIN) diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html index 12f133c..4189d68 100644 --- a/chrome/browser/resources/filebrowse.html +++ b/chrome/browser/resources/filebrowse.html @@ -6,12 +6,14 @@ <style type="text/css"> div.header { border-bottom: 1px solid #006; + border-left: 1px solid #006; + border-right: 1px solid #006; padding: 8px; margin: 0; width: 100%; left: 0; top: 0; - min-height: 26px; + height: 30px; position: absolute; -webkit-box-sizing: border-box; box-sizing: border-box; @@ -22,9 +24,18 @@ div.header { to(rgba(201, 212, 245, 1))); border-bottom-color: #999; border-bottom-width: 1px; + border-left-color: #999; + border-left-width: 1px; + border-right-color: #999; + border-right-width: 1px; color: black; } +.rowlink { + height: 100%; + width: 90%; +} + a.iconlink { display: block; font-family: helvetica; @@ -45,6 +56,47 @@ ul.filebrowselist { position: relative; } +.playbackelement { + width: 600px; + height: 600px; + position: fixed; + right: 0; + top: 0; + z-index:99999; + background:black; +} + +.fullscreenplayback { + width: 100%; + height: 100%; + position: fixed; + left: 0; + top: 0; + z-index:99999; + background:black; +} + +.imagepreview { + width: 600px; + position: fixed; + right: 0; + top: 0; + z-index:99999; + background:black; +} + +.fullscreentoggle { + top: 0; + right: 0; + width: 50px; + height: 50px; + z-index: 999999; + cursor: pointer; + background: url('../../app/theme/filebrowse_fullscreen.png'); + position:absolute; + background-repeat: no-repeat; +} + li.filebrowserow div.icon { float: left; margin-left: -44px; @@ -113,6 +165,7 @@ li.filebrowserow span.name { margin-top: 10px; margin-left: -22px; position: relative; + text-decoration:underline; } div.title { @@ -120,21 +173,37 @@ div.title { position: relative; font-size: .8em; font-weight: bold; - padding-top: 10px; + padding-top: 2px; } div.controlbutton { width: 20px; display:inline; position: absolute; - z-index:9999; + z-index:999; border:1px solid #abb6ce; background-color: #f5f7fc; padding-left: 7px; - padding-top: 4px; + padding-top: 2px; padding-bottom: 4px; padding-right: 7px; - height: 20px; + height: 15px; +} + +div.column { + width:250px; + height: 100%; + float:left; + position: relative; +} + +div.columnlist { + width: 100%; + bottom: 0; + top:30px; + position:absolute; + overflow-y:scroll; + overflow-x:hidden; } div.iconmedia { @@ -161,14 +230,14 @@ div.backbutton { -webkit-border-top-left-radius: 5px; -webkit-border-bottom-left-radius: 5px; left: 10px; - top: 10px + top: 5px } div.fwdbutton { -webkit-border-top-right-radius: 5px; -webkit-border-bottom-right-radius: 5px; left: 45px; - top: 10px; + top: 5px; } div.playbackcontainer { @@ -189,9 +258,37 @@ div.scanningcontainer { } div.container { - top: 50px; + top: 0; position: absolute; - width: 95%; + width: 100%; + left: 0; + bottom: 0; +} + +div.fullcontainer { + top: 0px; + position: absolute; + left: 0; + bottom: 0; + right: 600px; + overflow-y: hidden; + overflow-x: scroll; +} + +.popout { + right: 10px; + top: 10px; + width: 15px; + text-align: center; + height: 10px; + font-size: .4em; + background: rgb(239, 242, 249); + cursor: pointer; + z-index:99999; + padding-top: 1px; + border: 1px solid #999; + position: absolute; + -webkit-border-radius: 5px; } .mediacontainer { @@ -253,6 +350,12 @@ var pathArray = []; var currentNode = -1; var foundImages = []; var currentImageMenu = ''; +var inFullMode = false; +var videoPlaybackElement = null; +var photoPreviewElement = null; +var numColumns = 0; +var divArray = []; +var rootsDiv = null; function goBackInList() { if (currentNode > 0) { @@ -261,20 +364,88 @@ function goBackInList() { } }; +function toggleFullscreen() { + if (videoPlaybackElement != null) { + if (videoPlaybackElement.className == 'fullscreenplayback') { + videoPlaybackElement.className = 'playbackelement'; + } else { + videoPlaybackElement.className = 'fullscreenplayback'; + } + } +}; + function goForwardInList() { if (currentNode < (pathArray.length - 1)) { currentNode++; getDataForPath(pathArray[currentNode]); } }; +var lastScrollLeft = 0; +function animateScrollRight() { + + var main = $('main'); + main.scrollLeft += 20; + // since if its larger than a size, we know we reached the leftmost part when + // it stops growing, so clear it out and no more timeouts. + if (lastScrollLeft != main.scrollLeft) { + lastScrollLeft = main.scrollLeft; + setTimeout("animateScrollRight()", 15); + } else { + lastScrollLeft = 0; + } + +}; + +function getCurrentContainer() { + if (inFullMode) { + var newContainer = document.createElement('div'); + var main = $('inner'); + numColumns++; + main.style.width = (numColumns * 250) + 'px'; + newContainer.className = 'column'; + main.appendChild(newContainer); + animateScrollRight(); + return newContainer; + } else { + return $('main'); + } +}; + +function clearList(list) { + if (list.hasChildNodes()) { + while (list.childNodes.length >=1) { + list.removeChild(list.firstChild); + } + } +}; + +function rootsChanged() { + if (inFullMode) { + chrome.send('getRoots', []); + } +}; function browseFileResult(info, results) { - if (info.functionCall == 'getRoots' || - info.functionCall == 'getChildren') { - currentNode++; - createNewList('Removeable Media', results); + var lastDirArray = info.path.split('/'); + var lastDir = lastDirArray[lastDirArray.length - 1]; + if (info.functionCall == 'getRoots') { + if (rootsDiv) { + clearList(rootsDiv); + createNewList(lastDir, results, rootsDiv, info.path); + } else { + var main = getCurrentContainer(); + rootsDiv = main; + divArray.push(main); + + createNewList(lastDir, results, main, info.path); + } + } else if (info.functionCall == 'getChildren') { + var main = getCurrentContainer(); + divArray.push(main); + + createNewList(lastDir, results, main, info.path); } -} +}; function pathIsVideoFile(path) { return /\.(mp4|ogg|mpg|avi)$/i.test(path); @@ -288,6 +459,10 @@ function pathIsImageFile(path) { return /\.(jpg|png|gif)$/i.test(path); }; +function moveScrollLeft() { + var main = $('main'); + main.scrollLeft += 10; +} function setUpForPlayback(path) { var mediapath = 'file://' + path; @@ -347,6 +522,20 @@ function setUpForScanning() { * Window onload handler, sets up the page. */ function load() { + if(document.documentElement.clientWidth <= 400) { + inFullMode = false; + } else { + var main = $('main'); + main.className = 'fullcontainer'; + var innerContainer = document.createElement('div'); + innerContainer.className = 'container'; + innerContainer.id = 'inner'; + main.appendChild(innerContainer); + inFullMode = true; + $('back').style.display = 'none'; + $('fwd').style.display = 'none'; + } + if (document.location.href.indexOf('#') != -1) { var currentpathArray = document.location.href.split('#'); var path = currentpathArray[1]; @@ -355,30 +544,90 @@ function load() { } else if (pathIsVideoFile(path) || pathIsAudioFile(path)) { setUpForPlayback(path); } else { + currentNode++; pathArray.push(path); getDataForPath(path); } } else { + currentNode++; pathArray.push('roots'); getDataForPath('roots'); } }; -function descend(path) { +function jumpToNode(nodeNumber) { + if (currentNode == nodeNumber) { + return; + } + if (inFullMode) { + var main = $('inner'); + for (var x = (nodeNumber+1); x < divArray.length ; x++ ) { + main.removeChild(divArray[x]); + numColumns--; + } + divArray = divArray.slice(0,nodeNumber+1); + } + currentNode = nodeNumber; +} + +function descend(path, nodeNumber) { if (pathArray.length <currentNode) { pathArray = pathArray.slice(0, currentNode); } + jumpToNode(nodeNumber); + currentNode++; pathArray.push(path); getDataForPath(path); }; +function clearPreviewPane() { + if (videoPlaybackElement != null) { + document.body.removeChild($('fullscreentoggle')); + document.body.removeChild(videoPlaybackElement); + videoPlaybackElement = null; + } + if (photoPreviewElement != null) { + document.body.removeChild(photoPreviewElement); + photoPreviewElement = null; + } +}; + function playMediaFile(path) { - var newPath = 'chrome://filebrowse#' + path; - chrome.send('openNewPopupWindow', [newPath]); + if (inFullMode) { + if (videoPlaybackElement == null) { + videoPlaybackElement = document.createElement('video'); + videoPlaybackElement.className = 'playbackelement'; + videoPlaybackElement.autoplay = true; + videoPlaybackElement.controls = true; + videoPlaybackElement.src = 'file://' + path; + var toggleButton = document.createElement('div'); + toggleButton.className = 'fullscreentoggle'; + toggleButton.id = 'fullscreentoggle'; + toggleButton.onclick = toggleFullscreen; + document.body.appendChild(toggleButton); + document.body.appendChild(videoPlaybackElement); + } else { + videoPlaybackElement.src = 'file://' + path; + } + } else { + var newPath = 'chrome://filebrowse#' + path; + chrome.send('openNewPopupWindow', [newPath]); + } }; function showImage(path) { - chrome.send('openNewFullWindow', ['file://' + path]); + if (inFullMode) { + if (photoPreviewElement == null) { + photoPreviewElement = document.createElement('img'); + photoPreviewElement.className = 'imagepreview'; + photoPreviewElement.src = 'file://' + path; + document.body.appendChild(photoPreviewElement); + } else { + photoPreviewElement.src = 'file://' + path; + } + } else { + chrome.send('openNewFullWindow', ['file://' + path]); + } }; function clearImageMenus() { @@ -423,7 +672,7 @@ function uploadComplete(result) { // TODO(dhg): Do not use javascript: href, use onclick instead function createHrefForItem(path, isDirectory) { if (isDirectory) { - return 'javascript:descend("' + path + '");'; + return 'javascript:descend("' + path + '", ' + currentNode + ');'; } if (pathIsAudioFile(path)) { return 'javascript:playMediaFile("' + path + '");'; } if (pathIsVideoFile(path)) { @@ -492,32 +741,56 @@ function clearChildren(element) { element.innerHTML = ''; }; -function createNewList(title, results) { +function popout(path) { + var newPath = 'chrome://filebrowse#' + path; + chrome.send('openNewPopupWindow', [newPath]); +}; + +function createNewList(title, results, main, path) { + clearChildren(main); + + var mainList = document.createElement('div'); + mainList.className = 'columnlist'; var list = document.createElement('ul'); list.className = 'filebrowselist'; - var header = $('currenttitle'); - header.innerHTML = title; + + var header = document.createElement('div'); + header.className = 'header'; + var divTitle = document.createElement('div'); + divTitle.className = 'title'; + if (inFullMode) { + divTitle.style['text-align'] = 'center'; + } + divTitle.innerHTML = title; + if (inFullMode && (path.length != 0)) { + var popOutButton = document.createElement('div'); + popOutButton.innerHTML = '∏'; + popOutButton.className = 'popout'; + popOutButton.onclick = new Function('popout("' + path + '");'); + header.appendChild(popOutButton); + } + header.appendChild(divTitle); + main.appendChild(header); + main.appendChild(mainList); for (var x=0; x < results.length; x++) { var element = createNewItem(results[x].title, results[x].path, results[x].isDirectory); list.appendChild(element); } - var main = $('main'); - clearChildren(main); - main.appendChild(list); + mainList.appendChild(list); }; </script> <body onload="load();" onclick='clearImageMenus()'> -<div id='header' class='header'> +<div id='header' class=''> <div id='back' class='backbutton controlbutton' onclick='goBackInList();return false;'> <img src="../../app/theme/filebrowse_back.png" width='100%' height='100%'> </div> <div id='fwd' class='fwdbutton controlbutton' onclick='goForwardInList();return false;'> <img src="../../app/theme/filebrowse_forward.png" width='100%' height='100%'> </div> - <div id='currenttitle' class='title'></div> + <div id='currenttitle' class=''></div> </div><br> <div id='main' class='container'></div> </body> |