@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

AphrontBars

Summary: Aphront widgets that render the either a discrete or continuous value as a horizontal shape. Like a progress bar, or a five-star rating bar.

Test Plan:
`/uiexample/view/PhabricatorAphrontBarExample/` ...which shows this, amongst other things:

{F33898}

Reviewers: epriestley, chad

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2094

Differential Revision: https://secure.phabricator.com/D5122

+417
+9
src/__celerity_resource_map__.php
··· 604 604 ), 605 605 'disk' => '/rsrc/css/aphront/attached-file-view.css', 606 606 ), 607 + 'aphront-bars' => 608 + array( 609 + 'uri' => '/res/d7bd9032/rsrc/css/core/aphront-bars.css', 610 + 'type' => 'css', 611 + 'requires' => 612 + array( 613 + ), 614 + 'disk' => '/rsrc/css/core/aphront-bars.css', 615 + ), 607 616 'aphront-calendar-view-css' => 608 617 array( 609 618 'uri' => '/res/73061a31/rsrc/css/aphront/calendar-view.css',
+8
src/__phutil_library_map__.php
··· 17 17 'AphrontAjaxResponse' => 'aphront/response/AphrontAjaxResponse.php', 18 18 'AphrontApplicationConfiguration' => 'aphront/configuration/AphrontApplicationConfiguration.php', 19 19 'AphrontAttachedFileView' => 'view/control/AphrontAttachedFileView.php', 20 + 'AphrontBarView' => 'view/widget/bars/AphrontBarView.php', 20 21 'AphrontCSRFException' => 'aphront/exception/AphrontCSRFException.php', 21 22 'AphrontCalendarEventView' => 'applications/calendar/view/AphrontCalendarEventView.php', 22 23 'AphrontCalendarMonthView' => 'applications/calendar/view/AphrontCalendarMonthView.php', ··· 53 54 'AphrontFormToggleButtonsControl' => 'view/form/control/AphrontFormToggleButtonsControl.php', 54 55 'AphrontFormTokenizerControl' => 'view/form/control/AphrontFormTokenizerControl.php', 55 56 'AphrontFormView' => 'view/form/AphrontFormView.php', 57 + 'AphrontGlyphBarView' => 'view/widget/bars/AphrontGlyphBarView.php', 56 58 'AphrontHTMLResponse' => 'aphront/response/AphrontHTMLResponse.php', 57 59 'AphrontHTTPSink' => 'aphront/sink/AphrontHTTPSink.php', 58 60 'AphrontHTTPSinkTestCase' => 'aphront/sink/__tests__/AphrontHTTPSinkTestCase.php', ··· 71 73 'AphrontPagerView' => 'view/control/AphrontPagerView.php', 72 74 'AphrontPanelView' => 'view/layout/AphrontPanelView.php', 73 75 'AphrontPlainTextResponse' => 'aphront/response/AphrontPlainTextResponse.php', 76 + 'AphrontProgressBarView' => 'view/widget/bars/AphrontProgressBarView.php', 74 77 'AphrontProxyResponse' => 'aphront/response/AphrontProxyResponse.php', 75 78 'AphrontRedirectException' => 'aphront/exception/AphrontRedirectException.php', 76 79 'AphrontRedirectResponse' => 'aphront/response/AphrontRedirectResponse.php', ··· 638 641 'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php', 639 642 'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/PhabricatorAllCapsTranslation.php', 640 643 'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php', 644 + 'PhabricatorAphrontBarExample' => 'applications/uiexample/examples/PhabricatorAphrontBarExample.php', 641 645 'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php', 642 646 'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php', 643 647 'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php', ··· 1570 1574 'Aphront404Response' => 'AphrontHTMLResponse', 1571 1575 'AphrontAjaxResponse' => 'AphrontResponse', 1572 1576 'AphrontAttachedFileView' => 'AphrontView', 1577 + 'AphrontBarView' => 'AphrontView', 1573 1578 'AphrontCSRFException' => 'AphrontException', 1574 1579 'AphrontCalendarEventView' => 'AphrontView', 1575 1580 'AphrontCalendarMonthView' => 'AphrontView', ··· 1606 1611 'AphrontFormToggleButtonsControl' => 'AphrontFormControl', 1607 1612 'AphrontFormTokenizerControl' => 'AphrontFormControl', 1608 1613 'AphrontFormView' => 'AphrontView', 1614 + 'AphrontGlyphBarView' => 'AphrontBarView', 1609 1615 'AphrontHTMLResponse' => 'AphrontResponse', 1610 1616 'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase', 1611 1617 'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase', ··· 1623 1629 'AphrontPagerView' => 'AphrontView', 1624 1630 'AphrontPanelView' => 'AphrontView', 1625 1631 'AphrontPlainTextResponse' => 'AphrontResponse', 1632 + 'AphrontProgressBarView' => 'AphrontBarView', 1626 1633 'AphrontProxyResponse' => 'AphrontResponse', 1627 1634 'AphrontRedirectException' => 'AphrontException', 1628 1635 'AphrontRedirectResponse' => 'AphrontResponse', ··· 2134 2141 'PhabricatorActionView' => 'AphrontView', 2135 2142 'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation', 2136 2143 'PhabricatorAnchorView' => 'AphrontView', 2144 + 'PhabricatorAphrontBarExample' => 'PhabricatorUIExample', 2137 2145 'PhabricatorApplicationApplications' => 'PhabricatorApplication', 2138 2146 'PhabricatorApplicationAudit' => 'PhabricatorApplication', 2139 2147 'PhabricatorApplicationAuth' => 'PhabricatorApplication',
+75
src/applications/uiexample/examples/PhabricatorAphrontBarExample.php
··· 1 + <?php 2 + 3 + final class PhabricatorAphrontBarExample extends PhabricatorUIExample { 4 + 5 + public function getName() { 6 + return "Bars"; 7 + } 8 + 9 + public function getDescription() { 10 + return 'Like fractions, but more horizontal.'; 11 + } 12 + 13 + public function renderExample() { 14 + $out = ''; 15 + $out .= $this->renderTestThings('AphrontProgressBarView', 13, 10); 16 + $out .= $this->renderTestThings('AphrontGlyphBarView', 13, 10); 17 + $out .= $this->renderWeirdOrderGlyphBars(); 18 + $out .= $this->renderAsciiStarBar(); 19 + return phutil_safe_html($out); 20 + } 21 + 22 + private function wrap($title, $thing) { 23 + return id(new AphrontPanelView()) 24 + ->setHeader($title) 25 + ->appendChild($thing) 26 + ->render(); 27 + } 28 + 29 + private function renderTestThings($class, $max, $incr) { 30 + $bars = array(); 31 + for ($ii = 0; $ii <= $max; $ii++) { 32 + $bars[] = newv($class, array()) 33 + ->setValue($ii * $incr) 34 + ->setMax($max * $incr) 35 + ->setCaption("{$ii} outta {$max} ain't bad!"); 36 + } 37 + return $this->wrap( 38 + "Test {$class}", 39 + phutil_implode_html('', mpull($bars, 'render'))); 40 + } 41 + 42 + private function renderWeirdOrderGlyphBars() { 43 + $views = array(); 44 + $indices = array(1, 3, 7, 4, 2, 8, 9, 5, 10, 6); 45 + $max = count($indices); 46 + foreach ($indices as $index) { 47 + $views[] = id(new AphrontGlyphBarView()) 48 + ->setValue($index) 49 + ->setMax($max) 50 + ->setNumGlyphs(5) 51 + ->setCaption("Lol score is {$index}/{$max}") 52 + ->setGlyph(hsprintf('%s', 'LOL!')) 53 + ->setBackgroundGlyph(hsprintf('%s', '____')) 54 + ->render(); 55 + $views[] = hsprintf('<div style="clear:both;"></div>'); 56 + } 57 + 58 + return $this->wrap( 59 + "Glyph bars in weird order", 60 + phutil_implode_html('', $views)); 61 + } 62 + 63 + private function renderAsciiStarBar() { 64 + return $this->wrap( 65 + "Ascii star glyph bar", 66 + id(new AphrontGlyphBarView()) 67 + ->setValue(50) 68 + ->setMax(100) 69 + ->setCaption('Glyphs!') 70 + ->setNumGlyphs(10) 71 + ->setGlyph(hsprintf('%s', '*')) 72 + ->render()); 73 + } 74 + 75 + }
+63
src/view/widget/bars/AphrontBarView.php
··· 1 + <?php 2 + 3 + abstract class AphrontBarView extends AphrontView { 4 + 5 + private $color; 6 + private $caption = ''; 7 + 8 + const COLOR_DEFAULT = 'default'; 9 + const COLOR_WARNING = 'warning'; 10 + const COLOR_DANGER = 'danger'; 11 + 12 + const COLOR_AUTO_BADNESS = 'auto_badness'; // more = bad! :( 13 + const COLOR_AUTO_GOODNESS = 'auto_goodness'; // more = good! :) 14 + 15 + const THRESHOLD_DANGER = 0.85; 16 + const THRESHOLD_WARNING = 0.75; 17 + 18 + abstract protected function getRatio(); 19 + 20 + abstract protected function getDefaultColor(); 21 + 22 + final public function setColor($color) { 23 + $this->color = $color; 24 + return $this; 25 + } 26 + 27 + final public function setCaption($text) { 28 + $this->caption = $text; 29 + return $this; 30 + } 31 + 32 + final protected function getColor() { 33 + $color = $this->color; 34 + if (!$color) { 35 + $color = $this->getDefaultColor(); 36 + } 37 + 38 + switch ($color) { 39 + case self::COLOR_DEFAULT: 40 + case self::COLOR_WARNING: 41 + case self::COLOR_DANGER: 42 + return $color; 43 + } 44 + 45 + $ratio = $this->getRatio(); 46 + if ($color === self::COLOR_AUTO_GOODNESS) { 47 + $ratio = 1.0 - $ratio; 48 + } 49 + 50 + if ($ratio >= self::THRESHOLD_DANGER) { 51 + return self::COLOR_DANGER; 52 + } else if ($ratio >= self::THRESHOLD_WARNING) { 53 + return self::COLOR_WARNING; 54 + } else { 55 + return self::COLOR_DEFAULT; 56 + } 57 + } 58 + 59 + final protected function getCaption() { 60 + return $this->caption; 61 + } 62 + 63 + }
+102
src/view/widget/bars/AphrontGlyphBarView.php
··· 1 + <?php 2 + 3 + final class AphrontGlyphBarView extends AphrontBarView { 4 + 5 + const BLACK_STAR = "\xE2\x98\x85"; 6 + const WHITE_STAR = "\xE2\x98\x86"; 7 + 8 + private $value; 9 + private $max = 100; 10 + private $numGlyphs = 5; 11 + private $fgGlyph; 12 + private $bgGlyph; 13 + 14 + public function getDefaultColor() { 15 + return AphrontBarView::COLOR_AUTO_GOODNESS; 16 + } 17 + 18 + public function setValue($value) { 19 + $this->value = $value; 20 + return $this; 21 + } 22 + 23 + public function setMax($max) { 24 + $this->max = $max; 25 + return $this; 26 + } 27 + 28 + public function setNumGlyphs($nn) { 29 + $this->numGlyphs = $nn; 30 + return $this; 31 + } 32 + 33 + public function setGlyph(PhutilSafeHTML $fg_glyph) { 34 + $this->fgGlyph = $fg_glyph; 35 + return $this; 36 + } 37 + 38 + public function setBackgroundGlyph(PhutilSafeHTML $bg_glyph) { 39 + $this->bgGlyph = $bg_glyph; 40 + return $this; 41 + } 42 + 43 + protected function getRatio() { 44 + return min($this->value, $this->max) / $this->max; 45 + } 46 + 47 + public function render() { 48 + require_celerity_resource('aphront-bars'); 49 + $ratio = $this->getRatio(); 50 + $percentage = 100 * $ratio; 51 + 52 + $is_star = false; 53 + if ($this->fgGlyph) { 54 + $fg_glyph = $this->fgGlyph; 55 + if ($this->bgGlyph) { 56 + $bg_glyph = $this->bgGlyph; 57 + } else { 58 + $bg_glyph = $fg_glyph; 59 + } 60 + } else { 61 + $is_star = true; 62 + $fg_glyph = self::BLACK_STAR; 63 + $bg_glyph = self::WHITE_STAR; 64 + } 65 + 66 + $fg_glyphs = array_fill(0, $this->numGlyphs, $fg_glyph); 67 + $bg_glyphs = array_fill(0, $this->numGlyphs, $bg_glyph); 68 + 69 + $color = $this->getColor(); 70 + 71 + return phutil_tag( 72 + 'div', 73 + array( 74 + 'class' => "aphront-bar glyph color-{$color}", 75 + ), 76 + array( 77 + phutil_tag( 78 + 'div', 79 + array( 80 + 'class' => 'glyphs'.($is_star ? ' starstar' : ''), 81 + ), 82 + array( 83 + phutil_tag( 84 + 'div', 85 + array( 86 + 'class' => 'fg', 87 + 'style' => "width: {$percentage}%;", 88 + ), 89 + $fg_glyphs), 90 + phutil_tag( 91 + 'div', 92 + array(), 93 + $bg_glyphs) 94 + )), 95 + phutil_tag( 96 + 'div', 97 + array('class' => 'caption'), 98 + $this->getCaption()) 99 + )); 100 + } 101 + 102 + }
+60
src/view/widget/bars/AphrontProgressBarView.php
··· 1 + <?php 2 + 3 + final class AphrontProgressBarView extends AphrontBarView { 4 + 5 + const WIDTH = 100; 6 + 7 + private $value; 8 + private $max = 100; 9 + private $alt = ''; 10 + 11 + public function getDefaultColor() { 12 + return AphrontBarView::COLOR_AUTO_BADNESS; 13 + } 14 + 15 + public function setValue($value) { 16 + $this->value = $value; 17 + return $this; 18 + } 19 + 20 + public function setMax($max) { 21 + $this->max = $max; 22 + return $this; 23 + } 24 + 25 + public function setAlt($text) { 26 + $this->alt = $text; 27 + return $this; 28 + } 29 + 30 + protected function getRatio() { 31 + return min($this->value, $this->max) / $this->max; 32 + } 33 + 34 + public function render() { 35 + require_celerity_resource('aphront-bars'); 36 + $ratio = $this->getRatio(); 37 + $width = self::WIDTH * $ratio; 38 + 39 + $color = $this->getColor(); 40 + 41 + return phutil_tag( 42 + 'div', 43 + array( 44 + 'class' => "aphront-bar progress color-{$color}", 45 + ), 46 + array( 47 + phutil_tag( 48 + 'div', 49 + array('title' => $this->alt), 50 + phutil_tag( 51 + 'div', 52 + array('style' => hsprintf("width: %dpx;", $width)), 53 + '')), 54 + phutil_tag( 55 + 'span', 56 + array(), 57 + $this->getCaption()))); 58 + } 59 + 60 + }
+100
webroot/rsrc/css/core/aphront-bars.css
··· 1 + /** 2 + * @provides aphront-bars 3 + */ 4 + 5 + /** 6 + * Progress bars 7 + */ 8 + 9 + div.aphront-bar.progress { 10 + border: 0px; 11 + } 12 + 13 + div.aphront-bar.progress div { 14 + width: 100px; 15 + border: 1px solid; 16 + border-top-color: #A4A4A4; 17 + border-right-color: #BBB; 18 + border-bottom-color: #D5D5D5; 19 + border-left-color: #BBB; 20 + background: white; 21 + float: left; 22 + margin-right: 1em; 23 + } 24 + 25 + div.aphront-bar.progress div div { 26 + height: 10px; 27 + } 28 + 29 + div.aphront-bar.progress span { 30 + color: #555; 31 + } 32 + 33 + 34 + /** 35 + * Glyph bars 36 + */ 37 + 38 + div.aphront-bar.glyph { 39 + clear: both; 40 + } 41 + 42 + div.aphront-bar.glyph div.glyphs { 43 + padding: 0; 44 + margin: 0; 45 + 46 + float: left; 47 + position: relative; 48 + color: #aaa; 49 + font-family: monospace; 50 + height: 1.3em; 51 + } 52 + 53 + div.aphront-bar.glyph div.glyphs.starstar { 54 + /* http://daringfireball.net/2005/08/star_star */ 55 + font-family: "Hiragino Kaku Gothic Pro", "Osaka", "Zapf Dingbats"; 56 + } 57 + 58 + div.aphront-bar.glyph div.glyphs div.fg { 59 + padding: 0; 60 + margin: 0; 61 + float: left; 62 + position: absolute; 63 + overflow: hidden; 64 + } 65 + 66 + div.aphront-bar.glyph div.caption { 67 + padding: 0; 68 + margin: 0; 69 + float: left; 70 + margin-left: 1.5em; 71 + color: #666; 72 + } 73 + 74 + 75 + /** 76 + * Common color classes 77 + */ 78 + div.aphront-bar.progress.color-default div div { 79 + background: #6D84B4; 80 + } 81 + 82 + div.aphront-bar.glyph.color-default div.glyphs div.fg { 83 + color: #6D84B4; 84 + } 85 + 86 + div.aphront-bar.progress.color-warning div div { 87 + background: #FFCC5F; 88 + } 89 + 90 + div.aphront-bar.glyph.color-warning div.glyphs div.fg { 91 + color: #FFCC5F; 92 + } 93 + 94 + div.aphront-bar.progress.color-danger div div { 95 + background: #FF6E6E; 96 + } 97 + 98 + div.aphront-bar.glyph.color-danger div.glyphs div.fg { 99 + color: #FF6E6E; 100 + }