Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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