From 6b270734efef579d320adce73f9717db5604a6ae Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Fri, 13 Mar 2015 17:02:46 -0700 Subject: [PATCH] feat(title-bar): Custom titlebar in main app window (darwin-only) Summary: Only applies to the main window. Will be applied to secondary windows like the composer when design decides whether that window will have a toolbar. (white or gray at the top?) Test Plan: Run tests Reviewers: evan Reviewed By: evan Differential Revision: https://review.inboxapp.com/D1298 --- .../composer/lib/file-uploads.cjsx | 2 +- .../message-list/lib/message-list.cjsx | 2 +- src/atom.coffee | 4 + src/browser/atom-window.coffee | 2 +- src/browser/edgehill-application.coffee | 7 +- src/components/retina-img.cjsx | 1 + src/flux/stores/file-upload-store.coffee | 2 +- src/sheet-container.cjsx | 15 ++-- src/titlebar.cjsx | 13 ++++ static/workspace.less | 74 +++++++++++++++++++ 10 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 src/titlebar.cjsx diff --git a/internal_packages/composer/lib/file-uploads.cjsx b/internal_packages/composer/lib/file-uploads.cjsx index 8686b13e4..91c672412 100644 --- a/internal_packages/composer/lib/file-uploads.cjsx +++ b/internal_packages/composer/lib/file-uploads.cjsx @@ -35,7 +35,7 @@ FileUpload = React.createClass module.exports = FileUploads = React.createClass getInitialState: -> - uploads: FileUploadStore.uploadsForMessage(@props.localId) ? {} + uploads: FileUploadStore.uploadsForMessage(@props.localId) ? [] componentDidMount: -> @storeUnlisten = FileUploadStore.listen(@_onFileUploadStoreChange) diff --git a/internal_packages/message-list/lib/message-list.cjsx b/internal_packages/message-list/lib/message-list.cjsx index 65a710e20..bdab6e798 100755 --- a/internal_packages/message-list/lib/message-list.cjsx +++ b/internal_packages/message-list/lib/message-list.cjsx @@ -178,5 +178,5 @@ MessageList = React.createClass scrollTo = currentHeight - msgToScroll.getBoundingClientRect().height @getDOMNode().scrollTop = scrollTo -MessageList.minWidth = 600 +MessageList.minWidth = 680 MessageList.maxWidth = 900 diff --git a/src/atom.coffee b/src/atom.coffee index b58308f10..339e87df2 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -4,6 +4,7 @@ os = require 'os' path = require 'path' remote = require 'remote' shell = require 'shell' +React = require "react" _ = require 'underscore-plus' {deprecate} = require 'grim' @@ -458,6 +459,9 @@ class Atom extends Model maximize: -> ipc.send('call-window-method', 'maximize') + minimize: -> + ipc.send('call-window-method', 'minimize') + # Extended: Is the current window in full screen mode? isFullScreen: -> @getCurrentWindow().isFullScreen() diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 64bf958a4..3dc44eee3 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -25,7 +25,7 @@ class AtomWindow options = show: false - title: title ? 'Edgehill' + title: title ? 'Nilas' frame: frame ? true resizable: resizable ? true icon: @constructor.iconPath diff --git a/src/browser/edgehill-application.coffee b/src/browser/edgehill-application.coffee index bed938f47..4e2d7b3fa 100644 --- a/src/browser/edgehill-application.coffee +++ b/src/browser/edgehill-application.coffee @@ -399,7 +399,12 @@ class AtomApplication bootstrapScript ?= require.resolve('../window-bootstrap') resourcePath ?= @resourcePath neverClose = true - @mainWindow = new AtomWindow({bootstrapScript, resourcePath, devMode, safeMode, neverClose}) + frame = true + + if process.platform is 'darwin' + frame = false + + @mainWindow = new AtomWindow({bootstrapScript, resourcePath, devMode, safeMode, neverClose, frame}) # Public: Opens a secondary window, usually for displaying specific packages # diff --git a/src/components/retina-img.cjsx b/src/components/retina-img.cjsx index 0d1511afc..c741e4de3 100644 --- a/src/components/retina-img.cjsx +++ b/src/components/retina-img.cjsx @@ -36,6 +36,7 @@ RetinaImg = React.createClass pathIsRetina = path.indexOf('@2x') > 0 style = @props.style ? {} + style.WebkitUserDrag = 'none' style.zoom = if pathIsRetina then 0.5 else 1 for key, val of style diff --git a/src/flux/stores/file-upload-store.coffee b/src/flux/stores/file-upload-store.coffee index c2b4bbfa5..828fba9a3 100644 --- a/src/flux/stores/file-upload-store.coffee +++ b/src/flux/stores/file-upload-store.coffee @@ -26,7 +26,7 @@ FileUploadStore = Reflux.createStore ######### PUBLIC ####################################################### uploadsForMessage: (messageLocalId) -> - if not messageLocalId? then return {} + if not messageLocalId? then return [] _.filter @_fileUploads, (uploadData, uploadKey) -> uploadData.messageLocalId is messageLocalId diff --git a/src/sheet-container.cjsx b/src/sheet-container.cjsx index 0da610b76..4aae69f67 100644 --- a/src/sheet-container.cjsx +++ b/src/sheet-container.cjsx @@ -1,5 +1,6 @@ -React = require 'react' +React = require 'react/addons' Sheet = require './sheet' +TitleBar = require './titlebar' Flexbox = require './components/flexbox.cjsx' ReactCSSTransitionGroup = React.addons.CSSTransitionGroup @@ -13,7 +14,7 @@ ToolbarSpacer = React.createClass order: React.PropTypes.number render: -> -
+
Toolbar = React.createClass @@ -69,10 +70,14 @@ Toolbar = React.createClass components = items.map ({view, name}) => - + {components} - + recomputeLayout: -> @@ -148,7 +153,6 @@ FlexboxForRoles = React.createClass items = items.concat(ComponentRegistry.findAllByRole(role)) {items} - module.exports = SheetContainer = React.createClass className: 'SheetContainer' @@ -168,6 +172,7 @@ SheetContainer = React.createClass render: -> topSheetType = @state.stack[@state.stack.length - 1] +
diff --git a/src/titlebar.cjsx b/src/titlebar.cjsx new file mode 100644 index 000000000..0de77e0b4 --- /dev/null +++ b/src/titlebar.cjsx @@ -0,0 +1,13 @@ +React = require 'react' + +module.exports = +TitleBar = React.createClass + displayName: 'TitleBar' + + render: -> +
+ {atom.getCurrentWindow().getTitle()} + + + +
diff --git a/static/workspace.less b/static/workspace.less index db16a6a53..2573223fd 100644 --- a/static/workspace.less +++ b/static/workspace.less @@ -53,7 +53,74 @@ atom-workspace { left:100%; } +.sheet-title-bar { + height:24px; + line-height: 24px; + cursor: default; + background: @toolbar-background-color; + -webkit-app-region: drag; + padding: 3px; + padding-left:@spacing-half; + padding-right:60px; + text-align: center; + + button { + -webkit-app-region: no-drag; + display:inline-block; + padding:0; + width:13px; + height:13px; + margin:4px; + border-radius: 13px; + border: 1px solid rgba(0,0,0,0.2); + float:left; + } + .close { + background-color: #FB0015; + &:hover { + background-color: darken(#FB0015, 10%); + } + &:active { + background-color: darken(#FB0015, 20%); + } + } + .minimize { + background-color: #FCB40A; + &:hover { + background-color: darken(#FCB40A, 10%); + } + &:active { + background-color: darken(#FCB40A, 20%); + } + } + .maximize { + background-color: #0AAF00; + &:hover { + background-color: darken(#0AAF00, 10%); + } + &:active { + background-color: darken(#0AAF00, 20%); + } + } +} + +body.platform-win32, body.platform-linux { + .sheet-title-bar { + display:none; + } +} + +body.is-blurred { + .sheet-title-bar { + button { + background-color: desaturate(fade(#FCB40A, 20%), 100%); + } + } +} + .sheet-toolbar { + position: relative; + -webkit-app-region: drag; background: @toolbar-background-color; border-bottom: 1px solid @border-color-divider; width: 100%; @@ -68,6 +135,13 @@ atom-workspace { // to be one continuous bar. z-index: 10; + .item-container > * { + -webkit-app-region: no-drag; + } + .item-spacer { + -webkit-app-region: drag; + } + .btn-toolbar { margin-top: @spacing-half; margin-left: @spacing-three-quarters;