Skip to content

Commit

Permalink
[graf] Additional options for TPad::PlaceBox() method
Browse files Browse the repository at this point in the history
This is needed so that the new RooBrowser doesn't need to access the
private collision grid of the TPad. These additional options allow the
placement of the box with choice of priority over directions as well as
option to place within the margins of the pad.

Wanted for 6.28 release too!
  • Loading branch information
will-cern authored and guitargeek committed Jan 25, 2023
1 parent bce142c commit 77d8ab2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 18 deletions.
2 changes: 1 addition & 1 deletion core/base/inc/TVirtualPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ class TVirtualPad : public TObject, public TAttLine, public TAttFill,
virtual Int_t IncrementPaletteColor(Int_t i, TString opt) = 0;
virtual Int_t NextPaletteColor() = 0;

virtual Bool_t PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb) = 0;
virtual Bool_t PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb, Option_t* opt = "lb") = 0;

virtual TObject *CreateToolTip(const TBox *b, const char *text, Long_t delayms) = 0;
virtual void DeleteToolTip(TObject *tip) = 0;
Expand Down
2 changes: 1 addition & 1 deletion graf2d/gpad/inc/TPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ friend class TWebCanvas;
Int_t NextPaletteColor() override;

void DrawCollideGrid();
Bool_t PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb) override;
Bool_t PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb, Option_t* option = "lb") override;

virtual void x3d(Option_t *type=""); // Depreciated

Expand Down
77 changes: 61 additions & 16 deletions graf2d/gpad/src/TPad.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <locale>
#include <memory>

#include "TROOT.h"
Expand Down Expand Up @@ -3067,33 +3068,77 @@ Bool_t TPad::Collide(Int_t i, Int_t j, Int_t w, Int_t h)
///
/// \return `true` if the box could be placed, `false` if not.
///
/// \param[in] o pointer to the box to be placed
/// \param[in] w box width to be placed
/// \param[in] h box height to be placed
/// \param[out] xl x position of the bottom left corner of the placed box
/// \param[out] yb y position of the bottom left corner of the placed box
/// \param[in] o pointer to the box to be placed
/// \param[in] w box width to be placed
/// \param[in] h box height to be placed
/// \param[out] xl x position of the bottom left corner of the placed box
/// \param[out] yb y position of the bottom left corner of the placed box
/// \param[in] option l=left, r=right, t=top, b=bottom, w=within margins. Order determines
/// priority for placement. Default is "lb" (prioritises horizontal over vertical)

Bool_t TPad::PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb)
Bool_t TPad::PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb, Option_t* option)
{
FillCollideGrid(o);

Int_t iw = (int)(fCGnx*w);
Int_t ih = (int)(fCGny*h);

Int_t nxmax = fCGnx-iw-1;
Int_t nymax = fCGny-ih-1;
Int_t nxbeg = 0;
Int_t nybeg = 0;
Int_t nxend = fCGnx-iw-1;
Int_t nyend = fCGny-ih-1;
Int_t dx = 1;
Int_t dy = 1;

bool isFirstVertical = false;
bool isFirstHorizontal = false;

for (std::size_t i = 0; option[i] != '\0'; ++i) {
char letter = std::tolower(option[i]);
if (letter == 'w') {
nxbeg += fCGnx*GetLeftMargin();
nybeg += fCGny*GetBottomMargin();
nxend -= fCGnx*GetRightMargin();
nyend -= fCGny*GetTopMargin();
} else if (letter == 't' || letter == 'b') {
isFirstVertical = !isFirstHorizontal;
// go from top to bottom instead of bottom to top
dy = letter == 't' ? -1 : 1;
} else if (letter == 'l' || letter == 'r') {
isFirstHorizontal = !isFirstVertical;
// go from right to left instead of left to right
dx = letter == 'r' ? -1 : 1;
}
}

if(dx < 0) std::swap(nxbeg, nxend);
if(dy < 0) std::swap(nybeg, nyend);

auto attemptPlacement = [&](Int_t i, Int_t j) {
if (Collide(i, j, iw, ih)) {
return false;
} else {
xl = (Double_t)(i) / (Double_t)(fCGnx);
yb = (Double_t)(j) / (Double_t)(fCGny);
return true;
}
};

for (Int_t i = 0; i<nxmax; i++) {
for (Int_t j = 0; j<=nymax; j++) {
if (Collide(i,j,iw,ih)) {
continue;
} else {
xl = (Double_t)(i)/(Double_t)(fCGnx);
yb = (Double_t)(j)/(Double_t)(fCGny);
return kTRUE;
if(!isFirstVertical) {
for (Int_t i = nxbeg; i != nxend; i += dx) {
for (Int_t j = nybeg; j != nyend; j += dy) {
if (attemptPlacement(i, j)) return true;
}
}
} else {
// prioritizing vertical over horizontal
for (Int_t j = nybeg; j != nyend; j += dy) {
for (Int_t i = nxbeg; i != nxend; i += dx) {
if (attemptPlacement(i, j)) return true;
}
}
}

return kFALSE;
}

Expand Down

0 comments on commit 77d8ab2

Please sign in to comment.