@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.

PHUIImageMask

Summary: Adds a PHUI class for display images on a center point, with or without a mask.

Test Plan:
I am bad a math, so like, check that for me please. I tested using Photoshop. Class may need tweaked depending how we store the inline-comment coords.

{F167829}

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: epriestley, Korvin

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

+283 -12
+5 -2
resources/celerity/map.php
··· 81 81 'rsrc/css/application/phame/phame.css' => '19ecc703', 82 82 'rsrc/css/application/pholio/pholio-edit.css' => '3ad9d1ee', 83 83 'rsrc/css/application/pholio/pholio-inline-comments.css' => '95004a57', 84 - 'rsrc/css/application/pholio/pholio.css' => '6f87390f', 84 + 'rsrc/css/application/pholio/pholio.css' => 'd0502625', 85 85 'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb', 86 86 'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad', 87 87 'rsrc/css/application/phriction/phriction-document-css.css' => '7d7f0071', ··· 131 131 'rsrc/css/phui/phui-form.css' => 'b78ec020', 132 132 'rsrc/css/phui/phui-header-view.css' => 'a2071a67', 133 133 'rsrc/css/phui/phui-icon.css' => 'd8526aa1', 134 + 'rsrc/css/phui/phui-image-mask.css' => '5f4a6d5d', 134 135 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 135 136 'rsrc/css/phui/phui-list.css' => '43ed2d93', 136 137 'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec', ··· 230 231 'rsrc/image/credit_cards.png' => '72b8ede8', 231 232 'rsrc/image/darkload.gif' => '1ffd3ec6', 232 233 'rsrc/image/divot.png' => '94dded62', 234 + 'rsrc/image/examples/hero.png' => '979a86ae', 233 235 'rsrc/image/grippy_texture.png' => 'aca81e2f', 234 236 'rsrc/image/icon/fatcow/arrow_branch.png' => '2537c01c', 235 237 'rsrc/image/icon/fatcow/arrow_merge.png' => '21b660e0', ··· 750 752 'phabricator-uiexample-reactor-sendproperties' => '551add57', 751 753 'phabricator-zindex-css' => 'efb673ac', 752 754 'phame-css' => '19ecc703', 753 - 'pholio-css' => '6f87390f', 755 + 'pholio-css' => 'd0502625', 754 756 'pholio-edit-css' => '3ad9d1ee', 755 757 'pholio-inline-comments-css' => '95004a57', 756 758 'phortune-credit-card-form' => '2290aeef', ··· 771 773 'phui-form-view-css' => 'ed856191', 772 774 'phui-header-view-css' => 'a2071a67', 773 775 'phui-icon-view-css' => 'd8526aa1', 776 + 'phui-image-mask-css' => '5f4a6d5d', 774 777 'phui-info-panel-css' => '27ea50a1', 775 778 'phui-list-view-css' => '43ed2d93', 776 779 'phui-object-box-css' => 'ce92d8ec',
+4
src/__phutil_library_map__.php
··· 1026 1026 'PHUIHeaderView' => 'view/phui/PHUIHeaderView.php', 1027 1027 'PHUIIconExample' => 'applications/uiexample/examples/PHUIIconExample.php', 1028 1028 'PHUIIconView' => 'view/phui/PHUIIconView.php', 1029 + 'PHUIImageMaskExample' => 'applications/uiexample/examples/PHUIImageMaskExample.php', 1030 + 'PHUIImageMaskView' => 'view/phui/PHUIImageMaskView.php', 1029 1031 'PHUIInfoPanelExample' => 'applications/uiexample/examples/PHUIInfoPanelExample.php', 1030 1032 'PHUIInfoPanelView' => 'view/phui/PHUIInfoPanelView.php', 1031 1033 'PHUIListExample' => 'applications/uiexample/examples/PHUIListExample.php', ··· 3793 3795 'PHUIHeaderView' => 'AphrontView', 3794 3796 'PHUIIconExample' => 'PhabricatorUIExample', 3795 3797 'PHUIIconView' => 'AphrontTagView', 3798 + 'PHUIImageMaskExample' => 'PhabricatorUIExample', 3799 + 'PHUIImageMaskView' => 'AphrontTagView', 3796 3800 'PHUIInfoPanelExample' => 'PhabricatorUIExample', 3797 3801 'PHUIInfoPanelView' => 'AphrontView', 3798 3802 'PHUIListExample' => 'PhabricatorUIExample',
+1
src/applications/pholio/controller/PholioMockViewController.php
··· 100 100 101 101 $xaction_view = id(new PholioTransactionView()) 102 102 ->setUser($this->getRequest()->getUser()) 103 + ->setMock($mock) 103 104 ->setObjectPHID($mock->getPHID()) 104 105 ->setTransactions($xactions) 105 106 ->setMarkupEngine($engine);
+35 -5
src/applications/pholio/view/PholioTransactionView.php
··· 6 6 final class PholioTransactionView 7 7 extends PhabricatorApplicationTransactionView { 8 8 9 + private $mock; 10 + 11 + public function setMock($mock) { 12 + $this->mock = $mock; 13 + return $this; 14 + } 15 + 16 + public function getMock() { 17 + return $this->mock; 18 + } 19 + 9 20 protected function shouldGroupTransactions( 10 21 PhabricatorApplicationTransaction $u, 11 22 PhabricatorApplicationTransaction $v) { ··· 87 98 88 99 private function renderInlineContent(PholioTransaction $inline) { 89 100 $comment = $inline->getComment(); 101 + $mock = $this->getMock(); 102 + $images = $mock->getAllImages(); 103 + $images = mpull($images, null, 'getID'); 104 + 105 + $image = idx($images, $comment->getImageID()); 106 + if (!$image) { 107 + throw new Exception('No image attached!'); 108 + } 109 + 110 + $file = $image->getFile(); 111 + if (!$file->isViewableImage()) { 112 + throw new Exception('File is not viewable.'); 113 + } 114 + 115 + $image_uri = $file->getBestURI(); 90 116 91 - $thumb = phutil_tag( 92 - 'img', 93 - array( 94 - 'src' => '/pholio/inline/thumb/'.$comment->getImageID(), 95 - )); 117 + $thumb = id(new PHUIImageMaskView()) 118 + ->addClass('mrl') 119 + ->setImage($image_uri) 120 + ->setDisplayHeight(100) 121 + ->setDisplayWidth(200) 122 + ->withMask(true) 123 + ->centerViewOnPoint( 124 + $comment->getX(), $comment->getY(), 125 + $comment->getHeight(), $comment->getWidth()); 96 126 97 127 $link = phutil_tag( 98 128 'a',
+1 -1
src/applications/uiexample/examples/PHUIBoxExample.php
··· 114 114 $head4, 115 115 $obj4, 116 116 )); 117 - } 117 + } 118 118 }
+88
src/applications/uiexample/examples/PHUIImageMaskExample.php
··· 1 + <?php 2 + 3 + final class PHUIImageMaskExample extends PhabricatorUIExample { 4 + 5 + public function getName() { 6 + return 'Image Masks'; 7 + } 8 + 9 + public function getDescription() { 10 + return 'Display images with crops.'; 11 + } 12 + 13 + public function renderExample() { 14 + 15 + $image = celerity_get_resource_uri('/rsrc/image/examples/hero.png'); 16 + $display_height = 100; 17 + $display_width = 200; 18 + 19 + $mask1 = id(new PHUIImageMaskView()) 20 + ->addClass('ml') 21 + ->setImage($image) 22 + ->setDisplayHeight($display_height) 23 + ->setDisplayWidth($display_width) 24 + ->centerViewOnPoint(265, 185, 30, 140); 25 + 26 + $mask2 = id(new PHUIImageMaskView()) 27 + ->addClass('ml') 28 + ->setImage($image) 29 + ->setDisplayHeight($display_height) 30 + ->setDisplayWidth($display_width) 31 + ->centerViewOnPoint(18, 18, 40, 80); 32 + 33 + $mask3 = id(new PHUIImageMaskView()) 34 + ->addClass('ml') 35 + ->setImage($image) 36 + ->setDisplayHeight($display_height) 37 + ->setDisplayWidth($display_width) 38 + ->centerViewOnPoint(265, 185, 30, 140) 39 + ->withMask(true); 40 + 41 + $mask4 = id(new PHUIImageMaskView()) 42 + ->addClass('ml') 43 + ->setImage($image) 44 + ->setDisplayHeight($display_height) 45 + ->setDisplayWidth($display_width) 46 + ->centerViewOnPoint(18, 18, 40, 80) 47 + ->withMask(true); 48 + 49 + $mask5 = id(new PHUIImageMaskView()) 50 + ->addClass('ml') 51 + ->setImage($image) 52 + ->setDisplayHeight($display_height) 53 + ->setDisplayWidth($display_width) 54 + ->centerViewOnPoint(254, 272, 60, 240) 55 + ->withMask(true); 56 + 57 + $box1 = id(new PHUIObjectBoxView()) 58 + ->setHeaderText(pht('Center is in the middle')) 59 + ->appendChild($mask1); 60 + 61 + $box2 = id(new PHUIObjectBoxView()) 62 + ->setHeaderText(pht('Center is on an edge')) 63 + ->appendChild($mask2); 64 + 65 + $box3 = id(new PHUIObjectBoxView()) 66 + ->setHeaderText(pht('Center Masked')) 67 + ->appendChild($mask3); 68 + 69 + $box4 = id(new PHUIObjectBoxView()) 70 + ->setHeaderText(pht('Edge Masked')) 71 + ->appendChild($mask4); 72 + 73 + $box5 = id(new PHUIObjectBoxView()) 74 + ->setHeaderText(pht('Wide Masked')) 75 + ->appendChild($mask5); 76 + 77 + return phutil_tag( 78 + 'div', 79 + array(), 80 + array( 81 + $box1, 82 + $box2, 83 + $box3, 84 + $box4, 85 + $box5 86 + )); 87 + } 88 + }
+116
src/view/phui/PHUIImageMaskView.php
··· 1 + <?php 2 + 3 + final class PHUIImageMaskView extends AphrontTagView { 4 + 5 + private $image; 6 + private $withMask; 7 + 8 + private $displayWidth; 9 + private $displayHeight; 10 + 11 + private $centerX; 12 + private $centerY; 13 + private $maskH; 14 + private $maskW; 15 + 16 + public function setImage($image) { 17 + $this->image = $image; 18 + return $this; 19 + } 20 + 21 + public function setDisplayWidth($width) { 22 + $this->displayWidth = $width; 23 + return $this; 24 + } 25 + 26 + public function setDisplayHeight($height) { 27 + $this->displayHeight = $height; 28 + return $this; 29 + } 30 + 31 + public function centerViewOnPoint($x, $y, $h, $w) { 32 + $this->centerX = $x; 33 + $this->centerY = $y; 34 + $this->maskH = $h; 35 + $this->maskW = $w; 36 + return $this; 37 + } 38 + 39 + public function withMask($mask) { 40 + $this->withMask = $mask; 41 + return $this; 42 + } 43 + 44 + public function getTagName() { 45 + return 'div'; 46 + } 47 + 48 + public function getTagAttributes() { 49 + require_celerity_resource('phui-image-mask-css'); 50 + 51 + $classes = array(); 52 + $classes[] = 'phui-image-mask'; 53 + 54 + $styles = array(); 55 + $styles[] = 'height: '.$this->displayHeight.'px;'; 56 + $styles[] = 'width: '.$this->displayWidth.'px;'; 57 + 58 + return array( 59 + 'class' => implode(' ', $classes), 60 + 'styles' => implode(' ', $styles), 61 + ); 62 + 63 + } 64 + 65 + public function getTagContent() { 66 + 67 + /* Center it in the middle of the selected area */ 68 + $center_x = round($this->centerX + ($this->maskW / 2)); 69 + $center_y = round($this->centerY + ($this->maskH / 2)); 70 + $center_x = round($center_x - ($this->displayWidth / 2)); 71 + $center_y = round($center_y - ($this->displayHeight / 2)); 72 + 73 + $center_x = -$center_x; 74 + $center_y = -$center_y; 75 + 76 + $classes = array(); 77 + $classes[] = 'phui-image-mask-image'; 78 + 79 + $styles = array(); 80 + $styles[] = 'height: '.$this->displayHeight.'px;'; 81 + $styles[] = 'width: '.$this->displayWidth.'px;'; 82 + $styles[] = 'background-image: url('.$this->image.');'; 83 + $styles[] = 'background-position: '.$center_x.'px '.$center_y.'px;'; 84 + 85 + $mask = null; 86 + if ($this->withMask) { 87 + /* The mask is a 300px border around a transparent box. 88 + so we do the math here to position the box correctly. */ 89 + $border = 300; 90 + $left = round((($this->displayWidth - $this->maskW) / 2) - $border); 91 + $top = round((($this->displayHeight - $this->maskH) / 2) - $border); 92 + 93 + $mstyles = array(); 94 + $mstyles[] = 'left: '.$left.'px;'; 95 + $mstyles[] = 'top: '.$top.'px;'; 96 + $mstyles[] = 'height: '.$this->maskH.'px;'; 97 + $mstyles[] = 'width: '.$this->maskW.'px;'; 98 + 99 + $mask = phutil_tag( 100 + 'span', 101 + array( 102 + 'class' => 'phui-image-mask-mask', 103 + 'style' => implode(' ', $mstyles), 104 + ), 105 + null); 106 + } 107 + 108 + return phutil_tag( 109 + 'div', 110 + array( 111 + 'class' => implode(' ', $classes), 112 + 'style' => implode(' ', $styles), 113 + ), 114 + $mask); 115 + } 116 + }
+10 -4
webroot/rsrc/css/application/pholio/pholio.css
··· 99 99 100 100 .pholio-transaction-inline-comment .transaction-comment { 101 101 display: table-cell; 102 - vertical-align: middle; 102 + vertical-align: top; 103 103 padding-left: 8px; 104 + padding-top: 4px; 104 105 } 105 106 106 107 .pholio-mock-reticle { 107 108 position: absolute; 108 109 display: none; 109 110 box-sizing: border-box; 111 + border: 4px solid transparent; 110 112 } 111 113 112 114 .pholio-mock-reticle-selection { 113 - background-color: rgba(255, 255, 255, 0.50); 114 - border: 1px dashed #000; 115 + border: 1px solid rgba(0,0,0,.5); 116 + box-shadow: 0 0 0 4px rgba(255,255,255,.5); 115 117 } 116 118 117 119 .pholio-mock-reticle-draft { ··· 130 132 131 133 .pholio-mock-reticle-draft:hover, 132 134 .pholio-mock-reticle-final:hover { 133 - background-color: rgba(255, 255, 255, 0.50); 135 + border: 1px solid rgba(0,0,0,.5); 136 + box-shadow: 0 0 0 4px rgba(255,255,255,.5); 134 137 cursor: pointer; 138 + color: transparent; 139 + text-shadow: none; 140 + -webkit-text-stroke: 0; 135 141 } 136 142 137 143 .device-desktop .mock-has-cursor .pholio-mock-reticle {
+23
webroot/rsrc/css/phui/phui-image-mask.css
··· 1 + /** 2 + * @provides phui-image-mask-css 3 + */ 4 + 5 + 6 + .phui-image-mask { 7 + background: url('/rsrc/image/checker_lighter.png'); 8 + display: inline-block; 9 + border: 1px solid {$lightblueborder}; 10 + padding: 4px; 11 + position: relative; 12 + overflow: hidden; 13 + } 14 + 15 + .phui-image-mask-image { 16 + background-repeat: no-repeat; 17 + } 18 + 19 + .phui-image-mask-mask { 20 + border: 300px solid rgba(0, 0, 0, 0.5); 21 + background-clip: content-box; 22 + position: absolute; 23 + }
webroot/rsrc/image/examples/hero.png

This is a binary file and will not be displayed.