diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -149,6 +149,7 @@ 'rsrc/css/phui/phui-profile-menu.css' => '4a243229', 'rsrc/css/phui/phui-property-list-view.css' => '27b2849e', 'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591', + 'rsrc/css/phui/phui-segment-bar-view.css' => '728e4d19', 'rsrc/css/phui/phui-spacing.css' => '042804d6', 'rsrc/css/phui/phui-status.css' => '888cedb8', 'rsrc/css/phui/phui-tag-view.css' => '9d5d4400', @@ -825,6 +826,7 @@ 'phui-profile-menu-css' => '4a243229', 'phui-property-list-view-css' => '27b2849e', 'phui-remarkup-preview-css' => '1a8f2591', + 'phui-segment-bar-view-css' => '728e4d19', 'phui-spacing-css' => '042804d6', 'phui-status-list-view-css' => '888cedb8', 'phui-tag-view-css' => '9d5d4400', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1522,6 +1522,8 @@ 'PHUIPropertyListView' => 'view/phui/PHUIPropertyListView.php', 'PHUIRemarkupPreviewPanel' => 'view/phui/PHUIRemarkupPreviewPanel.php', 'PHUIRemarkupView' => 'infrastructure/markup/view/PHUIRemarkupView.php', + 'PHUISegmentBarSegmentView' => 'view/phui/PHUISegmentBarSegmentView.php', + 'PHUISegmentBarView' => 'view/phui/PHUISegmentBarView.php', 'PHUISpacesNamespaceContextView' => 'applications/spaces/view/PHUISpacesNamespaceContextView.php', 'PHUIStatusItemView' => 'view/phui/PHUIStatusItemView.php', 'PHUIStatusListView' => 'view/phui/PHUIStatusListView.php', @@ -5705,6 +5707,8 @@ 'PHUIPropertyListView' => 'AphrontView', 'PHUIRemarkupPreviewPanel' => 'AphrontTagView', 'PHUIRemarkupView' => 'AphrontView', + 'PHUISegmentBarSegmentView' => 'AphrontTagView', + 'PHUISegmentBarView' => 'AphrontTagView', 'PHUISpacesNamespaceContextView' => 'AphrontView', 'PHUIStatusItemView' => 'AphrontTagView', 'PHUIStatusListView' => 'AphrontTagView', diff --git a/src/applications/uiexample/examples/PhabricatorAphrontBarUIExample.php b/src/applications/uiexample/examples/PhabricatorAphrontBarUIExample.php --- a/src/applications/uiexample/examples/PhabricatorAphrontBarUIExample.php +++ b/src/applications/uiexample/examples/PhabricatorAphrontBarUIExample.php @@ -12,10 +12,7 @@ public function renderExample() { $out = array(); - $out[] = $this->renderTestThings('AphrontProgressBarView', 13, 10); - $out[] = $this->renderTestThings('AphrontGlyphBarView', 13, 10); - $out[] = $this->renderWeirdOrderGlyphBars(); - $out[] = $this->renderAsciiStarBar(); + $out[] = $this->renderRainbow(); return $out; } @@ -26,48 +23,46 @@ ->appendChild($thing); } - private function renderTestThings($class, $max, $incr) { + private function renderRainbow() { + $colors = array( + 'red', + 'orange', + 'yellow', + 'green', + 'blue', + 'indigo', + 'violet', + ); + + $labels = array( + pht('Empty'), + pht('Red'), + pht('Orange'), + pht('Yellow'), + pht('Green'), + pht('Blue'), + pht('Indigo'), + pht('Violet'), + ); + $bars = array(); - for ($ii = 0; $ii <= $max; $ii++) { - $bars[] = newv($class, array()) - ->setValue($ii * $incr) - ->setMax($max * $incr) - ->setCaption("{$ii} outta {$max} ain't bad!"); - } - return $this->wrap("Test {$class}", $bars); - } - private function renderWeirdOrderGlyphBars() { - $views = array(); - $indices = array(1, 3, 7, 4, 2, 8, 9, 5, 10, 6); - $max = count($indices); - foreach ($indices as $index) { - $views[] = id(new AphrontGlyphBarView()) - ->setValue($index) - ->setMax($max) - ->setNumGlyphs(5) - ->setCaption("Lol score is {$index}/{$max}") - ->setGlyph(hsprintf('%s', 'LOL!')) - ->setBackgroundGlyph(hsprintf('%s', '____')); - $views[] = hsprintf('
'); + for ($jj = -1; $jj < count($colors); $jj++) { + $bar = id(new PHUISegmentBarView()) + ->setLabel($labels[$jj + 1]); + for ($ii = 0; $ii <= $jj; $ii++) { + $bar->newSegment() + ->setWidth(1 / 7) + ->setColor($colors[$ii]); + } + $bars[] = $bar; } - return $this->wrap( - pht('Glyph bars in weird order'), - $views); - } - - private function renderAsciiStarBar() { - $bar = id(new AphrontGlyphBarView()) - ->setValue(50) - ->setMax(100) - ->setCaption(pht('Glyphs!')) - ->setNumGlyphs(10) - ->setGlyph(hsprintf('%s', '*')); + $bars = phutil_implode_html( + phutil_tag('br'), + $bars); - return $this->wrap( - pht('ASCII star glyph bar'), - $bar); + return $this->wrap(pht('Rainbow Bars'), $bars); } } diff --git a/src/view/phui/PHUISegmentBarSegmentView.php b/src/view/phui/PHUISegmentBarSegmentView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUISegmentBarSegmentView.php @@ -0,0 +1,57 @@ +width = $width; + return $this; + } + + public function getWidth() { + return $this->width; + } + + public function setColor($color) { + $this->color = $color; + return $this; + } + + public function setPosition($position) { + $this->position = $position; + return $this; + } + + protected function canAppendChild() { + return false; + } + + protected function getTagAttributes() { + $classes = array( + 'phui-segment-bar-segment-view', + ); + + if ($this->color) { + $classes[] = $this->color; + } + + // Convert width to a percentage, and round it up slightly so that bars + // are full if they have, e.g., three segments at 1/3 + 1/3 + 1/3. + $width = 100 * $this->width; + $width = ceil(100 * $width) / 100; + $width = sprintf('%.2f%%', $width); + + $left = 100 * $this->position; + $left = floor(100 * $left) / 100; + $left = sprintf('%.2f%%', $left); + + return array( + 'class' => implode(' ', $classes), + 'style' => "left: {$left}; width: {$width};", + ); + } + +} diff --git a/src/view/phui/PHUISegmentBarView.php b/src/view/phui/PHUISegmentBarView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUISegmentBarView.php @@ -0,0 +1,65 @@ +label = $label; + return $this; + } + + public function newSegment() { + $segment = new PHUISegmentBarSegmentView(); + $this->segments[] = $segment; + return $segment; + } + + protected function canAppendChild() { + return false; + } + + protected function getTagAttributes() { + return array( + 'class' => 'phui-segment-bar-view', + ); + } + + protected function getTagContent() { + require_celerity_resource('phui-segment-bar-view-css'); + + $label = $this->label; + if (strlen($label)) { + $label = phutil_tag( + 'div', + array( + 'class' => 'phui-segment-bar-label', + ), + $label); + } + + $segments = $this->segments; + + $position = 0; + foreach ($segments as $segment) { + $segment->setPosition($position); + $position += $segment->getWidth(); + } + + $segments = array_reverse($segments); + + $segments = phutil_tag( + 'div', + array( + 'class' => 'phui-segment-bar-segments', + ), + $segments); + + return array( + $label, + $segments, + ); + } + +} diff --git a/webroot/rsrc/css/phui/phui-segment-bar-view.css b/webroot/rsrc/css/phui/phui-segment-bar-view.css new file mode 100644 --- /dev/null +++ b/webroot/rsrc/css/phui/phui-segment-bar-view.css @@ -0,0 +1,71 @@ +/** + * @provides phui-segment-bar-view-css + */ + +.phui-segment-bar-label { + font-size: {$smallerfontsize}; + margin-bottom: 4px; +} + +.phui-segment-bar-segments { + background: {$lightgreybackground}; + border-radius: 4px; + position: relative; + overflow: hidden; + height: 8px; + border: 1px solid rgba(0, 0, 0, 0.15); +} + +.phui-segment-bar-segment-view { + position: absolute; + top: 0; + bottom: 0; + margin-left: -4px; + border-right: 5px solid; + border-radius: 0 4px 4px 0; +} + +.phui-segment-bar-segment-view.red { + background: {$red}; + border-color: {$red}; +} + +.phui-segment-bar-segment-view.orange { + background: {$orange}; + border-color: {$orange}; +} + +.phui-segment-bar-segment-view.yellow { + background: {$yellow}; + border-color: {$yellow} +} + +.phui-segment-bar-segment-view.green { + background: {$green}; + border-color: {$green}; +} + +.phui-segment-bar-segment-view.blue { + background: {$blue}; + border-color: {$blue}; +} + +.phui-segment-bar-segment-view.indigo { + background: {$indigo}; + border-color: {$indigo}; +} + +.phui-segment-bar-segment-view.violet { + background: {$violet}; + border-color: {$violet}; +} + +.phui-segment-bar-segment-view.pink { + background: {$pink}; + border-color: {$pink}; +} + +.phui-segment-bar-segment-view.sky { + background: {$sky}; + border-color: {$sky}; +}